Panel AA layout manageris aJava object associated with a particular component, almostalwaysa b ackgroun dcomponent, The layout manager controls the components containedwithin the compone
Trang 1controller events
import javax sound.Ulidi *;
public class MiniMuaicPlayer2
public static void main(String[] args) (
~n£MusicPlayer2 mini : new MiniMusicPlayar2();
mini-goO ;
Sequence seq = new Sequence (Sequence PPQ, 4) ;
Track track =s&q.createTrack();
(~ -I:h~ CO'I'tr
ol1ty-L -~T'nL~"ty\tha"cilty "'~ ~c:t.,i e'fo/t.~d ~e
.l \" l _ i,,~-tat~. 1 I "r.(
~ ,e"" 'S""' ·. t.KIl tothetD",,,,a,,a- ,
e ,e"t" '/ole'n F'"
public MidiEvent makeEvent (int cOJDd, int chan, int one, int two, int tick) (
MidiEvent event null;
try (
ShortMassage a ~ new ShortNessage():
a.BetM&ssage(comd, chan, on8, two);
evant = new Micli.Event(a, tick);
Trang 2Version Ihree: drawing graphics in thtte with the tltusic
This final version builds on version two by adding the GUI parts We build a
frame, add a drawing panel to it, and each time we get an event,we draw a
new rectangle and repaint the screen The only other change from version
two is that the notes play randomlyas opposed to simply moving up the
scale
The most important change to the code (besides building a simple GUI)
isthat we make the drawing panel implement the ControllerEventListener
rather than the program itself So when the drawing panel (an inner class)
gets the event, it knows how to take care of itself by drawing the rectangle
Complete code for this version is on the next page
The drawing panel inner class:
I' a list.eYltV'
C Tht clV'a ,iYl~yaYlt 'sclass MyDrawPanel extends JPanel implements ControllerEventListener
boolean msg =false; t r'~Lsd: a.fla~ to.faist,a",d ,~'" Stt i
W 1;1"\OtOI'Ily wht'"Wt g~ta", ~ve",t
public void controlChange(ShortMessage event) (
msg =true; f
repaint () ;r - We~ota",~vtnt, sow~setthe flagto
tl"\Ot and tall l"~pai"'tO
Wehav~tol.lS~ a fla~ b~tal.lS~OT»ER th ·
a",dw~ wanttoDai",iONL\/ h Lh Iln~sCllli~~~ t\"i~~~\" a\"tpainiO,
r T w tn1; ereSa OI'IvolJt\"Evtnt
g.setColor(new Color(r,gr,b»;
Tht I"est istod~ to ~t"'t\"aie
a\"andOllltolO\"and painta
Stllli-\"andolll \"tttan~lt
g.fillRect(x,y,ht, width);
} II close if
you are her e ~ 391
Trang 3public static void main(String[] args) (
Min1MusicPlayer3 mini = new Min1MusicPlayer3();
sequencer.addControllerEventListener(ml, new int[] {127»;
Sequence seq = new Sequence(Sequence.PPQ, 4);
Track track = seq.createTrack() ;
Trang 4Who am IP
A bunch of Java hot -shots, in full costume, are playIng the party game-Who
am Ir They give you a clue , and youtryto guess who they are, based on what they say Assume they always tell the truth about themselves If they happen to say something that could be true for more than one guy, then write down allioswhom that sentence applies Fill In the blanks next to the sentence with the names of oneor more attendees
Tonight'sattendees:
Any of the charming personalities from this chapter just might show upl
I got the whole GUI, In my hands
Every event type has one of these
The listener's key method
This method gives JFrame its size
You add codeto this method but never call It
When the user actually does something, It's an _ _
Most of these are event sources
I carry data back to the listener
An addXxxLlstener( ) method says an object is an _ _
How a listener signs up
The method where all the graphics code goes
I'm typically bound to an Instance
The 'g' In (Graphics g), Is really of class
The method that gets palntComponent( ) roiling
The package where most of the Swingers reside
394 chapter 12
Trang 5public static void main(String II args)
InnerButtan qui =new InnerButton();
guLgo () ;
}
public void gal) {
frame = new JFrame();
class BListener extends ActionListener {
public void actionPerformed(ActionEvent e) {
compiler and detertrtine whether this file
will cOl1Ipile If it won't co11IPile, haw
would you t'xx it, and if it does compile, what would it do?
Trang 6public static void main(String [I args)InnerButton qui ~ new InnerButton():
qui-go(I:
Who am I?
I got the whole GUI inmyhands JFrame
Every event type has one of these listener interface
The listener's key method actionPerlormed( )
This method givesJFrame its size setSize( )
You add code to this method but
never call it paintCompone.nt( )
a button that toggles between
AandB whenyou click it
When the user actually does
something, it's an _ _ event
Most of these are event sources swing components
I carry data back to the listener; event object
An addXxxListener( ) method
sa ys an obj ect is an _ event source
How a listener signs up addActionListe.ner( )
The method where all the
graphics code goes paintComponent( )
public void go(l {frame =new JFrame();
frame.setDefaultCloseOperation(
JPrame EXIT_ON_CLOSE) ;
The addActionListener( ) method takes a class that implements theActionl.is-
tener interface
b =new JButton("A")j
b addActionLiBtener( lIiWJLlstettar( I )l
I' m typically bound to an instance inner class
ActionListener is an interface interlacesareimplemented, notextended
The ' s'in (Graphics g) is
really of this class.
The method that gets
Trang 8Work on Your
Swing
Swing is easy. Unless you actuallycarewhere things end up on the screen Swing code
lookseasy,but then you compile it, run it, look at it and think- 'h~y,that'snot supposed to go
there."The thing that makes iteasytocodeIs the thing that makes Ithardtocanuo/-the
layout Manager Layout Manager objects control the size and location of the widgets in a Java GUJ They do a ton of work on your behalf, but you won't always like the results You want two buttons to be the same size,but they aren't You want the text field to be three inches long, but It's nine Or one Andunderthe label instead ofnextto It But with a tittle work, you can get layout managers to submit to your will In th is chapter, we'll work on our Swing and in addition
to layout managers, we'll learn more about wIdgets We'll make them, display them (wherewe
choose), and use themIna program It's not looking 100 good for Suzy
th is is a n ew c h ap te r 399
Trang 9components and containers
The things you put in a CUI The things a usersees and interacts with.Text
fields,buttons, scrollablelists,radio buttons, etc.areall components.In
fact, theyall extend javax swing JComponent
COlMpo.,etds can be nested
In Swing, virtuallyallcomponents are capable of holding other
components In other words, you can siUkjust about anything into anything
else But most of the time, you'll add userinteractive components such as
buttons and lists intobackground components such as frames and panels.
Although it'spossible to put, say, a panel inside a button, that's pretty
weird, and won't win you any usability awards
With the exception ofJFrame,though, the distinction betweeninteractive
components and ba.ckground components is artificial AJPanel for
example,isusually used as a background for grouping other components,
but even aJPanel can be interactive Just as with other components, you
can register for the JPanel 's events including mouse clicks and keystrokes
A widget is teduucal.l y
a Swing Com~ent._
you can stick in a GUI extends !rom
javaLSWing.JComponent.
Four steps to making a GUI (review)
• Make a window (e JFrame)
JFrame frama "" n_ JFrame () ;
• Make a component (button,textfield, erc.)
JButton button - ne JButton("click meU
) ;
• Add the component to the frame
frame getContantPane () add(BordarLayout EAST • button);
• Display it (give it a size and make it visible)
Trang 10Panel A
A layout manageris aJava object associated
with a particular component, almostalwaysa
b ackgroun dcomponent, The layout manager
controls the components containedwithin the
component the layout manager is associated
with, In other words, ifa frame holds a panel,
and the panel holds a button,the panel's layout
manager controls the size and placement of
the button, while the frame's layout manager
controls the size and placement ofthe _IIIIII!IIII!!!II -~~ ,
panel The button on the other hand
doesn't need a layout manager because the
button isn't holding other components
Ifa panel holds five things even ifthose
five things each have their own layout
managers, the size and location of the five
thingsin the panel are all controlled by the
panel's layout manager.Ifthose five things,
intum,holdotherthings, thea those other
things are placed according to the layout
manager of the thing holding them
When we sayholdwe really mean addas in, a
oanel holdsa button because the buttonwas
addedto the panel using something like:
~Panel.add(button);
Layou t managers come in several flavors, and
each background component can have its own
yo u tmanager.Layout managers have their
wnpolicies to follow when building alayout,
For example, one layout manager might insist
thatall components in a panel must be the same
size,arranged inagrid,while another layout
manager might let each component chooseits
own size, butSlack them vertically.Here's an
exampleof nested layouts:
JPanel panelA =new JPanel () ;
JPanel panelB =new JPanel() ;
Trang 11layout managers
How does the layout tttat1ager decide?
Different layout managers have different policies for arranging
components (like,arrange in a grid make themall the same size,
stack them vertically, etc.) but the components being layed out do
get at leastsomesmall say in the matter In general, the process of
laying out a background component looks something like this:
@) Add the panel to a frame
@ The frame's layout manager asks the panel how big the panel
prefers to be
@ The panel's layout monager uses its layout policies to decide
whetheritshould respect all, part, or none of the buttons'
everything vertically
<D Make a panel and add three buttons to it
@ The panel's layout manager asks each button-how big
that button prefers to be,
A layout scenario:
@ The frame's layout manager uses its layout policies to decide
whether it should respect all,part, or none of the panel's
preferences
Some layout managers respect the size the componentwants to
be.Ifthe button wants to be 30 pixels by 50 pixels, that's what the
layout manager allocates for that button,Other layout managers
respect only part of the component'spreferred size Ifthe button
wants to be 30 pixels by 50 pixels, it'll be 30 pixels by however
wide the button's backgroundpanel is, Still other layout managers
respect the preference of only the largestof the components
being layed out,and the rest of the components in that panel
are all made that same size.Insome cases, the work of the layout
manager can get very complex, but most of the time you can
figure out what the layout manager will probably do, once you get
to know that layout manager's policies
Trang 12Ihe Jig fhree layout tttat1agers:
border; flo~ and box.
-
BorderLayout
A BorderLayout manager divides a background
component into fiver~ions.Youcanadd only one
component per region toabackground controlled
by a BorderLayout manager.Components laid out
bythis manager usually don't get to have their
preferred size.9orderlayout Isthe default layout
II\Qna~ for Q fromel
FlowLayout
AFlowLayout manager acts kind of like a word
processor, except with components instead of
words.Each component is the size it wants to be,
and they're laid out left to right in the order that
they'readded with ·word-wrap" turned on So
when a component won'ttit horizontally, it drops
to thenext "line" in the layout.FlowLayout Isthe
default layout mo~,. for a pone"
BoxLayout
A BoxLayout manager is like FlowLayout in that
each component gets to have its own size, and
the components are placed in the order in which
they're added But unlike FlowLayout a BoxLayout
manager can stack the components vertically(or
horizontally, but usually we're just concerned with
vertically).It's like a FlowLayout but instead of
having automatic 'component wrapping', you can
insert a Sort of 'component return key' and force
-the components to start a new line
[ J o 0 -.
1\ :§)
you are here) 403
Trang 13border layout
about five regions:
east, west, north, south, and center
\ -u
Let's add a button to the!!!! region:
import javax swing.* ; t' \Alld.a ,t y.)t\(a¥
import java an *; ~BcKdlYLa'fOlO I' In.r
public class Buttonl
public static void ma.in (Strinq[l argos) I
Buttonl qui = new Buttonl () i
qui-goO;
JFrame frame = new JFrame () ; SVf.C,I 'fJButton button = new JButton ("cliclc me"); ( ' frame qetContentpane () lldd(BorderLayout.EASTI button)i
frame.Betsi~e(200/200);
frame.setVisible(true);
~
How did the BorderLayout manager come up withthis size for the button?
What are the factors the layout manage.r has toconsider?
Why isn'titwider or taller?
Trang 14Watch what happens when we give
the button more characters•
public void go() (
JFrame frame = new JFrame();
JButton button = new JButton("c1ick like you mean it");
!rame.getConcentPane() a dd (Bo r de r La you t EAST, button);
rllrespectitspreferredwidth But
rdon'tcare howtall it wantsto be:
it's ganna be as tall asthe frame,becausethat's my policy
Trang 15border layout
Let's try a button in the NORTH region
public void go() (
J~rame frame =new JFrame();
.mutton button '" new .JButton ("There is no spoon ");
frame.getCohtentPane().add(BorderLayouL.~,button);
frame.setSize(200,200);
frame.setVisible(true);
Now let's make the button ask to be ~II!!,
How do we do that? The button is already as wide
as it can ever be-as wide as the frame But we
cantryto make it tallerbygivingita bigger font
JButton button = new mutton ("Click This! ") ; ~ a"'t -to a\\~t.i,~ht Font bigFont = new Font ("serif", Font BOLD, 28); ~oYt,'nt'D\lt.tor-
button.aetFont(bigFont);
frame.getContentPane() add(BorderLayout.NORTB, button);
frame.setSlze(200,200);
frame.setVisible(true);
Trang 16I thinkrmgettingit ifrm ineesror
west,I getmypreferred widthbut the
height is up tothe layoutmanager And
if rminnorth orsouth, it'sjust the
opposite-I getmypreferred height, but
not width,
But wltst happens
in tlte center region?
The center region gets whatever's leftl
(except in one special case we'll look at later)
public void go ()
JFrame frame new JFrame();
JButton east new JButton("East");
JButton west new JButton("WestH
)JButton north = new JButc:.on("North");
JButton south = new JButton("SouthH
)JButton center = new JButton("CenterH
)frame.getContentPane() add(BorderLayout.&AST, east);
frarne.getContentPane() add(BorderLayout.WEST, west);
frame.getContentPane() add(BorderLayout.NORTH, north);
frame.gec:.ContentPane().add (BorderLayout SOUTH, south);
frame.getContentPane() add(BorderLayout.CENTER, center);
Trang 17Let's add a panel to the east region:
A JPanel's layout manager is FJowLayout, by default Wnen we add
a panel to a frame, the size and placement of the panel is still
under the BorderLayout manager's control But anytning insidethe
panel(in other words, components added to the panelbycalling
panel add (aComponent»)are under the panel's FfowLayout
manager's control We'll start by putting an empty panel in the fl'"£lme's
east region, and on the next pages we'll add things to the panel.
import javax.8winq.*;
import java.awt.·;
public class Panel1
publio static void main (SuingIl llrgs) (
Panell qui: new Panel1();
frame getContantpane () add (BorderLayout EAST, panel);
frams.setsize(200,200)i frame.setVisible(true) i
Trang 18public void go() {
Jframe frame = new Jframe();
JPanel panel = new JPanel();
panel.setBackground(Color.darkGray);
Let's add a button to the panel
th aYlt:\ aYld add-tht:Add t,hf~ 1:.0 e YCll'le\'sla'fOl>t ar.d~('f"
Cll'le\ t.o t.'ne~ya",e -r-:~.!- a dt.ht:~ya",e)s
JButton button'" new JButton ("shock me"); rHo ,) l-Ot'Ihols the'0)" hols -I:'neyaYlel
Trang 19flow layout
What happens if we add TWO buttons
to the panel?
public void go ()
JFrame frame new JFrame();
JPanel panel new JPanel();
panel.setBackground(Color.darkGray);
-rwD'o \:;\:P sJButton button = new JButton ("shock me"); ~ ,.jjy.e
JButton buttonTwo = new JButton("bliss"); V
panel add (button) ; - ' - -addB
panel add (buttonTwo) ;~ OT»to thl!: rand
frame.getContentPane() add (BorderLayout.EAST, panel);
~en your penCil
If the code above were modified to the code below,
what would the GUllook like?
JButton button = new JButton("shock me");
JButton buttonTwo = new JButton("bliss");
JButton buttonThree = new JButton("huh?H);
think the GUI would
Trang 20to put them side by side.
Unlike FlowLayout, BoxLayout can force a
'new line' to make the components wrap to
the next line, even If there's room for them
to fit horizontally.
But now you'llhave to change the panel's layout mancger from the
default FlowLayout to BoxLayout
panel) ;
JButton button =- new JButton("shock me");
Jautton buttonTwo = new Jautt.on("bliss");
public void got) {
JFrame frame = new JFrame(l ; a,.a~C" to~a~
JPanel panel = new JPanel () ; C\\a e-t\oIe \a'fO'l"t
t-panel setBackground (Color.darkGr:~iY\S~~ J 'rJo" u~o~
panel.s8tLsyout(new BoxLayout(panel, BoxLayout.Y_AXIS»;
~T n~ Bo~yovttoMb-illk-th~ to"'POhbltif;sI ' huds toknow
vertildl~lH ~ we lASe Y_AXI~ +~ a
you are here ~ 411
Trang 21layout managers
Q: How come you can't add directlytoa frame the way
you can to a panel?
meets the road In making something appear on the screen.
has to connect to the underlyl ng OS In order to accessthe
is the window frame and the content pane Isthe glass.You
pane with your own JPanel,to make your JPanel the frame's
content pane, using,
myFrama •etcontantpane(myPanel);
Q : can I change the layout manager of the frame?
What If I want the frame to use ftow Instead of border1
A:The easiest way to do this Is to make a panel, build
the GUI the way you want In the panel, and then make that
panel the frame's content pane using the code In the
prevl-ous answer (rather than using the default content pane).
Q : What If I want a different preferred size? Is there a
setSlzeO method for components1
A : Yes, there Is a setSlzeO, but the layout managers will
the component and the size you wa nt It to be.The preferred
(the component makes that decision for Itself) The layout
manager calls the component's getPreferredSlzeO method,
setSlzeO on the component.
Q:can't IJust put things where I want them? can I tum
the layout managers off?
A:vep.on a component by component basis,you can call
the exact screen locations and dimensions In the long run,
though, It's almost always easier to use layout managers.
• Layout managers control the size and location ofcomponents nested within other components
• When you add a component toanother component(sometimes referred10as abackground cornporent
but that's not a technical distinction), the addedcomponent is controlled bythe layout manager ofthe
backgroundcomponenl
• Alayout manager asks components for their
preferred size, before making a decision aboutthe layout Depending on the layout manager'spolicies,it might respect atl, some, or none ofthecomponent's wishes
• The BorderLayout manager lets you add acomponenttoone offive regions You must specifythe regionwhenyou add the component, using thefollowing syntax:
add (BorderLayout EAST, panel);
• WrthBordertayout, components in the north and
Components In the east and west get their preferredwidth, but not height The component in the centergets whatever isleff over (unless you usepack () ).
• The pack() method Is like shrink-wrap for thecomponents;Ituses the full preferred size ofthecenter component, then determines the size oftheframe using the center as a starting point, buildingthe rest based on what's in the other regions
• FlowLayout places components left to right toptobottom, In the order they were added, wrapping toanew line ofcomponents only when the componentswon't fit horizontally
• RowLayout gives components their preferred size inboth dimensions
• BoxLayout lets you align components stackedvertically, evenIfthey could fit side-by-sida UkeFlowLayout BoxLayout uses the preferred size ofthe component inboth dimensions
• BorderLayout isthe default layout manager for aframe; FlowLayout Isthe default for a panel
• Ifyou want a paneltouse something other than flow,you havetocall setLayout () on the panel
Trang 22Playit1Q with Swittg colitpottettts
You've learned the basics of layout managers, so now let'stryout a
few of the most common components: a text field,scrolling text area,
checkbox, and list, We won't show you the wholedarn API for each of
these, just a few highlights to get you started
JText:F1&1d field % n_ JTex.tField(20); ~e ~.,rl ~'t\d
J'TextField field: new JTAXtFi8ld(~Your nameff)i
• Get an ActionEvent when the user VOlAl,dll alSol'e~isk f
presses return or enter rtally'N.1l'1tiD htara~t~iY evel'lh ityOlA
l/.1tt- P'r't:~s dkty I everyti e thefiald.addActionLiataner(myActionListener) i
• Select/Highlight the textin the field
fiald.aelectAll();
• Put the cursor back in the field (so the user
can just start typing)field requeatFocua () ;
youare here ~ 413
Trang 23How to use It
• Makeit have a vertical scroll bar only
text area
JTextArea
Unlike JTextField, JTextArea can have more than one line of text It
takes Q little configuration to make one, because it doesn't come out of
the box with scroll bars or line wrappi"9.Tomake a J'TextAr'e(] scroll , you
have to stick it in a ScroliPane A ScroJiPane isanobject that r'e(]11y loves
to scroll and will take care of the text ereo's scrolli"9 needs '- \o \)
text.lIetLineWrap(true);~ T",,"II 01\line ~affi~ f a~st\"ollba\" l&SC Oftysc:roller.aetvertiea1Sc:rol1BarPolicy(ScrollPaneConlitants.VERTlCAL SCROLLBAR AL~IIcroller.set8orizonta1Sc:rol1BarPolicy(Sc:rollPaneConatants.BORIZONTAL_SCROLLBAR_NEVER);
• Append to the text that's in it
taxt.append("button cliakedH
)
• Select/Highlight thetext inthe field
taxt.lIelectAll();
• Put the cursor back inthe field(so the user
can just start typing)
text.requelltFocua() ;
Trang 24public void go() (
JFrame frame - new JFrame();
JPanel panel = new JPanel () ;
JButton button::; new JButton("Just Click It");
button addActionListener (this) ;
text::; new JTaxtArea(lO,20);
text.setLinewrap(true);
}
public static void main (String [] &rqs)
TextAreal qui c new TextAreal();
qui.go () ;
public class TaxtAreal implements ActionL~staner{
import jaYaX.swing.*;
import java.art.*;
import java.art.event.*;
JScrollPane scrollar ~ new JScrollPane{taxt);
scroller.setVerticalScrolLBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AL~YS);scrollar.setBorizontalScrollBarPolicy(ScrollPaneConstants.80RIZONTAL_SCROLLBAR_NEVER);panel add (scroller) ;
frame qetContentpane(l add(BorderLayout.CENTER, panel);
frame qetContentpane () add (BordarLayout.SOO'TB, button);
Trang 25Handle the event (and find out whether or not it's selected)
public void itemstateChanged(ItemEvent ev)
String onOrOff ="off";
if (check.isSelected(» onOrOff ="on";
System.out.println("Check box is " + onOrOff);
, Select or deselect it in code
check.setSelected(true);
check.setSelected(false);
O th UUlDere1atE}{l?~uesti9ns"
Q: Aren't the layout ers just more trouble than they'reworth? If I have to go to all thistrouble, I might as well just hard-code the size and coordinates forwhere everything should go
manag-A: Getting the exact layout you want from a layout man- ager can be a challenge But think about what the layout manager
is really doing for you Eventhe seemingly simple task of figuring out where things should go on the screen can be complex For example , the layout manager takes care of keeping your components from overlapping one another
In other words, it knows how to manage the spacing between components (and between the edge of the frame) Sure you can
do that yourself, but what happens
if you want components to be very tightly packed? You might get them placed just right, by hand, but that's only good for your JVM! Why? Because the components can be slightly different from platform to platform, especially if they use the underly ing platform 's
native 'look and fee 1/ , Subtle things like the bevel of the buttons can
be different in such a way that components that line up neatly
on one platform suddenly squish together on another
And we 're still not at the really Big Thing that layout managers do Think about what happens when the user resizesthe window! Or your GUI is dynamic, where com- ponents come and go If you had
to keep track of re-Iaying out all the components every time there 's
a change in the size or contents of
a background component yikes!
Trang 26Constructor
String [] H.atEntries '" ("a lpha", "beta", \'ga:nmta", "delta",
"apailon", "zeta", "eta H
, "theta "I;
list.addListSelectionListenar(this);
list'" new JLlst(liatEntrie.);
How to use It
• Make it have a vertical scrollbar
JSerollPane acroller '" new JScrolIPane(liat) ;
scroller.setVerticalScrol~Poliey(ScroIIPaneConstanta.VERTlCAL_SCROLL8AR_ALMAYS); acroller.setaorizontalScrollBarPolicy(ScrollPan8Constants.HORIZONTAL_SCROLLBAR_NEVER); panel.add(acroller);
Set the number of lines to show before scrolling
• Handle events (find out which thing in the list wasselected~ / fllt.j" this i~ test.
public void va.lueChanqed (ListselectionEvent lse) (E;"
String selecUon " (String) list getSelectedValue0 ; ~eiSdttudV~lueOad:. I~
rcwn.sa"Objett, Alisti 'f.li iud toOYII"/oL.~U"'''5• 0b:,)etu.' S:.
you are here. 417
Trang 27Code Kitchen
This part's optional We're ~ing the lull BeatBox, GUI and all In the Saving Objects chapter, we'll learn how to
save and restore drum patterns FinallyI in the networlung
Trang 28Makit1Q the JeatJox
This is the full code listing for this version of the BeatBox, with buttons for starting,
stopping, and changing the tempo.The code listing is complete,and
fully-annotated, but here's the overview:
•
•
•
•
Build a GUI that has 256 checkboxes (JCheckBox) that start out
unchecked, 16 labels (JLabel) for the instrument names, and four
buttons
Register an ActionListener for each of the four buttons We don't
need listeners for the individual checkboxes, because we aren't
trying to change the pattern sound dynamically (i.e.as soon as the
user checks a box) Instead, we wait until the user hits the 'start'
button, and then walk through all 256 checkboxes to get their state
and make a MIDI track
Set-up the MIDI system (you've done this before) including getting
a Sequencer, making a Sequence, and creating a track We are using
a sequencer method that's new to Java 5.0, setLoopCount( ) This
method allows you to specify how many times you want a sequence
to loop We're also using the sequence's tempo factor to adjust the
tempo up or down, and maintain the new tempo from one iteration of
the loop to the next
When the user hits 'start', the real action begins The event-handling
method for the 'start' button calls the buildTrackAndStartO method
In that method, we walk through all 256 checkboxes (one row at
a time, a single instrument across all 16 beats) to get their state,
then use the information to build a MIDI track (using the handy
makeEventO method we used in the previous chapter) Once the track
is built, we start the sequencer, which keeps playing (because we're
looping it) until the user hits 'stop'
you ar e here ~ 419
Trang 29public elass BeatBox {
~ The'S(dre ~e I\d"'CS ~the i~""LlftIents, dS aShi"
' " an-dY, to'<" bl.tildi"~ t.hc qUIlabels (on eJth 'row) ~
("Bass Drum", "Closed Hi-Bat", Snare", "Crash Cymbal", "Band Clap",
"Maxacas", "Whistle", "Low Conga",
"Low-mid Tom", "High Aqoqo" ,
public static void main (String[] args) {
new BestBox2 () buildGUI (J ;
checkboxList:: new ArrayList<JCheckBox.>() ;
Box buttonBox: new Box(BoxLayout.Y_AXIS);
JButton start c new JButton("Start");
start.addActionListener(new MyStartListener());
buttonBox.add(start) ;
JSutton stop: new JButton("Stop") ;
stop.addActionListener(naw MyStopListaner(»;
buttonBox add (stop) ;
JButton upTempo : new JButton("Tempo CpU);
upTempo.addActionListener(new MyUpTempoListener());
buttonBox,add(upTempo);
JSutton downTempo :: new JButton ("Tempo Down");
Trang 30downTempo addActionLi s tener(n_ MyDownTempoLis tener () ) ;
buttonBox.add(dovnTempo);
Box nameBox = new Box (80xLayout Y_AX! S) ;
for (int i = 0; i < 16; i++) {
nameBox.add(new Label (i.nst rumentNa.mes [i]» ;
background add (BorderLayout EAST, buttonBox) ;
background add (80rd.erLayout.WEST, namaBox);
theFrame.getcontentpane() add (background) ;
GridLayout grid = new GridLayout(16,16) ;
grid setVgap(1) ;
grid setHqap(2) ;
mainPanel = new JPanel(grid) ;
background add (BorcierLayout CEN"l'ER, mainPanel);
for (int i = 0; i < 256; i++) {
Trang 31sequence.deleteTrack(track) ;
for (int i = 0; i < 16; i++)
for (int j =0; j < 16; j++ ) { ~ Do this~OV"eath~ theBE.ATS ~OV" thisYOW
trackList [j) = 0; the key vall.lein thisslotin theayyay(the slotthat
} Ye~esents thisbeaV Otheywise, the inshWl'lent is
I I close inner loop NOT slAffosedto flay at this beat, so set it.toUyo·
makeTracks (trackList) ; -,.- :: - roY this i\'\StYWI'Ient., and~OV" all Ibbeats,
track add (makeEvent (176,1,127,0,16) ) ; ",ake eve"ts and add the",tothe hade
public class~ !iI ~ ~ :£! DI ~f Mimplements ActionListener
buildTrackAndStart();
}
Trang 32public class (mJ.HRa,~g~ implements ActionListener
public void actionPerformed(ActionEvent a) (
sequencer.stop() ;
}
II close inner class
public classr~EtItl=i!iij~jimplements ActionListener
public void actionPerformed(ActionEvent a) (
float tempoFactor =sequencer.getTempoFactor() ;
sequencer.setTempoFactor«float) (tempoFactor * 1.03»;
}
II close inner class
ublic class " '"".c "'! 'T ) " *9i ' :mr ':~ii l implements ActionListener
p :m % ",~ , ' w,~, , "iI , ,, ,, ,,, , ,.A '
public void actionPerformed(ActionEvent a) (
float tempoFactor =sequencer.getTempoFactor();
sequencer.setTempoFactor«float) (tempoFactor * 97 » ;
}
} II close inner class
The otheto il'll'leto dass
listel'letos tOt" the bl<ttol'lS
The TeMpo Fattoto stalesthe se,\\I.f:\'\te\'"'steMPO bythe tatk pY'o\fideGl The
~ deta",lt isJ.O, sowe'toe
adjlASti\'\5+/ - 3'0pe\'"
diek
~
public voidlllll.ll~(int[] list)
for (int i =0; i < 16; i++) (
int key =list[i];
i f (key != 0) {
track.add(makeEvent(144,9,key, 100,track.add(makeEvent(128,9,key, 100, ~) ); L Make the NOT~ON a\'\d
1+1»; ) NOT oFFe'le\'\ts a\'\d
add thew>tothe T\'"atk
public MidiEvent~ ~ ,ij ( int comd, int chan,
MidiEvent event =null;
try {
ShortMessage a =new ShortMessage();
a setMessage (comd, chan, one, two);
event =new MidiEvent(a, tick);
Trang 33exercise: Which Layout?
Which code goes with
Five of the slx screens below were made from one
of the code fragments on the opposite page Match each of the five code fragments with the layout that fragment would produce.
Trang 34e
code Fragments
panel setBackground (Color darkGray) ;
frame.getContentPane() add(BorderLayout.NORTH,panel);
panel.add(buttonTwo);
frame.getContentPane() add(BorderLayout.CENTER,button);
panel.setBackground(Color.darkGray);
panel.add(buttonTwo) ;
frame.getContentPane() add(BorderLayout.CENTER,button);
frame.getContentPane() add (BorderLayout.EAST, panel);
panel.setBackground(Color.darkGray);
panel.add(buttonTwo);
frame.getContentPane() add(BorderLayout.CENTER,button);
panel setBackground (Color darkGray) ;
panel add (button) ;
frame.getContentPane() add(BorderLayout.NORTH,buttonTwo) ;
frame.getContentPane() add (BorderLayout EAST, panel);
panel setBackground (Color.darkGray) ;
frame.getContentPane() add (BorderLayout SOUTH ,panel) ;
panel.add(buttonTwo) ;
frame.getContentPane() add (BorderLayout.NORTH ,button) ;
you are here; 425