gpt4 book ai didi

java - 带有自定义打开/关闭图标的自定义 JTree 单元渲染器

转载 作者:行者123 更新时间:2023-12-02 06:25:45 36 4
gpt4 key购买 nike

我想创建一个自定义的 JTree,它的节点是 JProgressBar 的,我让它像我想要的那样工作

enter image description here

但是您会注意到它缺少打开/关闭图标,我也希望它成为自定义 +/- 图标而不是标准的可扩展文件夹。不完全确定我做错了什么(在美化代码之前只是开发概念)

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;
}
}

最佳答案

如果 ProgressTreeCellRenderer 调用 setClosedIconsetOpenIcon 没有任何效果,因为您正在返回从 nodeMap 检索的另一个渲染器。您必须在 ProgressTreeCellRenderer2 的实现中添加图标。例如,尝试在 ProgressTreeCellRenderer2 中向面板添加图标:

panel.add((new JLabel((Icon)UIManager.get("Tree.closedIcon"))));

但是,请注意,您当前的实现非常昂贵。不仅每个节点都有一个新的渲染器,而且还可以在 getTreeCellRendererComponent() 内重新分配面板实例。尝试对具有预分配控件的所有节点使用单个渲染器,其中仅根据 getTreeCellRendererComponent 的参数更新属性。请参阅How to Use Trees有关渲染器详细信息和树显示自定义示例。

看看这个 answer (作者:@mKorbel)演示了表格中的单个进度条渲染器。

关于java - 带有自定义打开/关闭图标的自定义 JTree 单元渲染器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20547443/

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