©2006 pearson educationguis and event handling 1 of 34 guis and event handling graphical user...
TRANSCRIPT
©2006 Pearson Education GUIs and Event Handling
1 of 34
GUIs and Event Handling
• Graphical User Interfaces
• Using Some Common Swing Components
• LayoutManagers
• User Interaction with Listeners
©2006 Pearson Education GUIs and Event Handling
2 of 34
GUI defined
• Most applications today have Graphical User Interfaces (GUIs)
– GUIs provide user-controlled (i.e., graphical) way to send messages to system of objects
• We will be building programs with GUIs throughout the semester
• You are probably familiar with certain GUIs…
©2006 Pearson Education GUIs and Event Handling
3 of 34
GUI Components aka Widgets
• Some Components in Swing:– javax.swing.JButton– javax.swing.JToggleButton– javax.swing.JCheckBox– javax.swing.JRadioButton
• How to define buttons– pass String, java.awt.ImageIcon or both to
constructor as button’s label:
javax.swing.JButton _myButton = new javax.swing.JButton(“JButton”);
javax.swing.JButton _myButton = new javax.swing.JButton(smiley);
javax.swing.JButton _myButton = new javax.swing.JButton(“Name and Icon”, smiley);
©2006 Pearson Education GUIs and Event Handling
4 of 34
JRadioButtons & ButtonGroups
• How do we make options mutually exclusive?
– put them in a button group– javax.swing.ButtonGroup
• “javax.swing”, “java.awt”, etc package names elided throughout this lecture
• How to use a ButtonGroup:
– create buttonsJRadioButton _rb1 = new
JRadioButton(“Green, not Red”);
JRadioButton _rb2 = new
JRadioButton(“Red, not Green”);
– create ButtonGroup ButtonGroup _bgroup = new ButtonGroup();
– add() buttons to ButtonGroup_bgroup.add(_rb1);
_bgroup.add(_rb2);
• Buttons that can be added to ButtonGroup:
– JRadioButton– JToggleButton– JMenuItem (for advanced users)
©2006 Pearson Education GUIs and Event Handling
5 of 34
Labels and Strings
• What if we want to place text in our GUI but not in a button?
• Use javax.swing.JLabel!– constructed same as JButton– can change text using setText(String)
• So how do we harness the power of Strings?
• Strings are words, phrases, or any other sequence of alphanumeric characters, including blanks!
• Just another class, except for how you construct one– can use: String greeting = new String(“yo”);
– or, omit new and class name and just put characters between double quotation marks
String greeting = “yo”;
©2006 Pearson Education GUIs and Event Handling
6 of 34
More on the Power of Strings
• String Concatenation:– Combine Strings with ‘+’ operatorString firstName = “James”;String lastName = “Smith”;String fullName = firstName + lastName;// note that this becomes “JamesSmith”fullName = firstName + “ Q. ” + lastName;//“James Q. Smith” - blanks are characters!
• You can also concatenate strings with non-stringsint year = 2005;String date = “October ” + 6 + “, ” + year;
– date is now: October 6, 2005
• Can make a String from int (a kind of cast)– not concatenated with other charactersString yearAsString = “” + year;
– another useful example of concatenation:System.out.println(“value of x is ” + x);
©2006 Pearson Education GUIs and Event Handling
7 of 34
javax.swing.JSlider
• What is a slider, you ask?
– component that lets user graphically select a value by sliding a knob within a bounded interval
• Pass minimum and maximum values in constructor– must be ints– can be negative or positive
• Can be oriented either vertically or horizontally– orientation also passed in constructor– oriented horizontally by default– look at docs for more info
• How do we get value of the JSlider when we need it?– getValue(): returns an int
JSlider slider = new JSlider(0, 30);
©2006 Pearson Education GUIs and Event Handling
8 of 34
Painting components• How do we draw components on screen?
– just add component to JPanel• call add()…
– Java developers already defined paintComponent method for all GUI components (i.e., JButtons, etc…)
• do NOT have to override paintComponent
• Chain of command– add JButton to JFrame– call setVisible(true) on JFrame
• paint in 3 easy steps
– Step 1: Swing calls paintComponent on JFrame– Step 2: JFrame calls paintComponent on
JPanel– Step 3: JPanel calls paintComponent on
JButton
©2006 Pearson Education GUIs and Event Handling
9 of 34
Laying it all out
• Arranging components (either GUI widgets or sub-panels) in a JPanel
– could setLocation of each component by hand
• way too tedious
– use java.awt.LayoutManagers• Each JPanel contains layout object which
implements LayoutManager interface– arranges components automatically– can be added to JFrames as well
• Either pass LayoutManager to JPanel’s constructor or call setLayout
• By default JPanel comes with java.awt.FlowLayout
– simplest type of LayoutManager– arranges components from left to right,
top to bottom• moves to next row when at edge of panel
©2006 Pearson Education GUIs and Event Handling
10 of 34
In the right frame of mind
• Start with JFrame
public class SimpleButtonApp extends JFrame { public SimpleButtonApp() { super(“Mr Button"); this.setDefaultCloseOperation(EXIT_ON_CLOSE);
// create a Panel for the ButtonJPanel panel = new JPanel();
// create a Button and add it to the Panelpanel.add(new JButton(“Click Me!”));
// now add the Panel to the Frame this.add(panel); this.pack(); this.setVisible(true); } public static void main(String [] argv) { SimpleButtonApp app = new SimpleButtonApp(); }}
• Calling pack makes JFrame resize to fit contents (default size for JFrame is (0,0) ); here it fits to enclose the button which has a default size
©2006 Pearson Education GUIs and Event Handling
11 of 34
Something more practical
• We made a button appear in a frame…– not very useful by itself
• How do buttons respond when clicked? – notify “listener” object that responds – similar to timer notifying MyMoveListener in
last lecture• remember ActionListeners?
– timers produce an event on every tick – buttons produce an event on every click
• User interaction in Swing is event-based– when user does something, like click a button,
Swing produces an event– then event record is broadcast to all objects
listening; they respond to click
©2006 Pearson Education GUIs and Event Handling
12 of 34
Users Interacting • Depending on what type of event record you
need, add a different kind of listener• There are several listener interfaces in
java.awt.event and javax.swing.event packages– java.awt.event.ActionListener– java.awt.event.MouseListener– java.awt.event.KeyListener– javax.swing.event.ChangeListener– etc...
• The ActionListener interface is simplest– saw it in previous lecture – must define:
public void actionPerformed( java.awt.event.ActionEvent e);
• Call addActionListener(ActionListener) on component so it can notify listener on click
• Who creates class that implements ActionListener?– component itself (e.g. JButton)– no one else needs to know about inner class, so
preserve encapsulation
©2006 Pearson Education GUIs and Event Handling
13 of 34
Hand Simulation
public void
actionPerformed( ) {
/** Handle ActionEvent Here **/
}
ActionEvent e
ActionListener
©2006 Pearson Education GUIs and Event Handling
14 of 34
Houston…
• Problems– each button needs a corresponding ActionListener
• too many little files with very simple classes
– ActionListeners might need access to other classes’ instance variables which they could access or mutate (stay tuned…)
• too much parameter passing
• lose some encapsulation
• Solution– Remember Inner Classes?
• create a private class inside another class
• avoid a separate file for each
©2006 Pearson Education GUIs and Event Handling
15 of 34
Behold the inner, private class!
public class QuitButtonApp extends JFrame {
public QuitButtonApp() { super(“Quitter”);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
// QuitButton defined belowJButton quit = new QuitButton();
// place it in its container and displayJPanel panel = new JPanel();panel.add(quit);this.add(panel);this.pack(); // resize frame to fit
panelthis.setVisible(true);
}
public static void main (String[] argv) {QuitButtonApp app = new QuitButtonApp();
}}
public class QuitButton extends JButton {
public QuitButton() {super(“Quit”);addActionListener(new QuitListener());
}
private class QuitListener implements ActionListener {
public void actionPerformed(ActionEvent e)
{System.exit(0); // exit program
}}
}
©2006 Pearson Education GUIs and Event Handling
16 of 34
Instant Replay
public void
actionPerformed( ) {
System.exit(0);
}
ActionEvent e
QuitListener
©2006 Pearson Education GUIs and Event Handling
17 of 34
Double Take
private class QuitListener implements
ActionListener {
public void actionPerformed
(ActionEvent e) {
System.exit(0); // exit the program
}}
• No need for constructor– Java adds empty constructor at compile
time
• Keyword modifier private– no other classes need to know about it
• Next example shows private class can access all of containing class’ methods and instance variables, e.g., the button’s
Wait! There’s no constructor!!!
©2006 Pearson Education GUIs and Event Handling
18 of 34
GUI Maker
• Let’s use components and ActionListeners to make a simple GUI
• Program Specs:– make a program with a ColorShape which
can be moved with sliders– use RadioButtons to change color of shape– use labels to display values of sliders at all
times– must have quit button
©2006 Pearson Education GUIs and Event Handling
19 of 34
Growing Pains
• Can use the DrawingPanel from last lecture to draw the ColorShape
• Need quit button to be below DrawingPanel– FlowLayout only goes left to right, top to
bottom (will use grid layout for multiple rows and columns)
• java.awt.BorderLayout splits JPanel into 5 regions:– NORTH, SOUTH, EAST, WEST, CENTER
©2006 Pearson Education GUIs and Event Handling
20 of 34
BorderLayout
• Must specify region when adding to container with a BorderLayout:
panel.add(dp, java.awt.BorderLayout.CENTER);
• Do not have to fill all regions– regions are size (0, 0) by default– BorderLayout will adjust dynamically depending
on what has been added
– always add to CENTER first• CENTER is largest by default
• Examples:
component where
©2006 Pearson Education GUIs and Event Handling
21 of 34
BorderLayout in action
public class GUIApp extends JFrame {
public GUIApp() {
super(“Shaaaawing!”);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setLayout(new BorderLayout());
DrawingPanel dp = new DrawingPanel();
JPanel panel = new JPanel();
JButton quit = new QuitButton();
panel.add(quit);
this.add(dp, BorderLayout.CENTER);
this.add(panel, BorderLayout.SOUTH);
this.pack();
this.setVisible(true);
}
// Mainline elided
}
©2006 Pearson Education GUIs and Event Handling
22 of 34
More Growing Pains
• RadioButtons are also below the DrawingPanel– need another JPanel with it’s own LayoutManager
– layouts can be nested inside other layouts
• Let’s use java.awt.GridLayout– arranges components in a grid– add components left to right top to bottom– must specify grid size in constructor
• use 0 for infinite rows or columns
– each cell in grid is same size• size determined by largest element in grid
• Example: JPanel gpanel = new JPanel(); gpanel.setLayout(new GridLayout(3, 2)); gpanel.add(new JButton(“1”)); gpanel.add(new JButton(“2”)); gpanel.add(new JButton(“3”)); gpanel.add(new JButton(“4”)); gpanel.add(new JButton(“5”)); gpanel.add(new JButton(“6”));
©2006 Pearson Education GUIs and Event Handling
23 of 34
Nesting within nesting• How will this nesting structure work?
1. use FlowLayout to arrange RadioButtons in a row
JPanel radioRow = new JPanel();radioRow.add(redButton);radioRow.add(blueButton);radioRow.add(whiteButton);radioRow.add(greenButton);
2. use GridLayout to align components in a column: buttons, labels, and quit button
//(0, 1) means as many rows as needed, 1 col JPanel south = new JPanel(new GridLayout(0,1)); south.add(radioRow); south.add(labelRow); // coming later south.add(quit);
• GUIApp has too much code– factor layout code into new top-level
class• MainPanel.java
©2006 Pearson Education GUIs and Event Handling
24 of 34
Graphical Containment
• What components visually contain other components
• Essentially a preview of your GUI
JFrame
MainPanel
BorderLayout.CENTER
BorderLayout.NORTHBorderLayout.EAST
BorderLayout.SOUTH
GridLayout
FlowLayouts
JRadioButtons JButton
JLabels
JSlider
©2006 Pearson Education GUIs and Event Handling
25 of 34
Logical Containment
• Containment with respect to your code
• Shows all classes
– including non-GUI (none in this example)
• Also includes associations
• A UML diagram
• Logical containment and graphical containment can be the same
MainPanel
App
DrawingPanel
JRadioButton
JLabelJSlider
JButton
ColorShape
JPanel
FlowLayout
BorderLayout
©2006 Pearson Education GUIs and Event Handling
26 of 34
MainPanel.java
public class MainPanel extends JPanel {private ColorShape _shape;
public MainPanel() {super();this.setLayout(new BorderLayout());// initialize sub-panels// other initialization elidedDrawingPanel dp = new DrawingPanel(_shape);dp.setPreferredSize(new Dimension(300, 300));
// default FlowLayouts for rowsJPanel radioRow = new JPanel(); JPanel labelRow = new JPanel();
// create and add labels (y label elided)JLabel xLabel = new JLabel("X = 100");labelRow.add(xLabel);
ButtonGroup group = new ButtonGroup();
// pass true, button selected by defaultColorButton redButton = new
ColorButton("Red", true, Color.red, _shape, dp, group);
// other buttons the sameradioRow.add(redButton);// etc...
this.add(dp, BorderLayout.CENTER);this.add(south, BorderLayout.SOUTH);
}}
©2006 Pearson Education GUIs and Event Handling
27 of 34
And more…
• Adding sliders is easy– one to the north
– one to the east
– but JSliders don’t have addActionListener() method!
• Sliders can have many values– each value of slider counts as a state
• Sliders use…
Don’t forget to add your
JRadioButtons to a ButtonGroup
©2006 Pearson Education GUIs and Event Handling
28 of 34
javax.swing.event.ChangeListeners
• ChangeListeners can “hear” when component’s state has been changed– implementors must define:
public void stateChanged(
javax.swing.event.ChangeEvent e)
• Essentially works just like ActionListener• Components that can have
ChangeListeners:– JSliders– JRadioButtons– JCheckBoxes Hey! Do I need a
ChangeListener?
Why doesn’t anyone tell me these things?
©2006 Pearson Education GUIs and Event Handling
29 of 34
Missing reference…• ChangeListeners need a reference to
ColorShape in order to tell it to move…– could make accessor/mutators for ColorShape in DrawingPanel
• but other classes seem to need a reference to ColorShape too…
– put ColorShape in MainPanel• whoever needs it can get it passed to them when they
are constructed in MainPanel’s constructor• all initialization is localized• MainPanel does its job as top-level
• Result– DrawingPanel takes ColorShape in
constructor
• Also, certain classes need to be instance variables– action/change listeners need access to them
// MainPanel instance variablesprivate ColorShape _shape;private JSlider _xSlider, _ySlider;private JLabel _xLabel, _yLabel;private DrawingPanel _dp; // for repaint
©2006 Pearson Education GUIs and Event Handling
30 of 34
ChangeListenin’
// inside MoveSliderprivate class XListener implements ChangeListener {
private MoveSlider _slider;
public XListener(MoveSlider slider) {slider = slider;
}
public void stateChanged(ChangeEvent e) {
_label.setText("X = " + _slider.getValue());
_shape.setLocation(
_slider.getValue(), _shape.getY());
_dp.repaint();}
}• Step by step
– tell _label to display value– set x location of ColorShape– repaint new position of shape in DrawingPanel
• Don’t forget to addChangeListener() to your slider
©2006 Pearson Education GUIs and Event Handling
31 of 34
ActionListenin’• Only need to write one class for all radio
buttons!– takes a color in constructor– on actionPerformed:
• calls setFillColor on ColorShape• calls repaint on DrawingPanel
private class ColorChanger implements ActionListener {
private Color _myColor; public ColorChanger(Color c){ _myColor = c; }
public void actionPerformed(ActionEvent e) { _shape.setFillColor(_myColor); _dp.repaint(); } }
• RadioButtons can take either ChangeListener or ActionListener– in this case, didn’t need more detailed
event record than ActionListener
©2006 Pearson Education GUIs and Event Handling
32 of 34
And with that…
• You have now learned enough information to create your own programs, complete with graphics and user interaction!
• For more information on Swing, visit Sun’s free Swing tutorial at http://java.sun.com/docs/books/tutorial/uiswing/
• Joyous coding!
©2006 Pearson Education GUIs and Event Handling
33 of 34
©2006 Pearson Education GUIs and Event Handling
34 of 34