标签: jtree

过滤JTree

问题

对a应用过滤JTree以避免某些节点/叶子出现在渲染版本中JTree.理想情况下,我正在寻找一个允许动态过滤器的解决方案,但如果我能让静态过滤器工作,我会很高兴.

为了使它更容易一些,让我们假设JTree只支持渲染,而不是编辑.应该可以移动,添加,删除节点.

一个例子是a上面的搜索字段JTree,而在键入时,JTree只显示带有匹配的子树.

一些限制:它将用于可以访问JDK和SwingX的项目中.我想避免包含其他第三方库.

我已经想到了一些可能的解决方案,但这些都不是理想的

途径

基于模型的过滤

  • 装饰TreeModel以过滤掉一些值.快速而简单的版本很容易编写.过滤掉节点,并且在过滤器或委托TreeModel的每次更改时,装饰器都可以触发整个树发生变化的事件(treeStructureChanged根节点作为节点).将它与恢复选择状态和扩展状态的侦听器相结合JTree,你会得到一个或多或少有效的版本,但是来自它的事件TreeModel都搞砸了.这或多或少是这个问题中使用的方法
  • 装饰TreeModel但尝试点燃正确的事件.我(还)没有设法提出这个的工作版本.它似乎需要委托的副本,TreeModel以便能够在从委托模型中删除节点时使用正确的子索引触发事件.我认为有更多的时间我可以让它工作,但它只是感觉不对(过滤感觉像视图应该做的事情,而不是模型)
  • 装饰用于创建初始化的任何数据结构TreeModel.但是,这完全是不可重用的,并且可能和编写装饰器一样困难TreeModel

基于视图的过滤

这似乎是要走的路.过滤不应影响模型,只影响视图.

  • 我看了RowFilter上课.虽然javadoc似乎建议你可以结合使用它JTree:

    当与JTree相关联时,条目对应于节点.

    我找不到RowFilter(或RowSorter)和JTree班级之间的任何联系.RowFilterSwing教程的标准实现似乎表明RowFilter只能直接使用JTable(参见参考资料JTable#setRowSorter).没有类似的方法可供选择JTree

  • 我也看了一下JXTreejavadoc.它有一个ComponentAdapter可用的,并且javadoc ComponentAdapter表示RowFilter可以与目标组件进行交互,但我看不出如何建立RowFilter和之间的链接JTree
  • 我还没有看到如何JTable使用RowFilter …

java swing jtree swingx

34
推荐指数
3
解决办法
1万
查看次数

右键单击Java JTree的上下文菜单?

我正在尝试在Java JTree中实现弹出菜单.我已经对DefaultTreeCellRenderer(更改节点外观)和DefaultTreeCellEditor(创建组件以附加事件侦听器)进行了细分,因为显然DefaultTreeCellRenderer.getTreeCellRendererComponent()返回的组件不能这样做吗?).我真的不想"编辑"节点,只需在节点右键单击时弹出菜单,但这是我现在想到的唯一方法......

下面是我到目前为止的代码 - 我只想弄清楚如何捕获MouseEvents.它有点工作,但很糟糕.有什么更好的方法来完成我在这里要做的事情?

private class My_TreeCellRenderer extends DefaultTreeCellRenderer { 
    My_TreeCellRenderer() {
        super ();
    }   

    public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);

        // set label text and tool tips
        setText(((My_Object)value).getTreeLabel());
        setToolTipText(((My_Object)value).getTreeToolTip());

        return this;
    }
}

private class My_TreeCellEditor extends DefaultTreeCellEditor { 
    private MouseAdapter ma;

