java - JTree 中的 JCheckBox 不会抛出其 ActionListener
问题描述
我有一个JTree
, 和一个CustomTreeCellRenderer
, 我通过 JCheckBoxes 更改节点的表示。一切正常,直到这里。
现在,在我的 中CustomTreeCellRenderer
,当我定义JCheckBox
要返回的 时,我ActionListener
为它们中的每一个设置了 。
在 中ActionListener
,我只打印 的名称JCheckBox
,只是为了查看事件是否被触发。
我的问题如下:当我点击一个复选框来改变状态时,这个ActionListener
事件永远不会被触发,所以JCheckBox
点击的名字永远不会显示。我想我在这里没有做任何奇怪的事情,所以我无法理解为什么ActionListener
没有被解雇。可能是因为复选框在 a 内部,JTree
我必须做更多的事情才能使它起作用?我之前在复选框中使用了侦听器,但没有在树内使用,而且我不必做任何特别的事情......
我还看到,使用ItemListener
andChangeListener
而不是ActionListener
我的复选框,事件触发了很多次,这不是我想要的行为。我在使用这两个侦听器时搜索了这个多个事件触发,我发现了这个:
来自 jtree 中的 jcheckbox 的多个 ITEM_STATE_CHANGED 事件
我只想抛出一次事件,使用ActionListener
,我认为是因为JTree
,但我找不到它没有被触发的原因。
如果可以使用ItemListener
或ChangeListener
只抛出一次事件来做到这一点,那对我也有好处。
这是代码(我尽量简化它):
主类:
import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class MainItemListener {
public static void main(String[] args){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
JTree tree = new JTree();
//Define the root node
DefaultMutableTreeNode root = new DefaultMutableTreeNode("Root Node", true);
//Define the child nodes and add it to the root node
for (int i = 0; i < 3; i++){
DefaultMutableTreeNode childNode = new DefaultMutableTreeNode("Child " + i, false);
root.add(childNode);
}
//Set the tree model
DefaultTreeModel treeModel = new DefaultTreeModel(root);
tree.setModel(treeModel);
//Set my custom tree cell renderer
tree.setCellRenderer(new CustomTreeCellRenderer());
//Set the frame
frame.setSize(800,600);
frame.setVisible(true);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); // Close the application when closing the window
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent aEvent) {
System.exit(0); //Close Application
}
});
panel.add(tree, BorderLayout.CENTER);
frame.add(panel);
}
}
自定义树细胞渲染器:
import javax.swing.*;
import javax.swing.tree.DefaultTreeCellRenderer;
import java.awt.*;
public class CustomTreeCellRenderer extends DefaultTreeCellRenderer {
@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);
//Convert each node to a JCheckBox and return the JCheckBox
JCheckBox checkBox = new JCheckBox();
checkBox.setOpaque(true);
checkBox.setSelected(sel);
checkBox.setText(value.toString());
//Set the ActionListener to each JCheckBox
checkBox.addActionListener(new ActionListenerSample());
return checkBox;
}
}
动作监听器示例:
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class ActionListenerSample implements ActionListener {
//Just print the name of the JCheckBox to see how this event is fired
@Override
public void actionPerformed(ActionEvent e) {
JCheckBox component = (JCheckBox) e.getSource();
System.out.println(component.getText());
}
}
解决方案
推荐阅读
- java - 如何围绕设置器创建通用方法?
- node.js - UniversalWindowsPlatform (Node.js + Xamarin) 中的文本 CL/RF 错误
- eclipse - Eclipse C++:如何跳到第一个断点?
- firebase - 如何检索 Firebase 用户属性?
- css - 如果它前面有一个带有特殊类的 div,则在另一个类中设置一个类的样式
- c# - 从 Azure 发出 BadRequest 的持续推送消息
- mysql - React Ant Design 可编辑表
- python - 如何返回 python 数组的中间?
- asp.net - C# 类中的 SignalR Hub
- c# - HttpRequest 可描述为字符串