我正在尝试使用玻璃窗格使框架变灰,而单独的线程执行某些图像处理(img proc)。 img proc线程完成后,玻璃窗格应该再次隐形。我已经确认玻璃窗格运行正常,但是在img proc线程(确实按照预期执行,等待并通知工作)开始之前不会重新绘制。这就是我所拥有的:
GlassPane
类:
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);
}
...
}
构建框架的组件时:
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();
}
在按钮的动作监听器中:
...
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();
...
ctrlr.grayOut()
和ctrlr.showFull()
只是:
public void grayOut()
{
((MainUI) mainUI).setGlassPane(true);
}
public void showFull()
{
((MainUI) mainUI).setGlassPane(false);
}
我已经阅读了很多这种Painting in AWT and Swing以及执行此类操作的其他线程。在我看来,我做的事与那些成功的事情一样......我有什么微妙的缺失吗?
答案 0 :(得分:1)
这:lock.wait();
阻止事件调度线程,以便不会发生绘图。我会用SwingWorker来完成繁重的任务。也就是说,将图像处理设置为doInBackground()
以及wait
中done()
之后的内容。
// Inform the user the task is running
ctrlr.grayOut();
new SwingWorker<Void, Void>() {
@Override
public Void doInBackground() {
// process the image
...
return null;
}
@Override
protected void done() {
// Everything done, inform the user
...
ctrlr.showFull();
}
}.execute();