gpt4 book ai didi

java - 从单独的线程修改基于 PropertyChangeEvent 的 Swing 组件

转载 作者:行者123 更新时间:2023-11-30 09:18:01 24 4
gpt4 key购买 nike

如果我理解正确,当我直接从另一个线程修改 Swing 组件时,该操作应该放在 EDT 的事件队列中以防止与 GUI 的同步问题:

public class SwingFrame extends JFrame {

private JTextField _textField;

public SwingFrame() {
_textField = new JTextField();
Thread thread = new Thread(new SomeRunnable(_textField));
thread.start();
}
}

public class SomeRunnable implements Runnable {

private final JTextField _textField;

public SomeRunnable(final JTextField textField) {
_textField = textField;
}
@Override
public void run() {
// _textField.setText("Goodbye, Swing!"); /* wrong */
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
_textField.setText("Hello, Swing!");
}
});
}
}

我的问题是,当 Swing 组件不是在非 EDT 线程中直接修改,而是通过在从另一个线程接收 PropertyChangeEvent 的 EDT 上执行的 PropertyChangeListener 修改时,我是否需要遵循同样的习惯用法?

public class SwingFrame extends JFrame implements PropertyChangeListener {

private JTextField _textField;

public SwingFrame() {
_textField = new JTextField();
Thread thread = new Thread(new SomeRunnable());
thread.start();
}

@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("text")) {
_textField.setText(String.valueOf(evt.getNewValue()));
}
}
}

public class SomeRunnable implements Runnable {

private final PropertyChangeSupport _propertyChangeSupport;

public SomeRunnable() {
_propertyChangeSupport = new PropertyChangeSupport(this);
}
@Override
public void run() {
// Ok? Or wrap in EventQueue.invokeLater()?
_propertyChangeSupport.firePropertyChange("text", null, "Hello, Swing!");
}
}

PropertyChangeSupport 中似乎没有任何东西可以使它本质上“Swing 安全”,但我不想在不需要时不必要地调用 EventQueue.invokeLater() 使我的代码困惑。

最佳答案

只有 AWTEvent 对象从事件调度线程的上下文中处理,所有其他类型的事件通常是手动引发的(通常使用 for-loop 和列表注册听众)。

这意味着,在您的示例的上下文中,属性更改事件实际上将在 EDT 之外触发。因为大多数 Swing 组件都假定它们在 EDT 内收到通知,所以这确实很危险。

现在,您可以修改您的任何 PropertyChangeListener 以检查它们是否在 EDT 的上下文中执行,但您不能做的是更改其他注册的听众如何工作。

如果您需要这样做(我会质疑原因的原因),您应该将 firePropertyChange 包装在 invokeLater 调用中以将其重新同步回 EDT .

同样,您可以使用 SwingWorker发布更改,以便它们在 EDT 中为您处理...

关于java - 从单独的线程修改基于 PropertyChangeEvent 的 Swing 组件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18730971/

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