java - Java 中的操作优先级。 (对象在 GUI 更新之前实例化并运行?)

标签 java multithreading swing user-interface

我希望 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/

相关文章:

java - 注解访问修饰符 - 公共(public)与抽象

java - 检查属性是否与其他属性双向绑定(bind)

java - Dagger2 + Mockito : How to Unit Test this scenario?

c# - 使用具有多个模板参数的 Action 启动任务

java - 以编程方式确定 Coherence 主成员

multithreading - 通过线程下载图像错误

Java:加快我的代码速度

java - 设计UML类图工具

java - 我们可以放大缩小在 Canvas 上绘制的图形吗?

java - 将数据从 jtable 插入到 derby 数据库时出现重复条目