单击树外的任何位置时,从JTree中取消选择节点

dan*_*ano 7 java swing jtree

我正在使用JTree,正在使用DefaultTreeModel。这个树模型内部有一些节点,当我单击一个节点时,我会获得该节点的信息,然后更改背景颜色以显示该节点已被选中。

当我单击树上的任何位置时,可以调用树以清除选择吗?通过清除选择,我将能够再次更改背景色,但是clearSelection()当我从树中单击时,我不知道如何或在何处使用树的方法。

这是我正在使用的代码:

这个例子:

import javax.swing.*;
import javax.swing.tree.*;
import java.awt.*;

public class JTreeSelectDeselect {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel panel = new JPanel(new BorderLayout());
        JTree tree = new JTree();
        tree.setCellRenderer(new DeselectTreeCellRenderer());

        panel.add(tree, BorderLayout.LINE_START);
        panel.add(new JScrollPane(new JTextArea(10, 30)));
        frame.add(panel);

        frame.pack();
        frame.setVisible(true);
    }
}

class DeselectTreeCellRenderer extends DefaultTreeCellRenderer {

    @Override
    public Color getBackgroundSelectionColor() {
        return new Color(86, 92, 160);
    }

    @Override
    public Color getBackground() {
        return (null);
    }

    @Override
    public Color getBackgroundNonSelectionColor() {
        return new Color(23, 27, 36);
    }

    @Override
    public Component getTreeCellRendererComponent(JTree tree, Object value,
            boolean sel, boolean exp, boolean leaf, int row, boolean hasFocus) {
        super.getTreeCellRendererComponent(tree, value, sel, exp, leaf, row, hasFocus);

        setForeground(new Color(225, 225, 221, 255));
        setOpaque(false);

        return this;
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里展示了如何创建节点并使用树模型将其添加到树中以及如何设置自定义TreeCellRenderer

In the cell renderer I paint the selected node with a specific color, and if the node is deselected, I paint it using another color. When I change the selection of the nodes, their background is painting correctly, but when I click outside the tree, the selected node is not deselected, so it is not painted with the specific color established in the cell renderer.

There is a way to deselect the node when I click outside the tree?

And just if someone knows, there is a way to change some of the leafs by check boxes from the TreeCellRenderer? To have some children as labels and some others as check boxes. Because when I try to add check boxes it says (as I expected) that check boxes are not DefaultMutableTreeNode objects and I can't add them to the tree model.

Ioa*_*n M 6

首先,如果您只想更改一些颜色,则不需要对 DefaultTreeCellRenderer 进行子类化。您可以创建一个新的,根据需要设置颜色并将其设置到树上。在下面的代码示例中,我在 getDefaultTreeCellRenderer() 中完成了此操作。

您的面板包含两个元素:树和文本区域。为了实现您所需要的,我向树添加了一个鼠标侦听器和一个焦点侦听器:

  • 鼠标侦听器 - 当您在树内部或外部单击时,mouseClicked() 上的鼠标侦听器都会被触发(但不在 TextArea 中,因为我们有焦点侦听器)。 要检查您是否单击了单元格的边界,我们使用tree.getRowForLocation(e.getX(),e.getY()),如果它返回-1,这意味着我们单击了任何单元格外部,以便我们可以清除选择
  • 焦点侦听器 - 当您从 JTree 失去焦点并单击文本区域时,这将被触发,我们只需清除选择

我们需要两个侦听器,因为只有当您单击树及其周围而不是文本区域时才会触发第一个侦听器,而当您将焦点移出树区域并聚焦于文本区域时,第二个侦听器才会触发。

import javax.swing.*;
import javax.swing.tree.DefaultTreeCellRenderer;
import java.awt.*;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class JTreeSelectDeselect {

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);

        JPanel panel = new JPanel(new BorderLayout());
        JTree tree = new JTree();

        tree.setCellRenderer(getDefaultTreeCellRenderer());
        tree.addMouseListener(getMouseListener(tree));
        tree.addFocusListener(getFocusListener(tree));

        panel.add(tree, BorderLayout.LINE_START);
        panel.add(new JScrollPane(new JTextArea(10, 30)));
        frame.add(panel);

        frame.pack();
        frame.setVisible(true);
    }

    private static DefaultTreeCellRenderer getDefaultTreeCellRenderer() {
        DefaultTreeCellRenderer defaultTreeCellRenderer = new DefaultTreeCellRenderer();
        defaultTreeCellRenderer.setBackgroundSelectionColor(new Color(86, 92, 160));
        defaultTreeCellRenderer.setBackgroundNonSelectionColor(new Color(135, 151, 53));
        defaultTreeCellRenderer.setBackground(new Color(225, 225, 221, 255));
        defaultTreeCellRenderer.setForeground(new Color(225, 225, 221, 255));
        return defaultTreeCellRenderer;
    }

    private static FocusListener getFocusListener(final JTree tree) {
        return new FocusListener() {
            @Override
            public void focusGained(FocusEvent e) {

            }

            @Override
            public void focusLost(FocusEvent e) {
                System.out.println("focus lost");
                tree.clearSelection();
            }
        };
    }

    private static MouseListener getMouseListener(final JTree tree) {
        return new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                System.out.println("mouse clicked");
                if(tree.getRowForLocation(e.getX(),e.getY()) == -1) {
                    System.out.println("clicked outside a specific cell");
                    tree.clearSelection();
                }
            }

            @Override
            public void mousePressed(MouseEvent e) {

            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            @Override
            public void mouseEntered(MouseEvent e) {

            }

            @Override
            public void mouseExited(MouseEvent e) {

            }
        };
    }
}
Run Code Online (Sandbox Code Playgroud)