Title: Chapter 17 GUI Programming Component Layout, Additional GUI Components
1Chapter 17GUI Programming - Component Layout,
Additional GUI Components
- Layout Managers
- Assigning the Layout Manager
- FlowLayout Manager
- FlowLayout Alignment
- Layout Changes
- BorderLayout Manager
- Label Alignment
- GridLayout Manager
- Tic-Tac-Toe Program
- Embedded Layout Managers
- JPanel Class
- MathCalculator Program
- JTextArea Component
- JCheckBox Component
- JRadioButton Component
- JComboBox Component
- Job Application Example
2Layout Managers
- Layout managers automate the positioning of
components within containers. - They free the programmer from the difficult task
of figuring out the space needed for each
component and the pixel coordinate positions for
each component. - The layout manager looks at the size of its
container and the sizes of the container's
components. It then tries to fit the components
neatly into the container. - If a user resizes the window, the layout manager
takes that into account and adjusts the layout
accordingly. - If a programmer adjusts a component's size (e.g.,
by changing a label's font size), the layout
manager takes that into account and adjusts the
layout accordingly.
3Layout Managers
- The four most common layout manager classes
- FlowLayout
- BorderLayout
- GridLayout
- GridBagLayout
- All of these layout manager classes are in the
java.awt package so import that package.
4Assigning the Layout Manager
- To assign a particular layout manager to a JFrame
window, call the setLayout method as follows - setLayout(new ltlayout-manager-classgt())
- In the above code template, replace
ltlayoutmanagerclassgt by one of the layout
manager classes (e.g., FlowLayout, BorderLayout,
GridLayout). - If setLayout is not called, then the BorderLayout
manager is used (because that's the default
layout manager for a JFrame window).
5FlowLayout Manager
- The FlowLayout class implements a simple
one-compartment layout scheme that allows
multiple components to be inserted into the
compartment. - When a component is added to the compartment, it
is placed to the right of any components that
were previously added to the compartment. - If there is not enough room to add a component to
the right of previously added components, then
the new component is placed on the next line
(i.e., it "flows" to the next line).
6FlowLayout Alignment
- By default, components are placed in a FlowLayout
container using top, center alignment. - There's no way to change the vertical alignment.
But there is a way to change the horizontal
alignment. To do so, insert one of the FlowLayout
alignment constants (FlowLayout.LEFT,
FlowLayout.CENTER, FlowLayout.RIGHT) in the
FlowLayout constructor call. For example, here's
how to specify left alignment - setLayout(new FlowLayout(FlowLayout.LEFT))
7Layout Changes
- Normally, setLayout is called just once - when
the program initially lays out its components.
But if there's a need to dynamically adjust the
layout scheme, call setLayout again and then call
validate. For example, if you need to move a
container's components to the right, reassign the
layout like this - setLayout(new FlowLayout(FlowLayout.RIGHT))
- validate()
- The validate method causes the layout manager to
regenerate the component layout. If you attempt
to change your windows layout in some way (after
the window is initially displayed with
setVisible(true)), you'll need to call validate
to make the change take effect. - These method calls attempt to change the layout
- setLayout - adjust the layout scheme
- add - add a component
- remove remove a component
- setSize - change the window's size
8BorderLayout Manager
- The BorderLayout manager provides five
regions/compartments in which to insert
components. - The sizes of the five regions are determined at
run time, and they're based on the contents of
each region. - Thus, if the west region contains a long label,
the layout manager attempts to widen the west
region.
- Likewise, if the west region contains a short
label, the layout manager attempts to narrow the
west region.
9BorderLayout Manager
- More specifically, the sizes of the five regions
are determined as shown below.
East's contents determine this divider's position.
West's contents determine this divider's position.
North's contents determine this divider's
position.
South's contents determine this divider's
position.
10BorderLayout Manager
- If an outer region (North, South, East, West) is
empty, it collapses so that it does not take up
any space. - For example
- What happens if the north region is empty?
- What happens if the east and south regions are
both empty? - What happens if the center region is empty?
11BorderLayout Manager
- To add a component to a BorderLayout region, call
the container's add method like this - add(ltcomponentgt, ltregiongt)
- Replace ltcomponentgt by a component (a JLabel
object, a JButton object, etc.) and replace
ltregiongt by one of these named constants - BorderLayout.NORTH, BorderLayout.SOUTH,
BorderLayout.WEST, BorderLayout.EAST,
BorderLayout.CENTER - In the add method call, if the region argument is
omitted, then the center region is used (because
that's the default region). - With a BorderLayout container, you can add only
five components total, one for each of the five
regions. If you add a component to a region that
already has a component, then the new component
overlays the old component.
12AfricanCountries Program with Buttons
- import javax.swing.
- import java.awt.
- public class AfricanCountries extends JFrame
-
- private static final int WIDTH 325
- private static final int HEIGHT 200
- public AfricanCountries()
-
- setTitle("African Countries")
- setSize(WIDTH, HEIGHT)
- setLayout(new BorderLayout())
- setDefaultCloseOperation(EXIT_ON_CLOSE)
- add(new JButton("Tunisia"),
BorderLayout.NORTH) - add(new JButton("lthtmlgtSouthltbr
/gtAfricalt/htmlgt"), BorderLayout.SOUTH) - add(new JButton("Western Sahara"),
BorderLayout.WEST) - add(new JButton("Central African Republic"),
BorderLayout.CENTER) - add(new JButton("Somalia"),
BorderLayout.EAST)
13Label Alignment
- To specify a label's alignment within a
BorderLayout region, instantiate the label with
an alignment constant like this - new JLabel(ltlabel's-textgt, ltalignment-constantgt)
- Replace ltalignment-constantgt by one of these
named constants - SwingConstants.LEFT, SwingConstants.CENTER,
SwingConstants.RIGHT - Here's an example that adds a center-aligned
label to a BorderLayout north region - add(new JLabel("Tunisia", SwingConstants.CENTER),
- BorderLayout.NORTH)
14Label Alignment
- SwingConstants is an interface, defined in the
javax.swing package. - SwingConstants stores a set of GUI-related
constants that are commonly used by many
different GUI programs. - To access a named constant in an interface,
prefix it with the interface name. For example,
to access the LEFT alignment constant, prefix
LEFT with SwingConstants like this - SwingConstants.LEFT.
15GridLayout Manager
- The GridLayout manager lays out a container's
components in a rectangular grid. The grid is
divided into equal-sized cells. Each cell can
hold only one component. - To specify the use of a GridLayout manager for a
particular container, call setLayout like this - setLayout(new GridLayout(rows, cols, hGap, vGap))
of rows
Gap between columns, in pixels. Default value 0.
of columns
Gap between rows, in pixels. Default value 0.
16Adding Components
- To add a component to one of the container's
cells, call the add method like this - add(ltcomponentgt)
- The GridLayout manager positions components
within the container using left-to-right,
top-to-bottom order. The first added component
goes in the top-left-corner cell, the next added
component goes in the cell to the right of the
first component, etc.
17GridLayout Manager
- Here's an example that displays a two-row,
three-column table with six buttons - setLayout(new GridLayout(2, 3, 5, 5))
- add(new JButton("1"))
- add(new JButton("2"))
- add(new JButton("3"))
- add(new JButton("4"))
- add(new JButton("5"))
- add(new JButton("6"))
vertical gap 5 pixels
horizontal gap 5 pixels
18Specifying Number of Rows and Number of Columns
- Case 1
- If you know the number of rows and columns in
your table and the table is completely filled in
(i.e., there are no empty cells), call the
GridLayout constructor with the actual number of
rows and the actual number of columns. - Case 2
- Sometimes, you might want a row-oriented display.
- If that's the case, call the GridLayout
constructor with the actual number of rows for
the rows argument and 0 for the columns argument. - A 0 for the columns argument indicates that
you're leaving it up to the GridLayout manager to
determine the number of columns.
19Specifying Number of Rows and Number of Columns
- Case 2 (continued)
- Assume that you assign a container's layout like
this - setLayout(new GridLayout(2, 0))
- Assume that you add 5 buttons to the container.
- Here's the resulting display
20Specifying Number of Rows and Number of Columns
- Case 3
- Sometimes, you might want a column-oriented
display. - If that's the case, call the GridLayout
constructor with the actual number of columns for
the columns argument and 0 for the rows argument. - Assume that you assign a container's layout like
this - setLayout(new GridLayout(0, 4))
- After adding 5 buttons to the container, here's
the resulting display
21Common Errors
- If you call the GridLayout constructor with 0's
for both the rows and columns arguments, you'll
get a compilation error i.e., this generates a
compilation error - setLayout(new GridLayout(0, 0))
- If you call the GridLayout constructor with
non-0's for both the rows and columns arguments
and your table is not completely filled, you may
get unexpected results. - For example, the previous slide's four-column
window is not completely filled. Suppose you
accidentally specify a value for the rows
argument - setLayout(new GridLayout(2, 4))
- After adding 5 components to the container,
here's the resulting display
22Tic-Tac-Toe Program
This program displays a 3x3 grid of blank
buttons. When the first blank button is clicked,
its label changes to an X. Subsequent clicked
blank buttons change their labels to O and X in
alternating sequence.
- import javax.swing.
- import java.awt.
- import java.awt.event.
- public class TicTacToe extends JFrame
-
- private static final int WIDTH 200
- private static final int HEIGHT 220
- // keeps track of whether it's X's turn or O's
turn - private boolean xTurn true
- //
- public TicTacToe()
-
- setTitle("Tic-Tac-Toe")
- setSize(WIDTH, HEIGHT)
- setDefaultCloseOperation(EXIT_ON_CLOSE)
23Tic-Tac-Toe Program
- //
- // Create components and add to window.
- private void createContents()
-
- JButton button // re-instantiate this button
and use - // to fill entire board
- setLayout(new GridLayout(3, 3))
- for (int i0 ilt3 i)
-
- for (int j0 jlt3 j)
-
- button new JButton()
- button.addActionListener(new Listener())
- add(button)
- // end for j
- // end for i
24Tic-Tac-Toe Program
- //
- // If user clicks a button, change its label to
"X" or "O". - private class Listener implements
ActionListener -
- public void actionPerformed(ActionEvent e)
-
- JButton btn (JButton) e.getSource()
- if (btn.getText().isEmpty())
-
- btn.setText(xTurn ? "X" "O")
- xTurn !xTurn
-
- // end actionPerformed
- // end class Listener
- //
getSource's return type is Object. The JButton
cast operator is necessary to prevent a
compilation error.
25Embedded Layout Managers
- What layout manager scheme should be used for
this math-calculator window?
- The GridLayout manager is usually pretty good at
positioning components in an organized tabular
fashion, but it's limited by the fact that each
of its cells must be the same size.
26JPanel Class
- A JPanel container object is a generic storage
area for components. - If you have a complicated window with lots of
components, you may want to compartmentalize them
by storing groups of components in JPanel
containers. - JPanel containers are particularly useful with
GridLayout and BorderLayout windows because each
compartment in those layouts can store only one
component. If you need a compartment to store
more than one component, let that one component
be a JPanel container, and put multiple
components into the JPanel container.
27JPanel Class
- When using a JPanel container, do these things
- Since JPanel is in the javax.swing package,
import that package. - Instantiate a JPanel object
- JPanel ltJPanel-referencegt new
JPanel(ltlayout-managergt) - Add the components to the JPanel object
- ltJPanel-referencegt.add(ltcomponentgt)
- Add the JPanel object to the window
- add(ltJPanel-referencegt)
Optional argument. Default FlowLayout with
center alignment.
28JPanel Class
- For example, to create the top-left cell's panel
in the math-calculations program, do this - In the createContents method
- xPanel new JPanel(new FlowLayout(FlowLayout.CENT
ER)) - xPanel.add(xLabel)
- xPanel.add(xBox)
- add(xPanel)
29This MathCalculator program uses embedded layout
managers to display square root and logarithm
calculations.
- import javax.swing.
- import java.awt.
- import java.awt.event.
- public class MathCalculator extends JFrame
-
- private static final int WIDTH 380
- private static final int HEIGHT 110
- private JTextField xBox // user's input
value - private JTextField xSqrtBox // generated
square root - private JTextField xLogBox // generated
logarithm - //
- public MathCalculator()
-
- setTitle("Math Calculator")
- setSize(WIDTH, HEIGHT)
30MathCalculator Program
- //
- // Create components and add to window.
- private void createContents()
-
- JPanel xPanel // holds x label and its
text box - JPanel xSqrtPanel // holds "sqrt x" label
and its text box - JPanel xLogPanel // holds "log x" label and
its text box - JLabel xLabel
- JButton xSqrtButton
- JButton xLogButton
- Listener listener
- setLayout(new GridLayout(2, 2))
- // Create the x panel
- xLabel new JLabel("x")
- xBox new JTextField(8)
31MathCalculator Program
- // Create the square-root panel
- xSqrtButton new JButton("sqrt x")
- xSqrtBox new JTextField(8)
- xSqrtBox.setEditable(false)
- xSqrtPanel new JPanel(new
FlowLayout(FlowLayout.RIGHT)) - xSqrtPanel.add(xSqrtButton)
- xSqrtPanel.add(xSqrtBox)
- // Create the logarithm panel
- xLogButton new JButton("log x")
- xLogBox new JTextField(8)
- xLogBox.setEditable(false)
- xLogPanel new JPanel(new FlowLayout(FlowLayo
ut.RIGHT)) - xLogPanel.add(xLogButton)
- xLogPanel.add(xLogBox)
- // Add panels to the window
- add(xPanel)
- add(xSqrtPanel)
32MathCalculator Program
- listener new Listener()
- xSqrtButton.addActionListener(listener)
- xLogButton.addActionListener(listener)
- // end createContents
- //
- // Inner class for event handling.
- private class Listener implements
ActionListener -
- public void actionPerformed(ActionEvent e)
-
- double x // numeric value for user
entered x - double result // calculated value
- try
-
- x Double.parseDouble(xBox.getText())
33MathCalculator Program
- if (e.getActionCommand().equals("sqrt x"))
-
- if (x lt 0)
-
- xSqrtBox.setText("undefined")
-
- else
-
- result Math.sqrt(x)
- xSqrtBox.setText(String.format("7.5f",
result)) -
- // end if
- else // calculate logarithm
-
- if (x lt 0)
-
- xLogBox.setText("undefined")
-
getActionCommand retrieves the label of the
button that was clicked.
34MathCalculator Program
- // end else
- // end actionPerformed
- // end class Listener
- //
- public static void main(String args)
-
- new MathCalculator()
- // end main
- // end class MathCalculator
35JTextArea Component
- The JLabel component works great for displaying a
single line of text. But for displaying multiple
lines of text, you should use a JTextArea
component.
JTextArea component
JCheckBox component
36JTextArea Component
- To create a JTextArea component, call the
JTextArea constructor like this - JTextArea ltJTextArea-referencegt new
JTextArea(ltdisplay-textgt) - The display-text is the text that appears in the
JTextArea component. If the display-text argument
is omitted, then the JTextArea component displays
no initial text.
37JTextArea Component
- The JTextArea class, like all the GUI component
classes, has quite a few methods. Here are the
API headings and descriptions for some of the
more popular JTextArea methods - String getText()
- Returns the text area's text.
- void setText(String text)
- Assigns the text area's text.
- void setEditable(boolean flag)
- Makes the text box editable or non-editable.
- void setLineWrap(boolean flag)
- Turns line wrap on or off.
- void setWrapStyleWord(boolean flag)
- Specifies whether word boundaries are used for
line wrapping.
38JTextArea Component
This code creates the components in the
previously shown license agreement window.
- private void createContents()
-
- JTextArea license
- JCheckBox confirmBox
-
- setLayout(new BorderLayout())
- license new JTextArea(
- "SOFTWARE END-USER LICENSE AGREEMENT\n\n"
- "READ CAREFULLY This Software End-User
License Agreement" - " is a legal agreement between us, the
software provider, and" - " you, the end user of a software product
legitimately" - " purchased from us. You must accept this
agreement to" - " complete the sale of the software license.
If you do not" - " accept this agreement, you forfeit all
rights to your" - " current and future property and progeny.")
- license.setEditable(false)
- license.setLineWrap(true)
- license.setWrapStyleWord(true)
- confirmBox new JCheckBox(
39JCheckBox Component
- JCheckBox component interface
- A JCheckBox component displays a small square
with a label to its right. - When the square is blank, the check box is
unselected. When the square contains a check
mark, the check box is selected. - Users click on the check box in order to toggle
it between selected and unselected.
40JCheckBox Component
- To create a JCheckBox component, call the
JCheckBox constructor like this - JCheckBox ltJCheckBox-referencegt new
JCheckBox(ltlabelgt, ltselectedgt) - The label argument specifies the text that
appears at the right of the check box's square.
If the label argument is omitted, then no text
appears at the right of the check box's square. - The selected argument, a Boolean value, specifies
whether the check box is initially selected. If
the selected argument is omitted, then the check
box is initially unselected.
41JCheckBox Component
- Here are the API headings and descriptions for
some of the more popular JCheckBox methods - boolean isSelected()
- Returns true if the check box is selected and
false otherwise. - void setSelected(boolean flag)
- Makes the check box selected or unselected.
- String setVisible(boolean flag)
- Makes the check box visible or invisible.
- void setEnabled(boolean flag)
- Makes the check box enabled or disabled.
- void addActionListener(ActionListener listener)
- Adds a listener to the check box.
42JCheckBox Component
- Installation Options Example
43JCheckBox Component
- With a standard JButton button, you'll almost
always want to have an associated listener. - However, you may or may not want to have an
associated listener for a check box. - Use a listener if you want something to happen
immediately, right when the user checks or
unchecks the check box. - If there's no listener, then the check box simply
serves as an input entity. If that's the case,
then the check box's value (checked or unchecked)
would typically get read and processed when the
user clicks a button.
44JRadioButton Component
- JRadioButton component interface
- A JRadioButton component displays a small circle
with a label to its right. - When the circle is blank, the radio button is
unselected. - When the circle contains a large dot, the radio
button is selected. - Almost always, radio buttons come in groups.
- Within a radio-button group, only one radio
button can be selected at a time. - If an unselected button is clicked, the clicked
button becomes selected, and the previously
selected button in the group becomes unselected. - If a selected button is clicked, no change occurs
(i.e., the clicked button remains selected).
45JRadioButton Component
- To create a JRadioButton component, call the
JRadioButton constructor like this - JRadioButton ltJRadioButton-referencegt new
JRadioButton(ltlabelgt, ltselectedgt) - The label argument specifies the text that
appears at the right of the radio button's
circle. If the label argument is omitted, then no
text appears at the right of the radio button's
circle. - The selected argument, a Boolean value, specifies
whether the radio button is initially selected.
If the selected argument is omitted, then the
radio button is initially unselected. - This example shows how the standard and custom
radio buttons were created in the
installation-options program - standard new JRadioButton("Standard
(recommended)", true) - custom new JRadioButton("Custom")
46JRadioButton Component
- To enable the only-one-button-selected-at-a-time
functionality of a radio button group, create a
ButtonGroup object and add individual radio
button components to it. Here's how - ButtonGroup ltButtonGroup-referencegt new
ButtonGroup() - ltButtonGroup-referencegt.add(ltfirst-button-in-group
gt) - ...
- ltButtonGroup-referencegt.add(ltlast-button-in-groupgt
) - This example shows how the radio button group was
created for the standard and custom radio buttons
in the installation-options program - ButtonGroup rbGroup new ButtonGroup()
- rbGroup.add(standard)
- rbGroup.add(custom)
47JRadioButton Component
- Here are the API headings and descriptions for
some of the more popular JRadioButton methods - boolean isSelected()
- Returns true if the radio button is selected and
false otherwise. - void setSelected(boolean flag)
- Makes the radio button selected if the argument
is true. Does nothing if the argument is false. - String setVisible(boolean flag)
- Makes the radio button visible or invisible.
- void setEnabled(boolean flag)
- Makes the radio button enabled or disabled.
- void addActionListener(ActionListener listener)
- Adds a listener to the radio button.
48JComboBox Component
- A combo box allows the user to select an item
from a list of items. - Combo boxes are sometimes called drop-down lists
because when you click the combo box's down
arrow, a list of selection items drops down. - After a selection is made, the item list
disappears and only the selected item is
displayed. - Combo boxes are called "combo boxes" because they
are a combination of a text box (normally, they
look like a text box) and a list (when the down
arrow is clicked, they look like a list). - Combo boxes and radio-button groups are similar
in that they both allow the user to select one
item from a list of items. But a combo box takes
up less space on the window. So if you have a
long list of items to choose from, and you want
to save space, use a combo box rather than a
group of radio buttons.
49JComboBox Component
- Note this example where the user selects a day
from among the five week days
1. Initial display
2. After user clicks on down arrow
3. After user clicks on Thursday
50JComboBox Component
- How to implement a combo box
- Create an array of list options
- private String days
- "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday" - Create a combo-box object by passing the array to
the JComboBox constructor - JComboBox daysBox new JComboBox(days)
51JComboBox Component
- Here are the API headings and descriptions for
some of the more popular JComboBox methods - void setVisible(boolean flag)
- Makes the component visible or invisible.
- void setEditable(boolean flag)
- Makes the combo box's top portion editable or
non-editable. - Object getSelectedItem()
- Returns the item that is currently selected.
- void setSelectedItem(Object item)
- Changes the currently selected item to the item
that's passed in. - void addActionListener(ActionListener listener)
- Adds a listener to the combo box.
52Job Application Example
- The upcoming program implements a job application
by using check boxes, radio buttons, and a combo
box for input and dialog boxes for output.
This appears when user enters "good" values.
This appears when user enters "bad" values.
53Job Application Example
- import javax.swing.
- import java.awt.
- import java.awt.event.
- import javax.swing.border. // for
EmptyBorder - public class JobApplication extends JFrame
-
- private static final int WIDTH 250
- private static final int HEIGHT 300
- private JCheckBox java // Java Sun
certified? - private JCheckBox helpDesk // help-desk
experience? - private JCheckBox coffee // good coffee
maker? - private JRadioButton goodCitizen, criminal
- private JComboBox salary
- private String salaryOptions
- "20,000-59,000", "60,000-100,000",
"above 100,000" - private JButton submit // submit the
application
54Job Application Example
- //
- // Create components and add to window.
- private void createContents()
-
- ButtonGroup radioGroup
-
- // Need windowPanel for south-panel
separation and outer margin. - JPanel windowPanel new JPanel(new
BorderLayout(0, 10)) - windowPanel.setBorder(new EmptyBorder(10, 10,
10, 10)) - // centerPanel holds all components except
button - JPanel centerPanel new JPanel(new
GridLayout(11, 1)) -
- // Need a panel for button so it can be
center aligned - JPanel southPanel new JPanel(new
FlowLayout())
Without this line, our GridLayout components
would touch the left edge of the window. The
setBorder call allows us to specify a border. The
EmptyBorder class allows us to specify widths (in
pixels) for the top, left, bottom, and right
margins, respectively. The EmptyBorder class is
in the javax.swing.border package, so import that
package.
55Job Application Example
- java new JCheckBox("Java Sun certified")
- helpDesk new JCheckBox("help-desk
experience") - coffee new JCheckBox("able to make good
coffee") - goodCitizen new JRadioButton("law-abiding
citizen") - criminal new JRadioButton("violent
criminal") - radioGroup new ButtonGroup()
- radioGroup.add(goodCitizen)
- radioGroup.add(criminal)
- salary new JComboBox(salaryOptions)
- submit new JButton("Submit")
- submit.addActionListener(new
ButtonListener()) - centerPanel.add(new JLabel("Skills (check all
that apply)")) - centerPanel.add(java)
- centerPanel.add(helpDesk)
- centerPanel.add(coffee)
- centerPanel.add(new JLabel()) // filler
- centerPanel.add(new JLabel("Community
standing")) - centerPanel.add(goodCitizen)
56Job Application Example
- windowPanel.add(centerPanel,
BorderLayout.CENTER) - southPanel.add(submit)
- windowPanel.add(southPanel,
BorderLayout.SOUTH) - add(windowPanel)
- // end createContents
- //
- // Read entered values and display an
appropriate message. -
- private class ButtonListener implements
ActionListener -
- public void actionPerformed(ActionEvent e)
-
- if (
- (java.isSelected() helpDesk.isSelected(
) - coffee.isSelected())
- (goodCitizen.isSelected())
- (!salary.getSelectedItem().equals("above
100,000")))
57Job Application Example
- else
-
- JOptionPane.showMessageDialog(null,
- "Sorry, no jobs at this time.")
-
- // end actionPerformed
- // end class ButtonListener
- //
- public static void main(String args)
-
- new JobApplication()
-
- // end class JobApplication