I'm attempting to use a glass pane to gray out a frame while a separate thread performs some image processing (img proc). After the img proc thread finishes, the glass pane should go invisible again. I have confirmed that the glass pane is functioning properly, but repainting doesn't occur before the img proc thread (which indeed executes as expected with the wait and notify working as well) is started. Here's what I have:
The GlassPane
class:
class GlassPane extends JComponent implements MouseListener
{
GlassPane()
{
super();
setLayout(new BorderLayout());
setOpaque(false); // So that Color's alpha channel is used
addMouseListener(this);
}
@Override
protected void paintComponent(Graphics g)
{
Rectangle bounds = g.getClipBounds();
g.setColor(new Color(255,255,255,160));
g.fillRect(bounds.x, bounds.y, bounds.width, bounds.height);
}
...
}
While building the components of the frame:
gPane = new GlassPane();
rootFrame.setGlassPane(gPane);
setGlassPane( false );
...
public void setGlassPane( boolean gray )
{
if( gray )
keyCatcher.disable();
else
keyCatcher.enable();
gPane.setVisible(gray);
gPane.repaint(); // Also tried gPane.repaint(0);
gPane.invalidate();
}
And in the action listener of a button:
...
System.out.println( "Answer button pressed..." );
ctrlr.grayOut();
new Thread( new Runnable()
{
public void run(){
int responses[];
ImgProc ip = new ImgProc(ctrlr);
ArrayList<ColorModel> model = ctrlr.getColorModel();
responses = ip.findResponses( camContent.getCrntImage(), model, (source == ansAndDisplayBtn) );
ctrlr.setResponses(responses);
synchronized(lock)
{
lock.notifyAll();
System.out.println( "Notified..." );
}
}
}).start();
synchronized(lock)
{
try {
System.out.println( "Waiting..." );
lock.wait();
System.out.println( "Responses retreived..." );
} catch (InterruptedException e1) {
e1.printStackTrace();
}
qContent.answer();
qContent.updateResponses();
if( scrnMode )
{
proj_qContent.answer();
proj_qContent.updateResponses();
}
}
ctrlr.showFull();
...
Where ctrlr.grayOut()
and ctrlr.showFull()
are just:
public void grayOut()
{
((MainUI) mainUI).setGlassPane(true);
}
public void showFull()
{
((MainUI) mainUI).setGlassPane(false);
}
I've read over a lot of this Painting in AWT and Swing and other threads that perform this type of action. It appears to me that I'm doing the same thing as those that are successful...is there something subtle I am missing?
This:
lock.wait();
blocks the event dispatch thread so that no drawing can happen. I'd use a SwingWorker for the heavy task. That is, putting the image processing todoInBackground()
and the stuff you have after thewait
indone()
.