gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:19:21 24 4
gpt4 key购买 nike

我使用的是 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;
}
}

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

在单元格渲染器中,我用特定颜色绘制选定节点,如果取消选择节点,我使用另一种颜色绘制它。当我更改节点的选择时,它们的背景绘制正确,但是当我在树外单击时,所选节点没有取消选择,因此它没有使用单元格渲染器中建立的特定颜色绘制。

有一种方法可以在单击树外时取消选择节点吗?

如果有人知道,有一种方法可以通过 TreeCellRenderer 中的复选框来更改某些叶子吗?将一些 child 作为标签,将另一些 child 作为复选框。因为当我尝试添加复选框时,它说(如我所料)复选框不是 DefaultMutableTreeNode 对象,我无法将它们添加到树模型中。

最佳答案

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

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

  • 鼠标监听器 - on 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) {

}
};
}
}

关于java - 单击树外的任何位置时从 JTree 中取消选择节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55375531/

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