我有一个简单的TreeCellRenderer,它从节点中提取JButton,并将其输出到JTree。
public class ButtonCellRenderer extends JButton implements TreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
//setBackgroundNonSelectionColor(tree.getBackground());
ProgressButton b = null;
if ((value != null) && (value instanceof DefaultMutableTreeNode)) {
Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
if (userObject instanceof ProgressButton) {
b = (ProgressButton) userObject;
return b;
}
}
if (b == null) {
System.out.println("Null!");
DefaultTreeCellRenderer defaultRenderer = new DefaultTreeCellRenderer();
return defaultRenderer.getTreeCellRendererComponent(tree,
value, selected, expanded, leaf, row, hasFocus);
} else {
System.out.println("Returning label");
return new JLabel(b.getToolTipText(), b.getIcon(), SwingConstants.CENTER);
}
}
}
我不知道为什么,但它似乎陷入了循环,吃了大约30~50%的CPU。有没有办法消除这个?或者不必使用渲染器将JButton输出到树中?
我已经添加了上面修改过的代码,但是现在我遇到了一个问题,即按钮无法正常显示(它们都很小)。
答案 0 :(得分:5)
您正在调用super.getTreeCellRendererComponent
而不存储该值。如果稍后没有创建渲染器,则再次调用此方法(if c==null...
)。这本身就很昂贵。
更重要的是:
渲染器应该是一个重用的组件,并且只为要显示的特定值配置。这就是为什么默认实现重用标签并只设置文本,颜色,边框......这就是渲染器调用非常便宜的原因。
每次显示值时都会创建一个新的JLabel
:returnLab = new JLabel(text);
。这很贵。将为每个重绘事件中显示的每个单元调用此方法。这比构建组件网格要昂贵得多,并且违背了渲染器概念的全部目的。
请查看默认的渲染器实现,了解如何正确执行此操作。并查看tutorial。