Vous êtes sur la page 1sur 15

Lecture week 10

Events
1. Basic structure
2. Panels
3. Text fields
4. Layout managers
Grid layout
Border layout
5. Events
6. Event listener
7. Example: increment
8. Two buttons
Two listeners
9. Boxes and struts
10. The main method

1
1. Basic structure
To build a basic window system, you
• create a window
• create a panel with components
• add the panel to the window
• pack the window around the panel
• make the window visible on the screen

class Window extends JFrame


{ public Window()
{ setup();
build();
pack();
setVisible(true); }

private void setup()


{ setLocation(500, 500); }

private void build()


{ add(new Panel()); }
}

You add components as needed, and pack the window so it


is just large enough to fit all the components.

Common error: The window is tiny.


Fix: Pack the window.
Fix: Add something to the window.
Common error: Nothing shows on the screen.
Fix: Set the window to be visible.

2
2. Panels
You create a panel, add components to the panel, and add
the panel to the window. A panel has a layout to control where
the components are placed. In the simplest layout, components
appear in the order they are added, top left to bottom right.
Here is a GUI to add 1 to the input value:

class Panel extends JPanel


{ public Panel()
{ setup();
build(); }

private void setup()


{ setPreferredSize(new Dimension(300, 50));
setBorder(BorderFactory.
createLineBorder(Color.blue));
setLayout(new FlowLayout()); }

private void build()


{ add(new JLabel("Value"));
add(new JTextField(10));
add(new JButton("+1"));
}

A label (class JLabel) shows text. The colour of the text is set
by setForeground, and the colour of the background is set
by setBackground.

3
3. Text fields
A text field provides textual input and output. It can be set
to a fixed length, or given a string to display. The user can
type a value into the field.

JTextField field = new JTextField(10);


JTextField field = new JTextField("gerbils");

field.setText("A new string");


field.setForeground(Color.red);
field.setBackground(Color.yellow);

You can convert a string to a number with the static parse


methods provided by the numeric wrapper classes. These
methods accept a string and return a number:

String s = field.getText();
int i = Integer.parseInt(s);
double d = Double.parseDouble(s);
If the string is not a valid number the system throws a non-
fatal exception, so you may need to wrap the code in a try-
catch block.

A standard pattern is to define a public method that returns


a value of the correct type:

class Panel extends JPanel


{ private JTextField field;

public double value()


{ String s = field.getText();
return Double.parseDouble(s); }

4
4. Layout managers
A layout manager controls the way that components are
placed in a panel. There are three layout managers:

FlowLayout Add components in rows, from top left


to bottom right of panel.
GridLayout Arrange components in a grid
BorderLayout Arrange components in five regions:
North, South, East, West, Centre

The layout manager is created and passed to the panel:

setLayout(new FlowLayout());

The FlowLayout manager is the default, with components


centred in each row. You can set the layout so the components
are added from the centre, from left, and from right; the code
below adds components from the left edge of the panel.

setLayout(new FlowLayout(FlowLayout.LEFT));

You can adjust the horizontal and vertical distance between


components with a third FlowLayout constructor:

public FlowLayout(int alignment,


int horizontalGap,
int verticalGap);

5
Grid layout
A grid layout divides the window's content pane into cells
of the same size. The constructor takes two arguments, the
number of rows and columns. Components are added in row
and then column order.
class Panel extends JPanel
{ public Panel()
{ setup();
build(); }

private void setup()


{ setLayout(new GridLayout(3, 3)); }

private void build()


{ for (int i = 1; i <= 9; i++)
add(label(i)); }

private JLabel label(int i)


{ JLabel label = new JLabel(" Cell " + i);
label.setPreferredSize
(new Dimension(100, 50));
return label; }

6
BorderLayout
A BorderLayout with different sized panels is often
enough. A BorderLayout has five areas; north and south only
expand vertically, east and west only expand horizontally.

North

Center
West East

South
public class Panel extends JPanel
{ ...
setLayout(new BorderLayout());
add(label("left", 120), BorderLayout.WEST);
add(label("right", 40), BorderLayout.EAST);

private JLabel label(String name, int x)


{ JLabel label = new JLabel(name);
label.setPrefSize(new Dimension(x, 100));
return label; }

7
5. Events
You can now set up a GUI system so it is visible on the
screen, but to make it react to the user is a whole new story.
Your code has to react to events.

The class that handles events is called an event or action


listener. Class ActionListener provides the interface; an
interface is a set of abstract methods. You effect (provide an
effective method for) the interface methods.

When the user clicks on a button, the Java run-time system


generates an event and calls the actionPerformed method.
The effective code in that method then handles the event.

class Listener implements ActionListener


{ ...

public void actionPerformed(ActionEvent e)


{ code to handle events }
}

GUI processing thus has five stages:


1. Create the window.
2. Create panels with components.
3. Add the panels to the window.
4. Make the window visible.
5. Wait for the user to click on a button.
The generated event is passed to actionPerformed
The code in actionPerformed is then executed.

8
6. Event listeners
The last step is to add the action listener to the button, so
the button knows where to send the event:
button.addActionListener(listener);
The listener is usually a private class, coded inside the panel
class. A private class can access it's owner's attributes and
methods, and only the owner can create an object of that class.
A private class is placed at the end of the containing class.
public class Panel extends JPanel
{ private JTextField field = new JTField(10);

JButton button = new JButton("+1"));


button.addActionListener(new Listener());

private double value()


{ return Double.parseDouble
(field.getText()); }

private void showValue(double value)


{ field.setText(“” + value); }

private class Listener


implements ActionListener
{ public void actionPerformed(ActionEvent e)
{ showValue(value() + 1); }
} <-- end of private listener class
} <-- end of public panel class

Common error: Nothing happens when I click the button.


Fix: Add the action listener to the button.

9
7. Example: increment
GUI systems have a very different control structure from
non-GUI systems. Before, the root class drove the system by
creating objects and calling methods on those objects. Here,
the listener - the code in actionPerformed - drives the
system; it waits for events and then calls methods to react to
those events.

Each listener has its own thread of control. The GUI


objects are persistent (are not garbage collected) because they
can be accessed from the listener. To exit the whole system,
the user closes the window.

import javax.swing.*;

public class Window extends JFrame


{ public Window()
{ setup();
build();
pack();
setVisible(true); }

private void setup()


{ setLocation(500, 500); }

private void build()


{ add(new Panel()); }
}

10
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Panel extends JPanel


{ private JTextField field = new JTField(10);

public Panel()
{ setup();
build(); }

private void setup()


{ setPrefrredSize(new Dimension(300, 50));
setBorder(BorderFactory.
createLineBorder(Color.blue));
setLayout(new FlowLayout()); }

private void build()


{ add(new JLabel("Value"));
add(field);
JButton button = new JButton("+1"));
button.addActionListener(new Listener());
add(button); }

private double value()


{ return Double.parseDouble
(field.getText()); }

private void showValue(double value)


{ field.setText("" + value); }

private class Listener


implements ActionListener
{ public void actionPerformed(ActionEvent e)
{ showValue(value() + 1); }
}
}

11
8. Two buttons
A system with more than one button has to know which
button was clicked. The source of a button event is found by
matching
• the button object
if (e.getSource() == button)
• the button label
if (e.getActionCommand().equals("...")

This panel has two buttons. Both buttons have the same
listener, and the listener sorts out which button was pressed.
private void build()
{ ...
Listener listener = new Listener();
add(button("+1", listener));
add(button("-1", listener)); }

private class Listener


implements ActionListener
{ public void actionPerformed(actionEvent e)
{ String source = e.getActionCommand();
if (source.equals("+1"))
showValue(value() + 1);
else
showValue(value() - 1); }
}
}

12
Two listeners
Each button can have its own listener. This makes the
build and listener code very simple, so it is a very common
GUI coding pattern.

private void build()


{ ...
add(button("+1", new IncListener()));
add(button("-1", new DecListener())); }

private JButton button


(String label, ActionListener listener)
{ JButton button = new JButton(label);
button.addActionListener(listener);
return button; }

private class IncListener


implements ActionListener
{ public void actionPerformed(actionEvent e)
{ showValue(value() + 1); }
}

private class DecListener


implements ActionListener
{ public void actionPerformed(actionEvent e)
{ showValue(value() - 1); }
}

13
9. Boxes and struts
A box gives you fine control over where components
appear in a panel. You create the box, add components and
spaces (called struts) to the box, and add the box to the panel.

A vertical box adds components from top to bottom of the


box. A horizontal box adds components from left to right. The
following code places a horizontal gap of 50 pixels between
the two buttons.

private void build()


{ Box box = Box.createHorizontalBox();
box.add(button("+1", new IncListener()));
box.add(Box.createHorizontalStrut(50));
box.add(button("-1", new DecListener()));
add(box); }

Horizontal struts only work for horizontal boxes, and


vertical struts only work for vertical boxes. You can embed
boxes inside boxes to get exactly the look you want.

Close a window
To close a window, click on the cross at top right. To exit
the whole system when you close a window, set the close
operation on the window to exit on close; the method and
constant are supplied by class JFrame.

setDefaultCloseOperation(EXIT_ON_CLOSE);

14
10. The main method
The standard pattern is to use a static main method to
create the system. All the method does is call the constructor;
you do not need to store an object of the root class.

public class Root


{ public static void main()
{ new Window(); }
}

public class Window extends JFrame


{ ...
}

public class Panel extends JPanel


{ ...

private class Listener


implements ActionListener
{ ...
}
}

In BlueJ, you call the static main method from the class pop-
up window and no root object is created. The window appears
with its panels, and the system waits for user actions.

15

Vous aimerez peut-être aussi