简体   繁体   English

JTree节点的可变工具提示

[英]JTree node's changable tooltip

I have a JTree populated with some (custom) nodes. 我有一个JTree填充了一些(自定义)节点。 I have a class that's subclass of DefaultTreeCellRenderer and using that "MyTreeCellRenderer" i can set tooltips for each node in my tree. 我有一个类是DefaultTreeCellRenderer的子类,使用“MyTreeCellRenderer”我可以为树中的每个节点设置工具提示。 It works fine: JTree is populated, cell renderer is set, all added nodes do have tooltips. 它工作正常:JTree已填充,单元格渲染器已设置,所有添加的节点都有工具提示。 Problem is that i don't know how to change tooltip for certain node in already populated tree... How to do that? 问题是我不知道如何在已经填充的树中更改某个节点的工具提示...怎么做? Is there any way to "recreate" cell renderer for just one node in JTree? 有没有办法在JTree中为一个节点“重新创建”单元格渲染器?

I did it! 我做的! Instead of using extended CellRenderer i used "getTooltipText" method of tree (i extended the tree). 而不是使用扩展的CellRenderer我使用树的“getTooltipText”方法(我扩展了树)。 That way i was able to control text of tooltip according to object that has mouse pointer over it. 这样我就能够根据鼠标指针在其上的对象来控制工具提示的文本。

@Override
public String getToolTipText(MouseEvent evt) {
    if (getRowForLocation(evt.getX(), evt.getY()) == -1)
      return null;
    TreePath curPath = getPathForLocation(evt.getX(), evt.getY());
    TreeNode node = (TreeNode)curPath.getLastPathComponent();
    if(something)
        return "Empty";

    if(something_else)
        return "Not empty";

    return null;
  }

You will also need to tell the tooltip manager about your tree before the tooltips will render: 在工具提示呈现之前,您还需要告诉工具提示管理器您的树:

ToolTipManager.sharedInstance().registerComponent(myTree);

From what I understand of your question, you want to trigger the rendering of a specific node in the Tree. 根据我对您的问题的理解,您希望触发树中特定节点的呈现。 This should be performed through the TreeModel to fire the proper event (ie, treeNodesChanged). 这应该通过TreeModel执行以触发正确的事件(即treeNodesChanged)。 The DefaultTreeModel offers a utility method for that purpose: nodeChanged . DefaultTreeModel为此提供了一个实用工具方法: nodeChanged

However, tooltips in JTree are handled pro-actively by the JTree by reinvoking the TreeCellRenderer, meaning that nothing must be done for the tooltip to be changed. 但是,JTree中的工具提示由JTree通过重新调用TreeCellRenderer主动处理,这意味着不必对工具提示进行任何更改。 Every time the tooltip needs to be displayed, the rendering for the given node is performed. 每次需要显示工具提示时,都会执行给定节点的渲染。 See this example that continuously updates its tooltip (simply by moving the mouse around the nodes of the tree). 请参阅此示例,该示例不断更新其工具提示(只需在树的节点周围移动鼠标)。

import java.awt.Component;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Enumeration;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.ToolTipManager;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;

public class TestTree {

    public class MyTreeCellRenderer extends DefaultTreeCellRenderer {

        private int rendering = 0;

        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row,
                boolean hasFocus) {
            Component cell = super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
            if (cell instanceof JComponent) {
                ((JComponent) cell).setToolTipText("Hello " + rendering++);
                if (value instanceof Node && cell instanceof JLabel) {
                    ((JLabel) cell).setText(((Node) value).name);
                }
            }
            return cell;
        }
    }

    private JFrame f;
    private JTree tree;

    protected void initUI() {
        Node root = new Node("Root");
        fillTree(root, 5, "Some tree label");
        DefaultTreeModel model = new DefaultTreeModel(root);

        tree = new JTree(model);
        ToolTipManager.sharedInstance().registerComponent(tree);
        tree.setCellRenderer(new MyTreeCellRenderer());
        f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setLocationRelativeTo(null);
        f.add(new JScrollPane(tree));
        f.pack();
        f.setVisible(true);

    }

    public void fillTree(Node parent, int level, String label) {
        for (int i = 0; i < 5; i++) {
            Node node = new Node(label + " " + i);
            parent.addNode(node);
            if (level > 0) {
                fillTree(node, level - 1, label);
            }
        }

    }

    public class Node implements TreeNode {

        private Node parent;
        private List<Node> children;
        private String name;

        public Node(String name) {
            this.name = name;
            this.children = new ArrayList<TestTree.Node>();
        }

        public void addNode(Node child) {
            children.add(child);
            child.parent = this;
        }

        @Override
        public TreeNode getChildAt(int childIndex) {
            return children.get(childIndex);
        }

        @Override
        public int getChildCount() {
            return children.size();
        }

        @Override
        public Node getParent() {
            return parent;
        }

        @Override
        public int getIndex(TreeNode node) {
            return children.indexOf(node);
        }

        @Override
        public boolean getAllowsChildren() {
            return true;
        }

        @Override
        public boolean isLeaf() {
            return children.size() == 0;
        }

        @Override
        public Enumeration<Node> children() {
            return Collections.enumeration(children);
        }

    }

    public static void main(String[] args) {

        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestTree().initUI();
            }
        });
    }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM