在处理完成之前显示/更新组件

时间:2013-12-06 15:39:17

标签: java swing executorservice

我目前有一个带有swing gui的java程序,允许用户选择各种文件(xsl-fo和xml)并使用Render X生成PDF。我试着用一段时间弹出JFrame来显示一个按钮按下,然后会显示进度条或标签,以便让用户了解进度。但是,在实例化新帧时,它将显示为黑色,或者没有组件,然后在流程完成后显示。

private void RunButtonActionPerformed(java.awt.event.ActionEvent evt) {

    ExecutorService executor = Executors.newFixedThreadPool(8);

    //for reach file to process)
    for (int i = 0; i < count; i++) {
        Runnable worker = new ProcessThreader(conf, i);
        executor.execute(worker);
    }

    executor.shutdown();
    JFrame PercentageFrame = new JFrame();
    PercentageFrame.setVisible(true);
    PercentageFrame.setSize(200, 200);
    PercentageFrame.repaint();

    while (!executor.isTerminated()) {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            NarrowOptionPane.errorMessage("Interrupted: ", ex.getMessage());
        }
    }
    System.out.println("Complete");
}

运行按钮位于JPanel中,该JPanel位于JFrame中,主框架在main方法中实例化,并包含在稍后调用的方法中

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {

        @Override
        public void run() {
            JFrame frame = new MainFrame("PDF Producer");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
            frame.setSize(710, 530);
            frame.setResizable(false);
            frame.setLocationRelativeTo(null);
        }
    });
}

我是线程/执行器和java swing的新手,所以请轻松一点!感谢

2 个答案:

答案 0 :(得分:3)

在侦听器内执行的代码在Event Dispatch Thread上执行。因此Thread.sleep()导致EDT进入睡眠状态,这意味着GUI无法响应事件或重新绘制自身。

阅读Concurrency In Swing上Swing教程中的部分以获取更多信息。本教程中描述的一种解决方案是对长期运行的任务使用SwingWorker,并在结果可用时发布。

答案 1 :(得分:2)

您的while循环阻止EDT,删除它,您的代码就可以使用。

请参阅下一个示例ExecutorServiceJProgressBar

import java.awt.BorderLayout;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import javax.swing.JFrame;
import javax.swing.JProgressBar;

public class Example extends JFrame {

    private static JProgressBar progress;

    public static void main(String[] args) {
        final JFrame f = new JFrame();
        progress = new JProgressBar();
        progress.setStringPainted(true);
        progress.setIndeterminate(true);
        ExecutorService newCachedThreadPool = Executors.newFixedThreadPool(1);
        for( int i =0; i<10;i++){
            final int j = i;
            Runnable r = new Runnable() {

                @Override
                public void run() {
                    progress.setString(j+"");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            };
            newCachedThreadPool.submit(r);
        }
        f.getContentPane().add(progress,BorderLayout.CENTER);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setVisible(true);
    }

}

此处JFrame显示Runnable中执行的ExecutorService个数。此外,如果您需要从Runnables获取结果,请尝试使用Callable代替Runnable。在submit Callable的情况下,您可以获得Future个实例,从中可以获得结果。

了解ExecutorsCallableFuture