0

在我的 java 应用程序中,我使用 swing 来实现 UI。有一个名为theButton的按钮 ,它在以下及时的步骤中参与一些 IO 操作:

  1. 该按钮最初有文字“点击连接”
  2. 然后在连接操作开始之前,我希望theButton 显示“正在连接...”
  3. 然后 IO 操作开始
  4. IO 操作完成后,按钮现在显示“已连接(单击断开连接)”。

    • 问题
    • 我正在使用以下代码,但首先按钮的文本在 IO 开始之前不会更改为“正在连接...”!在 IO 开始之前,按钮实际上也没有被禁用!我应该在这里做什么?

--

// theButton with text "Click to connect is clicked"
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
theButton.setText("Trying to connect...");
theButton.setEnabled(false);// to avoid clicking several times! Some users cannot wait
theButton.repaint();
// doing some IO operation which takes few seconds
theButton.setText("connected ( click to disconnect)");
theButton.setEnabled(true);
theButton.repaint();
}
});
4

1 回答 1

3

你的问题在这里:

javax.swing.SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    theButton.setText("Trying to connect...");
    theButton.setEnabled(false);
    theButton.repaint();

    // doing some IO operation which takes few seconds // **********

    theButton.setText("connected ( click to disconnect)");
    theButton.setEnabled(true);
    theButton.repaint();
  }
});
  • 标有*******注释的代码正在 EDT 上运行,并将冻结您的应用程序及其所有正在绘制的内容。
  • 改用 SwingWorker 在后台线程中运行代码。
  • 请注意,不需要使用invokeLater(...)ActionListener 中的代码,因为默认情况下此代码已在 EDT 上运行。
  • 也摆脱你的repaint()电话,因为他们不需要,他们没有帮助。
  • 将 PropertyChangeListener 添加到您的 SwingWorker 以侦听何时完成,然后您可以重置您的 JButton。

而是这样做:

// code not compiled nor tested
javax.swing.SwingUtilities.invokeLater(new Runnable() {
  public void run() {
    theButton.setText("Trying to connect...");
    theButton.setEnabled(false);

    MySwingWorker mySwingWorker = new MySwingWorker();

    mySwingWorker.addPropertyChangeListener(new PropertyChangeListener() {
      // listen for when SwingWorker's state is done
      // and reset your button.
      public void propertyChange(PropertyChangeEvent pcEvt) {
        if (pcEvt.getNewValue() == SwingWorker.StateValue.DONE) {
          theButton.setText("connected ( click to disconnect)");
          theButton.setEnabled(true);
        }
      }
    });

    mySwingWorker.execute();
  }
});

// code not compiled nor tested
public class MySwingWorker extends SwingWorker<Void, Void> {
  @Override
  public void doInBackground() throws Exception {
    // doing some IO operation which takes few seconds
    return null;
  }
}

请务必阅读:Swing 中的并发

于 2013-07-23T21:05:09.707 回答