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