Presentation is loading. Please wait.

Presentation is loading. Please wait.

CS12420 – Swing and threads Lynda Thomas

Similar presentations


Presentation on theme: "CS12420 – Swing and threads Lynda Thomas"— Presentation transcript:

1 CS12420 – Swing and threads Lynda Thomas ltt@aber.ac.uk

2 Thread Thread of control –The idea was covered by Chris Can have multiple ones in one program See example Bouncer in this directory

3

4 In fact, We have already been using multiple threads, because When you use event handling code, this is handled by a different thread

5 Concurrency and Swing tutorial http://java.sun.com/docs/books/tutorial/ uiswing/concurrency/index.html A well-written Swing program uses concurrency to create a user interface that never "freezes" — the program is always responsive to user interaction, no matter what it's doing

6 A Swing programmer deals with the following kinds of threads: Initial threads, the threads that execute initial application code. The event dispatch thread, where all event- handling code is executed. Most code that interacts with the Swing framework must also execute on this thread. Worker threads, also known as background threads, where time-consuming background tasks are executed. The programmer does not need to provide code that explicitly creates these threads: they are provided by the runtime or the Swing framework. But the programmer works with them!

7 BUT what have we been doing? Initial threads, the threads that execute initial application code. The event dispatch thread, where all event- handling code is executed. Most code that interacts with the Swing framework must also execute on this thread. Worker threads, also known as background threads, where time-consuming background tasks are executed. We have created our GUIs here! We would have done complex stuff here – since all we had Should have done it here

8 …what you ?need? to know (cookbook style) 1.invokeLater() 2.SwingWorker And a couple of other things 1.Threads for animation 2.Double Buffering

9 1. invokeLater() Swing components should be created, queried, and manipulated on the event-dispatching thread We have not been doing this. public static void invokeLater(Runnable runnable) –Causes runnable to have its run method called in the dispatch thread of the EventQueue. This will happen after all pending events are processed.

10 So… Look at the new Bank in this directory It calls invokeLater() to be sure that the GUI is built in the right thread - we should ask the event dispatch thread to build our user interface rather than doing it ourself Code next slide

11 NEW: public static void main(String args[]) { new BankSwingMVC(); } public BankSwingMVC() { try { SwingUtilities.invokeLater( new Runnable() { public void run() { buildBankSwing(); } } ); } catch (Exception e) { S.o.p("invokeLater exception"+e); } } public void buildBankSwing() { setTitle("Bank"); setDefaultCloseOperation(…..); buttonPanel = new ButtonPanel(this); add ("North",buttonPanel); textPanel = new TextPanel(); add ("Center",textPanel); pack(); setVisible(true); } OLD: public static void main(String args[]) { new BankSwingMVC(); } //constructor builds a window public BankSwingMVC() { setTitle("Bank"); setDefaultCloseOperation(…..); buttonPanel = new ButtonPanel(this); add("North",buttonPanel); textPanel = new TextPanel(); add("Center",textPanel); pack(); setVisible(true); } ……

12 2. SwingWorker Time consuming code needs to be placed in a separate thread so that your GUI can still operate while it is running Since Java 1.6 this has been formalised in a SwingWorker thread First let’s run the code to see WHY THIS IS A PROBLEM Life-no-threads – doesn’t work properly No update Can’t stop Can’t even quit

13 How apply to Life There are 3 subdirectories here: –Life-no-threads – doesn’t work properly –Life-home-made-threads – an old solution –Life-properlythreads – PROPER WAY OF DOING IT –I’m actually going to go over the older solution, because it is easier to see the forest for the trees –see next slide

