gpt4 book ai didi

java - 在 Swing 线程之外的其他线程中初始化 Swing GUI 组件是否正确,只要它们不被附加?

转载 作者:行者123 更新时间:2023-12-01 16:54:52 25 4
gpt4 key购买 nike

为了加快应用程序启动速度,我将一些 GUI 生成代码移至工作线程。该线程创建所有 GUI 实例,然后使用 SwingUtilities.invokeLater 将它们附加到已经运行的应用程序 GUI。

我扩展了 ArrayList 以创建一个帮助程序类,该类会记住应该将哪些内容附加到哪些内容。

我这样使用它:

// This code runs in some other thread, not Swing thread
GUIAppendList list = new GUIAppendList();
JToggleButton button = new JToggleButton();
// The first variable represents already appended and rendered
// GUI element - for example menu
list.add(menuBarGlobalVariable, button);
// This will create all elements in Swing GUI thread
list.create();

GUIAppendList 创建如下项目:

  synchronized public void create() {
if(done)
return;
done = true;
SwingUtilities.invokeLater(new Runner(this));
}

protected static class Runner implements Runnable {
public final GUIAppendList list;
public Runner(GUIAppendList list) {
this.list = list;
}
@Override
public void run() {
for(AddChild c : list) {
c.join();
}
if(!list.after.isEmpty()) {
for(Runnable c : list.after) {
c.run();
}
}
}
}

但自从我这样做后,我的应用程序开始随机(到目前为止并不总是并且从未处于 Debug模式)卡住。创建 GUI 元素是否有可能导致即使它们没有连接到主窗口?

这是完整的附加程序类:

import java.awt.Component;
import java.awt.Container;
import java.util.ArrayList;
import javax.swing.SwingUtilities;

/**
* This class allows you to prepare a list of swing elements that should be
* joined together. After you create the list, use .create() method which will
* then add all the items within the Swing main thread. This is done using
* invokeLater.
* @author Jakub
*/
public class GUIAppendList extends ArrayList<GUIAppendList.AddChild> {
/**
* Represents two nodes, container and component.
*/
public static class AddChild {
public AddChild(Container parent, Component child) {
this.parent = parent;
this.child = child;
}
final Container parent;
final Component child;

// Joins the two elements together
// THIS MUST BE CALLED IN THE SWING THREAD!!!
void join() {
parent.add(child);
};
}

// Prevents from calling the add in the list multiple times
private boolean done = false;
// List of other actions to be executed after creating the GUI
protected ArrayList<Runnable> after = new ArrayList();

synchronized public void add(Container parent, Component child) {
this.add(new AddChild(parent, child));
}
synchronized public void after(Runnable action) {
after.add(action);
}
/**
* Will ask Swing to run our runnable object which will append all the items.
*/
synchronized public void create() {
if(done)
return;
done = true;
SwingUtilities.invokeLater(new Runner(this));
}

protected static class Runner implements Runnable {
public final GUIAppendList list;
public Runner(GUIAppendList list) {
this.list = list;
}
@Override
public void run() {
// Append all nodes to each other
for(AddChild c : list) {
c.join();
}
// Run after actions
if(!list.after.isEmpty()) {
for(Runnable c : list.after) {
c.run();
}
}
}
}
}

最佳答案

不,这是不正确的,所有 Swing 组件都必须在 EDT 上创建/修改/添加/删除。

关于java - 在 Swing 线程之外的其他线程中初始化 Swing GUI 组件是否正确,只要它们不被附加?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34602719/

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