| L11a.java | CChange.java |
| Toggler.java | |
| Mystery.java | |
changeColor method
System.out.println("Thread ID: " + Thread.currentThread().getId());
recompile, and then try the same two runs you did in the
previous step. What's the difference?
What's going on here? Well it turns out that all GUI programs are inherently multi-threaded. There's the main thread (ID 1), which any program has. There's also a thread called the "event dispatch thread", and that's the thread on which all calls to GUI "listeners" (ActionListeners, WindowListeners, etc) occur. Somewhere on the event dispatch thread's call-stack is a record for a call to a function that is essentially an infinite loop that waits for the next GUI action, and the starts calling the necessary functions to respond - a process that eventually results in listeners being called. After all those calls are made, the stack eventually goes back down to the function with the infinite loop ... which waits around for the next GUI action.
So now think about our example above: with argument 0, the call to CChange.changeColor() was made in main(), which means a new record for the CChange.changeColor() call was made on the Thread 1 call stack. Thus, the event dispatch thread was left free to wait for events and, ultimately, to call the Toggler actionPerformed() method. On the other hand, with argument 1, the call to CChange.changeColor() was made in Mystery's actionPerformed() method, which means a new record on the event dispatch thread's call stack. Thus, the event dispatch thread couldn't do anything until the call to CChange.changeColor() returned, which required the user to complete typing the color name and press enter. In other words, the GUI was locked up until we finished!
This is a huge issue in programming GUIs with Java's Swing API: you can't execute any method on the event dispatch thread that doesn't return really quickly. Otherwise you'll lock up the GUI. So what do you do if a GUI event like a mouse click is supposed to initiate some long-running function call? Well, you create a new Thread for it to run in!
Be prepared to demo this to your instructor if asked!
Note: If your feeling a bit ambitious, you might want to
look into the issue of what happens if you go crazy and
double-click or triple-click the Mystery Button. It doesn't
quite work the way you'd like. If you want to fix that,
you might look at Thread's isAlive() method, although
there are other ways to deal with it that just use boolean
flags.
With a little cleverness, you can make it so that after a click
of the Mystery Button, all subsequent clicks are ignored until
a color is entered in response to the first one.
java L11TimerThe timer looks like this when it is launched



Here are a few useful tidbits for you:
Thread.sleep(1000); will put the
thread in which it is executed to sleep for one second.
Look at
the
sleep() API documentation carefully ... there might be
exceptions!
JLabel lab = new JLabel("foo");
lab.setPreferredSize(new Dimension(60,15));
JTextField tf = new JTextField(10);Note too that you can call
setText on a
JTextField object to set the text that appears, even though
the user might go change it later.
Demo this to your instructor to get credit!