Lecture X – Layout Management
Download
Report
Transcript Lecture X – Layout Management
Java Swing
Layout Management
1
Laying out components
Manage realized components
Determine size and position
Each container has a layout manager
• (usually)
2
Layout managers –
general aspects
Creating a layout manager
Consulting managers
Types of managers
Choosing managers
Other features of component layout
All Covered very well here:
• http://java.sun.com/docs/books/tutorial/uiswing/layout/
using.html
3
Creating a layout manager
Default layout managers
• JFrame, JDialog, JApplet have BorderLayout
• JPanel has FlowLayout
Except when used as a Content Pane (Border Layout)
Setting the layout manager for a
container
• JFrame frame = new JFrame();
frame.setLayout(new FlowLayout());
• JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout());
4
Consulting layout managers (1)
Consulted automatically when
container may need to change its
appearance.
These methods result in consultation,
but DON’T trigger new layout
• add(), remove(), removeAll()
• getAlignmentX(), getAlignmentY()
• getPreferredSize(), getMinimumSize(),
getMaximumSize()
5
Consulting layout managers (2)
These methods actually result in the
manager performing layout.
• JFrame.pack();
Causes this Window to be sized to fit the preferred size
and layouts of its subcomponents.
• JFrame.show() & JFrame.setVisible(true);
Shows the component
• JComponent.revalidate();
This method will automatically be called on this component
when a property value changes. Looks for all dependent
components and calls validate() on them. Validate() causes a
container to lay out its subcomponents again
6
Layout managers - types
BorderLayout
BoxLayout
FlowLayout
GridLayout
GridBagLayout
CardLayout
7
BorderLayout
Five areas
•
•
•
•
Specify location as argument of add method
•
•
NORTH, SOUTH, EAST, WEST and CENTER
Not all areas must be used
Do not assume a default area for components
Centre gets as much area as possible
pane.setLayout(new BorderLayout());
pane.add(new JButton(“Button 1 (NORTH)”), BorderLayout.NORTH);
Setting gaps between components (default = 0)
• BorderLayout.setHgap(int gap);
• BorderLayout.setVgap(int gap);
• BorderLayout(int horizontalGap, int verticalGap) - Constructor
8
BorderLayout
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BorderWindow extends JFrame {
public BorderWindow() {
//--- use default content pane
Container contentPane = getContentPane();
//--- Use the content pane's default BorderLayout.
//--- contentPane.setLayout(new BorderLayout());
//unnecessary
//--- under 1.5 can just commented out line as content pane
//--- is implcitly obtained
//--- add(new JButton("Button 1 (NORTH)"),
//--BorderLayout.NORTH);
contentPane.add(new JButton("Button 1 (NORTH)"),
9
BorderLayout
contentPane.add(new JButton("Button 1 (NORTH)"),
BorderLayout.NORTH);
contentPane.add(new JButton("2 (CENTER)"),
BorderLayout.CENTER);
contentPane.add(new JButton("Button 3 (WEST)"),
BorderLayout.WEST);
contentPane.add(new JButton("Long-Named Button 4
(SOUTH)"),
BorderLayout.SOUTH);
contentPane.add(new JButton("Button 5 (EAST)"),
BorderLayout.EAST);
}
setDefaultCloseOperation(EXIT_ON_CLOSE);
10
BorderLayout
public static void main(String args[]) {
BorderWindow window = new
BorderWindow();
window.setTitle("BorderLayout");
window.pack();
window.setVisible(true);
}
}
11
BoxLayout (1)
Components on top / next to each other
• Direction is your choice
Tries to size components at preferred
height for Y_AXIS or width for X_AXIS
Width as largest component width
• See above picture
12
BoxLayout (2)
Space fillers
• Rigid -
fixed-size space between two components
• Glue -
taking up no space unless you pull apart the components
that it's sticking to. Helps reposition extra space (default is at end)
•
• Custom -
Use this to specify a component with whatever
minimum, preferred, and maximum sizes you want
13
BoxLayout (3)
Component sizes
• Respect Max, Min and Preferred Sizes of
components
Alignment
• Comes into play when not all components are the same
width
• Can specify Left (0), Centre (0.5) or Right (1). Or Top
Middle Bottom
If you are having layout problems,
first treat as an Alignment issue,
then examine sizes.
14
BoxLayout
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BoxWindow extends JFrame {
public BoxWindow() {
Container contentPane = getContentPane();
contentPane.setLayout(new BoxLayout(contentPane,
BoxLayout.Y_AXIS));
addAButton("Button 1", contentPane);
addAButton("2", contentPane);
addGlue(contentPane);
addAButton("Button 3", contentPane);
addCustomFiller(contentPane);
addAButton("Long-Named Button 4", contentPane);
addAButton("Button 5", contentPane);
}
setDefaultCloseOperation(EXIT_ON_CLOSE);
private void addAButton(String text, Container container) {
JButton button = new JButton(text);
button.setAlignmentX(Component.CENTER_ALIGNMENT);
container.add(button);
}
public void addGlue(Container container) {
container.add(Box.createVerticalGlue());
}
public void addCustomFiller(Container container) {
Dimension minSize = new Dimension(300, 30);
Dimension prefSize = new Dimension(300, 30);
Dimension maxSize = new Dimension(Short.MAX_VALUE, 30);
container.add(new Box.Filler(minSize, prefSize, maxSize));
}
public static void main(String args[]) {
BoxWindow window = new BoxWindow();
}
}
window.setTitle("BoxLayout");
window.pack();
window.setVisible(true);
15
BoxLayout
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BoxWindow extends JFrame {
public BoxWindow() {
Container contentPane = getContentPane();
contentPane.setLayout(new BoxLayout(contentPane,
BoxLayout.Y_AXIS));
addAButton("Button 1", contentPane);
addAButton("2", contentPane);
addGlue(contentPane);
addAButton("Button 3", contentPane);
addCustomFiller(contentPane);
addAButton("Long-Named Button 4", contentPane);
addAButton("Button 5", contentPane);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
16
BoxLayout
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BoxWindow extends JFrame {
public BoxWindow() {
private void addAButton(String text, Container container) {
JButton button = new JButton(text);
button.setAlignmentX(Component.CENTER_ALIGNMENT);
container.add(button);
}
public void addGlue(Container container) {
container.add(Box.createVerticalGlue());
}
17
BoxLayout
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class BoxWindow extends JFrame {
public static void main(String args[]) {
BoxWindow window = new BoxWindow();
}
}
window.setTitle("BoxLayout");
window.pack();
window.setVisible(true);
18
FlowLayout
Very simple - JPanel’s default
Components in row(s)
At preferred size
Alignment
• FlowLayout.LEFT
• FlowLayout.CENTRE
• FlowLayout.RIGHT
Gaps
• Default = 5
• Specifying - setter hGap vGap methods or
via constructor
19
FlowLayout
public class FlowWindow extends JFrame {
public FlowWindow() {
Container contentPane = getContentPane();
//contentPane.setLayout(new FlowLayout());
//default = centre, 5, 5
contentPane.setLayout(new
FlowLayout(FlowLayout.RIGHT, 30, 5));
contentPane.add(new JButton("Button 1"));
contentPane.add(new JButton("2"));
contentPane.add(new JButton("Button 3"));
contentPane.add(new JButton("Long-Named Button
4"));
contentPane.add(new JButton("Button 5"));
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
20
FlowLayout
public static void main(String args[]) {
FlowWindow window = new
FlowWindow();
window.setTitle("FlowLayout");
window.pack();
window.setVisible(true);
}
}
21
GridLayout
Grid of cells - all same size
Components take all space in a cell
Gaps
• default = 5
• use setter methods hGap and vGap
• or via arguments to constructor
Re-sizing
• Cells resize to be as large as possible in given
window / container
22
GridLayout
public class GridWindow extends JFrame {
public GridWindow() {
Container contentPane = getContentPane();
//contentPane.setLayout(new GridLayout(0,2));
contentPane.setLayout(new GridLayout(0,3,20,20));
contentPane.add(new JButton("Button 1"));
contentPane.add(new JButton("2"));
contentPane.add(new JButton("Button 3"));
contentPane.add(new JButton("Long-Named Button 4"));
contentPane.add(new JButton("Button 5"));
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
23
GridBagLayout (1)
Very flexible (and complex!)
Rows can have different heights
Columns can have different lengths
Uses cells in a grid
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
JPanel pane = new JPanel();
pane.setLayout(gridbag);
//--- For each component to be added to this container:
//--- ...Create the component...
//--- ...Set instance variables in the GridBagConstraints instance...
gridbag.setConstraints(theComponent, c);
24
pane.add(theComponent);
GridBagLayout (2)
Constraints
• set in an instance of a gridBagConstraints Object
• gridx and gridy - The row and column of the upper left of the
component
• Anchor - Where to display within cell when component is smaller than
it
• fill - How to size component when cell is larger than components
requested size
• insets - External padding - min space between component and cell
edges
• ipadx, ipady - Internal padding - What to add to min size of
components
• weightx and weighty - How to distribute extra space (padding)
• gridwidth and gridheight - Number of columns or rows the component
uses
• More explanation here:
http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbagConstraints.html
Example explained very well here:
•
http://java.sun.com/docs/books/tutorial/uiswing/layout/gridbagExample.html
25
GridBagLayout
public class GridBagWindow extends JFrame {
public GridBagWindow() {
JButton button;
Container contentPane = getContentPane();
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints c = new GridBagConstraints();
contentPane.setLayout(gridbag);
//set all components to fill all available Horzontal space
c.fill = GridBagConstraints.HORIZONTAL;
button = new JButton("Button 1");
c.weightx = 0.5;
c.gridx = 0;
c.gridy = 0;
gridbag.setConstraints(button, c);
26
CardLayout
Manages objects (usually JPanels) in
sets
Works much like tabbed pane
Choose cards by
• Asking for card in order added to
container
• Going backwards or forwards
• Specifying card by name
27
CardLayout
public class CardWindow extends JFrame
implements ItemListener {
JPanel cards;
final static String BUTTONPANEL = "JPanel with JButtons";
final static String TEXTPANEL = "JPanel with JTextField";
public CardWindow() {
Container contentPane = getContentPane();
//Put the JComboBox in a JPanel to get a nicer look.
String comboBoxItems[] = { BUTTONPANEL, TEXTPANEL };
JPanel cbp = new JPanel();
JComboBox c = new JComboBox(comboBoxItems);
c.setEditable(false);
c.addItemListener(this);
cbp.add(c);
//Use the default layout manager, BorderLayout
contentPane.add(cbp, BorderLayout.NORTH);
cards = new JPanel();
cards.setLayout(new CardLayout());
JPanel p1 =
p1.add(new
p1.add(new
p1.add(new
new JPanel();
JButton("Button 1"));
JButton("Button 2"));
JButton("Button 3"));
JPanel p2 = new JPanel();
p2.add(new JTextField("TextField", 20));
cards.add(p1, BUTTONPANEL);
cards.add(p2, TEXTPANEL);
contentPane.add(cards, BorderLayout.CENTER);
}
setDefaultCloseOperation(EXIT_ON_CLOSE);
public void itemStateChanged(ItemEvent evt) {
CardLayout cl = (CardLayout)(cards.getLayout());
cl.show(cards, (String)evt.getItem());
}
28
Choosing layout managers (1)
In order to display a component in as
much space as it can get, consider:
• BorderLayout
Component in centre
• GridBagLayout
fill=GridBagConstraints.BOTH
• BoxLayout
Component specifies very large
preferred/maximum sizes
29
Choosing layout managers (2)
To display a few components in a
compact row:
• JPanel’s default FlowLayout
• BoxLayout
Display a few components of the
same size in rows and columns
• GridLayout
30
Choosing layout managers (3)
Display a few components in a row
or column, with different spacing
between them and custom
component sizes
• BoxLayout
Display a complex layout that has
many components
• GridBagLayout
• Using JPanel grouping and hierarchies
31
Layout managers - other layout
features
Absolute positioning of components
• When
• How
Customising layout managers
• When
• How
32
Absolute positioning (1)
Don’t do it; unless…
• component size isn’t affected by container size
or font & look’n’feel changes
e.g. desktop panes containing internal frames
• custom container performs size & position
calculations particular to container
e.g. split panes
33
Absolute positioning (2)
Key points from NoneWindow.java
• Instruct window to use no Layout:
.contentPane.setLayout(null);
• Set components size and position with
XYZ.setBounds(x, y, width, height);
• Set window size with:
window.setSize(x, y);
34
Absolute positioning
public class NoneWindow extends JFrame {
private JButton b1, b2, b3;
public NoneWindow() {
Container contentPane = getContentPane();
contentPane.setLayout(null);
b1 = new JButton("one");
contentPane.add(b1);
b2 = new JButton("two");
contentPane.add(b2);
b3 = new JButton("three");
contentPane.add(b3);
b1.setBounds(25, 5, 75, 20);
b2.setBounds(55, 35, 75, 20);
b3.setBounds(300, 200, 75, 30);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
35
Custom layout managers (1)
Ensure no existing manager does
the job
• GridBagLayout / BoxLayout
• Layout manager downloads
If your trying to do it, chances are
someone else has done it already…
• DECLARE use of external code in
coursework
36
Custom layout managers (2)
Create class which implements Layout Manager
interface
• e.g. public class myManager implements LayoutManager
Must have 5 methods required by interface
•
•
•
•
•
void addLayoutComponent(String, Component)
void removeLayoutComponent(Component)
Dimension preferredLayoutSize(Container)
Dimension minimumLayoutSize(Container)
void layoutContainer(Container)
See below URL for more documentation
• http://java.sun.com/docs/books/tutorial/uiswing/layout/custom.html
37
Summary
Creating a layout manager
Consulting managers
Types of managers
• BorderLayout
• BoxLayout
• FlowLayout
GridLayout
GridBagLayout
CardLayout
Choosing managers
Absolute positioning
Custom layout managers
Next : Abstract Model Widgets
38