我在树中的某些节点上有一个带有图标的JTree。它们出现并且工作正常但是当我选择带有图标的节点时,渲染器不会渲染整个节点但是看起来应用了偏移量,就好像它认为图标仍然在节点的左侧,如下所示:
渲染器的代码(扩展DefaultTreeCellRenderer)如下:
public ProfileTreeRenderer() {
super.setLeafIcon(null);
super.setClosedIcon(null);
super.setOpenIcon(null);
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
Component c = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
if (c instanceof JLabel) {
JLabel label = (JLabel) c;
label.setHorizontalTextPosition(SwingConstants.LEADING);
}
if(sel && !hasFocus) {
setBackgroundSelectionColor(UIManager.getColor("Panel.background"));
setTextSelectionColor(UIManager.getColor("Panel.foreground"));
} else {
setTextSelectionColor(UIManager.getColor("Tree.selectionForeground"));
setBackgroundSelectionColor(UIManager.getColor("Tree.selectionBackground"));
}
if (value instanceof ProfileNode) {
ProfileNode node = (ProfileNode) value;
if (node.isUsed() && !sel) {
c.setForeground(Color.GRAY);
}
if (node.getIcon() != null) {
setIcon(node.getIcon());
}
}
}
我无法理解为什么渲染器会应用此偏移量,所以有人能提供一种方法来使用图标完全选择节点吗?树本身的SSCCE代码如下。
public class Example extends JDialog {
public Example() {
JTree tree = new JTree(createModel());
tree.setCellRenderer(new ProfileTreeRenderer());
setLayout(new BorderLayout());
add(tree, BorderLayout.CENTER);
}
private TreeModel createModel() {
ProfileNode root = new ProfileNode("Profiles");
ProfileNode userA = new ProfileNode("Example User A");
ProfileNode userB = new ProfileNode("Example User B");
// You'll need to subsitute your own 16x16 icons here
userA.setIcon(ImageSet.USER_ICON);
userB.setIcon(ImageSet.USER_ICON);
root.add(userA);
root.add(userB);
return new DefaultTreeModel(root);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Example().setVisible(true);
}
});
}
}
ProfileNode类:
public class ProfileNode extends DefaultMutableTreeNode {
@Getter private String labelDisplay;
@Getter @Setter private ImageIcon icon;
@Getter @Setter private boolean isUsed = false;
public ProfileNode(String labelDisplay) {
this.labelDisplay = labelDisplay;
}
@Override
public String toString() {
return labelDisplay;
}
}
提前致谢。
答案 0 :(得分:2)
问题是DefaultTreeCellRenderer专门为open / leaf / close图标使用它的icon属性:它假设 - 如果图标!= null - 它位于组件的开头(即使它不是)并且相应地调整选择。您需要重新调整...或使用SwingX渲染器: - )
类似的东西:
JXTree tree = new JXTree();
tree.expandAll();
IconValue iv = new IconValue() {
Icon icon = XTestUtils.loadDefaultIcon("green-orb.png");
@Override
public Icon getIcon(Object value) {
return value.toString().contains("s") ? icon : null;
}
};
StringValue converter = new MappedValue(StringValues.TO_STRING, iv);
WrappingProvider provider = new WrappingProvider(IconValues.NONE, converter);
// hacking around missing api ...
LabelProvider wrappee = (LabelProvider) provider.getWrappee();
wrappee.getRendererComponent(null).setHorizontalTextPosition(JLabel.LEADING);
TreeCellRenderer r = new DefaultTreeRenderer(provider);
tree.setCellRenderer(r);