    My_TreeCellEditor(JTree tree, DefaultTreeCellRenderer renderer) {
        super (tree, renderer);
        ma = new MouseAdapter() {
            public void mousePressed(MouseEvent e) { …
Run Code Online (Sandbox Code Playgroud)

java contextmenu jtree

29
推荐指数
4
解决办法
4万
查看次数

在JTree中添加和删除节点

我有一个非常基本的JTree.因为我匆忙,TreeModel如果不需要,我宁愿不使用.我写了一个SSCCE来揭露这个问题:

有时我会添加一个节点.其他时候我删除它们.当我推送时Add,正确添加了一个节点.当我推Remove,它应该删除节点,但它没有.此外,如果我尝试添加多个节点,树只会保留我添加的第一个节点.

我写了一个更新方法JTree,我首先擦除从根节点挂起的所有节点,然后我看看我必须创建哪些节点和子节点.

除了不使用TreeModel操作树之外,我在这里做错了什么?

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;


public class TreeTest {
    private JFrame myFrame;
    private JTree myTree;
    private JButton addButton, removeButton;

    private int numberOfNodes;
    private DefaultMutableTreeNode rootNode;

    private ArrayList<String> graphicIDS;
    private ArrayList<String> graphicInfo;

    public static void main (String [ ] args){
        new TreeTest();
    }

    public TreeTest() { …
Run Code Online (Sandbox Code Playgroud)

java swing jtree tree-nodes treemodel

20
推荐指数
1
解决办法
6万
查看次数

Java Swing:需要一个高质量的JTree和复选框

我正在寻找一个包含复选框的JTree实现,其中包含:

  • 选择一个节点时,将自动选择树中的所有后续节点

  • 取消选择一个节点时,将自动取消选择树中的所有后续节点

  • 如果已选择父节点,并且已从其后续节点之一中删除选择,则将更改节点颜色,以使其直观,即虽然选择了此父节点,但并未选择其所有后续节点(如选择时一样)要在通用安装程序中安装的组件)

  • 点击节点即可(无需按住'Ctrl'键!):

    • 如果已选择该节点,则将取消选中该节点及其所有后继节点
    • 如果未选择该节点,则会选择该节点及其所有后继节点

我在网上寻找一些简单的东西,却找不到我想要的简单东西.

有谁知道这种树的良好实现?

java checkbox swing jtree jcheckbox

19
推荐指数
1
解决办法
1万
查看次数

实现JTree工具提示的最佳方法是什么?

由于JTree和TreeModel不提供开箱即用的工具提示,您如何看待,为JTree提供特定于项目的工具提示的最佳方法是什么?

编辑:(之后回答我自己的问题.)

@Zarkonnen:感谢getTooltipText的想法.

我发现了覆盖DefaultTreeCellRenderer的另一种(可能还是更好的)方法并且想要分享它:

public class JTreeWithToolTips {
    private static class OwnRenderer extends DefaultTreeCellRenderer {
        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value,
                boolean sel, boolean expanded, boolean leaf, int row,
                boolean hasFocus) {
            setToolTipText("foobar" + row);
            return super.getTreeCellRendererComponent(tree, value, sel,
                    expanded, leaf, row, hasFocus);
        }
    }

    public static void main(String[] args) {
        JTree tree = new JTree(new Object[] { "foo", "bar", "foobar" });
        tree.setCellRenderer(new OwnRenderer());
        ToolTipManager.sharedInstance().registerComponent(tree);

        JFrame frame = new JFrame();
        frame.getContentPane().add(tree);
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}
Run Code Online (Sandbox Code Playgroud)

java swing tooltip jtree

18
推荐指数
1
解决办法
1万
查看次数

在设置新的TreeModel时如何自动扩展JTree?

我有自定义JTree和习惯JModel; 当我给它一个新的模型时,我会让JTree"自动扩展".目前,它只是将所有节点折叠到根目录.

这是一个例子:

private class CustomTree extends JTree {

    @Override
    public boolean isExpanded(TreePath path) {
        return ((Person) path.getLastPathComponent).hasChildren();

}

private class CustomTreeModel extends TreeModel {

    // ... omitting various implementation details

    @Override
    public boolean isLeaf(Object object) {
        return !((Person) object).hasChildren();
    }

}

Model model = new Model();
Person bob = new Person();
Person alice = new Person();
bob.addChild(alice);
model.setRoot(bob);
JTree tree = new CustomTree(new CustomTreeModel(model));
Run Code Online (Sandbox Code Playgroud)

此时,树正确显示:

- BOB
  - ALICE
Run Code Online (Sandbox Code Playgroud)

Alice是Bob的孩子(在数据和可视化树中)

但是,如果我打电话:

tree.setModel(new CustomTreeModel(model));
Run Code Online (Sandbox Code Playgroud)

一切都崩溃了:

+ …
Run Code Online (Sandbox Code Playgroud)

java tree swing jtree

18
推荐指数
3
解决办法
2万
查看次数

Java检测jtree上的CTRL + X组合键

我需要一个例子来说明如何添加一个键盘处理程序来检测何时按下Ctrl+ C,Ctrl+ X,Ctrl+ .CJTree

之前我用菜单快捷键做了这个,但没有成功.

java keyboard-shortcuts jtree

17
推荐指数
2
解决办法
5万
查看次数

这些错误和警告图标作为java资源在哪里?

我有一个自定义树单元格渲染器,我用它来渲染自定义图标JTree,我真的很喜欢警告图标和JOptionPane分别为警告消息和错误消息显示的错误图标.显然,我可以使用下面的代码来获取我自己使用的图标,但这很重要,需要我实例化我永远不会使用的对话框:

public class ValidationCellRenderer extends DefaultTreeCellRenderer {
    private Icon warnIcon;
    private Icon errorIcon;

    public ValidationCellRenderer() {
        JOptionPane optionPane = new JOptionPane(new Object(), 
            JOptionPane.WARNING_MESSAGE);
        warnIcon = optionPane.getIcon();
        optionPane = new JOptionPane(new Object(), 
            JOptionPane.ERROR_MESSAGE);
        errorIcon = optionPane.getIcon();
    }
}
Run Code Online (Sandbox Code Playgroud)

必须有更好的方法将这些图标作为资源,但我找不到从Java API中执行此操作的简单方法.有人有什么建议吗?

java swing jtree

16
推荐指数
2
解决办法
7960
查看次数

在将一些节点添加到底层模型后,如何刷新JTree?

首先,我要说我不使用DefaultTreeModel.我实现了自己的TreeModel,所以我不能使用DefaultXXX.问题是:通过我的模型定义的一些addStuff()方法,我将节点添加到底层数据结构.然后我通过调用addStuff()函数中的treeNodesChanged()来通知监听器(我知道有treeNodesInserted方法,但它是一样的.它只是用不同的方法通知监听器).现在,其中一个监听器是我的主窗体中的静态类,这个监听器可以告诉JTree,它也包含在我的主窗体中,用于刷新自身.如何告诉JTree从模型中"重新加载"其部分或全部节点?

更新:发现这个问题虽然不完全相同,但它给出了我想要的答案.

更新2:我的问题不是如何通知查看器(JTree),而是在模型通知后应该以什么方式重新加载jtree.

首先让我说,我知道刷新树以反映底层更改的唯一方法是调用updateUI(),或重用setModel()方法.基本上,我的问题是:

假设TreeModelListener刚刚通过(通过TreeModelListener API)通知模型中发生了更改.好的,现在呢?

我有这个问题,因为JTree没有实现TreeModelListener.因此,在我的情况下,监听器是JTree的容器,或实现监听器的内部类,与Jtree位于同一容器中.

所以假设我是一个TreeModelListener实现,和我的兄弟JTree一起幸福地生活在一个JForm中.突然我的方法treeNodesInserted(TreeModelEvent evt)被调用.现在我该怎么做?如果我从我内部调用Jtree.updateUI(),那么模型的侦听器List会抛出ConcurrentModification异常.我可以调用updateUI以外的其他东西吗?

我尝试了很多东西,但只有updateUI刷新了JTree.所以我在听众之外做了.从JForm,我只是调用模型的方法来改变不正常的结构,然后我调用updateUI.没有使用TreeModelListener.

UPDATE3:我发现注册了隐式TreeModelListeners.在我的模型的addTreeModelListener(TreeModelListener监听器)实现中,我放了一个debug system.out行:

System.out.println("listener added: " + listener.getClass().getCanonicalName());
Run Code Online (Sandbox Code Playgroud)

当我执行jTree.setModel(model)时,我看到了这个调试输出:

监听器添加:javax.swing.JTree.TreeModelHandler

监听器添加:javax.swing.plaf.basic.BasicTreeUI.Handler

引发ConcurrentModificationException是因为对jtree.updateUI()的调用会重新注册侦听器(只有plaf,而不是两者),因此当我在侦听器通知循环中调用updateUI时会抛出它.现在刷新树的唯一方法是在TreeModelListener之外进行.有关更好解决方案的任何意见或想法吗?我错过了什么吗?

java swing jtree

16
推荐指数
4
解决办法
6万
查看次数

在JTree中拖放节点

我很难创建一个JTree,它允许通过在JTree中拖放节点来重组节点.这似乎应该相对简单.我在线查看了一些示例,但我似乎无法在自己的代码中实现它.

例如,sun提供的允许在不同组件之间拖动到树中,而不是从树本身内拖动.

我还发现这可以让你将文本拖到JTree中,但不能在树中拖动.




import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import javax.swing.tree.*;

public class DndTree {

    public static void main(String args[]) {
        Runnable runner = new Runnable()  {

            public void run() {
                JFrame f = new JFrame("D-n-D JTree");
                f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel top = new JPanel(new BorderLayout());
                JLabel dragLabel = new JLabel("Drag me:");
                JTextField text = new JTextField();
                text.setDragEnabled(true);
                top.add(dragLabel, BorderLayout.WEST);
                top.add(text, BorderLayout.CENTER);
                f.add(top, BorderLayout.NORTH);

                final JTree tree = new JTree();
                final DefaultTreeModel model = (DefaultTreeModel) tree.getModel(); …

java swing drag-and-drop jtree

13
推荐指数
1
解决办法
2万
查看次数