EPITA Première Année Cycle Ingénieur marwan.burelle@lse.epita.fr http://www.lse.epita.fr
Overview 1 2
Different toolkits AWT: the good-old one, lakes some features and has a plateform specific look n feel (anyway, AWT is deprecated) Swing: a better AWT with a unified Look n feel and better drawing algorithms. SWT: the toolkit from Eclipse backed on native toolkits.
Swing Swing could have been a demonstration of classical design patterns in action, the whole concept heavily relies on: Decorator Composite Facade Chain of responsibility (internal) A graphical application in Java can be seen as tree (Composite) rooted by a JFrame and where nodes are widget and layout. The layout concept help you hierarchically describes your interface and provide a nive way to organize your widget The whole API is event-driven meaning that all you have to do is to connect event and operations triggered by those events.
SwingSet2 demo
Exploring The BorderLayout SimpleFrame import javax.swing.*; import java.awt.borderlayout; import java.awt.container; import java.awt.dimension; public class SimpleFrame { public static void main(string[] args) { javax.swing.swingutilities.invokelater( new Runnable() { public void run() { show(); );
Exploring The BorderLayout SimpleFrame private static void show() { JFrame frame = new JFrame("BorderLayout"); frame.setdefaultcloseoperation( JFrame.EXIT_ON_CLOSE); JButton labelt = new JButton("Top"); JButton labelb = new JButton("Bottom"); JButton labelc = new JButton("Center"); JButton labell = new JButton("Left"); JButton labelr = new JButton("Right"); Container pane = frame.getcontentpane(); pane.add(labelt, BorderLayout.PAGE_START); pane.add(labelb, BorderLayout.PAGE_END); pane.add(labelc, BorderLayout.CENTER); pane.add(labell, BorderLayout.LINE_START); pane.add(labelr, BorderLayout.LINE_END); frame.pack(); frame.setvisible(true);
Adding an Event Listener SimpleFrame static void addbuttonevent(final JButton b) { final String name = b.gettext(); ActionListener listener = new ActionListener() { int c = 0; public void actionperformed(actionevent e) { out.println(name); c++; b.settext(name + " clicked (" + c + ")"); ; b.addactionlistener(listener);
We Got Threads? A swing application always runs with 3 threads doing separate works in order to keep the application the most responsible as possible: Initial Thread: the threads that execute initial application code. Event Dispatch Thread: where all the stuff about event is done. Worker Threads: where the background heavy work is done. These threads are created directly by the framework, the only things you need to know is how to interract with them.
Initial Threads The only role of the initial thread is to launch the invoke the GUI creation that will be run by the Event Dispatch Thread. Syntax: invokelater javax.swing.swingutilities.invokelater( new Runnable() { public void run() { BuildGUI(); );
Event Dispatch Thread The place for all event and swing activities Almost all swing action must be done in that thread: swing operations are not thread safe, so we must keep them bound to one thread. Task in the Event Dispatch Thread must be short: if a task take too long, it will make the interface unresponsive or freezing Globaly, if you start your GUI with the previous method, it will run on the wrigth thread.
Worker Threads Background taskes (often long one) are supposed to run asynchronously with the GUI and thus run on one or more Worker Threads. javax.swing.swingworker is an abstract class used to build task to be scheduled on the worker threads. You must define a method doinbackground that launch the work You may define also a method called done that will be executed by the Event Dispatch Thread. javax.swing.swingworker implements the Futur<T> interface and thus we are able to wait for result using method get. Beware, get is blocking and you ll probably invoke it from the Event Dispatch Thread, it then can freeze your interface. There s an overloaded variant of get taking a time-out value to avoid long waiting.
Live Updates We sometime need to push update to the interface before the end of the computation. javax.swing.swingworker provides a method publish that let you make values available for the Event Dispatch Thread. The Event Dispatch Thread will access these values through the method process that you thus need to override.
Workers Syntax: SwingWorker class MyWorker extends SwingWorker<O, I> { O doinbackground() { // do your job here // and public sometimes... publish(new I(...)); void process(list<i> values) { // display things here
Other Tools You can cancel a running job from the Event Dispatch Thread using the method worker.cancel(true) The worker will be able to test the cancelation state using the method iscancelled() You can use the progress property (an int ranging from 0 to 100) to indicate progression (using setprogress and getprogress) You also have the state variable indicating the current state through the possible values: PENDING, STARTED, DONE