Transcript Document

Chapter 14 – Graphical User
Components Part 2
Outline
14.1
14.2
14.3
14.4
14.5
14.6
14.7
14.8
14.9
14.10
14.11
14.12
14.13
Introduction
JTextArea
Creating a Customized Subclass of JPanel
JPanel Subclass that Handles Its Own Events
JSlider
Windows: Additional Notes
Using Menus with Frames
JPopupMenu
Pluggable Look-and-Feel
JDesktopPane and JInternalFrame
JTabbedPane
Layout Managers: BoxLayout and GridBagLayout
(Optional Case Study) Thinking About Objects: Model-ViewController
 2003 Prentice Hall, Inc. All rights reserved.
Chapter 14 – Graphical User
Components Part 2
14.14
Used
(Optional) Discovering Design Patterns: Design Patterns
in Packages java.awt and javax.swing
14.14.1 Creational Design Patterns
14.14.2 Structural Design Patterns
14.14.3 Behavioral Design Patterns
14.14.4 Conclusion
 2003 Prentice Hall, Inc. All rights reserved.
14.1 Introduction
• Advanced GUI components
– Text areas
– Sliders
– Menus
• Multiple Document Interface (MDI)
• Advanced layout managers
– BoxLayout
– GridBagLayout
 2003 Prentice Hall, Inc. All rights reserved.
