gpt4 book ai didi

java - JTree 异步节点创建与 JGraph 库不一致

转载 作者:行者123 更新时间:2023-12-02 07:22:52 25 4
gpt4 key购买 nike

我正在创建一个带有 rootNode 的 Jtree,然后创建另一个异步更新根节点的线程。

如果我在某个 JPanel 中独立运行这个 Jtree,它的效果会非常好,它甚至可以在项目中的某个地方工作,但我被要求在一些新的 swing 组件中使用这个 Jtree。

在新的 Swing Panel 中,它不会完全填充,它仅填充在 Jtree 在屏幕上呈现之前插入的节点(在开始时几毫秒)。一旦 Jtree 被渲染,它就不会被更新。现在有趣的部分是我还在节点上创建了一个鼠标监听器,以便我可以通过右键单击创建节点功能来创建一个新节点,并创建该新节点并将其添加到 Jtree 根节点上。

要添加的重要一点是,我使用 newThread(){void run}).start() 方法创建一个线程来在 Jtree 上添加节点,因为我之前从未觉得需要 SwingUtilities.invokeLater 方法。但现在,如果我使用 SwingUtilities.invokeLater 方法,主窗口也不会打开,它只是在启动过程中停止,我刚刚检查了 SwingUtilities.invokeLater 也可以与旧组件一起正常工作,当然独立工作也很好。

我确实调用 model.nodeStructureChanged(changedNode);添加节点后,这就是它之前工作正常的原因。

请帮忙,代码很难提取,并且 Jtree 代码之前工作正常,可能是某些组件阻止包含的小部件异步刷新自身?

编辑更新以包含一些代码,我正在使用 Nick 提供的 Temp 类:-

    public BasicGraphEditor(String appTitle, mxGraphComponent component)
{
// Stores and updates the frame title
this.appTitle = appTitle;

// Stores a reference to the graph and creates the command history
graphComponent = component;
final mxGraph graph = graphComponent.getGraph();
undoManager = createUndoManager();

// Do not change the scale and translation after files have been loaded
graph.setResetViewOnRootChange(false);

// Updates the modified flag if the graph model changes
graph.getModel().addListener(mxEvent.CHANGE, changeTracker);

// Adds the command history to the model and view
graph.getModel().addListener(mxEvent.UNDO, undoHandler);
graph.getView().addListener(mxEvent.UNDO, undoHandler);

// Keeps the selection in sync with the command history
mxIEventListener undoHandler = new mxIEventListener()
{
@Override
public void invoke(Object source, mxEventObject evt)
{
List<mxUndoableChange> changes = ((mxUndoableEdit) evt
.getProperty("edit")).getChanges();
graph.setSelectionCells(graph
.getSelectionCellsForChanges(changes));
}
};

undoManager.addListener(mxEvent.UNDO, undoHandler);
undoManager.addListener(mxEvent.REDO, undoHandler);

// Creates the graph outline component
graphOutline = new mxGraphOutline(graphComponent);

// Creates the library pane that contains the tabs with the palettes
libraryPane = new JTabbedPane();

/////////////////////////////////////////////////
// Only change i have done here: start
////////////////////////////////////////////////
Temp tempExplorer = new Temp();

libraryPane.add("new Explorere", tempExplorer);

/////////////////////////////////////////////////
// Only change i have done here: End
////////////////////////////////////////////////

// Creates the inner split pane that contains the library with the
// palettes and the graph outline on the left side of the window
JSplitPane inner = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
libraryPane, graphOutline);
inner.setDividerLocation(320);
inner.setResizeWeight(1);
inner.setDividerSize(6);
inner.setBorder(null);

// Creates the outer split pane that contains the inner split pane and
// the graph component on the right side of the window
JSplitPane outer = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, inner,
graphComponent);
outer.setOneTouchExpandable(true);
outer.setDividerLocation(200);
outer.setDividerSize(6);
outer.setBorder(null);

// Creates the status bar
statusBar = createStatusBar();

// Display some useful information about repaint events
installRepaintListener();

// Puts everything together
setLayout(new BorderLayout());
add(outer, BorderLayout.CENTER);
add(statusBar, BorderLayout.SOUTH);
installToolBar();

// Installs rubberband selection and handling for some special
// keystrokes such as F2, Control-C, -V, X, A etc.
installHandlers();
installListeners();
updateTitle();
}

上面的类来自 Jgraph 库 https://github.com/jgraph/jgraphx我只是像上面一样添加 jtree 组件,没有其他更改。请帮忙。

最佳答案

除非明确声明,否则 Swing 不是线程安全的。在 the JavaDocs for JTree ,它明确表示这不是线程安全的。如果您在 EDT 之外的线程中更新它,则无法保证任何内容都能正常工作。因此,如果您想从不同的线程更新 JTree,则需要使用 SwingUtilities.invokeLater(Runnable run); 以便将请求放在 EDT 上。

我建议使用一个数据结构来存储 JTree 的信息,并且仅使用 JTree 进行用户交互(而不是数据存储)。

编辑

下面是在组件模型中使用 SwingUtilities.invokeLater() 更新 JTree 的示例。无需您发布任何代码,这是我必须使用的最好的方法。请尝试使用它来重现您的问题(将您的代码片段添加到此示例中,直到您缩小问题范围)。

import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;

public class Temp extends JPanel{
JTree tree = new JTree();

public Temp(){
JScrollPane jsp = new JScrollPane(tree);

// Creates the library pane that contains the tabs with the palettes
JTabbedPane libraryPane = new JTabbedPane();

libraryPane.add("new Explorere", jsp);

// Creates the inner split pane that contains the library with the
// palettes and the graph outline on the left side of the window
JSplitPane inner = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
libraryPane, new JPanel());
inner.setDividerLocation(320);
inner.setResizeWeight(1);
inner.setDividerSize(6);
inner.setBorder(null);

// Creates the outer split pane that contains the inner split pane and
// the graph component on the right side of the window
JSplitPane outer = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, inner,
new JPanel());
outer.setOneTouchExpandable(true);
outer.setDividerLocation(200);
outer.setDividerSize(6);
outer.setBorder(null);

// Puts everything together
setLayout(new BorderLayout());
add(outer, BorderLayout.CENTER);
}

public static void main(String[] args) {
final Temp temp = new Temp();
SwingUtilities.invokeLater(new Runnable(){

@Override
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(temp);
frame.pack();
frame.setVisible(true);
}});

Thread updater = new Thread(temp.new CustomThread());
updater.start();
}

public class CustomThread implements Runnable{

@Override
public void run() {
for(int i = 0; i < 1000; i++){
updateTree("New Item "+ i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}

public void updateTree(final String nodeToAdd){
SwingUtilities.invokeLater(new Runnable(){

@Override
public void run() {
DefaultTreeModel model = (DefaultTreeModel) tree.getModel();
DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();
DefaultMutableTreeNode child = new DefaultMutableTreeNode(nodeToAdd);
model.insertNodeInto(child, root,root.getChildCount());
tree.scrollPathToVisible(new TreePath(child.getPath()));
}});

}

}
}

关于java - JTree 异步节点创建与 JGraph 库不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13975810/

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