Events (163328 bytes) - Marco Ronchetti

1
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Events
Gestione
degli
eventi
2
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Achieving OS Independence
AWT
Button
Swing
Button
Button
Peer
Lightweight
Button
Peer
Motif
Button
OS
3
Programmazione 2 - Marco Ronchetti
Modello 1.0
Fac.Scienze – Università di Trento
Event is
generated for a
component
Component gets
the event
Execute
handleEvent
HandleEvent
returns true
HandleEvent returns f alse
Pass event to
Container
Ricorda: un Container è un Component!
Event is
consumed
4
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
handleEvent()
Questo codice fa
parte del sorgente di
AWT
public boolean handleEvent(Event evt) {
switch (evt.id) {
case Event.MOUSE_ENTER: return mouseEnter(evt, evt.x, evt.y);
case Event.MOUSE_EXIT:
return mouseExit(evt, evt.x, evt.y);
case Event.MOUSE_MOVE:
return mouseMove(evt, evt.x, evt.y);
case Event.MOUSE_DOWN:
return mouseDown(evt, evt.x, evt.y);
case Event.MOUSE_DRAG:
return mouseDrag(evt, evt.x, evt.y);
case Event.MOUSE_UP:
return mouseUp(evt, evt.x, evt.y);
case Event.KEY_PRESS:
case Event.KEY_ACTION:
return keyDown(evt, evt.key);
case Event.KEY_RELEASE:
case Event.KEY_ACTION_RELEASE: return keyUp(evt, evt.key);
case Event.ACTION_EVENT: return action(evt, evt.arg);
case Event.GOT_FOCUS:
return gotFocus(evt, evt.arg);
case Event.LOST_FOCUS:
return lostFocus(evt, evt.arg);
}
return false;
}
5
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Event (1.0)
/* Modifier constants */
public static final int SHIFT_MASK
public static final int CTRL_MASK
public static final int META_MASK
ublic static final int ALT_MASK
/* Action keys */
public static final int HOME
ublic static final int END
public static final int PGUP
public static final int PAUSE
public static final int INSERT
/* Non-action
public static
public static
public static
public static
public static
keys */
final int
final int
final int
final int
final int
= 1 << 0;
= 1 << 1;
= 1 << 2;
= 1 << 3;
= 1000;
= 1001;
= 1002;...
= 1024;
= 1025;
ENTER
BACK_SPACE
TAB
ESCAPE
DELETE
=
=
=
=
=
'\n';
'\b';
'\t';
27;
127;
Questo codice fa
parte del sorgente di
AWT
6
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Event (1.0)
Questo codice fa
parte del sorgente di
AWT
/* Base for all window events. */
private static final int WINDOW_EVENT = 200;
public static final int WINDOW_DESTROY = 1 + WINDOW_EVENT;
public static final int WINDOW_EXPOSE = 2 + WINDOW_EVENT;
public static final int WINDOW_ICONIFY = 3 + WINDOW_EVENT;
public static final int WINDOW_DEICONIFY = 4 + WINDOW_EVENT;
public static final int WINDOW_MOVED
= 5 + WINDOW_EVENT;
/* Base for all keyboard events. */
private static final int KEY_EVENT
= 400;
public static final int KEY_PRESS
= 1 + KEY_EVENT;
public static final int KEY_RELEASE
= 2 + KEY_EVENT;
public static final int KEY_ACTION
= 3 + KEY_EVENT;
public static final int KEY_ACTION_RELEASE = 4 + KEY_EVENT;
/* Base for all mouse events. */
private static final int MOUSE_EVENT
public static final int MOUSE_DOWN
public static final int MOUSE_UP
public static final int MOUSE_MOVE
public static final int MOUSE_ENTER
public static final int MOUSE_EXIT
public static final int MOUSE_DRAG
=
=
=
=
500;
1 + MOUSE_EVENT;
2 + MOUSE_EVENT;
3 + MOUSE_EVENT;
= 4 + MOUSE_EVENT;
= 5 + MOUSE_EVENT;
= 6 + MOUSE_EVENT;
7
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Event (1.0)
/* Scrolling events
public static final
public static final
public static final
public static final
public static final
public static final
public static final
*/
int
int
int
int
int
int
int
private static final int SCROLL_EVENT = 600;
SCROLL_LINE_UP = 1 + SCROLL_EVENT;
SCROLL_LINE_DOWN
= 2 + SCROLL_EVENT;
SCROLL_PAGE_UP = 3 + SCROLL_EVENT;
SCROLL_PAGE_DOWN
= 4 + SCROLL_EVENT;
SCROLL_ABSOLUTE = 5 + SCROLL_EVENT;
SCROLL_BEGIN
= 6 + SCROLL_EVENT;
SCROLL_END
= 7 + SCROLL_EVENT;
/* List Events */
private static final int LIST_EVENT = 700;
public static final int LIST_SELECT
= 1 + LIST_EVENT;
public static final int LIST_DESELECT
= 2 + LIST_EVENT;
Questo
codice fa
parte del
sorgente di
AWT
/* Misc Event */
private static final int MISC_EVENT
= 1000;
//This event indicates that the user wants some action to occur public static
final int ACTION_EVENT
= 1 + MISC_EVENT;
public static final int LOAD_FILE
= 2 + MISC_EVENT;
public static final int SAVE_FILE
= 3 + MISC_EVENT;
public static final int GOT_FOCUS
= 4 + MISC_EVENT;
public static final int LOST_FOCUS = 5 + MISC_EVENT;
8
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Dealing with events-1.0
import java.awt.*;
import java.awt.event.*;
class Applicazione extends Frame {
int lastx, lasty;
Graphics g;
Button clear_button;
public static void main(String s[]) {
new Applicazione();}
Applicazione() {
setSize(200,200);
clear_button = new Button("Clear");
add(clear_button,BorderLayout.NORTH);
show();
g=getGraphics(); //dopo la show!
}
/** Respond to mouse clicks */
public boolean mouseDown(
Event e, int x, int y) {
lastx = x; lasty = y;
return true; }
/** Respond to mouse drags */
public boolean mouseDrag(
Event e, int x, int y) {
g.setColor(Color.black);
g.drawLine(lastx, lasty, x, y);
lastx = x; lasty = y;
return true; }
/** Respond to key presses */
public boolean keyDown(
Event e, int key) {
if ((e.id == Event.KEY_PRESS) &&
(key == 'c')) {
clear();
return true;
} else return false;
}
/** Respond to Button clicks */
public boolean action(
Event e, Object arg) {
if (e.target == clear_button) {
clear();
return true;
} else return false;
}
/** convenience method to erase the
scribble */
public void clear() {
g.setColor(this.getBackground());
g.fillRect(0, 0, bounds().width,
bounds().height);
}
}
9
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Eventi 1.1
Nel modello di Java 1.0 a ciascuna componente vengono
notificati gli eventi che la riguardano, ed e’ poi sua responsabilità
gestirli (eventualmente scalandoli nella gerarchia di contenimento).
Il modello di Java 1.1 invece “centralizza” la gestione degli eventi
facendo riferimento a delle classi “Listener”, presso le quali chi
genera eventi deve registrarsi. La gestione dell’evento e’
responsabilità del listener.
A volte, per semplicità, e’ possibile unificare il generatore
ed il gestore degli eventi. Anche in questo caso comunque si ha
un vantaggio: la classe risulta chiaramente firmata come
“implements Xlistener”.
10
Programmazione 2 - Marco Ronchetti
Modello 1.1
Listener interface
Fac.Scienze – Università di Trento
Component
x
Container non entra in gioco
AWTEvent
Event is
generated for a
component
Component has not
registered for that
event class
Event is discarded
Component has registered
for that event class
Component gets
the event
Event is
consumed
Component
passes the Event
to Listener
Listener executes
suitable method
11
Programmazione 2 - Marco Ronchetti
multiListenerDemo
Fac.Scienze – Università di Trento
package listenersdemo;
import javax.swing.*; import java.awt.*; import java.awt.event.*;
public class MultiListener
extends JPanel implements ActionListener {
JTextArea topTextArea;
JTextArea bottomTextArea;
JButton button1, button2;
JLabel l = null;
final static String newline = "\n";
public static void main(String[] args) {
createAndShowGUI();
}
12
Programmazione 2 - Marco Ronchetti
multiListenerDemo
private static void createAndShowGUI() {
Fac.Scienze – Università di Trento
//Create and set up the window.
JFrame frame = new JFrame("MultiListener");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Create and set up the content pane.
JComponent newContentPane = new MultiListener();
frame.setContentPane(newContentPane);
//Display the window.
frame.pack();
frame.setVisible(true);
}
13
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
multiListenerDemo
public MultiListener() {
super(new FlowLayout());
l = new JLabel("Cosa sento io:");
add(l);
topTextArea = new JTextArea();
topTextArea.setEditable(false);
JScrollPane topScrollPane = new JScrollPane(topTextArea);
Dimension preferredSize = new Dimension(200, 75);
topScrollPane.setPreferredSize(preferredSize);
add(topScrollPane);
l = new JLabel("Cosa sente la spia:");
add(l);
bottomTextArea = new JTextArea();
bottomTextArea.setEditable(false);
14
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
multiListenerDemo
JScrollPane bottomScrollPane = new JScrollPane(bottomTextArea);
bottomScrollPane.setPreferredSize(preferredSize);
add(bottomScrollPane);
button1 = new JButton("Fra Martino campanaro");
add(button1);
button2 = new JButton("Dormi tu?");
add(button2);
button1.addActionListener(this);
button2.addActionListener(this);
button2.addActionListener(new Spia(bottomTextArea));
setPreferredSize(new Dimension(400, 300));
}
public void actionPerformed(ActionEvent e) {
topTextArea.append(e.getActionCommand() + newline);
topTextArea.setCaretPosition(topTextArea.getDocument().getLength());
}
}
15
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
multiListenerDemo
class Spia
implements ActionListener {
JTextArea myTextArea;
public Spia(JTextArea ta) {
myTextArea = ta;
}
public void actionPerformed(ActionEvent e) {
myTextArea.append(e.getActionCommand()
+ MultiListener.newline);
myTextArea.setCaretPosition(myTextArea.getDocument().getLength());
}
}
16
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Design considerations
The most important rule to keep in mind about event listeners
that they should execute very quickly. Because all drawing
and event-listening methods are executed in the same thread,
a slow event-listener method can make the program seem
unresponsive and slow to repaint itself.
You might choose to implement separate classes for different
kinds of event listeners. This can be an easy architecture to
maintain, but many classes can also mean reduced
performance.
When designing your program, you might want to implement
your event listeners in a class that is not public, but
somewhere more hidden. A private implementation is a more
secure implementation.
17
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Low-Level Events and Semantic Events
Events can be divided into two groups: low-level events and
semantic events. Low-level events represent window-system
occurrences or low-level input. Everything else is a semantic
event.
Examples of low-level events include mouse and key events —
both of which result directly from user input.
Examples of semantic events include action and item events.
Whenever possible, you should listen for semantic events
rather than low-level events. That way, you can make your
code as robust and portable as possible. For example, listening
for action events on buttons, rather than mouse events, means
that the button will react appropriately when the user tries to
activate the button using a keyboard alternative or a look-andfeel-specific gesture.
18
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Listeners/Adapters
public class MyClass implements MouseListener {
...
someObject.addMouseListener(this);
...
/* Empty method definition. */
public void mousePressed(MouseEvent e) { }
/* Empty method definition. */
public void mouseReleased(MouseEvent e) { }
/* Empty method definition. */
public void mouseEntered(MouseEvent e) { }
/* Empty method definition. */
public void mouseExited(MouseEvent e) { }
public void mouseClicked(MouseEvent e) { ...//Event listener
implementation goes here... } }
19
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Listeners/Adapters
/* * An example of extending an adapter class instead
of * directly implementing a listener interface. */
public class MyClass extends MouseAdapter {
...
someObject.addMouseListener(this);
...
public void mouseClicked(MouseEvent e) { ...//Event
listener implementation goes here... }
}
20
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Inner classes
//An example of using an inner class.
public class MyClass extends JFrame {
...
someObject.addMouseListener(
new MyAdapter());
...
class MyAdapter extends MouseAdapter {
public void mouseClicked(MouseEvent e){
...//Event listener implementation goes here... }
}}
21
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Anonymous Inner classes
//An example of using an inner class.
public class MyClass extends JFrame {
...
someObject.addMouseListener(
new MouseAdapter() {
public void mouseClicked(MouseEvent e){
...//Event listener implementation goes here... }
}
});
...
}
22
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Inner classes
An instance of InnerClass can exist only within
an instance of EnclosingClass and it has direct
access to the instance variables and methods
of its enclosing instance.
23
Programmazione 2 - Marco Ronchetti
Listeners supported by all Swing components
component listener
Fac.Scienze – Università di Trento
Listens for changes in the component's size, position, or visibility.
focus listener
Listens for whether the component gained or lost the ability to receive keyboard
input.
key listener
Listens for key presses; key events are fired only by the component that has the
current keyboard focus.
mouse listener
Listens for mouse clicks and mouse movement into or out of the component's
drawing area.
mouse-motion listener
Listens for changes in the cursor's position over the component.
mouse-wheel listener (introduced in 1.4)
Listens for mouse wheel movement over the component.
24
Programmazione 2 - Marco Ronchetti
Fac.Scienze – Università di Trento
Altri listeners
action
caret
change
document
undoable edit
item
list
selection
window
+ Listeners speciali per componenti specifiche
(treeNodeExpansion, ecc)