Custom JTree cell renderers with custom open/close icons
我想创建一个自定义的 JTree,它的节点是 JProgressBar\\'s 我有这个工作就像我想要的那样
但是你会注意到它缺少了它的打开/关闭图标,我也希望它是一个自定义的 /- 图标,而不是标准的可扩展文件夹。不完全确定我做错了什么(只是在美化代码之前开发这个概念)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | package com.testingarea; import java.awt.Component; import java.awt.Graphics; import java.util.HashMap; import javax.swing.BoxLayout; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTree; import javax.swing.UIManager; import javax.swing.plaf.IconUIResource; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeCellRenderer; public class TestTrees { public static void main(String args[]) { JFrame frame = new JFrame("Tree"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); ProgressTreeCellRenderer renderer = new ProgressTreeCellRenderer(); JProgressBar progressBar = new JProgressBar(0, 100); progressBar.setValue(50); progressBar.setStringPainted(true); DefaultMutableTreeNode top = new DefaultMutableTreeNode(progressBar); renderer.getNodeMap().put(top, new ProgressTreeCellRenderer2(progressBar)); createNodes(top, renderer); DefaultTreeModel model = new DefaultTreeModel(top); JTree tree = new JTree(model); tree.setCellRenderer(renderer); JScrollPane pane = new JScrollPane(tree); tree.clearSelection(); frame.getContentPane().add(pane); frame.setSize(250, 250); frame.setVisible(true); } private static void createNodes(DefaultMutableTreeNode top, ProgressTreeCellRenderer renderer) { JProgressBar progressBar1 = new JProgressBar(0, 100); progressBar1.setValue(25); progressBar1.setStringPainted(true); DefaultMutableTreeNode one = new DefaultMutableTreeNode(progressBar1); top.add(one); renderer.getNodeMap().put(one, new ProgressTreeCellRenderer2(progressBar1)); JProgressBar progressBar2 = new JProgressBar(0, 100); progressBar2.setValue(25); progressBar2.setStringPainted(true); DefaultMutableTreeNode two = new DefaultMutableTreeNode(progressBar2); top.add(two); renderer.getNodeMap().put(two, new ProgressTreeCellRenderer2(progressBar2)); } } @SuppressWarnings("serial") class ProgressTreeCellRenderer extends DefaultTreeCellRenderer { private HashMap<DefaultMutableTreeNode, ProgressTreeCellRenderer2> nodeMap = new HashMap<DefaultMutableTreeNode, ProgressTreeCellRenderer2>(); @Override public Component getTreeCellRendererComponent(JTree tree, final Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { if(nodeMap.containsKey(value)) { //I was expecting this to work, alas it does not? setClosedIcon(new IconUIResource(new NodeIcon('+'))); setOpenIcon(new IconUIResource(new NodeIcon('-'))); return nodeMap.get(value).getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); } return super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); } public HashMap<DefaultMutableTreeNode, ProgressTreeCellRenderer2> getNodeMap() { return nodeMap; } } class ProgressTreeCellRenderer2 implements TreeCellRenderer { private JProgressBar _progressBar; private DefaultTreeCellRenderer _defaultRenderer; public ProgressTreeCellRenderer2(JProgressBar progressBar) { _progressBar = progressBar; _defaultRenderer = new DefaultTreeCellRenderer(); } @Override public Component getTreeCellRendererComponent(JTree tree, final Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { Component render = _defaultRenderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus); final JPanel panel = new JPanel(); BoxLayout layout = new BoxLayout(panel, BoxLayout.X_AXIS); panel.setLayout(layout); panel.add(_progressBar); render = panel; return render; } } class NodeIcon implements Icon { private static final int SIZE = 9; private char type; public NodeIcon(char type) { this.type = type; } public void paintIcon(Component c, Graphics g, int x, int y) { g.setColor(UIManager.getColor("Tree.background")); g.fillRect(x, y, SIZE - 1, SIZE - 1); g.setColor(UIManager.getColor("Tree.hash").darker()); g.drawRect(x, y, SIZE - 1, SIZE - 1); g.setColor(UIManager.getColor("Tree.foreground")); g.drawLine(x + 2, y + SIZE / 2, x + SIZE - 3, y + SIZE / 2); if (type == '+') { g.drawLine(x + SIZE / 2, y + 2, x + SIZE / 2, y + SIZE - 3); } } public int getIconWidth() { return SIZE; } public int getIconHeight() { return SIZE; } } |
如果
但是,请注意,您当前的实现非常昂贵。不仅每个节点都有一个新的渲染器,而且您在
看看这个答案(由@mKorbel 提供),它说明了表格中的单个进度条渲染器。