T u t o

advertisement
Tutorial 6
Topics
Event handling in Swing
o Swing events
o Event listeners
o Register an event handler to an object
o Implement the event-handling
SwingApplication
o GUI
o Event handling
o Multiple events
o Adapter
Java 2D and drawing editor
o Basic shapes
o Stroke and fill
Tutorial problems
Design problems
Event handling in Swing
Event handling is of fundamental importance to programs with a graphic user
interface. It can be intimidating for beginning programmers. However, event handling
is MUCH simpler than you thought. Here is a summary of the three key components of
an event handling process:
Event (click a button, press a key, etc.)
Listener interface(ActionListener, WindowListner, etc.)
Object (button, frame, textfield, etc.) who is “listening to” the event
Swing Event
Every time the user types a character or clicks a button, the Java virtual machine
(JVM) generates an event. Here are a few examples of Swing events:
Act that results in the event
User clicks a button or presses Return
while typing in a text field
User closes a frame (main window)
User presses a mouse button
User moves the mouse over a component
Component becomes visible
Component gets the keyboard focus
Table or list selection changes
Listener type
ActionListener
WindowListener
MouseListener
MouseMotionListener
ComponentListener
FocusListener
ListSelectionListener
Event Listener
Each event can trigger one or more listeners of that event. As we talked about last
week, an event listener is a Java interface, which contains a collection of method
declarations. The classes that implement the interface must define those methods.
Here is a list of events, listeners, and methods:
Event
Listener Interface Listener methods
WindowEvent WindowListener
windowActivated(WindowEvent e)
windowDeactivated(WindowEvent e)
windowClosed(WindowEvent e)
windowClosing(WindowEvent e)
windowOpened(WindowEvent e)
windowDeiconified(WindowEvent e)
windowIconified(WindowEvent e)
ActionEvent
ItemEvent
TextEvent
FocusEvent
ActionListener
ItemListener
TextListener
FocusListener
KeyEvent
KeyListenmer
actionPerformed(ActionEvent e)
itemStateChanged(ItemEvent e)
textValueChanged(TextEvent e)
focusGained(FocusEvent e)
focusLost(FocusEvent e)
keyPressed(KeyEvent e)
keyReleased(KeyEvent e)
keyTyped(KeyEvent e)
For example, when the user clicks a button, the ActionListener will be notified, which
then triggers the actionPerformed method to be executed.
Register an event handler for the object
To listen to an event, an object must register to be that event’s listener. The
following code creates a JButton and registers an ActionListener for it.
JButton button = new JButton("I'm a Swing button!");
button.addActionListener(this); 3 Steps to Implement an Event Handler
To implement an event handler, you must take the following three steps:
1. Implement a listener interface:
public class MyClass implements ActionListener
2. Add the listener to an object:
button.addActionListener(this)
3. Define the methods of the listener interface:
public void actionPerformed(ActionEvent e){
...//code that reacts to the action..
}
Next we will demonstrate how it works using the SwingApplication example.
SwingApplication
The SwingApplication is an example we pulled from the Java Tutorial. It is a “buttonclick” counter - every time user clicks the button, the label is updated
Last week, we talked about the graphic components of this application. In this section,
we will study how it interfaces with the user. In other words, when user clicks a
button, what will the application do?
GUI
Just to refresh our memory, here is the GUI section of the code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SwingApplication extends JFrame{ int numClicks = 0;
JPanel pane = new JPanel();
JLabel label = new JLabel(“Number of button clicks: “ + numClicks);
JButton button = new JButton("I'm a Swing button!");
//Constructor
SwingApplicatin (){
super (“SwingApplication”); //set the frame title
pane.setLayout(new GridLayout(0, 1));
pane.add(button);
pane.add(label);
this.getContentPane().add(pane, BorderLayout.CENTER);
}
public static void main(String[] args){
SwingApplication app = new SwingApplication();
app.pack();
app.setVisible(true);
}
}
Event Handling
Let's follow the steps we outlined in last section
Event:
Object:
Interface:
ActionEvent
button
ActionListener with the method actionPerformed
Here is the code:
1. Implement a listener interface:
public class SwingApplication extends JFrame implements ActionListener
2. Add the listener to the button (after it is created)
button.addActionListener(this);
3. Define the methods of the listener interface:
Public void actionPerformed (ActionEvent e)
{
numClicks ++;
label.setText (“Number of button clicks: “ + numClicks);
}
Multiple Objects Listening
What if there are multiple objects listening to the same event? How does Java
determine which actionPerformed method to execute? For example, we have two
buttons, b1 and b2. Both of them are registered as an ActionListener. If user clicks b1,
a message “b1 is clicked” is printed on the label. If user clicks b2, the message “b2 is
clicked” is printed. Therefore, we need to implement the actionPerformed method as
follows:
JButton b1 = new JButton (“B1”);
b1.addActionListener (this);
JButton b2 = new JButton (“B2”);
b2.addActionListener (this);
……………………….
Public void actionPerformed (ActionEvent e)
{
if (e.getSource() == b1) //which object is the event source?
label.setText (“b1 is printed”);
if (e.getSource() == b2)
label.setText (“b2 is printed”);
}
Adapter Classes
Now, lets go back to our SwingApplication. We need to implement another event – we
want the application to exit when the user closes the window. Again, we will follow
the steps:
Event:
Object:
Interface:
WindowEvent
frame
WindowListener with the method windowClosing ….
Wait a minute; there are 7 methods in the WindowListener interface. As we mentioned
earlier that the class implementing the interfaces should define ALL of the methods in
that interface. This rule is fine for interfaces like ActionListener that has only one
method. But WindowListener has 7, I mean 7, methods. Do I have to implement all of
them, even though I only need one?
The answer is yes and no. If you implement WindowListener, YES you have to
implement ALL 7 methods. I know, typing code for six methods that don’t do anything
is the kind of tedious busywork that nobody likes. To simplify this task, Java developed
an adapter class for each listener interface that has more than one method. An
adapter class implements all the methods in the interface but does nothing with them.
Here is how to use an adapter.
frame.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
}
); Here, we defined an anonymous inner class of type WindowAdapter as the
parameter of addWindowListener (). You can learn more about inner classes from the
textbook (p.281). Here, you only need to know how to use it.
Java 2D and Drawing Editor
The Java 2D API provides enhanced two-dimensional graphics, text, and imaging
capabilities for Java programs. It supports line art, text, and images in a flexible, fullfeatured framework for developing richer user interfaces, sophisticated drawing
programs and image editors. This section will build upon the lecture example with
some additional features.
Basic Shapes
g2.draw(new Line2D.Double(x, y+rectHeight, x+rectWidth, y));
g2.draw(new Rectangle2D.Double(x, y, rectWidth, rectHeight));
g2.draw(new Ellipse2D.Double(x, y, rectWidth, rectHeight));
g2.draw(new RoundRectangle2D.Double(x, y, rectWidth,
rectHeight, 10, 10));
g2.draw(new Arc2D.Double(x, y, rectWidth, rectHeight, 90,
135, Arc2D.OPEN));
Stroking and Filling Graphics
We can easily apply fancy line styles and fill patterns to the graphics by changing the
stroke and paint attributes of the Graphics2D context.
Stroke enables you to specify different widths and dashing patterns for lines and
curves. For example, the following example created a thick-line arc (see the above
table):
BasicStroke wideStroke = new BasicStroke(8.0f);
g2.setStroke(wideStroke);
g2.draw(new Arc2D.Double(x, y, rectWidth, rectHeight, 90, 135, Arc2D.OPEN));
Fill patterns are defined by the Paint interface. The Java 2D A PI provides three Paint
implementations: Color, TexturePaint and GradientPaint. TexturePaint defines a fill
pattern using a simple image fragment that is repeated uniformly. GradientPaint
defines a fill pattern as a gradient between two colors. Here are two examples, one
using Color and the other using GradientPaint
g2.setPaint(Color.red);
g2.fill(new Arc2D.Double(x, y, rectWidth, rectHeight, 90, 135,
Arc2D.OPEN));
GradientPaint redtowhite = new
GradientPaint(x,y,red,x+rectWidth, y,white);
g2.setPaint(redtowhite);
g2.fill (new Ellipse2D.Double(x, y, rectWidth, rectHeight));
Tutorial Problems
Exercise 1: Answer the following questions
Question 1: What is an event object?
a)
b)
c)
d)
An event object represents one specific event, such as a mouse click.
An event object is an object that listens for mouse clicks.
An event object is a list of all the events that have happened in the system.
An event object is what your program does in response to an event.
Question 2: If there are several buttons in a frame, will each one generate its own
events when the user clicks on it?
a)
b)
c)
d)
Yes---each event is unique and is generated by a specific button.
No---events are indistinguishable from each other.
Yes---each button is allowed to generate one event. After that it is silent.
No---only event listeners are unique.
Question 3: Can a single listener object respond to several types of events from the
same component?
a) Yes---there is always only one listener in the entire program, so it has to
respond to all types of events.
b) No---there must be a specific listener object for each type of event from each
component in a GUI.
c) Yes---as long as it has an appropriate method for each type.
d) No---a program can only respond to one type of event
Exercise 2:
The LabelCopy class has 2 labels, sourceLabel and targetLabel, and 1 button. Here is
the code for creating the GUI.
import javax.swing.*;
public class LabelCopy extends JPanel{
JLabel sourceLabel, targetLabel;
JButton copyButton;
public LabelCopy(){
sourceLabel = new JLabel("Source Label");
targetLabel = new JLabel("Target label");
button = new JButton("Copy");
add(sourceLabel);
add(button);
add(targetLabel);
}
public static void main (String[] args){
JFrame frame = new JFrame (“Exercise 2”);
LabelCopy pane = new LabelCopy();
frame.getContentPane().add(pane, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
} Now, modify the LabelCopy class definition so that when user clicks the button, the
text in the sourceLabel is copied to the targetLabel
Design Problem
Develop a simple integer calculator. It has two text fields, a label that displays the
result, and 4 radio buttons (+, -, *, /). Here is how it works:
§
§
§
Input numbers in the text fields, e.g. 10 .. 10
Choose the operation by selecting one of the radio buttons, e.g. +
The label will display the result based on the selected operation, e.g. 20
Note, what you get from the textfield is a string. You need to convert it to an int.
Here is the code
int firstInput = Integer.parseInt(string1);
Related documents
Download