14.2 JTextArea
• JTextArea
– Area for manipulating multiple lines of text
– extends JTextComponent
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Outline
// Fig. 14.1: TextAreaDemo.java
// Copying selected text from one textarea to another.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
TextAreaDemo.ja
va
public class TextAreaDemo extends JFrame {
private JTextArea textArea1, textArea2;
private JButton copyButton;
// set up GUI
public TextAreaDemo()
{
super( "TextArea Demo" );
Line 16
Lines 18-24
Create Box container for
organizing GUI components
Box box = Box.createHorizontalBox();
String string = "This is a demo string to\n" +
"illustrate copying text\nfrom one textarea to \n" +
"another textarea using an\nexternal event\n";
// set up textArea1
textArea1 = new JTextArea( string, 10, 15 );
box.add( new JScrollPane( textArea1 ) );
Populate JTextArea with
String, then add to Box
 2003 Prentice Hall, Inc.
All rights reserved.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
Outline
// set up copyButton
copyButton = new JButton( "Copy >>>" );
box.add( copyButton );
copyButton.addActionListener(
new ActionListener() {
TextAreaDemo.ja
va
// anonymous inner class
// set text in textArea2 to selected text from textArea1
public void actionPerformed( ActionEvent event )
{
textArea2.setText( textArea1.getSelectedText() );
}
Lines 44-45
When user presses JButton,
textArea1’s highlighted text
is copied into textArea2
} // end anonymous inner class
); // end call to addActionListener
// set up textArea2
textArea2 = new JTextArea( 10, 15 );
textArea2.setEditable( false );
box.add( new JScrollPane( textArea2 ) );
Line 36
Instantiate uneditable JTextArea
// add box to content pane
Container container = getContentPane();
container.add( box );
// place in BorderLayout.CENTER
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
setSize( 425, 200 );
setVisible( true );
} // end constructor TextAreaDemo
public static void main( String args[] )
{
TextAreaDemo application = new TextAreaDemo();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
Outline
TextAreaDemo.ja
va
} // end class TextAreaDemo
 2003 Prentice Hall, Inc.
All rights reserved.
14.3 Creating a Customized Subclass of
JPanel
• Extend JPanel to create new components
– Dedicated drawing area
• Method paintComponent of class JComponent
 2003 Prentice Hall, Inc. All rights reserved.
Outline
1
// Fig. 14.2: CustomPanel.java
2
// A customized JPanel class.
3
import java.awt.*;
4
import javax.swing.*;
CustomPanel.jav
5
a
6
public class CustomPanel extends JPanel {
7
public final static int CIRCLE = 1, SQUARE = 2;
Store integer representing
Line 8
8
private int shape;
shape
to
draw
9
10
// use shape to draw an oval or rectangle
Line 11
11
public void paintComponent( Graphics g )
12
{
Line 25
13
super.paintComponent( g );
Override method
14
paintComponent of
15
if ( shape == CIRCLE )
class JComponent to
16
g.fillOval( 50, 10, 60, 60 );
17
else if ( shape == SQUARE )
draw oval or rectangle
18
g.fillRect( 50, 10, 60, 60 );
19
}
20
21
// set shape value and repaint CustomPanel
22
public void draw( int shapeToDraw )
23
{
24
shape = shapeToDraw;
25
repaint();
Method repaint calls method paintComponent
26 }
27
28 } // end class CustomPanel
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 14.3: CustomPanelTest.java
// Using a customized Panel object.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class CustomPanelTest extends JFrame {
private JPanel buttonPanel;
private CustomPanel myPanel;
private JButton circleButton, squareButton;
Outline
CustomPanelTest
.java
Lines 18-19
// set up GUI
public CustomPanelTest()
{
super( "CustomPanel Test" );
// create custom drawing area
myPanel = new CustomPanel();
myPanel.setBackground( Color.GREEN );
Instantiate CustomPanel object
and set background to green
// set up squareButton
squareButton = new JButton( "Square" );
squareButton.addActionListener(
 2003 Prentice Hall, Inc.
All rights reserved.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
new ActionListener() {
Outline
// anonymous inner class
// draw a square
public void actionPerformed( ActionEvent event )
{
myPanel.draw( CustomPanel.SQUARE );
}
} // end anonymous inner class
); // end call to addActionListener
CustomPanelTest
.java
Line 30
When user presses squareButton,
draw square on CustomPanel
Line 45
circleButton = new JButton( "Circle" );
circleButton.addActionListener(
new ActionListener() {
// anonymous inner class
// draw a circle
public void actionPerformed( ActionEvent event )
{
myPanel.draw( CustomPanel.CIRCLE );
}
} // end anonymous inner class
When user presses circleButton,
draw circle on CustomPanel
); // end call to addActionListener
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
// set up panel containing buttons
buttonPanel = new JPanel();
buttonPanel.setLayout( new GridLayout( 1, 2 ) );
buttonPanel.add( circleButton );
buttonPanel.add( squareButton );
Outline
CustomPanelTest
Use GridLayout to organize buttons
.java
// attach button panel & custom drawing area to content pane
Container container = getContentPane();
container.add( myPanel, BorderLayout.CENTER );
container.add( buttonPanel, BorderLayout.SOUTH );
Line 54
setSize( 300, 150 );
setVisible( true );
} // end constructor CustomPanelTest
public static void main( String args[] )
{
CustomPanelTest application = new CustomPanelTest();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
} // end class CustomPanelTest
 2003 Prentice Hall, Inc.
All rights reserved.
14.4 JPanel Subclass that Handles Its Own
Events
• JPanel
– Does not support conventional events
• e.g., events offered by buttons, text areas, etc.
– Capable of recognizing lower-level events
• e.g., mouse events, key events, etc.
– Self-contained panel
• Listens for its own mouse events
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Outline
// Fig. 14.4: SelfContainedPanel.java
// A self-contained JPanel class that handles its own mouse events.
package com.deitel.jhtp5.ch14;
SelfContainedPa
nel.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Line 16
public class SelfContainedPanel extends JPanel {
private int x1, y1, x2, y2;
Lines 23-24
// set up mouse event handling for SelfContainedPanel
public SelfContainedPanel()
{
Self-contained JPanel
// set up mouse listener
listens for MouseEvents
addMouseListener(
new MouseAdapter() {
// anonymous inner class
// handle mouse press event
public void mousePressed( MouseEvent event )
{
x1 = event.getX();
y1 = event.getY();
}
Save coordinates where user
pressed mouse button
 2003 Prentice Hall, Inc.
All rights reserved.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// handle mouse release event
public void mouseReleased( MouseEvent event )
{
x2 = event.getX();
y2 = event.getY();
repaint();
}
Outline
Save coordinates whereSelfContainedPa
user released
mouse button, then
repaint
nel.java
Lines 30-31
} // end anonymous inner class
Line 40
); // end call to addMouseListener
// set up mouse motion listener
addMouseMotionListener(
new MouseMotionAdapter() {
Self-contained JPanel listens
Lines 47-48
for when mouse moves
// anonymous inner class
// handle mouse drag event
public void mouseDragged( MouseEvent event )
{
x2 = event.getX();
y2 = event.getY();
repaint();
}
Save coordinates where user
dragged mouse, then repaint
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
Outline
} // end anonymous inner class
); // end call to addMouseMotionListener
SelfContainedPa
nel.java
} // end constructor SelfContainedPanel
// return preferred width and height of SelfContainedPanel
public Dimension getPreferredSize()
{
return new Dimension( 150, 100 );
}
Lines 69-70
// paint an oval at the specified coordinates
public void paintComponent( Graphics g )
{
super.paintComponent( g );
g.drawOval( Math.min( x1, x2 ), Math.min( y1, y2 ),
Math.abs( x1 - x2 ), Math.abs( y1 - y2 ) );
Draw oval
}
} // end class SelfContainedPanel
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// Fig. 14.5: SelfContainedPanelTest.java
// Creating a self-contained subclass of JPanel that processes
// its own mouse events.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.deitel.jhtp5.ch14.SelfContainedPanel;
Outline
SelfContainedPa
nelTest.java
Lines 17-18
public class SelfContainedPanelTest extends JFrame {
private SelfContainedPanel myPanel;
// set up GUI and mouse motion event handlers for application window
public SelfContainedPanelTest()
{
// set up a SelfContainedPanel
Instantiate SelfContaintedPanel
myPanel = new SelfContainedPanel();
object and set background to yellow
myPanel.setBackground( Color.YELLOW );
Container container = getContentPane();
container.setLayout( new FlowLayout() );
container.add( myPanel );
 2003 Prentice Hall, Inc.
All rights reserved.
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// set up mouse motion event handling
addMouseMotionListener(
new MouseMotionListener() {
Register anonymous-inner-class Outline
object
to handle mouse motion events
// anonymous inner class
// handle mouse drag event
public void mouseDragged( MouseEvent event )
{
setTitle( "Dragging: x=" + event.getX() +
"; y=" + event.getY() );
}
// handle mouse move event
public void mouseMoved( MouseEvent event )
{
setTitle( "Moving: x=" + event.getX() +
"; y=" + event.getY() );
}
SelfContainedPa
nelTest.java
Line 25
30-41
Display StringLines
in title
bar
indicating x-y coordinate where
mouse-motion event occurred
} // end anonymous inner class
); // end call to addMouseMotionListener
setSize( 300, 200 );
setVisible( true );
} // end constructor SelfContainedPanelTest
 2003 Prentice Hall, Inc.
All rights reserved.
51
52
53
54
55
56
57
58
public static void main( String args[] )
{
SelfContainedPanelTest application = new SelfContainedPanelTest();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
Outline
SelfContainedPa
nelTest.java
} // end class SelfContainedPanelTest
 2003 Prentice Hall, Inc.
All rights reserved.
14.5 JSlider
• JSlider
– Enable users to select from range of integer values
– Several features
• Tick marks (major and minor)
• Snap-to ticks
• Orientation (horizontal and vertical)
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.6 JSlider component with horizontal
orientation
thumb
 2003 Prentice Hall, Inc. All rights reserved.
tick mark
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// Fig. 14.7: OvalPanel.java
// A customized JPanel class.
import java.awt.*;
import javax.swing.*;
public class OvalPanel extends JPanel {
private int diameter = 10;
// draw an oval of the specified diameter
public void paintComponent( Graphics g )
{
super.paintComponent( g );
g.fillOval( 10, 10, diameter, diameter );
Outline
OvalPanel.java
Line 14
Line 18
Draw filled oval of diameter
}
// validate and set diameter, then repaint
public void setDiameter( int newDiameter )
{
// if diameter invalid, default to 10
diameter = ( newDiameter >= 0 ? newDiameter : 10 );
repaint();
}
Set diameter, then repaint
 2003 Prentice Hall, Inc.
All rights reserved.
25
26
27
28
29
30
31
32
33
34
35
36
37
// used by layout manager to determine preferred size
public Dimension getPreferredSize()
{
return new Dimension( 200, 200 );
}
Outline
OvalPanel.java
// used by layout manager to determine minimum size
public Dimension getMinimumSize()
{
return getPreferredSize();
}
} // end class OvalPanel
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
Outline
// Fig. 14.8: SliderDemo.java
// Using JSliders to size an oval.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
SliderDemo.java
Lines 18-19
public class SliderDemo extends JFrame {
private JSlider diameterSlider;
private OvalPanel myPanel;
// set up GUI
public SliderDemo()
{
super( "Slider Demo" );
// set up OvalPanel
myPanel = new OvalPanel();
myPanel.setBackground( Color.YELLOW );
Lines 22-23
Instantiate OvalPanel object
and set background to yellow
Instantiate horizontal JSlider object
with min. value of 0, max. value of 200
and initial thumb location at 10
// set up JSlider to control diameter value
diameterSlider =
new JSlider( SwingConstants.HORIZONTAL, 0, 200, 10 );
diameterSlider.setMajorTickSpacing( 10 );
diameterSlider.setPaintTicks( true );
 2003 Prentice Hall, Inc.
All rights reserved.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// register JSlider event listener
diameterSlider.addChangeListener(
new ChangeListener() {
// anonymous inner
Register anonymous
Outline
ChangeListener object
to handle JSlider events
class
SliderDemo.java
// handle change in slider value
public void stateChanged( ChangeEvent e )
{
myPanel.setDiameter( diameterSlider.getValue() );
}
} // end anonymous inner class
); // end call to addChangeListener
Line 28
Line 35
When user accesses JSlider,
set OvalPanel’s diameter
according to JSlider value
// attach components to content pane
Container container = getContentPane();
container.add( diameterSlider, BorderLayout.SOUTH );
container.add( myPanel, BorderLayout.CENTER );
setSize( 220, 270 );
setVisible( true );
} // end constructor SliderDemo
 2003 Prentice Hall, Inc.
All rights reserved.
52
53
54
55
56
57
58
public static void main( String args[] )
{
SliderDemo application = new SliderDemo();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
Outline
SliderDemo.java
} // end class SliderDemo
 2003 Prentice Hall, Inc.
All rights reserved.
14.6 Windows: Additional Notes
• JFrame
– Windows with title bar and border
– Subclass of java.awt.Frame
• Subclass of java.awt.Window
– Heavyweight component
– Three operations when user closes window
• DISPOSE_ON_CLOSE
• DO_NOTHING_ON_CLOSE
• HIDE_ON_CLOSE
 2003 Prentice Hall, Inc. All rights reserved.
14.7 Using Menus with Frames
• Menus
– Allows for performing actions with cluttering GUI
– Contained by menu bar
• JMenuBar
– Comprised of menu items
• JMenuItem
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Outline
// Fig. 14.9: MenuTest.java
// Demonstrating menus
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
MenuTest.java
public class MenuTest extends JFrame {
private final Color colorValues[] =
{ Color.BLACK, Color.BLUE, Color.RED, Color.GREEN };
private JRadioButtonMenuItem colorItems[], fonts[];
private JCheckBoxMenuItem styleItems[];
private JLabel displayLabel;
private ButtonGroup fontGroup, colorGroup;
private int style;
Line 22
// set up GUI
public MenuTest()
{
super( "Using JMenus" );
// set up File menu and its menu items
JMenu fileMenu = new JMenu( "File" );
fileMenu.setMnemonic( 'F' );
Instantiate File JMenu
 2003 Prentice Hall, Inc.
All rights reserved.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
Outline
// set up About... menu item
JMenuItem aboutItem = new JMenuItem( "About..." );
aboutItem.setMnemonic( 'A' );
Instantiate About… JMenuItem
fileMenu.add( aboutItem );
to be placed in fileMenu MenuTest.java
aboutItem.addActionListener(
new ActionListener() {
Line 26
// anonymous inner class
// display message dialog when user selects About...
public void actionPerformed( ActionEvent event )
{
JOptionPane.showMessageDialog( MenuTest.this,
"This is an example\nof using menus",
"About", JOptionPane.PLAIN_MESSAGE );
When
}
}
// end anonymous inner class
Lines 36-38
Line 46
user selects About…
JMenuItem, display message
dialog with appropriate text
); // end call to addActionListener
// set up Exit menu item
JMenuItem exitItem = new JMenuItem( "Exit" );
exitItem.setMnemonic( 'x' );
fileMenu.add( exitItem );
exitItem.addActionListener(
Instantiate Exit JMenuItem
to be placed in fileMenu
 2003 Prentice Hall, Inc.
All rights reserved.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
new ActionListener() {
Outline
// anonymous inner class
// terminate application when user clicks exitItem
public void actionPerformed( ActionEvent event )
{
System.exit( 0 );
When
}
MenuTest.java
user selects Exit
Line 56
JMenuItem, exit system
}
// end anonymous inner class
Line 64
); // end call to addActionListener
Line 69
// create menu bar and attach it to MenuTest window
JMenuBar bar = new JMenuBar();
Instantiate JMenuBar
setJMenuBar( bar );
to contain JMenus
bar.add( fileMenu );
// create Format menu, its submenus and menu items
JMenu formatMenu = new JMenu( "Format" );
formatMenu.setMnemonic( 'r' );
Instantiate Format JMenu
// create Color submenu
String colors[] = { "Black", "Blue", "Red", "Green" };
 2003 Prentice Hall, Inc.
All rights reserved.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
JMenu colorMenu = new JMenu( "Color" );
colorMenu.setMnemonic( 'C' );
Instantiate Color JMenu
Outline
(submenu of Format JMenu)
colorItems = new JRadioButtonMenuItem[ colors.length ];
colorGroup = new ButtonGroup();
ItemHandler itemHandler = new ItemHandler();
MenuTest.java
Line 75
// create color radio button menu items
for ( int count = 0; count < colors.length; count++ ) {
Lines 78-79
colorItems[ count ] =
Instantiate
new JRadioButtonMenuItem( colors[ count ] );
JRadioButtonMenuItems
Line 96 for
colorMenu.add( colorItems[ count ] );
Color JMenu and ensure that only
colorGroup.add( colorItems[ count ] );
one menu item is selected at a time
colorItems[ count ].addActionListener( itemHandler );
}
// select first Color menu item
colorItems[ 0 ].setSelected( true );
// add format menu to menu bar
formatMenu.add( colorMenu );
formatMenu.addSeparator();
Separator places line
between JMenuItems
// create Font submenu
String fontNames[] = { "Serif", "Monospaced", "SansSerif" };
 2003 Prentice Hall, Inc.
All rights reserved.
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
JMenu fontMenu = new JMenu( "Font" );
fontMenu.setMnemonic( 'n' );
Instantiate Font JMenu
(submenu of Format JMenu)
fonts = new JRadioButtonMenuItem[ fontNames.length ];
fontGroup = new ButtonGroup();
Outline
MenuTest.java
Line 101
// create Font radio button menu items
for ( int count = 0; count < fonts.length; count++ ) {
fonts[ count ] = new JRadioButtonMenuItem( fontNames[ count ] );
Lines 104-105
fontMenu.add( fonts[ count ] );
fontGroup.add( fonts[ count ] );
Instantiate
fonts[ count ].addActionListener( itemHandler );
JRadioButtonMenuItems for
}
// select first Font menu item
fonts[ 0 ].setSelected( true );
Font JMenu and ensure that only
one menu item is selected at a time
fontMenu.addSeparator();
// set up style menu items
String styleNames[] = { "Bold", "Italic" };
styleItems = new JCheckBoxMenuItem[ styleNames.length ];
StyleHandler styleHandler = new StyleHandler();
 2003 Prentice Hall, Inc.
All rights reserved.
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
// create style checkbox menu items
for ( int count = 0; count < styleNames.length; count++ ) {
styleItems[ count ] =
new JCheckBoxMenuItem( styleNames[ count ] );
fontMenu.add( styleItems[ count ] );
styleItems[ count ].addItemListener( styleHandler );
}
Outline
MenuTest.java
// put Font menu in Format menu
formatMenu.add( fontMenu );
// add Format menu to menu bar
bar.add( formatMenu );
// set up label to display text
displayLabel = new JLabel( "Sample Text", SwingConstants.CENTER );
displayLabel.setForeground( colorValues[ 0 ] );
displayLabel.setFont( new Font( "Serif", Font.PLAIN, 72 ) );
getContentPane().setBackground( Color.CYAN );
getContentPane().add( displayLabel, BorderLayout.CENTER );
setSize( 500, 200 );
setVisible( true );
} // end constructor
 2003 Prentice Hall, Inc.
All rights reserved.
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
public static void main( String args[] )
{
MenuTest application = new MenuTest();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
Outline
MenuTest.java
Invoked when user selects JMenuItem
Line 163
menu items
// inner class to handle action events from
private class ItemHandler implements ActionListener {
Lines 168 and 176
// process color and font selections
public void actionPerformed( ActionEvent event )
Determine which font
or 169
colorand
Lines
{
menu generated178
event
// process color selection
for ( int count = 0; count < colorItems.length; count++ )
if ( colorItems[ count ].isSelected() ) {
displayLabel.setForeground( colorValues[ count ] );
break;
}
// process font selection
for ( int count = 0; count < fonts.length; count++ )
177-
Set font or color of JLabel,
respectively
if ( event.getSource() == fonts[ count ] ) {
displayLabel.setFont(
new Font( fonts[ count ].getText(), style, 72 ) );
break;
}
 2003 Prentice Hall, Inc.
All rights reserved.
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
Outline
repaint();
} // end method actionPerformed
MenuTest.java
} // end class ItemHandler
Line 192
Invoked when user selects
// inner class to handle item events from check box menu
items
JCheckBoxMenuItem
private class StyleHandler implements ItemListener {
Lines 197-202
// process font style selections
public void itemStateChanged( ItemEvent e )
{
style = 0;
// check for bold selection
if ( styleItems[ 0 ].isSelected() )
style += Font.BOLD;
Determine new font style
// check for italic selection
if ( styleItems[ 1 ].isSelected() )
style += Font.ITALIC;
displayLabel.setFont(
new Font( displayLabel.getFont().getName(), style, 72 ) );
 2003 Prentice Hall, Inc.
All rights reserved.
206
207
repaint();
208
}
209
210
} // end class StyleHandler
211
212 } // end class MenuTest
Outline
MenuTest.java
 2003 Prentice Hall, Inc.
All rights reserved.
14.8 JPopupMenu
• Context-sensitive popup menus
– JPopupMenu
– Menu generated depending on which component is accessed
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 14.10: PopupTest.java
// Demonstrating JPopupMenus
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PopupTest extends JFrame {
private JRadioButtonMenuItem items[];
private final Color colorValues[] =
{ Color.BLUE, Color.YELLOW, Color.RED };
private JPopupMenu popupMenu;
Outline
PopupTest.java
Line 23
// set up GUI
public PopupTest()
{
super( "Using JPopupMenus" );
ItemHandler handler = new ItemHandler();
String colors[] = { "Blue", "Yellow", "Red" };
// set up popup menu and its items
ButtonGroup colorGroup = new ButtonGroup();
popupMenu = new JPopupMenu();
items = new JRadioButtonMenuItem[ 3 ];
Instantiate JPopupMenu object
 2003 Prentice Hall, Inc.
All rights reserved.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Outline
// construct each menu item and add to popup menu; also
// enable event handling for each menu item
for ( int count = 0; count < items.length; count++ ) {
items[ count ] = new JRadioButtonMenuItem( colors[ count ] );
PopupTest.java
popupMenu.add( items[ count ] );
colorGroup.add( items[ count ] );
Create JRadioButtonMenuItem
Lines 29-32
items[ count ].addActionListener( handler );
objects to add to JPopupMenu
}
Lines 46 and 52
getContentPane().setBackground( Color.WHITE );
// declare a MouseListener for the window that displays
// a JPopupMenu when the popup trigger event occurs
addMouseListener(
new MouseAdapter() {
// anonymous inner class
// handle mouse press event
public void mousePressed( MouseEvent event )
{
checkForTriggerEvent( event );
}
// handle mouse release event
public void mouseReleased( MouseEvent event )
{
checkForTriggerEvent( event );
}
Determine whether popuptrigger event occurred
when user presses or
releases mouse button
 2003 Prentice Hall, Inc.
All rights reserved.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// determine whether event should trigger popup menu
private void checkForTriggerEvent( MouseEvent event )
{
if ( event.isPopupTrigger() )
popupMenu.show(
event.getComponent(), event.getX(), event.getY() );
}
} // end anonymous inner clas
Outline
PopupTest.java
Lines 59-60
Show JPopupMenu if
popup-trigger occurred
); // end call to addMouseListener
setSize( 300, 200 );
setVisible( true );
} // end constructor PopupTest
public static void main( String args[] )
{
PopupTest application = new PopupTest();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
 2003 Prentice Hall, Inc.
All rights reserved.
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// private inner class to handle menu item events
private class ItemHandler implements ActionListener {
// process menu item selections
public void actionPerformed( ActionEvent event )
{
// determine which menu item was selected
for ( int i = 0; i < items.length; i++ )
if ( event.getSource() == items[ i ] ) {
getContentPane().setBackground( colorValues[ i ] );
return;
}
}
} // end private inner class ItemHandler
} // end class PopupTest
Outline
Invoked when user selects
PopupTest.java
JRadioButtonMenuItem
Line 82
Line 87
Determine which
JRadioButtonMenuItem was selected,
then set window background color
 2003 Prentice Hall, Inc.
All rights reserved.
14.9 Pluggable Look-and-Feel
• Pluggable look-and-feel
– Change look-and-feel dynamically
• e.g., Microsoft Windows look-and-feel to Motif look-and-feel
– Flexible
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
// Fig. 14.11: LookAndFeelDemo.java
// Changing the look and feel.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Outline
LookAndFeelDemo
.java
public class LookAndFeelDemo extends JFrame {
Line 9
private final String strings[] = { "Metal", "Motif", "Windows" };
private UIManager.LookAndFeelInfo looks[];
private JRadioButton radio[];
private ButtonGroup group;
Hold installed look-and-feel information
private JButton button;
private JLabel label;
private JComboBox comboBox;
// set up GUI
public LookAndFeelDemo()
{
super( "Look and Feel Demo" );
Container container = getContentPane();
// set up panel for NORTH of BorderLayout
JPanel northPanel = new JPanel();
northPanel.setLayout( new GridLayout( 3, 1, 0, 5 ) );
 2003 Prentice Hall, Inc.
All rights reserved.
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// set up label for NORTH panel
label = new JLabel( "This is a Metal look-and-feel",
SwingConstants.CENTER );
northPanel.add( label );
// set up button for NORTH panel
button = new JButton( "JButton" );
northPanel.add( button );
Outline
LookAndFeelDemo
.java
// set up combo box for NORTH panel
comboBox = new JComboBox( strings );
northPanel.add( comboBox );
// create array for radio buttons
radio = new JRadioButton[ strings.length ];
// set up panel for SOUTH of BorderLayout
JPanel southPanel = new JPanel();
southPanel.setLayout( new GridLayout( 1, radio.length ) );
// set up radio buttons for SOUTH panel
group = new ButtonGroup();
ItemHandler handler = new ItemHandler();
 2003 Prentice Hall, Inc.
All rights reserved.
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
for ( int count = 0; count < radio.length; count++ ) {
radio[ count ] = new JRadioButton( strings[ count ] );
radio[ count ].addItemListener( handler );
group.add( radio[ count ] );
southPanel.add( radio[ count ] );
}
Outline
LookAndFeelDemo
.java
// attach NORTH and SOUTH panels to content pane
container.add( northPanel, BorderLayout.NORTH );
container.add( southPanel, BorderLayout.SOUTH );
// get installed look-and-feel information
looks = UIManager.getInstalledLookAndFeels();
setSize( 300, 200 );
setVisible( true );
radio[ 0 ].setSelected( true );
} // end constructor LookAndFeelDemo
// use UIManager to change look-and-feel of GUI
private void changeTheLookAndFeel( int value )
{
 2003 Prentice Hall, Inc.
All rights reserved.
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// change look and feel
try {
UIManager.setLookAndFeel( looks[ value ].getClassName() );
SwingUtilities.updateComponentTreeUI( this );
}
// process problems changing look and feel
catch ( Exception exception ) {
exception.printStackTrace();
}
Outline
LookAndFeelDemo
.java
Change look-and-feel
Lines 77-78
}
public static void main( String args[] )
{
LookAndFeelDemo application = new LookAndFeelDemo();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
// private inner class to handle radio button events
private class ItemHandler implements ItemListener {
// process user's look-and-feel selection
public void itemStateChanged( ItemEvent event )
{
for ( int count = 0; count < radio.length; count++ )
 2003 Prentice Hall, Inc.
All rights reserved.
101
if ( radio[ count ].isSelected() ) {
102
label.setText( "This is a " +
103
strings[ count ] + " look-and-feel" );
104
comboBox.setSelectedIndex( count );
105
changeTheLookAndFeel( count );
106
}
107
}
108
109
} // end private inner class ItemHandler
110
111 } // end class LookAndFeelDemo
Outline
LookAndFeelDemo
.java
 2003 Prentice Hall, Inc.
All rights reserved.
14.10 JDesktopPane and JInternalFrame
• Multiple document interface
– Main (parent) window
– Child windows
– Switch freely among documents
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Outline
// Fig. 14.12: DesktopTest.java
// Demonstrating JDesktopPane.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class DesktopTest extends JFrame {
private JDesktopPane theDesktop;
DesktopTest.jav
a
Manages JInternalFrame child
Line 8
windows displayed in JDesktopPane
// set up GUI
public DesktopTest()
{
super( "Using a JDesktopPane" );
// create menu bar, menu and menu item
JMenuBar bar = new JMenuBar();
JMenu addMenu = new JMenu( "Add" );
JMenuItem newFrame = new JMenuItem( "Internal Frame" );
addMenu.add( newFrame );
bar.add( addMenu );
setJMenuBar( bar );
// set up desktop
theDesktop = new JDesktopPane();
getContentPane().add( theDesktop );
 2003 Prentice Hall, Inc.
All rights reserved.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// set up listener for newFrame menu item
newFrame.addActionListener(
new ActionListener() {
Outline
Handle event when user
selects JMenuItem
// anonymous inner class
// display new internal window
public void actionPerformed( ActionEvent event ) {
// create internal frame
JInternalFrame frame = new JInternalFrame(
"Internal Frame", true, true, true, true );
// attach panel to internal frame content pane
Container container = frame.getContentPane();
MyJPanel panel = new MyJPanel();
container.add( panel, BorderLayout.CENTER );
// set size internal frame to size of its contents
frame.pack();
DesktopTest.jav
a
Invoked when user
Line 30
selects JMenuItem
Line 35
Create JInternalFrame
Lines 38-39
JPanels can
be added
Lines
43-44
to JInternalFrames
Line 47
Use preferred
size for window
// attach internal frame to desktop and show it
theDesktop.add( frame );
frame.setVisible( true );
}
} // end anonymous inner class
 2003 Prentice Hall, Inc.
All rights reserved.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
); // end call to addActionListener
setSize( 600, 460 );
setVisible( true );
Outline
DesktopTest.jav
a
} // end constructor
public static void main( String args[] )
{
DesktopTest application = new DesktopTest();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
} // end class DesktopTest
// class to display an ImageIcon on a panel
class MyJPanel extends JPanel {
private ImageIcon imageIcon;
private String[] images = { "yellowflowers.png", "purpleflowers.png",
"redflowers.png", "redflowers2.png", "lavenderflowers.png" };
// load image
public MyJPanel()
{
 2003 Prentice Hall, Inc.
All rights reserved.
80
int randomNumber = ( int ) ( Math.random() * 5 );
81
imageIcon = new ImageIcon( images[ randomNumber ] );
82
}
83
84
// display imageIcon on panel
85
public void paintComponent( Graphics g )
86
{
87
// call superclass paintComponent method
88
super.paintComponent( g );
89
90
// display icon
91
imageIcon.paintIcon( this, g, 0, 0 );
92
}
93
94
// return image dimensions
95
public Dimension getPreferredSize()
96
{
97
return new Dimension( imageIcon.getIconWidth(),
98
imageIcon.getIconHeight() );
99
}
100
101 } // end class MyJPanel
Outline
DesktopTest.jav
a
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
Internal Frames
Minimized internal frames
Minimize
Maximize Close
DesktopTest.jav
a
Position the mouse over any corner of
a child window to resize the window (if
resizing is allowed).
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
DesktopTest.jav
a
 2003 Prentice Hall, Inc.
All rights reserved.
14.11 JTabbedPane
• Arranges GUI components into layers
– One layer visible at a time
– Access each layer via a tab
– JTabbedPane
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Outline
// Fig. 14.13: JTabbedPaneDemo.java
// Demonstrating JTabbedPane.
import java.awt.*;
import javax.swing.*;
public class JTabbedPaneDemo extends JFrame
JTabbedPaneDemo
.java
{
Line 14
// set up GUI
public JTabbedPaneDemo()
{
super( "JTabbedPane Demo " );
Line20
// create JTabbedPane
JTabbedPane tabbedPane = new JTabbedPane();
Line 27
Create a
JTabbedPane
// set up pane11 and add it to JTabbedPane
JLabel label1 = new JLabel( "panel one", SwingConstants.CENTER );
JPanel panel1 = new JPanel();
panel1.add( label1 );
tabbedPane.addTab( "Tab One", null, panel1, "First Panel" );
Add the first panel
// set up panel2 and add it to JTabbedPane
JLabel label2 = new JLabel( "panel two", SwingConstants.CENTER );
JPanel panel2 = new JPanel();
Add
panel2.setBackground( Color.YELLOW );
panel2.add( label2 );
tabbedPane.addTab( "Tab Two", null, panel2, "Second Panel" );
the second panel
 2003 Prentice Hall, Inc.
All rights reserved.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
// set up panel3 and add it to JTabbedPane
JLabel label3 = new JLabel( "panel three" );
JPanel panel3 = new JPanel();
panel3.setLayout( new BorderLayout() );
panel3.add( new JButton( "North" ), BorderLayout.NORTH );
panel3.add( new JButton( "West" ), BorderLayout.WEST );
panel3.add( new JButton( "East" ), BorderLayout.EAST );
panel3.add( new JButton( "South" ), BorderLayout.SOUTH );
panel3.add( label3, BorderLayout.CENTER );
tabbedPane.addTab( "Tab Three", null, panel3, "Third Panel" );
// add JTabbedPane to container
getContentPane().add( tabbedPane );
Outline
JTabbedPaneDemo
.java
Line 38
Add the third panel
setSize( 250, 200 );
setVisible( true );
} // end constructor
public static void main( String args[] )
{
JTabbedPaneDemo tabbedPaneDemo = new JTabbedPaneDemo();
tabbedPaneDemo.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
} // end class CardDeck
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
JTabbedPaneDemo
.java
 2003 Prentice Hall, Inc.
All rights reserved.
14.12 Layout Managers: BoxLayout and
GridBagLayout
• Layout Managers
– BoxLayout
– GridBagLayout
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.14 Additional layout managers
Layout Manager
BoxLayout
Description
GridBagLayout
A layout manager similar to GridLayout. Unlike GridLayout, each
component size can vary and components can be added in any order.
A layout manager that allows GUI components to be arranged left-toright or top-to-bottom in a container. Class Box declares a container with
BoxLayout as its default layout manager and provides static methods
to create a Box with a horizontal or vertical BoxLayout.
 2003 Prentice Hall, Inc. All rights reserved.
BoxLayout Layout Manager
• BoxLayout
– Arranges GUI components
• Horizontally along x-axis
• Vertically along y-axis
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// Fig. 14.15: BoxLayoutDemo.java
// Demonstrating BoxLayout.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Outline
BoxLayoutDemo.j
ava
public class BoxLayoutDemo extends JFrame {
Lines 15-18
// set up GUI
public BoxLayoutDemo()
{
super( "Demostrating BoxLayout" );
// create Box containers with BoxLayout
Box horizontal1 = Box.createHorizontalBox();
Box vertical1 = Box.createVerticalBox();
Box horizontal2 = Box.createHorizontalBox();
Box vertical2 = Box.createVerticalBox();
Line 24
Create Boxes
final int SIZE = 3; // number of buttons on each Box
// add buttons to Box horizontal1
for ( int count = 0; count < SIZE; count++ )
horizontal1.add( new JButton( "Button " + count ) );
Add three JButtons to
horizontal Box
 2003 Prentice Hall, Inc.
All rights reserved.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
// create strut and add buttons to Box vertical1
for ( int count = 0; count < SIZE; count++ ) {
vertical1.add( Box.createVerticalStrut( 25 ) );
vertical1.add( new JButton( "Button " + count ) );
}
Add three JButtons to vertical
Box
Outline
// create horizontal glue and add buttons to Box horizontal2
for ( int count = 0; count < SIZE; count++ ) {
horizontal2.add( Box.createHorizontalGlue() );
horizontal2.add( new JButton( "Button " + count ) );
}
Strut guarantees space
BoxLayoutDemo.j
between components
ava
Add three JButtons to
Lines
27-30
horizontal
Box
Line 28
Glue guarantees
expandable
space between components
Lines 33-36
// create rigid area and add buttons to Box vertical2
for ( int count = 0; count < SIZE; count++ ) {
Add three JButtons to vertical
vertical2.add( Box.createRigidArea( new Dimension( 12, 8 ) ) );
Line 34
vertical2.add( new JButton( "Button " + count ) );
Rigid area guarantees
}
Box
Lines
fixed component
size39-42
// create vertical glue and add buttons to panel
JPanel panel = new JPanel();
panel.setLayout( new BoxLayout( panel, BoxLayout.Y_AXIS ) );
Line 40
for ( int count = 0; count < SIZE; count++ ) {
panel.add( Box.createGlue() );
panel.add( new JButton( "Button " + count ) );
}
 2003 Prentice Hall, Inc.
All rights reserved.
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// create a JTabbedPane
JTabbedPane tabs = new JTabbedPane(
JTabbedPane.TOP, JTabbedPane.SCROLL_TAB_LAYOUT );
// place each container on tabbed pane
tabs.addTab( "Horizontal Box", horizontal1 );
tabs.addTab( "Vertical Box with Struts", vertical1 );
tabs.addTab( "Horizontal Box with Glue", horizontal2 );
tabs.addTab( "Vertical Box with Rigid Areas", vertical2 );
tabs.addTab( "Vertical Box with Glue", panel );
getContentPane().add( tabs );
Outline
Create a JTabbedPane
to hold the Boxes
BoxLayoutDemo.j
ava
Lines 54-55
// place tabbed pane on content pane
setSize( 400, 220 );
setVisible( true );
} // end constructor
public static void main( String args[] )
{
BoxLayoutDemo application = new BoxLayoutDemo();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
} // end class BoxLayoutDemo
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
BoxLayoutDemo.j
ava
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
BoxLayoutDemo.j
ava
 2003 Prentice Hall, Inc.
All rights reserved.
GridBagLayout Layout Manager
• GridBagLayout
– Flexible GridBagLayout
• Components can vary in size
• Components can occupy multiple rows and columns
• Components can be added in any order
– Uses GridBagConstraints
• Specifies how component is placed in GridBagLayout
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.16 Designing a GUI that will use
GridBagLayout
Column
0
0
1
Row
2
3
 2003 Prentice Hall, Inc. All rights reserved.
1
2
Fig. 14.17 GridBagConstraints fields
GridBagConstraints
field
fill
Description
gridx
Resize the component in specified direction ( NONE, HORIZONTAL,
VERTICAL, BOTH) when the display area is larger than the
component.
The column in which the component will be placed.
gridy
The row in which the component will be placed.
gridwidth
The number of columns the component occupies.
gridheight
The number of rows the component occupies.
weightx
The portion of extra space to allocate horizontally. The grid slot can
become wider when extra space is available.
weighty
The portion of extra space to allocate vertically. The grid slot can
become taller when extra space is available.
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.18 GridBagLayout with the weights
set to zero
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
Outline
// Fig. 14.19: GridBagDemo.java
// Demonstrating GridBagLayout.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
GridBagDemo.jav
a
public class GridBagDemo extends JFrame {
private Container container;
private GridBagLayout layout;
private GridBagConstraints constraints;
Line 19
Line 22
// set up GUI
public GridBagDemo()
{
super( "GridBagLayout" );
container = getContentPane();
layout = new GridBagLayout();
container.setLayout( layout );
Set GridBagLayout
as layout manager
// instantiate gridbag constraints
constraints = new GridBagConstraints();
// create GUI components
JTextArea textArea1 = new JTextArea( "TextArea1", 5, 10 );
JTextArea textArea2 = new JTextArea( "TextArea2", 2, 2 );
Used to determine
component location
and size in grid
 2003 Prentice Hall, Inc.
All rights reserved.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
Outline
String names[] = { "Iron", "Steel", "Brass" };
JComboBox comboBox = new JComboBox( names );
JTextField textField = new JTextField(
JButton button1 = new JButton( "Button
JButton button2 = new JButton( "Button
JButton button3 = new JButton( "Button
"TextField" );
1" );
2" );
3" );
If user resizes GridBagDemo.jav
Container,
first JTextArea
is filled
a
entire allocated area in grid
Line 38
First
JTextArea
spans
// weightx and weighty for textArea1 are both 0: the default
one row and three columns
// anchor for all components is CENTER: the default
Line 39
constraints.fill = GridBagConstraints.BOTH;
If user resizes Container, first
addComponent( textArea1, 0, 0, 1, 3 );
JButton fills horizontally
Linein
42grid
// weightx and weighty for button1 are both 0: the default
constraints.fill = GridBagConstraints.HORIZONTAL;
addComponent( button1, 0, 1, 2, 1 );
// weightx and weighty for comboBox are both 0: the default
// fill is HORIZONTAL
addComponent( comboBox, 2, 1, 2, 1 );
If user
// button2
constraints.weightx = 1000; // can grow wider
constraints.weighty = 1;
// can grow taller
constraints.fill = GridBagConstraints.BOTH;
addComponent( button2, 1, 1, 1, 1 );
Line
43 two
First JButton
spans
rows and one column
Line 51
resizes Container,
second JButton fills extra space
 2003 Prentice Hall, Inc.
All rights reserved.
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
// fill is BOTH for button3
constraints.weightx = 0;
constraints.weighty = 0;
addComponent( button3, 1, 2, 1, 1 );
// weightx and weighty for textField are both 0, fill is BOTH
addComponent( textField, 3, 0, 2, 1 );
Outline
GridBagDemo.jav
a
// weightx and weighty for textArea2 are both 0, fill is BOTH
addComponent( textArea2, 3, 2, 1, 1 );
setSize( 300, 150 );
setVisible( true );
} // end constructor GridBagDemo
// method to set constraints on
private void addComponent( Component component,
int row, int column, int width, int height )
{
// set gridx and gridy
constraints.gridx = column;
constraints.gridy = row;
 2003 Prentice Hall, Inc.
All rights reserved.
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// set gridwidth and gridheight
constraints.gridwidth = width;
constraints.gridheight = height;
// set constraints and add component
layout.setConstraints( component, constraints );
container.add( component );
Outline
GridBagDemo.jav
a
}
public static void main( String args[] )
{
GridBagDemo application = new GridBagDemo();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
} // end class GridBagDemo
 2003 Prentice Hall, Inc.
All rights reserved.
Outline
GridBagDemo.jav
a
 2003 Prentice Hall, Inc.
All rights reserved.
GridBagConstraints Constants RELATIVE
and REMAINDER
• Constants RELATIVE and REMAINDER
– Used in place of variables gridx and gridy
– RELATIVE
• Specifies next-to-last component placement in row or column
• Component should be placed next to one previously added
– REMAINDER
• Specifies component as last component in row or column
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Fig. 14.20: GridBagDemo2.java
// Demonstrating GridBagLayout constants.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GridBagDemo2 extends JFrame {
private GridBagLayout layout;
private GridBagConstraints constraints;
private Container container;
Outline
GridBagDemo2.ja
va
Lines 18-19
Line 22
// set up GUI
public GridBagDemo2()
{
super( "GridBagLayout" );
container = getContentPane();
layout = new GridBagLayout();
container.setLayout( layout );
// instantiate gridbag constraints
constraints = new GridBagConstraints();
// create GUI components
String metals[] = { "Copper", "Aluminum", "Silver" };
JComboBox comboBox = new JComboBox( metals );
Set GridBagLayout
as layout manager
Used to determine
component location
and size in grid
 2003 Prentice Hall, Inc.
All rights reserved.
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Outline
JTextField textField = new JTextField( "TextField" );
String fonts[] = { "Serif", "Monospaced" };
JList list = new JList( fonts );
String names[] = { "zero", "one", "two", "three", "four" };
JButton buttons[] = new JButton[ names.length ];
GridBagDemo2.ja
va
Line 43
for ( int count = 0; count < buttons.length; count++ )
buttons[ count ] = new JButton( names[ count ] );
// define GUI component constraints for textField
constraints.weightx = 1;
constraints.weighty = 1;
constraints.fill = GridBagConstraints.BOTH;
constraints.gridwidth = GridBagConstraints.REMAINDER;
addComponent( textField );
Line 48
Specify textField as last
Linerow
52
(only) component in first
// buttons[0] -- weightx and weighty are 1: fill is BOTH
constraints.gridwidth = 1;
addComponent( buttons[ 0 ] );
// buttons[1] -- weightx and weighty are 1: fill is BOTH
constraints.gridwidth = GridBagConstraints.RELATIVE;
addComponent( buttons[ 1 ] );
Place button[0] as first
component in second row
Place button[1] right
next to button[0]
 2003 Prentice Hall, Inc.
All rights reserved.
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
// buttons[2] -- weightx and weighty are 1: fill is BOTH
constraints.gridwidth = GridBagConstraints.REMAINDER;
addComponent( buttons[ 2 ] );
// comboBox -- weightx is 1: fill is BOTH
constraints.weighty = 0;
constraints.gridwidth = GridBagConstraints.REMAINDER;
addComponent( comboBox );
// buttons[3] -- weightx is 1: fill is BOTH
constraints.weighty = 1;
constraints.gridwidth = GridBagConstraints.REMAINDER;
addComponent( buttons[ 3 ] );
// buttons[4] -- weightx and weighty are 1: fill is BOTH
constraints.gridwidth = GridBagConstraints.RELATIVE;
addComponent( buttons[ 4 ] );
// list -- weightx and weighty are 1: fill is BOTH
constraints.gridwidth = GridBagConstraints.REMAINDER;
addComponent( list );
Outline
Place button[2] right
next to button[1]
GridBagDemo2.ja
va
Specify comboBox as last
Line 56
(only) component in third row
Line 61
Specify buttons[3]
Line 66 as last
(only) component in fourth row
Line 70
Place button[4] as first
component inLine
fifth74row
Specify list as last
component in fifth row
setSize( 300, 200 );
setVisible( true );
}
// end constructor
 2003 Prentice Hall, Inc.
All rights reserved.
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// add a Component to the container
private void addComponent( Component component )
{
layout.setConstraints( component, constraints );
container.add( component );
// add component
}
Outline
GridBagDemo2.ja
va
public static void main( String args[] )
{
GridBagDemo2 application = new GridBagDemo2();
application.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
}
// end class GridBagDemo2
 2003 Prentice Hall, Inc.
All rights reserved.
14.13 (Optional Case Study) Thinking About
Objects: Model-View-Controller
• Model-View-Controller
– Architectural pattern for building systems
– Divide system responsibilities into three parts
• Model
– Maintains program data and logic
• View
– Visual representation of model
• Controller
– Processes user input and modifies model
– Step by step
• User uses controller to change data in model
• Model then informs view of change
• View changes visual presentation to reflect change
 2003 Prentice Hall, Inc. All rights reserved.
Model-View-Controller Elevator Simulation
• Model-View-Controller in elevator simulation
– Example
• User presses First Floor of Second Floor Jbutton
– Controller adds Person to model
• Model notifies view of Person’s creation
• View displays Person on Floor in response to notification
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.21 Class diagram of the elevator
simulation
javax.swing.JFrame
application
1
ElevatorCaseStudy
1
1
ElevatorSimulationListener
1
1
ElevatorSimulation
MVC model
 2003 Prentice Hall, Inc. All rights reserved.
ElevatorView
view
1
ElevatorController
controller
14.13 (Optional Case Study) Thinking About
Objects: Model-View-Controller
• Component diagram (UML)
– Models “pieces” (components) used by system
• e.g., .class file, .java files, images, packages, etc.
– Notation
• Components are represented as “plugs”
• Packages are represented as “folders”
• Dotted arrows indicate dependencies among components
– Changing one component requires changing another
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.22 Artifacts of the elevator simulation
model
executable
ElevatorCaseStudy.class
<<file>>
ElevatorSimulation.java
compilation
ElevatorSimulationListener
imports
view
<file>>
<<file>>
imports
ElevatorView.java
ElevatorCaseStudy.java
controller
imports
<file>>
ElevatorController.java
 2003 Prentice Hall, Inc. All rights reserved.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Outline
// ElevatorController.java
// Controller for Elevator Simulation
package com.deitel.jhtp5.elevator.controller;
ElevatorControl
ler.java
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
Line 15
// Deitel packages
import com.deitel.jhtp5.elevator.model.*;
import com.deitel.jhtp5.elevator.event.*;
import com.deitel.jhtp5.elevator.ElevatorConstants;
Lines 19-20
public class ElevatorController extends JPanel
implements ElevatorConstants {
// controller contains two JButtons
private JButton firstControllerButton;
private JButton secondControllerButton;
ElevatorController
GUI for elevator simulation
JButtons for creating
Persons on Floor
// reference to ElevatorSimulation
private ElevatorSimulation elevatorSimulation;
 2003 Prentice Hall, Inc.
All rights reserved.
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public ElevatorController( ElevatorSimulation simulation )
{
elevatorSimulation = simulation;
setBackground( Color.WHITE );
// add first button to controller
firstControllerButton = new JButton( "First Floor" );
add( firstControllerButton );
// add second button to controller
secondControllerButton = new JButton( "Second Floor" );
add( secondControllerButton );
// anonymous inner class registers to receive ActionEvents
// from first Controller JButton
firstControllerButton.addActionListener(
new ActionListener() {
// invoked when a JButton has been pressed
public void actionPerformed( ActionEvent event )
{
// place Person on first Floor
elevatorSimulation.addPerson(
FIRST_FLOOR_NAME );
Outline
ElevatorControl
ler.java
Line 40
Lines 47-48
Register JButtons with
separate anonymous
ActionListeners
Add Person to respective
Floor, depending on
JButton that user pressed
 2003 Prentice Hall, Inc.
All rights reserved.
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// disable user input
firstControllerButton.setEnabled( false );
}
} // end anonymous inner class
);
// anonymous inner class registers to receive ActionEvents
// from second Controller JButton
secondControllerButton.addActionListener(
new ActionListener() {
// invoked when a JButton has been pressed
public void actionPerformed( ActionEvent event )
{
// place Person on second Floor
elevatorSimulation.addPerson(
SECOND_FLOOR_NAME );
Outline
ElevatorControl
ler.java
Line 58
Register JButtons
with
separate anonymous
Lines 65-66
ActionListeners
Lines 51 and 69
Add Person to respective
Floor, depending on
JButton that user pressed
// disable user input
secondControllerButton.setEnabled( false );
}
} // end anonymous inner class
);
Disable JButton after
Person is created (so user
cannot create more than one
Person on Floor)
 2003 Prentice Hall, Inc.
All rights reserved.
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// anonymous inner class enables user input on Floor if
// Person enters Elevator on that Floor
elevatorSimulation.addPersonMoveListener(
new PersonMoveListener() {
// invoked when Person has entered Elevator
public void personEntered(
PersonMoveEvent event )
{
// get Floor of departure
String location =
event.getLocation().getLocationName();
Outline
ElevatorControl
Enable ElevatorModel
ler.java
to listener for
PersonMoveEvents
Line 76
Lines 89 and 93
// enable first JButton if first Floor departure
if ( location.equals( FIRST_FLOOR_NAME ) )
firstControllerButton.setEnabled( true );
// enable second JButton if second Floor
else
secondControllerButton.setEnabled( true );
} // end method personEntered
// other methods implementing PersonMoveListener
public void personCreated(
PersonMoveEvent event ) {}
Enable JButton after Person
enters Elevator (so user can
create another Person)
 2003 Prentice Hall, Inc.
All rights reserved.
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116 }
public void personArrived(
PersonMoveEvent event ) {}
public void personExited(
PersonMoveEvent event ) {}
Outline
ElevatorControl
ler.java
public void personDeparted(
PersonMoveEvent event ) {}
public void personPressedButton(
PersonMoveEvent event ) {}
} // end anonymous inner class
);
} // end ElevatorController constructor
 2003 Prentice Hall, Inc.
All rights reserved.
1
2
3
4
5
6
7
8
9
10
// ElevatorConstants.java
// Constants used between ElevatorModel and ElevatorView
package com.deitel.jhtp5.elevator;
public interface ElevatorConstants {
Outline
ElevatorConstan
ts.java
public static final String FIRST_FLOOR_NAME = "firstFloor";
public static final String SECOND_FLOOR_NAME = "secondFloor";
public static final String ELEVATOR_NAME = "elevator";
}
 2003 Prentice Hall, Inc.
All rights reserved.
14.13 (Optional Case Study) Thinking About
Objects: Model-View-Controller
• Classes Location
– Subclasses Elevator and Floor
• Attribute capacity no longer needed
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.25 Modified class diagram showing generalization of
superclass Location and subclasses Elevator and Floor
Location
- locationName : String
# setLocationName( String ) : void
+ getLocationName( ) : String
+ getButton( ) : Button
+ getDoor( ) : Door
Elevator
- moving : Boolean = false
- summoned : Boolean = false
- currentFloor : Location
- destinationFloor : Location
- travelTime : Integer = 5
+ ride( ) : void
+ requestElevator( ) : void
+ enterElevator( ) : void
+ exitElevator( ) : void
+ departElevator( ) : void
+ getButton( ) : Button
+ getDoor( ) : Door
 2003 Prentice Hall, Inc. All rights reserved.
Floor
+ getButton( ) : Button
+ getDoor( ) : Door
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
Outline
// ElevatorCaseStudy.java
// Application with Elevator Model, View, and Controller (MVC)
package com.deitel.jhtp5.elevator;
ElevatorCaseStu
dy.java
// Java core packages
import java.awt.*;
Lines 12-14
// Java extension packages
import javax.swing.*;
// Deitel packages
import com.deitel.jhtp5.elevator.model.*;
import com.deitel.jhtp5.elevator.view.*;
import com.deitel.jhtp5.elevator.controller.*;
Lines 19-21
Import packages model,
view and controller
public class ElevatorCaseStudy extends JFrame {
// model, view and controller
private ElevatorSimulation model;
private ElevatorView view;
private ElevatorController controller;
// constructor instantiates model, view, and controller
public ElevatorCaseStudy()
{
ElevatorCaseStudy
aggregates one instance
each of classes
ElevatorSimulation,
ElevatorView and
ElevatorController
 2003 Prentice Hall, Inc.
All rights reserved.
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
super( "Deitel Elevator Simulation" );
// instantiate model, view and controller
model = new ElevatorSimulation();
view = new ElevatorView();
controller = new ElevatorController( model );
// register View for Model events
model.setElevatorSimulationListener( view );
// add view and controller to ElevatorCaseStudy
getContentPane().add( view, BorderLayout.CENTER );
getContentPane().add( controller, BorderLayout.SOUTH );
} // end ElevatorCaseStudy constructor
// main method starts program
public static void main( String args[] )
{
// instantiate ElevatorCaseStudy
ElevatorCaseStudy simulation = new ElevatorCaseStudy();
simulation.setDefaultCloseOperation( EXIT_ON_CLOSE );
simulation.pack();
simulation.setVisible( true );
}
Outline
ElevatorCaseStu
dy.java
Line 34
Register ElevatorSimulation
as listener for ElevatorView
Lines 37-38
Add ElevatorView and
ElevatorController to
ElevatorCaseStudy
}
 2003 Prentice Hall, Inc.
All rights reserved.
14.14 (Optional) Discovering Design Patterns: Design Patterns
Used in Packages java.awt and javax.swing
• Continue design-patterns discussion
– Design patterns associated with Java GUI components
• GUI components take advantage of design patterns
 2003 Prentice Hall, Inc. All rights reserved.
14.14.1 Creational Design Patterns
• Factory Method design pattern
– Suppose we design system that opens image from file
• Several image formats exist (e.g., GIF, JPEG, etc.)
– Each image format has different structure
• Method createImage of class Component creates Image
• Two Image objects (one for GIF image, one for JPEG image)
• Method createImage uses parameter to determine proper
Image subclass from which to instantiate Image object
createImage( "image.gif" );
– Returns Image object with GIF data
createImage( "image.jpg" );
– Returns Image object with JPEG data
• Method createImage is called a factory method
– Determines subclass to instantiate object at run time
 2003 Prentice Hall, Inc. All rights reserved.
14.14.2 Structural Design Patterns
• Adapter design pattern
– Used with objects with incompatible interfaces
• Allows these objects to collaborate with each other
• Object’s interface adapts to another object’s interface
– Similar to adapter for plug on electrical device
• European electrical sockets differ from those in United States
• American plug will not work with European socket
• Use adapter for plug
– Class MouseAdapter
• Objects that generate MouseEvents adapts to objects that
handle MouseEvents
 2003 Prentice Hall, Inc. All rights reserved.
14.14.2 Structural Design Patterns
• Bridge design pattern
– Design class Button for Windows and Macintosh systems
• Class contains button information (e.g., String label)
• Subclasses Win32Button and MacButton
– Contain look-and-feel information
• Problem with this approach
– Creating class ImageButton (subclass of Button)
• Requires creating Win32ImageButton and
MacImageButton
• Solution:
– Separate abstraction (i.e., Button) from implementation
(i.e., Win32Button and MacButton)
– Button contains reference (bridge) to ButtonPeer
• Handles platform-specific implementations
 2003 Prentice Hall, Inc. All rights reserved.
14.14.2 Structural Design Patterns
• Composite design pattern
– Organize components into hierarchical structures
• Each node represents component
• All nodes implement same interface
– Polymorphism ensures clients traverse all nodes uniformly
– Used by Swing components
• JPanel is JContainer subclass
• JPanel object can contain GUI component
– JPanel remains unaware of component’s specific type
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.27 Inheritance hierarchy for class
JPanel
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing.JPanel
 2003 Prentice Hall, Inc. All rights reserved.
14.14.3 Behavioral Design Patterns
• Chain-of-Responsibility design pattern
– Determine object that handles message at run time
– Three-line office-phone system
• First line handles call
• If first line is busy, second line handles call
• If second line is busy, third line handles call
– Message sent through “chain”
• Each object in chain decides whether to handle message
– If unable to handle message, that object sends message to
next object in chain
– Method processEvent of class Button
• Handles AWTEvent or sends to next object
 2003 Prentice Hall, Inc. All rights reserved.
14.14.3 Behavioral Design Patterns
• Command design pattern
– Applications provide several ways to perform same task
• Edit menu with menu items for cutting and copying text
• Toolbar and popup menus may offer same feature
– Encapsulate functionality (command) in reusable object
• e.g., “cut text” functionality
• Functionality can then be added to menus, toolbars, etc.
• Developers code functionality only once
 2003 Prentice Hall, Inc. All rights reserved.
14.14.3 Behavioral Design Patterns
• Observer design pattern
– Design program for viewing bank-account information
• Class BankStatementData store bank-statement data
• Class TextDisplay displays data in text format
• Class BarGraphDisplay displays data in bar-graph format
• Class PieChartDisplay displays data in pie-chart format
• BankStatementData (subject) notifies Display classes
(observers) to display data when it changes
– Subject notifies observers when subject changes state
• Observers act in response to notification
• Promotes loose coupling
– Used by
• class java.util.Observable
• class java.util.Observer
 2003 Prentice Hall, Inc. All rights reserved.
Fig. 14.28 Basis for the Observer design
pattern
Observers
TextDisplay
Subject
BankStatementData
notifies
BarGraphDisplay
PieChartDisplay
 2003 Prentice Hall, Inc. All rights reserved.
14.14.3 Behavioral Design Patterns
• Strategy design pattern
– Encapsulates algorithm
– LayoutManagers are strategy objects
• Classes FlowLayout, BorderLayout, GridLayout, etc.
– Implement interface LayoutManager
• Each class uses method addLayoutComponent
– Each method implementation uses different algorithm
• FlowLayout adds components left-to-right
• BorderLayout adds components in five regions
• GridLayout adds components in specified grid
• Class Container has LayoutManager reference
– Use method setLayout
• Select different layout manager at run time
 2003 Prentice Hall, Inc. All rights reserved.
14.14.3 Behavioral Design Patterns
• Template Method design pattern
– Objects share single algorithm defined in superclass
– Consider Fig.14.28
• Display objects use same algorithm to acquire and display data
– Get statements from BankStatementData
– Parse statements
– Display statements
• Create superclass BankStatementDisplay
– Provides methods that comprise algorithm
– Subclasses override “display” method, because each
subclass displays data differently
 2003 Prentice Hall, Inc. All rights reserved.