Download Graphical User Interface Review Implementing event

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Further Object-Oriented Programming
Lecture 5
Graphical User Interface Review
Implementing event-handlers using Inner
Classes
Elena Lazovska
Faculty of Computer Science and IT
New York University Skopje
[email protected]
1
The Abstract Windowing Toolkit AWT
The Abstract Windowing Toolkit provides a set of GUI components in the
package java.awt
The AWT supports the most common user interface idioms
The AWT makes use of the GUI components of the underlying platform
• Has the look and feel of the native windowing toolkit
• The same AWT GUI may have a different appearance on different
platforms
With J2SE came Swing components that allow a uniform look and feel to
be specified across different platforms
• Most Swing components are pure Java components
2
The Java Foundation Classes JFC
The Java Foundation Classes form a set of classes for cross platform
GUI development
The Swing GUI components are part of JFC
• They exist in the package javax.swing
• Swing makes use of some of the classes found in AWT
Swing provides alternatives to most of the GUI components found in
AWT
• For examples JButton is a Swing alternative to Button found in AWT
• Swing GUI components are more portable and flexible than the
original AWT GUI components and generally preferred
3
Java GUI programming utilizes the classes
shown in this hierarchical diagram
4
JComponent and its subclasses are the basic
elements for building graphical user interfaces
5
Composite Design Pattern
GUI components need to be displayed somewhere
• A container manages a set of components
Java makes use of the Composite Design Pattern
• A component is the super class
• A container IS A component but HAS A collection of components
6
JFrame – A Swing Container
JFrame is an example of a top level swing container
• As are JDialog, JWindow and JApplet
A top level swing container contains an instance of JRootPane
JRootPane extends JComponent and contains:
• A Component called the Glass Pane
• A JLayeredPane
A JlayeredPane contains:
• A Container called the ContentPane that is accessible via the
getContentPane method of the top level swing container
• An optional JMenuBar
7
Using JFrame
JFrame theFrame = new JFrame("Testing JFrame");
theFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
theFrame.setSize(300,100);
theFrame.setVisible(true);
8
Extending the JFrame class
Normally JFrame is used as a starting point:
import java.awt.*;
import javax.swing.*;
public class PeteFrame extends JFrame
{
private JButton button1;
private JLabel label1;
public PeteFrame (String sTitle)
{
super (sTitle);
Container contentPane;
contentPane = getContentPane();
contentPane.setLayout(new FlowLayout());
9
Extending the JFrame class (continued)
button1 = new JButton("A button");
label1 = new JLabel("this is a label");
contentPane.add(label1);
contentPane.add(button1);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300,100);
this.setVisible(true);
}
public static void main(String args[])
{
new PeteFrame("Pete's sample frame");
}
}
10
Content Pane Delegation
As from JDK 1.5 just use the JFrame’s add method
• Known as content Pane Delegation
import java.awt.*;
import javax.swing.*;
public class PeteFrame extends JFrame {
private JButton button1;
private JLabel label1;
public PeteFrame(String sTitle) {
super(sTitle);
button1 = new JButton("A button");
label1 = new JLabel("this is a label");
setLayout(new FlowLayout());
add(label1);
add(button1);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(300, 100);
this.setVisible(true);
}
public static void main(String args[]) {
new PeteFrame("Pete's sample frame");
}
}
11
Closing JFrames
It is possible to choose what happens when a JFrame is closed
The setDefaultCloseOperation is used
It takes a single argument and suitable constants are defined in JFrame:
• DO_NOTHING_ON_CLOSE
• HIDE_ON_CLOSE
• DISPOSE_ON_CLOSE
• EXIT_ON_CLOSE
For example from the previous slide:
• this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
12
Layout Manager
How are the components positioned within a container?
How do you want them to be positioned?
Java allows the positioning to be decoupled from the container
• The container HAS A Layout Manager
• A suitable layout can be plugged in
13
Layout Manager
The positions of the components added to a container is determined
by a layout manager
In the previous example a flow layout manager was used
• contentPane.setLayout(new FlowLayout());
Some examples of existing layout managers are:
• FlowLayout
– left to right and horizontally centred
• BorderLayout
– NORTH, SOUTH, EAST, WEST and CENTER
• GridLayout - evenly spaced rows and columns
• GridBagLayout
• CardLayout
14
Events
We know how to add GUI components but at the moment there is little
or no user interaction
Java GUIs are event driven
• Any user interaction with a GUI component generates an event
• An application handles the events
An application must explicitly listen for events
The component on which an event is fired or generated is called the
source object or source component.
For example a JButton generates an event when it is clicked
A JButton can have an ActionListener added
The ActionListener has a method called actionPerformed that is invoked
when the button is clicked
15
JButton and the ActionListener Interface
Java makes use of the following design pattern to allow application
specific code to be added to handle an event
16
Adding an ActionListener
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MyFrame extends JFrame{
private JButton stopButton;
…
public MyFrame (String sTitle)
{
…
stopButton = new JButton("Stop");
stopButton.addActionListener( new StopButtonListener());
add(stopButton);
…
17
Building the ActionListener
The ActionListener interface specifies one method that must be
implemented to realize the interface
class StopButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
Note the ActionEvent that is passed to the method
• This describes the event in more detail
In this example the application exits when the button is clicked
18
Using this class as the ActionListener
in the previous example we defined the ActionListener for the JButton in
a separate class
it is also possible for the class that holds the reference to the JButton
object to listen for the JButton events
• the class will need to implement the ActionListener interface
• and contain an actionPerformed() method
public class MyFrame extends JFrame implements ActionListener{
private JButton stopButton;
public MyFrame (String sTitle)
{
stopButton = new JButton("Stop");
stopButton.addActionListener(this);
contentPane.add(stopButton);
...}
public void actionPerformed(ActionEvent e)
{
System.exit(0); }
}....
19
Events
if the same event handler is used for more than one component we need a
way to distinguish them
The ActionEvent e passed into the actionPerformed method contains
information about the event
One piece of information is the component that generated the event
• This is obtained using the getSource method
• e.getSource( )
if (e.getSource() == stopButton)
System.exit(0);
else if (e.getSource() == messageButton)
{
JOptionPane.showMessageDialog(this, label1.getText());
}
20
Writing a separate event handler class
vs.
Implementing the ActionListener interface in the containing
class and using it as the event handler
what are the advantages and disadvantages these two
approaches?
21
A better way?
we need an approach that allows us to
• separate the container-class code from the event-handling code
• yet allow the container and the event-handler to access each
other’s member variables
• and preferably have a separate class to handle each event
– rather than having a long selection statement to decide on the appropriate action for a
given event
• want to increase cohesion without unnecessary coupling
the solution is to use an inner class
• An inner class has access to the enclosing class
22
Using Inner Classes
public class MyFrame extends JFrame
{
private JButton stopButton;
private JButton messageButton;
private JLabel label1;
public MyFrame (String sTitle)
{
.....
stopButton.addActionListener(new StopButtonListener());
messageButton.addActionListener(new MessageButtonListener());
.......
}
private class StopButtonListener implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
}
private class MessageButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e)
{
JOptionPane.showMessageDialog(MyFrame.this, label1.getText());
}
23
}
Using Inner Classes
note that JOptionPane.showMessageDialog takes a reference to the
parent frame
which is this instance of the outer class
• not the inner class
• referenced using MyFrame.this
OuterClassName.this is a reference to the outer class instance
24
Anonymous Inner Classes
in the last example, only one instance of each inner class was created
• when providing a parameter to the addActionListener method of the
appropriate JButton
why not define the class where it is used?
• if we do this, we don’t even need to name it
ActionListener sbl = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
};
stopButton.addActionListener(sbl);
25
Anonymous Inner classes
ActionListener sbl = new ActionListener() { .....
we declare sbl to be of type ActionListener
• that means it must be an instance of a class that implements the
ActionListener interface
ActionListener sbl = new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
};
we then construct an instance of our anonymous class that implements
this interface, using the keyword new
the definition of the class follows the call to the constructor, within
brackets { }
the class implements the actionPerformed method defined by the
interface
the entire statement ends with a semicolon
• after the closing } of the anonymous class
26
Anonymous Inner classes
an anonymous inner class can either
• implement an interface
• or extend a class
the syntax is the same in both cases
if it extends a class, it cannot define any new methods
• remember the reference is to an instance of the superclass
• so there is no way to call any new subclass methods
• the anonymous class can override existing superclass methods, and
implement abstract ones
27
Anonymous Inner classes
/** from SCJP*/
run:
public class AnnonymousDriver {
popcorn
public static void main(String args[]){
annonymous popcorn
Popcorn popcorn = new Popcorn();
popcorn.pop();
Food f =new Food();
Popcorn p=f.getP();
p.pop();
}
}
class Popcorn {
public void pop() {
System.out.println("popcorn");
}
}
class Food {
private Popcorn p = new Popcorn() {
public void pop() {
System.out.println("annonymous popcorn");
}
};
public Popcorn getP() {
return p;
}
}
28
Argument-defined Anonymous Inner Classes
in the preceding example the object sbl created using the anonymous
class definition was only used as an argument to the JButton’s
addActionListener method
there was actually no need to define the class and create the instance
in advance
instead, the entire class can be anonymously specified and created in
the method argument list
stopButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
System.exit(0);
} }
);
make sure the brackets match!
29
Argument-define Anonymous Inner Classes
this syntax may look strange, but it is commonly used to define GUI
event handlers
the event handler code is defined at the same place it is attached to its
component
no unnecessary object references are created
if the event-handling code is more than a few lines, can put it in a
separate outer class method and call the method from the inner
class
30
Summary
In this lecture we have:
• briefly review GUI programming in Java
• looked at different ways of defining event handling classes for active
components
• seen that inner classes, and particularly anonymous inner classes,
are useful in defining event handlers
Reading
GUIs
• Liang chapters 15 and 11
• Sun Java tutorial "Creating a GUI with JFC / Swing"
Inner classes
• Liang sections 15.2 and 15.3
• Sun Java tutorial “Learning the Java Language: Classes and Objects:
Nested classes”
31