Hi, I'm building a versioning server-client pair using RMI and I thought it would be fun to have a little traffic light to indicate that something is happening: green means go ahead, red means it's busy doing something. I wrote Light.java, an excruciatingly simple traffic light. At the start of the actionPerformed method in the versioning client, I set it red (which calls repaint internally), and at the end I set it green. There's only one problem: it doesn't work. I wrote a little demo (Test.java) Here's what happens: when setColor is called in some places (say, the Test constructor), it works just fine (whee, it's a traffic light!). when setColor is called within the actionPerformed method, the repaint doesn't go through until the end of the actionPerformed method is reached. I tried doing repaint(10L), with the same result. Here's my explanation: the event distributing thread is a higher-priority thread than the repainting one, and this somehow messes up the repaint() call. Let's make the assumption that I haven't made a glaring error (may not be a reasonable assumption since my brain is a bit fried), and assume that this is in fact a bug. Now, this is by no means a major bug, and I'm sure I could do a work-around, but if repaint(10L) is called, shouldn't paint get called within 10 ms, regardless of what other threads are executing? Or am I on crack? Thanks, dstn.
import java.awt.*; import java.awt.event.*; public class Test extends Frame implements ActionListener { Light light; Button go; public static void main(String[] args) { new Test(); } public Test() { light = new Light(15); light.setColor(Color.green); go = new Button("Go!"); go.addActionListener(this); setBackground(Color.white); add("North", go); add("South", light); setTitle("Test!"); pack(); show(); } public void actionPerformed(ActionEvent e) { light.setColor(Color.red); try { Thread.sleep(2000L); } catch (InterruptedException ie) { } light.setColor(Color.blue); try { Thread.sleep(2000L); } catch (InterruptedException ie) { } light.setColor(Color.green); } }
import java.awt.*; public class Light extends Canvas { int dia; public Light(int d) { dia = d; } public Dimension getPreferredSize() { return new Dimension(dia,dia); } public void setColor(Color c) { setForeground(c); System.out.println("Repaint!"); repaint(10L); } public void update(Graphics g) { System.out.println("Update!"); paint(g); } public void paint(Graphics g) { System.out.println("Painting (color is " + getForeground().toString() + ")"); g.setColor(getBackground()); g.fillRect(0,0,getSize().width,getSize().height); g.setColor(getForeground()); g.fillOval(0,0,dia,dia); } }