14 Basic algorithm for when running public void runalot() { int i=0; s=“first iteration" ; while (true) { calc(); if (!change()) { s="stable in "+i+" moves"; repaint(); break;} if (i==100){ s="100 times still changing";repaint(); break;} copy(); i++; s=i+" iterations"; try{ Thread.sleep(20); } catch (Exception e) { System.out.println("exception "+e);} repaint(); } } forever{ calculate next generation copy into current generation slowdown paint screen }

15 The problem is that runalot() is resource intensive particularly calc() which looks at every square many times for every square (all 100 of them) look at ALL its neighbours and decide if it lives in next generation While it is running nothing else can happen So, instead, it needs to be in its own thread DOESN’T WORK: public void actionPerformed(ActionEvent e){ if (e.getSource()==b1) c.step(); if (e.getSource()==b2) c.clear(); if (e.getSource()==b3) c.runalot(); if (e.getSource()==b4) c.stopit(); } …. class NewCanvas extends JPanel implements MouseListener { //lots deleted public void runalot() { int i=0; s="1 iteration" ; while (true) { calc(); if (!change()) { s="stable in "+i+" moves"; repaint(); break;} if (i==100){ s="100 times still changing";repaint(); break;} copy(); i++; s=i+" iterations"; try{ Thread.sleep(20); } catch (Exception e) { System.out.println("exception "+e);} //tried it with the above and without still won't repaint or stop! repaint(); }

16 OLD (homemade solution WORKS): //lots deleted //in the actionPerformed() : if (e.getSource()==b3){ runningThread=new Thread(c); runningThread.start(); } class NewCanvas extends JPanel implements MouseListener, Runnable{ //lots deleted public void run(){ //calling start() calls run() int i=0; s=“first iteration" ; keepGoing=true; try{ while (keepGoing) { calc(); if (!change()) { s="stable in "+i+" moves"; repaint(); break;} if (i==100) { s="100 still changing"; repaint(); break;} copy(); i++; s=i+" iterations"; Thread.sleep(200); repaint(); } } catch (InterruptedException e) { } DOESN’T WORK: public void actionPerformed(ActionEvent e){ if (e.getSource()==b1) c.step(); if (e.getSource()==b2) c.clear(); if (e.getSource()==b3) c.runalot(); if (e.getSource()==b4) c.stopit(); } …. class NewCanvas extends JPanel implements MouseListener { //lots deleted public void runalot() { int i=0; s=first iteration" ; while (true) { calc(); if (!change()) { s="stable in "+i+" moves"; repaint(); break;} if (i==100){ s="100 times still changing";repaint(); break;} copy(); i++; s=i+" iterations"; try{ Thread.sleep(20); } catch (Exception e) { System.out.println("exception "+e);} //tried it with the above and without still won't repaint or stop! repaint(); }

17 CORRECT SOLUTION Java6 and later: class NewCanvas extends JPanel implements MouseListener {//no need for Runnable lots deleted public void startCalc(){ // This method has work to do and so properly creates a SwingWorker, that is, // gets another thread to do that work see ***** below for how kicked off class Calculator extends SwingWorker, String> { public List doInBackground() { int i=0; s=“starting" ; keepGoing=true; try{ while (keepGoing) { board.calc(); i++; if (!board.isChange()) {s="stable in "+i+" moves"; repaint(); break;} if (i>=100) //had to make this >= {s="100 times still changing";repaint();break;} board.copy(); s=“iteration “+ I; // Call the inherited publish method and publish an intermediate result. //This method prepares intermediate results ready for the event dispatch thread (EDT). // When ready the EDT will call the process method with the list of messages. publish(s); i++; Thread.sleep(200); } catch (InterruptedException e) { } return null; } // Overrides the inherited process method called by the EDT when it is ready with a list of intermediate data protected void process(List messagesSoFar) { for (String message : messagesSoFar) { System.out.println(message); repaint(); } // ***** //Create the worker object and then schedule to run it on a worker thread Calculator worker = new Calculator(); worker.execute(); }

18 Read more at : http://java.sun.com/products/jfc/tsc/articles/ threads/threads2.html http://java.sun.com/products/jfc/tsc/articles/ threads/threads2.html The example code is at: http://java.sun.com/products/jfc/tsc/articles/ threads/src/Example1.java http://java.sun.com/products/jfc/tsc/articles/ threads/src/Example1.java If you need this you will know (GUI will seize up) You should know about this idea, so you can look it up when needed And you should use the ‘invokeLater’ stuff in 1.

19 In this lecture (so far) 2 things How to properly set up GUI using invokeLater() How to use SwingWorker so that your GUI doesn’t freeze Here endeth the things about Swing that could be on a CS124 exam

20 A couple of other odds and ends

21 1. Animation You may also need to use a new thread for animation Animation is basically just drawing different images (think on paper) in a loop (draw, cover, redraw, etc) Needs thread because otherwise the calls to repaint() get stacked up and then you will not see the multiple images See code in sample-animation-code directory

22 //This is an example of how to run an animation //It uses a class called NewCanvas to display the animation public class Main extends JFrame implements ActionListener{ private NewCanvas c; //panel for animation private JPanel p; //panel for button private JButton b; //push button /////////////////////////////////////////////////////////// public static void main(String args[]) { new Main(); } //////////////////The next bit is actually separate from the animation //////////////////use the invokeLater() public Main() { try{ SwingUtilities.invokeLater(new Runnable() {public void run() { build(); }}); } catch (Exception e) { System.out.println("invokeLater exception"+e); } public void build(){ //deleted } ///////////////////////////////////////////////////////when button pressed public void actionPerformed(ActionEvent e){ if (e.getSource()==b){ c.move(); //run the animation } //This is the class that actually displays the animation //puts a picture of aber in background and runs 3 faces public class NewCanvas extends JPanel implements Runnable { private MediaTracker mTracker; private Image backgroundImage; //needed for background private Image animateImage[]=new Image[3]; //needed for the images private Thread animator; //need to run this in separate thread private int current=0; //which image for animation //set up public NewCanvas() { //all mediatracker stuff deleted repaint(); current=0; } //called when button pressed public void move(){ animator=new Thread(this); animator.start(); //CALLS run() } //do the animation public void run(){ for (int j=0;j<6;j++) { //LOOP!!!! try { Thread.sleep(200); } catch (InterruptedException e) { break; } current=(current+1)%3; repaint(); //calls paintComponent() } //draw the image public void paintComponent(Graphics g) {

23 2. Double Buffering Double buffering Change a picture all at once instead of redrawing a bit at a time Several years ago this was really important because of speed Still matters for games – these examples don’t really show benefit run BadUpdateFrame and GoodUpdateFrame

24 BadUpdateFrame.java import javax.swing.*; public class BadUpdateFrame extends SimpleFrame { private UpdatePanel uppane; private Drawing drawing; public BadUpdateFrame() { drawing = new Drawing(); uppane = new UpdatePanel(drawing); add(uppane); pack(); } public void badDemo() { uppane.repaint(); drawing.flipLines(); uppane.repaint(); drawing.flipLines(); uppane.repaint(); drawing.flipLines(); } …… //deleted } GoodUpdateFrame.java /* create 2 drawings: drawing1 and drawing2 /* public void goodDemo() { uppane.repaint(); drawing2.flipLines(); uppane.setDrawing(drawing2); uppane.repaint(); drawing1.copy(drawing2); drawing1.flipLines(); uppane.setDrawing(drawing1); uppane.repaint(); } */

25 There is more about this in later modules!

26 What have I taught that could be on an exam? What is a design pattern? What is the MVC design pattern? What is the Observer/Observable design pattern? Why do we need SwingWorker threads? What does invokeLater() do? What does a Listener class do and how do you use it? Suppose I want to put a button in a Swing application, what are the three things that I need to do?


Download ppt "CS12420 – Swing and threads Lynda Thomas"

Similar presentations


Ads by Google