【问题标题】:AWT event thread interruptionAWT 事件线程中断
【发布时间】:2011-10-05 15:39:15
【问题描述】:

我有代码:

import java.awt.Dimension;
import java.util.Observable;
import java.util.Observer;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;


public class Test2 {

JFrame frame = null;
JPanel panel = null;
JButton button = null;
Task task = null;
Indicator indicator = null;
Runnable computation;

public static void main(String[] args) {
    new Test2().start();
}

public void start() {
    SwingUtilities.invokeLater(new Dialog());
}

private void process1() {
    int result = 0;

    for (int i=0; i<100000; i++) {
        result = (int) Math.ceil(++result + Math.sqrt(result));

        System.out.println("proc1 " + result);
    }
}

private void process2() {
    int result = 0;

    for (int i=0; i<100000; i++) {
        result = (int) Math.ceil(++result + Math.sqrt(result)*500);

        System.out.println("proc2 " + result);
    }
}

private class Computation implements Runnable {

    public void run() {

        process1();
        task.setProgress(2);
        process2();
        task.setProgress(3);
    }

}

private class Dialog implements Runnable {

    public Dialog() {
    }

    public void run() {
        frame = new JFrame("Test");
        panel = new JPanel();
        panel.setPreferredSize(new Dimension(300, 200));
        frame.getContentPane().add(panel);
        button = new JButton("b1");
        panel.add(button);
        indicator = new Indicator();
        task = new Task();
        task.addObserver(indicator);

        frame.pack();
        frame.setVisible(true);

        computation = new Computation();
        SwingUtilities.invokeLater(computation);
    }
}

private class Task extends Observable {

    int progress;

    public Task() {

    }

    public void setProgress(int progress) {
        this.progress = progress;
        setChanged();
        notifyObservers();
    }

    public int getProgress() {
        return progress;
    }
}

private class Indicator implements Observer {

    @Override
    public void update(Observable arg0, Object arg1) {
        button.setText(((Task)arg0).getProgress()+"");
    }
}
}

所以我有两个耗时的操作(process1 和 process2)。我的目标是在 process1 完成后,更新 swing-button(参见 task.setProgress 方法)。

问题在于 process1() 和 process2() 完成后执行更新。

【问题讨论】:

    标签: java multithreading swing awt


    【解决方案1】:

    ..update 在 process1() 和 process2() 完成后执行。

    不要在 EDT 上执行长时间运行的任务,有关详细信息,请参阅 Concurrency in Swing。实现这一目标的一种方法是使用SwingWorker


    ..如果我使用两个SwingWorkers 来执行process1()process2(),那么它们的执行顺序是不可预测的。我需要process2() 后跟process1()。我怎样才能得到这个?

    在 1 SwingWorkerdoInBackground() 方法中调用这两个方法,在适当的时间用适当的值调用 SwingWorker.setProgress(int)。例如

    ... doInBackground() {
        setProgress(0);
        process1();
        setProgress(50);
        process2();
        setProgress(100);
    }
    

    【讨论】:

    • +1 @CHEM_Eugene 我认为 button.setText(((Task)arg0).getProgress()+""); 只被调用一次,然后有任何更新的进度,但你可以调试它,添加 System.out.println,或者包装这个代码行到 invokeLater()
    • Andrew Thompson,如果我使用两个 SwingWorker 来执行 process1() 和 process2(),那么它们的执行顺序是不可预测的。我需要 process2() 后跟 process1()。我怎样才能得到这个?
    • 使用一个SwingWorker 调用process1() 然后process2()(按此顺序)。虽然我一定误解了你,因为这个答案看起来很明显。
    • 我不能使用一个 SwingWorker,因为我需要在 process1() 和 process2() 之后更新进度条
    • 对不起,我给出了错误的例子......真的,process1() 和 process2() 与 GUI 一起工作。所以,我不能用 SwingWorker 调用它们。
    猜你喜欢
    • 2014-08-10
    • 2012-12-24
    • 2011-09-19
    • 1970-01-01
    • 1970-01-01
    • 2019-06-02
    • 2015-01-09
    • 1970-01-01
    • 2012-01-21
    相关资源
    最近更新 更多