我什么时候应该使用javax.swing.SwingUtilities.invokeLater()?

用户名

我有一个使用的GUI JProgressBarGUI具有JBUTTONs调用以下代码的代码:

public void updateProgressBar(int x) {
    System.out.println(javax.swing.SwingUtilities.isEventDispatchThread());
    healthBar.setValue(x);
}

但是我也做了一个循环,定期调用相同的方法。

public class Loop implements Runnable {
    public void run() {
        while (true) { Thread.sleep(2000); updateProgressBar(0); }
    }
}

现在,据我所知,任何更改我的GUI的操作都需要从EDT执行。JProgressBar.setValue(x)更改我的GUI,然后从Loop类调用它时,isEventDispatchThread检查将失败,这一切都很好且不稳定。但是,我不明白的是,这是否也意味着我应该使用SwingUtilities.invokeLater()on setValue()我担心的是,由于我不知道setValue()实际的工作方式,因此我invokeLater()不必要地使用了它,甚至破坏了使用它的东西。

我不知道如何问我的问题,还有以下更好的方法:如果我不知道更改GUI的方法不是从EDT调用的,那我还知道我必须使用invokeLater()吗?

充满鳗鱼的气垫船

一种可能的解决方案是创建一种方法,该方法检查线程是否为EDT,如果是,则直接更新该条,否则将其在EDT上排队:

public void updateProgressBar(int value) {
   progressBar.setValue(value);
}

public void safeUpdateProgressBar(final int value) {
   if (SwingUtilities.isEventDispatchThread()) {
      updateProgressBar(value);
   } else {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            updateProgressBar(value);
         }
      });
   }
}

但是有很多方法可以给这只猫蒙皮。例如,

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.*;

public class ProgExample extends JPanel {
   private JProgressBar progressBar = new JProgressBar(0, 100);

   public ProgExample() {
      progressBar.setBorderPainted(true);
      progressBar.setStringPainted(true);
      add(progressBar);
      add(new JButton(new ProgressAction1("Action 1", KeyEvent.VK_1, this)));
      add(new JButton(new ProgressAction2("Action 2", KeyEvent.VK_2, this)));
      add(new JButton(new ProgressAction3("Action 3", KeyEvent.VK_3, this)));
   }

   public void updateProgressBar(int value) {
      progressBar.setValue(value);
   }

   public void safeUpdateProgressBar(final int value) {
      if (SwingUtilities.isEventDispatchThread()) {
         updateProgressBar(value);
      } else {
         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
               updateProgressBar(value);
            }
         });
      }
   }

   private static void createAndShowGui() {
      ProgExample mainPanel = new ProgExample();

      JFrame frame = new JFrame("ProgExample");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class ProgressAction1 extends AbstractAction {
   private static final int MAX_VALUE = 100;
   protected static final long SLEEP_TIME = 100;
   protected static final int STEP = 2;
   private ProgExample gui;

   public ProgressAction1(String name, int mnemonic, ProgExample gui) {
      super(name);
      putValue(MNEMONIC_KEY, mnemonic);
      this.gui = gui;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      new Thread(new Runnable() {
         private int value = 0;
         @Override
         public void run() {
            while (value <= MAX_VALUE) {
               gui.safeUpdateProgressBar(value);
               value += STEP;
               try {
                  Thread.sleep(SLEEP_TIME);
               } catch (InterruptedException e) {}
            }
            gui.safeUpdateProgressBar(MAX_VALUE);
         }
      }).start();
   }
}

class ProgressAction2 extends AbstractAction {
   private static final int MAX_VALUE = 100;
   protected static final long SLEEP_TIME = 100;
   protected static final int STEP = 2;
   private ProgExample gui;

   public ProgressAction2(String name, int mnemonic, ProgExample gui) {
      super(name);
      putValue(MNEMONIC_KEY, mnemonic);
      this.gui = gui;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      final SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
         private int value = 0;

         @Override
         protected Void doInBackground() throws Exception {
            while (value <= MAX_VALUE) {
               setProgress(value);
               value += STEP;
               try {
                  Thread.sleep(SLEEP_TIME);
               } catch (InterruptedException e) {}
            }
            setProgress(MAX_VALUE);
            return null;
         }
      };
      worker.addPropertyChangeListener(new PropertyChangeListener() {

         @Override
         public void propertyChange(PropertyChangeEvent pcEvt) {
            if ("progress".equals(pcEvt.getPropertyName())) {
               gui.updateProgressBar(worker.getProgress());
            }
         }
      });
      worker.execute();
   }
}

class ProgressAction3 extends AbstractAction {
   private static final int MAX_VALUE = 100;
   protected static final int SLEEP_TIME = 100;
   protected static final int STEP = 2;
   private ProgExample gui;

   public ProgressAction3(String name, int mnemonic, ProgExample gui) {
      super(name);
      putValue(MNEMONIC_KEY, mnemonic);
      this.gui = gui;
   }

   @Override
   public void actionPerformed(ActionEvent e) {
      new Timer(SLEEP_TIME, new ActionListener() {
         int value = 0;

         @Override
         public void actionPerformed(ActionEvent e) {
            if (value <= MAX_VALUE) {
               gui.updateProgressBar(value);
               value += STEP;
            } else {
               gui.updateProgressBar(MAX_VALUE);
               ((Timer) e.getSource()).stop();
            }

         }
      }).start();
   }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

什么是SwingUtilities.invokeLater

任何人都可以在此代码中解释javax.swing.SwingUtilities.invokeLater的使用

与在Java Swing程序中使用SwingUtilities.invokeLater()方法有关的一些疑问

SwingUtilities InvokeLater-什么是不良做法?

SwingUtilities.invokeLater()为什么需要它?

SwingUtilities.invokeLater是做什么的?

SwingUtilities.invokeLater

为什么要在main方法中使用SwingUtilities.invokeLater?

如何使用 SwingUtilities.invokeLater 调用阻塞模式

Java:即使使用SwingUtilities.invokeLater,线程也不会修改GUI

我应该在SwingWorker.doInBackground()内部使用SwingUtilities.invokeLater()吗?

为什么即使使用SwingUtilities.invokeLater后我的GUI仍然挂起?

使用invokeLater后,Swing UI不更新

在Java游戏循环中使用“ SwingUtilities.invokeLater()”是一种不好的做法吗?

SwingWorker和SwingUtilities.invokeLater之间的区别

SwingUtilities.invokeLater ...是否存在invokeNow?

Android中类似的功能SwingUtilities.invokeLater?

从SwingUtilities.InvokeLater调用中获取返回值?

Java Swing主JFrame:为什么SwingUtilities.getAncestorOfClass返回null?

SWT / Eclipse 3.x API中的SwingUtilities invokeLater等效吗?

SwingUtilities.invokeLater需要一个Runnable并在EDT上运行它吗?

Platform.RunLater(),swingUtilities.InvokeLater()和线程(可运行)混淆

Swing组件什么时候可以“显示”?

为什么invokeLater的主线程中执行?

我应该如何处理SwingUtilities.invokeAndWait引发的异常

Java Swing EDT:如何通过SwingUtilities.invokeAndWait知道哪些线程正在等待EventDisplay的执行?

我什么时候应该使用GROUP BY?

我什么时候应该使用blockingGet?

我什么时候应该使用SynchronousQueue