GUI不会在每次点击时更新图像,因为图形的新图像在生成每个新图像时需要花费时间,因此GUI显示上一个图像

时间:2014-06-08 19:51:16

标签: java image swing graph swingworker

我在GUI上显示当前有问题,我使用的Swing Worker根据我的要求不能正常工作。有点帮助我在每次点击时更新图像,而图像生成需要时间,因为图像是通过图形生成的。我对我的项目感到震惊...... enter code here

private static void show1(){
            SwingWorker<Void,Void> worker1= new SwingWorker<Void,Void>(){
                @Override
                protected Void doInBackground() throws Exception {
                    Thread.sleep(100);
                gp.GraphPanel();// here in graph panel image is not updated         
                    return null;
            }
            protected void done() {
            }
        };      
        worker1.execute();      
            }
    // show1 is called inside action listener 
        public static JScrollPane GraphPanel() 
        {             // some code here
                   ImageIcon imgIcon=new ImageIcon(FILE_NAME.filename+".png");
            label.setIcon( imgIcon);
            pane2.add(label);
                    JScrollPane grphPane= new JScrollPane(pane2);
                    return grphPane;

        }

2 个答案:

答案 0 :(得分:1)

您只能从事件调度线程访问 Swing 组件。另一方面,您尝试从JScrollPane构建和访问doInBackground。 SwingWorker的doInBackground在辅助工作线程上执行。这是后台任务应该发生的地方。如果图像准备需要时间,您可以在doInBackground中执行此操作。然后,覆盖done()方法,您可以在其中将生成的图像添加到UI。 done()上执行了Event Dispatch Thread。有关详细信息,请参阅Concurrency in Swing

这是一个简单的例子:

class Worker extends SwingWorker<Image, Void> {
    @Override
    protected Image doInBackground() throws Exception {
        Image image = ImageIO.read(new File("some path"));
        //TODO process the image
        return image;
    }

    @Override
    protected void done() {
        try {
            Image image = get();
            //TODO use the image
            //ImageIcon imgIcon = new ImageIcon(image);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
}

答案 1 :(得分:1)

Aqua的回答是您使用SwingWorker的正确方法,但是,您对所产生的实例JScrollPane无效GraphPane方法

此方法创建GraphPane的新实例...

public static JScrollPane GraphPanel() 
{             // some code here
    ImageIcon imgIcon=new ImageIcon(FILE_NAME.filename+".png");
    label.setIcon( imgIcon);
    pane2.add(label);
    JScrollPane grphPane= new JScrollPane(pane2);
    return grphPane;
}

但是把它称为......

gp.GraphPanel();

对此没有任何意义,您应该将此方法的结果添加到您的UI ...

根据您的代码示例,label似乎是一个实例变量,如果它已经在屏幕上,您只需设置其图标属性并让UI自行更新

public void updateGraph() 
{             // some code here
    ImageIcon imgIcon=new ImageIcon(FILE_NAME.filename+".png");
    label.setIcon( imgIcon);
}

另外,尽可能避免使用static,这表明您的设计需要运作