有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java在线程执行额外处理之前和之后重新绘制玻璃窗格

我试图使用一个玻璃窗格来灰显一个框架,同时一个单独的线程执行一些图像处理(img proc)。在img proc线程完成后,玻璃窗格应该再次不可见。我已经确认玻璃窗格功能正常,但在img proc线程(它确实按照预期执行,同时等待和通知工作)启动之前,不会进行重新绘制。以下是我所拥有的:

{}类:

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和其他执行这种类型操作的线程。在我看来,我做的事情和那些成功的人一样。。。有什么微妙的东西我错过了吗


共 (1) 个答案

  1. # 1 楼答案

    这:lock.wait();阻塞事件分派线程,因此无法进行绘图。我会用SwingWorker来完成这项繁重的任务。也就是说,将图像处理放在doInBackground()上,并在done()中的wait后面放置您拥有的东西

    // 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();