我希望 GUI 在实例化对象并实际执行工作之前将按钮的标题从“Go”更改为“Working...”。完成后,我希望按钮的标题切换回“开始”。
代码如下:
private class convert implements ActionListener {
public void actionPerformed(ActionEvent e) {
JButton button = (JButton)e.getSource();
button.setText("Working...");
button.setEnabled(false);
anObject name = new AnObject();
boolean result = name.methodName(chooser.getSelectedFile(),encoding);
// A bunch of stuff was here but irrelevant to the question,
// so it was removed to save room.
button.setEnabled(true);
button.setText("Go");
}
实际发生的是 name 被实例化,methodName 被调用,然后按钮在屏幕上更新,尽管我已经告诉 VM首先更改按钮标题。
我的工作理论是,鉴于我没有使这个程序线程化,这与操作优先级或 JVM 的内部线程化或其他...有关...
有什么建议吗?
最佳答案
我知道您已经接受了一个解决方案,但由于您遇到了“卡住的 gui”综合症,您肯定有线程问题,而 invokeLater 不会解决您的问题。正如 extraneon 上面提到的,您需要一个 SwingWorker 或一些后台线程来解决这个问题。另外,我认为这是使用 AbstractAction 而不是 ActionListener 的好例子。例如:
import java.awt.Dimension;
import java.awt.event.*;
import javax.swing.*;
@SuppressWarnings("serial")
public class Convert extends AbstractAction {
private static final long SLEEP_TIME = 3000; // 3 seconds
private String enabledText;
private String disabledText;
public Convert(String enabledText, String disabledText) {
super(enabledText);
this.enabledText = enabledText;
this.disabledText = disabledText;
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (!(source instanceof JButton)) {
return;
}
final JButton button = (JButton) source;
setButtonEnabled(button, false);
new SwingWorker<Void, Void>() {
@Override
protected Void doInBackground() throws Exception {
// TODO: long-running code goes here.
// Emulated by Thread.sleep(...)
Thread.sleep(SLEEP_TIME);
return null;
}
@Override
protected void done() {
setButtonEnabled(button, true);
}
}.execute();
}
public void setButtonEnabled(JButton button, boolean enabled) {
if (enabled) {
button.setText(enabledText);
button.setEnabled(true);
} else {
button.setText(disabledText);
button.setEnabled(false);
}
}
private static void createAndShowUI() {
JFrame frame = new JFrame("Convert");
frame.getContentPane().add(new ConvertGui());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}
@SuppressWarnings("serial")
class ConvertGui extends JPanel {
public ConvertGui() {
add(new JButton(new Convert("GO", "Working...")));
}
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
}
关于java - Java 中的操作优先级。 (对象在 GUI 更新之前实例化并运行?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6806920/