我创建了在performAction方法中执行某些操作的swing应用程序,但是当我创建一个显示progressBar的线程时,progressBar在performAction方法中将不可见,但最后,progressBar将以值100显示%直接
主要课程:
filename=$(scutil --get ComputerName); touch $filename.txt
窗口类:
import javax.swing.*;
import javax.swing.plaf.ButtonUI;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class main {
public static void main(String[] args) {
JFrame win = new JFrame("Test");
FlowLayout layout = new FlowLayout();
Button b1 = new Button("Click ");
win.add(b1);
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
window win = new window();
win.start();
try
{
Thread.sleep(2000);
}
catch(InterruptedException e5){}
}
});
win.setLayout(layout);
win.setSize(500, 300);
win.setLocationRelativeTo(null);
win.setVisible(true);
win.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
答案 0 :(得分:3)
是的,在Thread
处理程序中创建新的actionPerformed
是安全的。
但是,除了事件调度线程(EDT)之外,没有任何线程必须与Swing组件进行交互。
要在Swing中创建动画或延迟,您必须使用javax.swing.Timer
。永远不允许在EDT上执行Thread.sleep()
,并且不希望你希望这样做。
要从衍生线程返回EDT,您必须使用SwingUtilities.invokeLater()
或SwingUtilities.invokeAndWait()
。
使用SwingWorker
是在Swing中执行后台任务的首选方法。它处理从后台任务到EDT的部分和最终结果的通信和发布,以便在GUI组件中显示。
以下是使用SwingWorker
将代码翻译为工作示例。使用Swing Button
代替AWT JButton
。该程序使用invokeAndWait
创建,以确保在EDT上进行主窗口构造。使用lambda函数,但如果需要,可以用new Runnable() { }
内部类替换它。 “按钮0”到“按钮100”进度报告从SwingWorker
后台任务发布,以便在EDT中进行处理。在EDT有机会处理它们之前,后台线程可以生成多个结果;在这里,我们只将最后一个结果显示在按钮中。
public class Main {
public static void main(String[] args) throws Exception {
SwingUtilities.invokeAndWait(() -> {
JFrame win = new JFrame("Test");
win.setLayout(new FlowLayout());
JButton b1 = new JButton("Click");
b1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
DoWork work = new DoWork();
work.execute();
}
});
win.add(b1);
win.setSize(500, 300);
win.setLocationRelativeTo(null);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
});
}
}
class DoWork extends SwingWorker<Void, String> {
JFrame fen;
JButton b2;
DoWork() {
fen = new JFrame("New window");
fen.setLayout(new FlowLayout());
b2 = new JButton();
fen.add(b2);
fen.setSize(100, 100);
fen.setLocationRelativeTo(null);
fen.setVisible(true);
fen.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
@Override
protected Void doInBackground() throws Exception {
for (int i = 0; i <= 100; i++) {
publish("Button " + i);
Thread.sleep(10);
}
return null;
}
@Override
protected void process(List<String> data) {
String last = data.get(data.size() - 1);
b2.setText(last);
}
@Override
protected void done() {
fen.dispose();
}
}
可以对此代码进行一些改进。用于显示结果的JLabel
代替JButton
,进度窗口为JDialog
,或者更好ProgressMonitor
。这些留给了学生。