gpt4 book ai didi

java - 是什么导致任意 JTree 节点错误地显示它们的名称,我该如何阻止它发生?

转载 作者:塔克拉玛干 更新时间:2023-11-02 20:02:53 27 4
gpt4 key购买 nike

我已经从 XML 数据构建了一个相当大的 JTree,实际上有数千个节点,其中大部分显示正确。但是由于某些原因,某些节点的 userData 字符串没有完全显示,而是被截短或完全截断,并在名称末尾附加了 ...

enter image description here

受影响的节点似乎是随机的,并且每次刷新树或从 XML 重新创建时都不同。

我已经排除的事情:

空间不足,无法显示全名。

  1. JTree 位于具有充足水平空间的 JScrollPane 内,JScrollPane 甚至不显示水平滚动条以指示空间不足。

  2. 即使是最短的名字也会受到影响。

  3. 所有缩短的节点名称的截止点都不一致。

从 XML 加载的名称不完整

  1. 如果受影响的节点不是叶节点,然后展开或折叠,则在重新呈现时会正确显示全名,在此过程中根本不会引用 XML。

编辑:

根据要求对 JTree 背后的代码进行一些解释:

TreeModel 的创建和树的种群:

public XMLDialogTree(Document doc)
{
DefaultTreeModel treeModel = new DefaultTreeModel(buildTreeNode(doc.getElementsByTagName("Dialogs").item(0)));
setModel(treeModel);
}

// A recursive function to build the tree
private DefaultMutableTreeNode buildTreeNode(Node xmlNode)
{
// Make sure the node's name is a description of what it is, as opposed to a generic XML tag
XMLDialogTreeNode = new XMLDialogTreeNode(xmlNode.getAttributes().getNamedItem("name").getNodeValue());
treeNode.controlName = xmlNode.getNodeName();

// Add children to the treeNode based on the xmlNode's children
NodeList nodeList = xmlNode.getChildNodes();
for (int i = 0; i < nodeList.getLength(); i++)
{
Node tempNode = nodeList.item(i);
if (tempNode.getNodeType() == Node.ELEMENT_NODE)
{
// loop again if has child nodes
treeNode.add(buildTreeNode(tempNode));
}
}
return treeNode;
}

doc 是一个包含已解析 XML 的 org.w3c.dom.Document,而 XMLDialogTreeNode 实际上只是一个 javax。 swing.tree.DefaultMutableTreeNode 扩展为包含 String controlName = "CustomNodeName"

自定义 CellRenderer 如下,代码几乎都是加载自定义图标,不会影响显示名称。

public class XMLDialogTreeCellRenderer extends DefaultTreeCellRenderer
{
private static final long serialVersionUID = 1L;

// Icons used in the JTree, loaded once on an as needed basis once, and stored here.
private static final Map<String, Icon> icons = new HashMap<String, Icon>();

static
{
// Make sure the default icon is loaded
loadIcon("_not_found");
}

@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean exp, boolean leaf, int row, boolean hasFocus)
{
XMLDialogTreeNode node = (XMLDialogTreeNode) value;

setIcons(node.controlName);

super.getTreeCellRendererComponent(tree, value, sel, exp, false/* leaf */, row, hasFocus);
return this;
}

/**
* Assigns both the open and close icons, which are specific to a certain control. Loads them if necessary.
*
* @param controlName
* - The name of the control in the XML and the name of the image in the resources.treeIcons package.
*/
private final void setIcons(String controlName)
{
// Make sure the Node has a controlName set
if (controlName != null)
{
// Try and get a pre-loaded icon
Icon controlIcon = icons.get(controlName);
// It wasn't there, try loading it
if (controlIcon == null)
loadIcon(controlName);

// If the icon doesn't exist, it is set to a default so this code is safe
setOpenIcon(controlIcon);
setClosedIcon(controlIcon);
// Stop here so we don't just set the default icons again
return;
}
setOpenIcon(getDefaultOpenIcon());
setClosedIcon(getDefaultClosedIcon());
}

/**
*
*
* @param iconName
* @return
*/
private static final void loadIcon(String iconName)
{
URL url = XMLDialogTreeCellRenderer.class.getResource("/com/phabrix/resources/dialogTreeIcons/" + iconName + ".png");
if (url == null)
{
// Tell the developer that they need to make a new icon for a new control type
if (Main.DEBUG && !iconName.equals("Dialogs"))
System.out.println("There is no icon for the control named: " + iconName);
url = XMLDialogTreeCellRenderer.class.getResource("/com/phabrix/resources/dialogTreeIcons/_not_found.png");
}

icons.put(iconName, new ImageIcon(Toolkit.getDefaultToolkit().getImage(url)));
}
}

最佳答案

如此简单的答案;这段代码:

// Try and get a pre-loaded icon
Icon controlIcon = icons.get(controlName);
// It wasn't there, try loading it
if (controlIcon == null)
loadIcon(controlName);

变成了这段代码:

// Try and get a pre-loaded icon
Icon controlIcon = icons.get(controlName);
// It wasn't there, try loading it
if (controlIcon == null)
{
loadIcon(controlName);
controlIcon = icons.get(controlName);
}

请注意,在检查我们的 Icon 变量是否为 null 并确保 Icon 已加载到程序中后,我现在实际上要确保 Icon 变量已更新,因此它不再为 null。

我的树中受影响的节点并不像我之前想象的那样随机或波动。它始终是每个图标绘制的第一个节点(不同取决于我打开树的顺序)。我加载每个图标一次,然后缓存它(树很大,多次重新加载相同的图标对性能有很大影响)。本质上,节点是用文本创建的,然后在显示后设置了一个图标,这会分流文本并导致结尾被截断。如上,解决方案是第一次加载后不要忘记设置图标。一个更好的解决方案是对我的 icons.get() 进行包装,以确保返回图标并封装缓存优化。

关于java - 是什么导致任意 JTree 节点错误地显示它们的名称,我该如何阻止它发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26505936/

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