我应该在 EDT 中创建 swing 元素吗?
我遇到了编辑非线程安全图形元素的并发问题,但我正在创建它们,它们还没有显示,如果它们很多或者它们需要一些时间来分配会卡住 GUI ,不是吗?
这里是我使用 EDT 来显示但不创建我的 GUI 结构的示例:
public class Launcher {
private final SwingWorker worker;
private final JFrame frame;
private final JLabel label;
private final JProgressBar progressBar;
public Launcher() {
// init user interface
frame = new JFrame();
JPanel panel = new JPanel(new BorderLayout());
label = new JLabel("Launching...", SwingConstants.CENTER);
progressBar = new JProgressBar(0, 100);
progressBar.setIndeterminate(true);
panel.add(label, BorderLayout.CENTER);
panel.add(progressBar, BorderLayout.PAGE_END);
initUI(panel);
worker = new LauncherWorker(this);
worker.addPropertyChangeListener((PropertyChangeListener)this);
}
private void initUI(final Component panel) {
if (!SwingUtilities.isEventDispatchThread()) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
DirectaChatLauncher.this.initUI(panel);
} //run()
});
return;
}
Container contentPane = frame.getContentPane();
contentPane.setLayout(new BorderLayout());
contentPane.add(panel, BorderLayout.PAGE_END);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
int progress = (Integer) evt.getNewValue();
progressBar.setValue(progress);
}
}
private void setProgression(final String msg) {
label.setText(msg);
}
class LauncherWorker extends SwingWorker<Boolean, String> {
private final Launcher LAUNCHER;
public LauncherWorker(Launcher launcher) {
super();
LAUNCHER = launcher;
}
@Override
protected Boolean doInBackground() throws Exception {
setProgress(0);
publish("Started");
...
setProgress(100);
publish("Launched");
Thread.sleep(1000);
return Boolean.TRUE;
}
@Override
protected void process(List<String> chunks) {
LAUNCHER.setProgression(chunks.get(0));
}
@Override
public void done() {
LAUNCHER.done();
}
}
}
还好吗,因为元素还没有显示?还是应该全部移到 initUI()
中?
最佳答案
在 Swing 中 separable model architecture ,一个 View 组件监听它的模型。因为 View 可能会任意响应模型更新生成的事件,所以相应的模型必须也在 EDT 上更新。您可以通过以下两种基本方法之一来减少延迟:
使用
EventQueue.invokeLater()
来自一个单独的线程,如图所示 here .使用
SwingWorker
获得列举的额外好处here .
关于java - 我应该将 swing 元素分配/创建到 EDT 中吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33520222/