当内容发生变化时,JTree中的JLabel不会调整大小

时间:2013-10-16 17:06:09

标签: java swing jlabel jtree treecellrenderer

我有一个行为如此的JTree:

  • root有一个RootObject类型的用户对象;它使用明文标签,在树的整个生命周期内都是静态的。
  • 每个孩子都有一个类型为ChildObject的用户对象,该对象可能处于以下三种状态之一:未运行,正在运行或已完成。
  • ChildObject未运行时,它是明文标签。
  • ChildObject正在运行时,它会使用图标资源并切换到HTML呈现,因此文本以斜体显示。
  • ChildObject完成后,它会使用不同的图标资源,并使用HTML呈现以粗体显示文字。

目前,我的代码如下:

public class TaskTreeCellRenderer extends DefaultTreeCellRenderer {
    private JLabel label;

    public TaskTreeCellRenderer() {
        label = new JLabel();
    }

    public Component getTreeCellRendererComponent(JTree tree,
           Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        Object nodeValue = ((DefaultMutableTreeNode) value).getUserObject();

        if (nodeValue instanceof RootObject) {
            label.setIcon(null);
            label.setText(((RootObject) nodeValue).getTitle());
        } else if (nodeValue instanceof ChildObject) {
            ChildObject thisChild = (ChildObject) nodeValue;

            if (thisChild.isRunning()) {
                label.setIcon(new ImageIcon(getClass().getResource("arrow.png")));
                label.setText("<html><nobr><b>" + thisChild.getName() + "</b></nobr></html>");
            } else if (thisChild.isComplete()) {
                label.setIcon(new ImageIcon(getClass().getResource("check.png")));
                label.setText("<html><nobr><i>" + thisChild.getName() + "</i></nobr></html>");
            } else {
                label.setIcon(null);
                label.setText(thisChild.getName());
            }
        }

        return label;
    }
}

在大多数情况下,这很好。初始树使用明文使标签呈现良好状态。问题是,一旦ChildObject实例开始改变状态,JLabel就会更新以使用HTML呈现,但不会调整大小以补偿文本或图标。例如:

初始状态:
http://imageshack.us/a/img14/3636/psxi.png

正在进行中:
http://imageshack.us/a/img36/7426/bl8.png

成品:
http://imageshack.us/a/img12/4117/u34l.png

我出错的任何想法?提前谢谢!

1 个答案:

答案 0 :(得分:2)

因此,您需要告诉树模型内容已更改。 每次更改ChildObject的状态时,您必须执行以下操作:

((DefaultTreeModel)tree.getModel()).reload(node);

nodeDefaultMutableTreeNode,其中包含已更改的ChildObject。

如果子对象的状态在Swing-Thread(EDT)之外被更改,请不要忘记使用SwingUtilities.invokeLater()。