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);
}
}