首页 > 解决方案 > JTree 中的 JCheckBox 不会抛出其 ActionListener

问题描述

我有一个JTree, 和一个CustomTreeCellRenderer, 我通过 JCheckBoxes 更改节点的表示。一切正常,直到这里。

现在,在我的 中CustomTreeCellRenderer,当我定义JCheckBox要返回的 时,我ActionListener为它们中的每一个设置了 。

在 中ActionListener,我只打印 的名称JCheckBox,只是为了查看事件是否被触发。

我的问题如下:当我点击一个复选框来改变状态时,这个ActionListener事件永远不会被触发,所以JCheckBox点击的名字永远不会显示。我想我在这里没有做任何奇怪的事情,所以我无法理解为什么ActionListener没有被解雇。可能是因为复选框在 a 内部,JTree我必须做更多的事情才能使它起作用?我之前在复选框中使用了侦听器,但没有在树内使用,而且我不必做任何特别的事情......

我还看到,使用ItemListenerandChangeListener而不是ActionListener我的复选框,事件触发了很多次,这不是我想要的行为。我在使用这两个侦听器时搜索了这个多个事件触发,我发现了这个:

来自 jtree 中的 jcheckbox 的多个 ITEM_STATE_CHANGED 事件

我只想抛出一次事件,使用ActionListener,我认为是因为JTree,但我找不到它没有被触发的原因。

如果可以使用ItemListenerChangeListener只抛出一次事件来做到这一点,那对我也有好处。

这是代码(我尽量简化它):

主类:

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());
}
}

标签: javaswingawt

解决方案


推荐阅读