Java for Interfaces and Networks (DT3010, HT10) Mouse Events, Timers, Serialization Federico Pecora School of Science and Technology Örebro University federico.pecora@oru.se Federico Pecora Java for Interfaces and Networks Lecture 11 1 / 21
Outline 1 Mouse Events 2 Timers 3 Serialization Federico Pecora Java for Interfaces and Networks Lecture 11 2 / 21
Mouse Events Outline 1 Mouse Events 2 Timers 3 Serialization Federico Pecora Java for Interfaces and Networks Lecture 11 3 / 21
Mouse Events Listening to Mouse Events Java provides a number of classes and interfaces for listening to mouse events, among which interface MouseMotionListener: listens to mouse motion events (moving, dragging), can track precise motion of the mouse interface MouseWheelListener: provides listener for wheel events (e.g., scrolling down a scrollbar with mouse wheel) class MouseListener: listens to mouse clicking and hover events Also, some adapter classes are provided (i.e., eliminating the need to implement each method of the interface), among which class MouseAdapter: provides default implementation of all three interfaces Federico Pecora Java for Interfaces and Networks Lecture 11 4 / 21
Mouse Events Interfaces MouseListener and MouseMotionListener public interface MouseListener extends EventListener { public void mousepressed(mouseevent e); public void mousereleased(mouseevent e); public void mouseclicked(mouseevent e); public void mouseentered(mouseevent e); public void mouseexited(mouseevent e); } public interface MouseMotionListener extends EventListener { public void mousedragged(mouseevent e); public void mousemoved(mouseevent e); } Federico Pecora Java for Interfaces and Networks Lecture 11 5 / 21
Mouse Events Interfaces MouseListener and MouseMotionListener mousepressed() occurs when the user presses the mouse button mousereleased() occurs when the user releases the mouse button mouseclicked() occurs when the user presses and releases the mouse button (double click is two mouse clicks in succession) mousepressed() and mousereleased() methods are both called first mouseentered()/mouseexited() occurs when the mouse enters/leaves the component you are listening to Federico Pecora Java for Interfaces and Networks Lecture 11 6 / 21
Mouse Events Interfaces MouseListener and MouseMotionListener mousedragged() occurs when the user presses the mouse button and moves the mouse before releasing the button does not trigger mouseclicked() mousepressed() and mousereleased() methods are both called does not trigger mousemoved() mousemoved() occurs when the mouse moves within the component without being dragged Federico Pecora Java for Interfaces and Networks Lecture 11 7 / 21
Mouse Events Interface MouseMotionListener: example An application with two simple components over which we listen to mouse events and log them in a text area Federico Pecora Java for Interfaces and Networks Lecture 11 8 / 21
Mouse Events Interface MouseMotionListener: example First, let s make a BlankArea class (an extension of JPanel) which we will for making test components BlankArea.java 1 class BlankArea extends JPanel { 2 final Dimension mysize = new Dimension(100, 100); 3 public BlankArea() { 4 setbackground(new Color(0.98f, 0.97f, 0.85f)); 5 setborder(new LineBorder(Color.green, 2)); 6 } 7 public Dimension getpreferredsize() { return mysize; } 8 public Dimension getminimumsize() { return mysize; } 9 } // class BlankArea Federico Pecora Java for Interfaces and Networks Lecture 11 8 / 21
Mouse Events Interface MouseMotionListener: example Now let s put two BlankAreas in a JPanel, together with a JTextArea to see the mouse events, and instantiate the listeners Mousepanel.java 1 class Mousepanel extends JPanel { 2 public Mousepanel() { 3 super(new FlowLayout()); 4 JPanel blankpanel1 = new JPanel(); 5 blankpanel1.setbackground(new Color(0.98f, 0.97f, 0.85f)); 6 Dimension size = new Dimension(100, 100); 7 blankpanel1.setpreferredsize(size); 8 blankpanel1.setminimumsize(size); 9 blankpanel1.setborder(new LineBorder(Color.red, 2)); 10 add(blankpanel1); 11 BlankArea blankpanel2 = new BlankArea(); 12 add(blankpanel2); 13 //... Federico Pecora Java for Interfaces and Networks Lecture 11 8 / 21
Mouse Events Interface MouseMotionListener: example Now let s put two BlankAreas in a JPanel, together with a JTextArea to see the mouse events, and instantiate the listeners Mousepanel.java (cont.) 14 JTextArea textarea = new JTextArea(); 15 textarea.seteditable(false); 16 JScrollPane scrollpane = new JScrollPane(textarea, 17 JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 18 JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 19 scrollpane.setpreferredsize(new Dimension(300, 75)); 20 add(scrollpane); 21 MyListener lyssnare = new MyListener(textarea); 22 blankpanel1.addmousemotionlistener(lyssnare); 23 blankpanel2.addmousemotionlistener(lyssnare); 24 setpreferredsize(new Dimension(400, 200)); 25 } //MousePanel 26 //... Federico Pecora Java for Interfaces and Networks Lecture 11 8 / 21
Mouse Events Interface MouseMotionListener: example At this point we define the mouse motion listener Mousepanel.java (cont.) 27 private class MyListener implements MouseMotionListener { 28 private JTextArea textarea; 29 public MyListener(JTextArea ta) { textarea = ta; } 30 public void mousemoved(mouseevent e) { 31 log("moving", e); 32 } 33 public void mousedragged(mouseevent e) { 34 log("dragging", e); 35 } 36 //... Federico Pecora Java for Interfaces and Networks Lecture 11 8 / 21
Mouse Events Interface MouseMotionListener: example At this point we define the mouse motion listener Mousepanel.java (cont.) 37 private void log(string eventdescription, MouseEvent e) { 38 textarea.append(eventdescription + 39 " (" + e.getx() + "," + e.gety() + ")" + 40 " in " + 41 e.getcomponent().getclass().getname() + "\n"); 42 textarea.setcaretposition( 43 textarea.getdocument().getlength()); 44 } 45 } //class MyListener 46 } //class MousePanel Federico Pecora Java for Interfaces and Networks Lecture 11 8 / 21
Mouse Events Interface MouseMotionListener: example Finally, the JFrame... MouseWindow.java 1 class MouseWindow extends JFrame { 2 public MouseWindow() { 3 super("mousemotionlistener Demo"); 4 getcontentpane().add(new Mousepanel()); 5 pack(); 6 } 7 public static void main(string[] args) { 8 MouseWindow m = new MouseWindow(); 9 m.setdefaultcloseoperation(jframe.exit_on_close); 10 m.setvisible(true); 11 } 12 } //class MouseWindow Federico Pecora Java for Interfaces and Networks Lecture 11 8 / 21
Mouse Events Interface MouseListener: example Now we want a listener that can react to mouse clicks We can implement the MouseListener interface in addition to the MouseMotionListener interface... Federico Pecora Java for Interfaces and Networks Lecture 11 9 / 21
Mouse Events Interface MouseListener: example Instantiating the new listener Mousepanel.java (cont.) 14 //... 15 MyListener lyssnare = new MyListener(textarea); 16 blankpanel1.addmousemotionlistener(lyssnare); 17 blankpanel2.addmousemotionlistener(lyssnare); 18 MyListener2 lyssnare2 = new MyListener2(textarea); 19 blankpanel1.addmouselistener(lyssnare2); 20 blankpanel2.addmouselistener(lyssnare2); 21 //... Federico Pecora Java for Interfaces and Networks Lecture 11 9 / 21
Mouse Events Interface MouseListener: example Defining the new listener Mousepanel.java (cont.) 27 private class MyListener2 implements MouseListener { 28 private JTextArea textarea; 29 public MyListener2(JTextArea ta) { textarea = ta; } 30 public void mousepressed(mouseevent e) { 31 log("mouse pressed; num clicks = " + 32 e.getclickcount(), e); 33 } 34 public void mousereleased(mouseevent e) { 35 log("mouse released; num clicks = " + 36 e.getclickcount(), e); 37 } 38 public void mouseentered(mouseevent e) { 39 log("mouse enters", e); 40 } Federico Pecora Java for Interfaces and Networks Lecture 11 9 / 21
Mouse Events Interface MouseListener: example Defining the new listener Mousepanel.java (cont.) 41 public void mouseexited(mouseevent e) { 42 log("mouse exits", e); 43 } 44 public void mouseclicked(mouseevent e) { 45 log("mouse clicked; num clicks = " + 46 e.getclickcount(), e); 47 } 48 private void log(string eventdescription, MouseEvent e) { 49 textarea.append(eventdescription + 50 " (" + e.getx() + "," + e.gety() + ")" + 51 " in " + 52 e.getcomponent().getclass().getname() + "\n"); 53 textarea.setcaretposition( 54 textarea.getdocument().getlength()); 55 } 56 } //class MyListener2 Federico Pecora Java for Interfaces and Networks Lecture 11 9 / 21
Mouse Events Interface MouseAdapter: example Our two listeners are long because the have to implement all methods of the interfaces MouseMotionListener and MouseListener If we do not need all mouse events, we can extend the abstract class MouseAdapter Federico Pecora Java for Interfaces and Networks Lecture 11 10 / 21
Mouse Events Interface MouseAdapter: example Mousepanel.java (cont.) 14 private class MyListener3 extends MouseAdapter 15 implements MouseListener { 16 private JTextArea textarea; 17 public MyListener3(JTextArea ta) { textarea = ta; } 18 public void mouseclicked(mouseevent e) { 19 log("mouse click; num clicks = " + 20 e.getclickcount(), e); 21 } 22 private void log(string eventdescription, MouseEvent e) { 23 textarea.append(eventdescription + 24 " (" + e.getx() + "," + e.gety() + ")" + 25 " in " + 26 e.getcomponent().getclass().getname() + "\n"); 27 textarea.setcaretposition( 28 textarea.getdocument().getlength()); 29 } 30 } //class MyListener3 31 //... Federico Pecora Java for Interfaces and Networks Lecture 11 10 / 21
Timers Outline 1 Mouse Events 2 Timers 3 Serialization Federico Pecora Java for Interfaces and Networks Lecture 11 11 / 21
Timers High-level thread support As we saw in the previous lecture, Java offers a number of facilitations for building multi-threaded GUIs As of Java 1.3, there exists the class java.util.timer used to perform tasks repeatedly or after a delay There exists also javax.swing.timer, a similar class which is dedicated to GUI support facilitates developing repeating/delayed tasks which need to update the GUI separates the actual waiting from the event dispatch thread Federico Pecora Java for Interfaces and Networks Lecture 11 12 / 21
Timers java.util.timer example Presenter.java (cont.) 20 public static void main(string[] args) { 21 Presenter t1 = new Presenter("FirstThread", 0.1); 22 Presenter t2 = new Presenter("SecondThread", 0.2); 23 Presenter t3 = new Presenter("ThirdThread", 0.3); 24 } //main 25 } //class Presenter <-- IMPLEMENTED IN LEC. 4 linux> java Presenter FirstThread SecondThread ThirdThread FirstThread SecondThread FirstThread ThirdThread FirstThread SecondThread FirstThread FirstThread ThirdThread SecondThread FirstThread FirstThread SecondThread FirstThread ThirdThread FirstThread SecondThread FirstThread FirstThread ThirdThread SecondThread FirstThread FirstThread SecondThread Federico Pecora Java for Interfaces and Networks Lecture 11 13 / 21
Timers java.util.timer example In the version implemented in lecture 4, it was possible that the threads were not synchronized linux> java Presenter... FirstThread... ThirdThread SecondThread SecondThread FirstThread FirstThread FirstThread SecondThread java.util.timer and its companion class java.util.timertask provide a way to overcome this easily! Federico Pecora Java for Interfaces and Networks Lecture 11 13 / 21
Timers java.util.timer example PresenterTask.java 1 public class PresenterTask extends TimerTask { 2 private String message; 3 private double sleeptime; 4 private int steps; 5 public PresenterTask(String message, double sleeptime) { 6 this.message = message; 7 this.sleeptime = sleeptime; 8 this.steps = 0; 9 Timer timer = new Timer(); 10 timer.schedule(this, 0, (int)(sleeptime * 1000)); 11 } 12 //... Federico Pecora Java for Interfaces and Networks Lecture 11 13 / 21
Timers java.util.timer example PresenterTask.java (cont.) 12 public void run() { 13 for (int i = 0; i < this.steps; ++i) 14 System.out.print(" "); 15 ++this.steps; 16 System.out.println(this.message); 17 } //run 18 public static void main(string[] args) { 19 PresenterTask t1 = new PresenterTask("FirstThread", 0.1); 20 PresenterTask t2 = new PresenterTask("SecondThread", 0.2); 21 PresenterTask t3 = new PresenterTask("ThirdThread", 0.3); 22 } //main 23 } //class PresenterTask Federico Pecora Java for Interfaces and Networks Lecture 11 13 / 21
Timers java.util.timer example Instantiate a java.util.timer Extend java.util.timertask this class looks a lot like a thread, in that it has a run() method schedule() one or more instances of your TimerTasks on the Timer NB: each Timer object is a single background thread that is used to execute all of the timer s tasks, sequentially so actually we are not running three threads anymore! NB: TimerTasks should complete quickly, and Timer does not offer real-time guarantees Federico Pecora Java for Interfaces and Networks Lecture 11 13 / 21
Timers Timers in Swing The class javax.swing.timer offers similar functionality, but tailored to the needs of GUI development The purpose of this class is to fire one or more ActionEvents after a specified delay e.g., used to animate components To set up a javax.swing.timer you create a javax.swing.timer object register one or more ActionListeners on it start the timer using the start() method Federico Pecora Java for Interfaces and Networks Lecture 11 14 / 21
Timers Timers in Swing Setting up a javax.swing.timer 1 int delay = 1000; //milliseconds 2 ActionListener taskperformer = new ActionListener() { 3 public void actionperformed(actionevent evt) { 4 //Define task to perform... 5 } 6 }; 7 new Timer(delay, taskperformer).start(); Like java.util.timers, also javax.swing.timers perform their waiting using a single, shared thread However, the action event handlers for javax.swing.timers execute on the event dispatch thread Therefore it is safe to perform operations on Swing components... but they must end quickly! Federico Pecora Java for Interfaces and Networks Lecture 11 15 / 21
Serialization Outline 1 Mouse Events 2 Timers 3 Serialization Federico Pecora Java for Interfaces and Networks Lecture 11 16 / 21
Serialization What is serialization? Can object instances exist outside the JVM? Object serialization provides a means to flatten your objects for storage/transport outside the running JVM can make persistent object instances provides stream mechanism for writing and reading object instances Not all classes are serializable, only those that implement the interface Serializable this does not include Thread, Socket,...... but does include a large number of other classes, including Swing components Federico Pecora Java for Interfaces and Networks Lecture 11 17 / 21
Serialization Serialization: example Let s make a simple class that is serializable Data.java 1 class Data implements Serializable { 2 private int n; 3 public Data(int n) { this.n = n; } 4 public String tostring() { return Integer.toString(n); } 5 } //class Data Federico Pecora Java for Interfaces and Networks Lecture 11 18 / 21
Serialization Serialization: example Let s instantiate some Data objects and output them to a file... SerializationTest.java 1 public class SerializationTest { 2 public static void main(string[] args) 3 throws ClassNotFoundException, IOException { 4 Data d1 = new Data(17); 5 Data d2 = new Data(4711); 6 Data d3 = new Data(7); 7 ObjectOutputStream out = 8 new ObjectOutputStream( 9 new FileOutputStream("data.out")); 10 out.writeobject(d1); 11 out.writeobject(d2); 12 out.writeobject(d3); 13 out.close(); // Also flushes output 14 }//main 15 }// class SerializationTest Federico Pecora Java for Interfaces and Networks Lecture 11 18 / 21
Serialization Serialization: example The three objects instances are stored in the binary file data.out (53 bytes long) linux> more data.out <AC><ED>^@^Esr^@^DData<BB>4^Z^S<8D><F8><A4>\ ^B^@^AI^@^Anxp^@^@^@^Qsq^@~^@^@ ^@^@^Rgsq^@~^@^@^@^@^@^G Federico Pecora Java for Interfaces and Networks Lecture 11 18 / 21
Serialization Serialization: example Let s read the instances back in form the file... SerializationTest.java (cont.) 15 ObjectInputStream in = 16 new ObjectInputStream( 17 new FileInputStream("data.out")); 18 Data d4 = (Data)in.readObject(); 19 Data d5 = (Data)in.readObject(); 20 Data d6 = (Data)in.readObject(); 21 System.out.println("d1 = " + d1); 22 System.out.println("d2 = " + d2); 23 System.out.println("d3 = " + d3); 24 System.out.println("d4 = " + d4); 25 System.out.println("d5 = " + d5); 26 System.out.println("d6 = " + d6); 27 }//main 28 }// class SerializationTest Federico Pecora Java for Interfaces and Networks Lecture 11 18 / 21
Serialization Serialization: example Let s read the instances back in form the file... linux> java SerializationTest d1 = 17 d2 = 4711 d3 = 7 d4 = 17 d5 = 4711 d6 = 7 Federico Pecora Java for Interfaces and Networks Lecture 11 18 / 21
Serialization Serialization: example Notice that we could take advantage of Java s late binding to invoke the appropriate method (i.e., avoid cast to Data class) SerializationTest.java (cont.) 15 ObjectInputStream in = 16 new ObjectInputStream( 17 new FileInputStream("data.out")); 18 Data d4 = (Data)in.readObject(); 19 Data d5 = (Data)in.readObject(); 20 Object d6 = in.readobject(); 21 System.out.println("d1 = " + d1); 22 System.out.println("d2 = " + d2); 23 System.out.println("d3 = " + d3); 24 System.out.println("d4 = " + d4); 25 System.out.println("d5 = " + d5); 26 System.out.println("d6 = " + d6); 27 //... Federico Pecora Java for Interfaces and Networks Lecture 11 18 / 21
Serialization Serialization: example Late binding ensures that the method Data.toString() is invokes instead of Object.toString() linux> java SerializationTest d1 = 17 d2 = 4711 d3 = 7 d4 = 17 d5 = 4711 d6 = 7 Federico Pecora Java for Interfaces and Networks Lecture 11 18 / 21
Serialization Serialization: transient Notice that instead of a FileOutputStream, we could have given a Socket s output stream Now, what if we have members of our serializable class that are not serializable? We can mark these members as transient allows to mark members as excluded from the serialization Federico Pecora Java for Interfaces and Networks Lecture 11 19 / 21
Serialization Serialization: transient Marking Thread member as transient PersistentAnimation.java 1 public class PersistentAnimation 2 implements Serializable, Runnable { 3 transient private Thread animator; 4 private int animationspeed; 5 public PersistentAnimation(int animationspeed) { 6 this.animationspeed = animationspeed; 7 animator = new Thread(this); 8 animator.start(); 9 } 10 public void run() { /* do animation */ } 11 } Federico Pecora Java for Interfaces and Networks Lecture 11 20 / 21
Serialization Serialization: transient Marking Thread member as transient PersistentAnimation.java 1 public class PersistentAnimation 2 implements Serializable, Runnable { 3 transient private Thread animator; 4 private int animationspeed; 5 public PersistentAnimation(int animationspeed) { 6 this.animationspeed = animationspeed; 7 animator = new Thread(this); 8 animator.start(); 9 } 10 public void run() { /* do animation */ } 11 } However, the reloaded PersistentAnimation will not work! This is because the constructor is not re-invoked Federico Pecora Java for Interfaces and Networks Lecture 11 20 / 21
Serialization Serialization: transient To overcome this limitation, we modify the protocol by implementing writeobject() and readobject() PersistentAnimation.java 1 public class PersistentAnimation 2 implements Serializable, Runnable { 3 transient private Thread animator; 4 private int animationspeed; 5 public PersistentAnimation(int animationspeed) { 6 this.animationspeed = animationspeed; 7 startanimation(); 8 } 9 public void run() { /* do animation */ } 10 private void writeobject(objectoutputstream out) 11 throws IOException { 12 out.defaultwriteobject(); 13 } 14 //... Federico Pecora Java for Interfaces and Networks Lecture 11 20 / 21
Serialization Serialization: transient To overcome this limitation, we modify the protocol by implementing writeobject() and readobject() PersistentAnimation.java (cont.) 15 private void readobject(objectinputstream in) 16 throws IOException, ClassNotFoundException { 17 in.defaultreadobject(); 18 startanimation(); 19 } 20 private void startanimation() { 21 animator = new Thread(this); 22 animator.start(); 23 } 24 } Federico Pecora Java for Interfaces and Networks Lecture 11 20 / 21
Serialization Serialization: transient The two methods writeobject() and readobject() are private neither method is inherited and overridden or overloaded This solution allows to avoid that whoever is de-serializing does not have to invoke some ad-hoc method to properly re-create the object Overview of workflow 1 implement interface Serializable 2 mark non-serializable fields as transient 3 provide writeobject() and readobject() methods if there is any additional operation to be performed upon serialization/de-serialization Federico Pecora Java for Interfaces and Networks Lecture 11 20 / 21
Serialization Mouse Events, Timers, Serialization Thank you! Federico Pecora Java for Interfaces and Networks Lecture 11 21 / 21