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



我希望GUI在对象实例化并实际完成工作之前将按钮的标题从"Go"更改为"Working…"。完成后,我希望按钮的标题切换回"Go"。"

代码如下:

    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无法解决您的问题。正如前面提到的,你需要一个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);
   }
}

一个"ActionPerformed"回调发生在事件线程中,通常在它返回之前GUI上不会更新任何内容。如果您想更新gui,做一些事情,然后再次更新它,您将需要更新gui并生成一个线程并返回。然后线程必须执行它的动作,然后执行swingutility。

试试swinguutilities . invokelater ().

private class convert implements ActionListener {
public void actionPerformed(ActionEvent e) {
    final JButton button = (JButton)e.getSource();
    button.setText("Working...");
    button.setEnabled(false);
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            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("Convert");
        }
    });
}

相关内容

  • 没有找到相关文章

最新更新