いくつかの(カスタム)ノードが設定されたJTreeがあります。DefaultTreeCellRendererのサブクラスであるクラスがあり、その「MyTreeCellRenderer」を使用して、ツリーの各ノードにツールチップを設定できます。正常に動作します。JTreeにデータが入力され、セルレンダラーが設定され、追加されたすべてのノードにツールチップがあります。問題は、すでに入力されているツリーの特定のノードのツールチップを変更する方法がわからないことです...それを行う方法は?JTreeの1つのノードに対してのみセルレンダラーを「再作成」する方法はありますか?
2 に答える
やったよ!拡張CellRendererを使用する代わりに、ツリーの「getTooltipText」メソッドを使用しました(ツリーを拡張しました)。そうすることで、マウスポインタが上にあるオブジェクトに応じてツールチップのテキストを制御することができました。
@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;
}
また、ツールチップがレンダリングされる前に、ツリーについてツールチップマネージャーに通知する必要があります。
ToolTipManager.sharedInstance().registerComponent(myTree);
私があなたの質問について理解していることから、あなたはツリー内の特定のノードのレンダリングをトリガーしたいと思います。これはTreeModel
、適切なイベント(つまり、treeNodesChanged)を発生させるためにを介して実行する必要があります。はDefaultTreeModel
、その目的のためのユーティリティメソッドnodeChangedを提供します。
ただし、JTreeのツールチップは、TreeCellRendererを再度呼び出すことにより、JTreeによってプロアクティブに処理されます。つまり、ツールチップを変更するために何もする必要はありません。ツールチップを表示する必要があるたびに、特定のノードのレンダリングが実行されます。ツールチップを継続的に更新するこの例を参照してください(ツリーのノード内でマウスを動かすだけです)。
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();
}
});
}
}