我目前有一个带有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的新手,所以请轻松一点!感谢
答案 0 :(得分:3)
在侦听器内执行的代码在Event Dispatch Thread上执行。因此Thread.sleep()导致EDT进入睡眠状态,这意味着GUI无法响应事件或重新绘制自身。
阅读Concurrency In Swing上Swing教程中的部分以获取更多信息。本教程中描述的一种解决方案是对长期运行的任务使用SwingWorker
,并在结果可用时发布。
答案 1 :(得分:2)
您的while
循环阻止EDT
,删除它,您的代码就可以使用。
请参阅下一个示例ExecutorService
和JProgressBar
:
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
个实例,从中可以获得结果。