gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 07:46:04 25 4
gpt4 key购买 nike

我有一个使用 JProgressBar 的 GUI。 GUI 具有调用以下代码的 JBUTTON:

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 检查失败,这一切都很好但不稳定。然而,我无法理解的是,这是否也意味着我应该在 setValue() 上使用 SwingUtilities.invokeLater()。我担心的是,由于我不知道 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();
}
}

关于java - 我什么时候应该使用 javax.swing.SwingUtilities.invokeLater()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25954521/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com