The question is whether java.awt.Canvas.setBackground(Color)
may safely be called from the main thread (i.e. outside event dispatch thread) without risk of crashing.
Background
I am drafting an undergraduate lession about finite automata and seek a way to visualise their behaviour. I do not want to distract my students' attention from the subject by threading issues. Java Swing requires precautions concerning threads when setting up and changing the GUI, see:
So Swing appears not to be an option at this stage. The above articles seem to be concerned about Swing rather than AWT. As to AWT, I read in
the promising statement that
AWT Components were intended to be thread safe
Question re-worded
Is sufficient thread-safety documented in the AWT documentation so that I can rely on it for the Canvas class in all JREs?
Demo code sample
The AWT-related code I am talking about is as simple as the following colour-changer in Colours.java
:
import java.awt.Frame;
import java.awt.Canvas;
import java.awt.Color;
/** Demonstrates Java AWT operated from main thread. */
public class Colours {
private static final Color[] colours = {
Color.RED, Color.GREEN, Color.BLUE
};
public static void main ( final String[] arguments ) {
final Frame frame = new Frame( "Colours" );
final Canvas canvas = new Canvas();
frame.setSize( 320, 200 );
frame.add( canvas );
frame.setVisible( true );
final ExitListener exitListener = new ExitListener();
frame.addWindowListener( exitListener );
int choice = 0;
while ( ! exitListener.isExiting() ) {
canvas.setBackground( colours[choice] );
if ( ++choice >= colours.length ) {
choice = 0;
}
try {
Thread.sleep( 1000 );
} catch ( final InterruptedException e ) {}
}
}
}
and ExitListener.java
:
import java.awt.Window;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
public class ExitListener implements WindowListener {
private boolean isExiting = false;
public boolean isExiting () {
return isExiting;
}
@Override
public void windowActivated ( final WindowEvent e ) {}
@Override
public void windowClosed ( final WindowEvent e ) {}
@Override
public void windowClosing ( final WindowEvent e ) {
isExiting = true;
final Window window = e.getWindow();
window.dispose();
}
@Override
public void windowDeactivated ( final WindowEvent e ) {}
@Override
public void windowDeiconified ( final WindowEvent e ) {}
@Override
public void windowIconified ( final WindowEvent e ) {}
@Override
public void windowOpened ( final WindowEvent e ) {}
}
N.B.: java.awt.event.WindowAdapter has not been used on purpose, because inheritance of state will be covered later in the course.