java-SwingWorker doens';在EDT线程中调用Thread.sleep()时,无法运行
我试图创建一个程序来解决二次方程和计算解决时间。我有一个按钮,当我点击它时,计算将开始。我的SwingWorker用于计时,它将每1秒更新一次时间。由于计算速度很快,我在JButton actionPerformed中调用Thread.sleep(),这样我就可以看到SwingWorker正在计算时间,但当我在EDT Thread中调用Thread.sleep(3000)时,SwingWorker不工作,而是在方程求解完成后等待打印出运行时间=3秒。我如何解决这个问题,使SwingWorker每1秒更新一次时间,而不是只打印3秒java-SwingWorker doens';在EDT线程中调用Thread.sleep()时,无法运行,java,multithreading,swing,swingworker,Java,Multithreading,Swing,Swingworker,我试图创建一个程序来解决二次方程和计算解决时间。我有一个按钮,当我点击它时,计算将开始。我的SwingWorker用于计时,它将每1秒更新一次时间。由于计算速度很快,我在JButton actionPerformed中调用Thread.sleep(),这样我就可以看到SwingWorker正在计算时间,但当我在EDT Thread中调用Thread.sleep(3000)时,SwingWorker不工作,而是在方程求解完成后等待打印出运行时间=3秒。我如何解决这个问题,使SwingWorker每
//SwingWorker for counting time
public class Worker extends SwingWorker<Integer, Long> {
private JLabel label;
public Worker(JLabel label) {
this.label = label;
}
@Override
protected Integer doInBackground() throws Exception {
long i = System.currentTimeMillis();
Timer SimpleTimer = new Timer(10, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
publish(System.currentTimeMillis() - i);
}
});
SimpleTimer.start();
return 1;
}
protected void process(List<Long> chunks) {
for(long i : chunks) {
label.setText("" + i);
}
}
}
//Solving quadratic function in JButton actionPerformed
private void solveActionPerformed(java.awt.event.ActionEvent evt) {
int a, b, c;
double x1, x2;
int i = 0;
try {
a = Integer.parseInt(inputA.getText());
b = Integer.parseInt(inputB.getText());
c = Integer.parseInt(inputC.getText());
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Re-enter.");
return;
}
Worker worker = new Worker(clock);
worker.execute();
try {
Thread.sleep(3000);
} catch (Exception e) {
}
double delta = b * b - 4 * a * c;
if(delta < 0) {
result.setText(".");
} else if(delta == 0) {
result.setText("x1 = x2 = " + -b / 2 * a);
} else {
x1 = (-b + Math.sqrt(delta)) / (2 * a);
x2 = (-b - Math.sqrt(delta)) / (2 * a);
result.setText("<html>x1 = " + x1 + "<br>x2 = " + x2 + "</html>");
}
}
//计算时间的SwingWorker
公共类Worker扩展SwingWorker{
私人标签;
公共工作者(JLabel标签){
this.label=标签;
}
@凌驾
受保护的整数doInBackground()引发异常{
长i=System.currentTimeMillis();
计时器SimpleTimer=新计时器(10,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
发布(System.currentTimeMillis()-i);
}
});
SimpleTimer.start();
返回1;
}
受保护的无效进程(列表块){
用于(长i:块){
label.setText(“+i”);
}
}
}
//JButton中二次函数的求解
private void solveActionPerformed(java.awt.event.ActionEvent evt){
INTA、b、c;
双x1,x2;
int i=0;
试一试{
a=Integer.parseInt(inputA.getText());
b=Integer.parseInt(inputB.getText());
c=Integer.parseInt(inputC.getText());
}捕获(例外e){
showMessageDialog(这是“重新输入”);
回来
}
工人=新工人(时钟);
worker.execute();
试一试{
睡眠(3000);
}捕获(例外e){
}
双三角=b*b-4*a*c;
if(δ<0){
result.setText(“.”);
}else if(delta==0){
result.setText(“x1=x2=“+-b/2*a”);
}否则{
x1=(-b+数学sqrt(δ))/(2*a);
x2=(-b-数学sqrt(delta))/(2*a);
result.setText(“x1=“+x1+”
x2=“+x2+”);
}
}
现在我找到了一个解决方案,我将计时器和计算代码放在同一个线程类中:
public class NewThread implements Runnable {
private JLabel label, result;
private int a, b, c;
public NewThread(JLabel label, int a, int b, int c, JLabel result) {
this.label = label;
this.a = a;
this.b = b;
this.c = c;
this.result = result;
}
@Override
public void run() {
double x1, x2;
long i = System.currentTimeMillis();
Timer timer = new Timer(10, new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
label.setText("Thoi gian tinh toan: " + (Math.round(System.currentTimeMillis() - i) / 1000) + " giay");
}
});
timer.start();
try {
Thread.sleep(3000);
} catch (Exception e) {
}
double delta = b * b - 4 * a * c;
if(delta < 0) {
result.setText("Phuong trinh vo nghiem.");
} else if(delta == 0) {
result.setText("Phuong trinh co nghiem kep x1 = x2 = " + -b / 2 * a);
} else {
x1 = (-b + Math.sqrt(delta)) / (2 * a);
x2 = (-b - Math.sqrt(delta)) / (2 * a);
result.setText("<html>Phuong co 2 nghiem.<br>x1 = " + x1 + "<br>x2 = " + x2 + "</html>");
}
timer.stop();
}
public类NewThread实现可运行{
专用JLabel标签、结果;
私人int a、b、c;
公共新线程(JLabel标签、int a、int b、int c、JLabel结果){
this.label=标签;
这个a=a;
这个.b=b;
这个.c=c;
this.result=结果;
}
@凌驾
公开募捐{
双x1,x2;
长i=System.currentTimeMillis();
计时器计时器=新计时器(10,新ActionListener(){
@凌驾
已执行的公共无效操作(操作事件e){
label.setText(“Thoi gian tinh toan:”+(Math.round(System.currentTimeMillis()-i)/1000)+“giay”);
}
});
timer.start();
试一试{
睡眠(3000);
}捕获(例外e){
}
双三角=b*b-4*a*c;
if(δ<0){
结果.setText(“Phuong trinh vo nghiem”);
}else if(delta==0){
结果.setText(“Phuong trinh co nghiem kep x1=x2=“+-b/2*a”);
}否则{
x1=(-b+数学sqrt(δ))/(2*a);
x2=(-b-数学sqrt(delta))/(2*a);
result.setText(“Phuong co 2 nghiem.
x1=“+x1+”
x2=“+x2+”);
}
timer.stop();
}
我的SwingWorker用于计时,它将每1秒更新一次时间
如果此工作人员的唯一责任是使用经过的时间更新标签,那么a是更好的选择。让SwingWorkerdoInBackground()
实现执行繁重的计算,最后,done()
实现可能会停止计时器并显示最终结果
不要在EDT中调用Thread.sleep()
,因为它将冻结整个GUI事件处理,并且您可能只会看到最终结果,而不会看到预期的定期更新
使现代化
仅添加一个简单的代码段作为开始:
public void startCalculation() {
Timer timer = new Timer(1000, new ActionListener() {
AtomicInteger elapsedSeconds = new AtomicInteger();
@Override
public void actionPerformed(ActionEvent evt) {
label.setText(String.format("Elapsed time: %d seconds", elapsedSeconds.incrementAndGet()));
}
});
SwingWorker<Integer, Void> worker = new SwingWorker<Integer, Void>() {
@Override
protected Integer doInBackground() throws Exception {
// do heavy stuff
Thread.sleep(3000); // it is safe to "sleep" here because it's not executed in the EDT
return 1;
}
@Override
protected void done() {
timer.stop();
// update the GUI with the results here if it's required
}
};
timer.start();
worker.execute();
}
public void startCalculation(){
计时器计时器=新计时器(1000,新ActionListener(){
AtomicInteger elapsedSeconds=新的AtomicInteger();
@凌驾
已执行的公共无效操作(操作事件evt){
label.setText(String.format(“运行时间:%d秒”,elapsedSeconds.incrementAndGet());
}
});
SwingWorker worker=新SwingWorker(){
@凌驾
受保护的整数doInBackground()引发异常{
//做重活
Thread.sleep(3000);//在这里“sleep”是安全的,因为它不是在EDT中执行的
返回1;
}
@凌驾
受保护的void done(){
timer.stop();
//如果需要,在此处使用结果更新GUI
}
};
timer.start();
worker.execute();
}
@AndrewThompson我对此很失望。如果你能帮我,然后关闭这个。如果你在EDT中使用sleep
或任何其他耗时的操作,GUI将不会更新,因为它们都在EDT中运行(被阻止)。这正是让一个SwingWorker
-将长时间运行的任务与GUI任务分开的原因。在其他工作中,睡眠和计算应该在一(秒)SwingWorker
(或只是一个简单的线程)“我对此感到失望。”我无法向你表达其他人有多在乎你。这是你需要解决的问题,或者让你感到沮丧,对其他人来说,这纯粹是学术问题。如果你想要快速的答案,请仔细倾听说明并遵循提供的建议。我决定不只是关闭