3

可能重复:
通过单击摆动中的按钮多次更改标签文本不起作用

我正在使用 Java Swing 开发一个 GUI,其中我使用了两个组件 JButton 和 JLabel。JLabel 的文本最初设置为“单击按钮”。单击按钮后,我希望 JLabel 的文本更改为“正在处理”。最后更改为“已处理”

因此,当我单击按钮时,控件转到 ActionPerformed,其中我使用 setText() 方法将 JLabel 的文本设置为“处理”。ActionPerformed 中的最后一条语句是使用 setText() 将 JLabel 的文本设置为“已处理”。

当我运行程序时,标签显示“单击按钮”。最后它变为“已处理”。但是,它从不显示“处理中”。

4

2 回答 2

9

因为它现在不工作的原因是处理 GUI 刷新的 Java 线程也处理侦听器的事件。因此,当您调用该setText()方法时,它会告诉 GUI 线程(称为 EDT for Event Dispatch Thread)更新组件,但现在无法完成,因为 EDT 当前正在actionPerformed()执行您的代码的方法中。

所以我认为你应该把做任何工作的代码和改变你的 JLabel 的文本放在一个新的线程中。因此,EDT 会在actionPerformed()JLabel 的文本更改时启动它,然后可以自由地更新 GUI。

像这样:(你必须实现 run 方法)

public void actionPerformed(ActionEvent e) {
    Thread t = new Thread(new Runnable() {
        @Override
        public void run() {
            myLabel.setText("Processing");
            //Do the job
            myLabel.setText("Processed");
        }     
    });
    t.start();
}

理想情况下,setText()必须从 EDT 本身调用更改组件的方法和其他方法以避免错误……在我给您的示例中,情况并非如此。如果您想这样做,请使用此方法:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
        myLabel.setText("my text");
    }
});
于 2012-11-06T22:16:05.890 回答
1

“Processing”和“Processed”文本的设置之间必须有一个延迟JLabel,否则文本的变化将太快而无法观察。

一种方法是在两次调用之间使用Swing Timer 。setTextJButton ActionListener可能看起来像这样:

public void actionPerformed(ActionEvent e) {
    label.setText("Processing...");

    ActionListener taskPerformer = new ActionListener() {
        public void actionPerformed(ActionEvent evt) {
            label.setText("Processed");
        }
    };
    Timer timer = new Timer(1000, taskPerformer); // delay one sec
    timer.setRepeats(false);
    timer.start();
}
于 2012-11-06T22:08:22.507 回答