首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在JToggleButton中保存选择

在JToggleButton中保存选择
EN

Stack Overflow用户
提问于 2016-12-04 21:23:26
回答 1查看 71关注 0票数 1

对于一个我一直在做的项目,我不得不在每一行上创建一个带有JToggleButtonJToggleButton,实际上每行都有两个。因此,为了完成这项工作,正如您将在MCVE中看到的那样,我编写了一个自定义DefaultTreeCellRenderer和一个自定义AbstractCellEditor

但是,编辑是否选择JToggleBox存在问题。最初,当您选择要更改的第一个值时,它工作得很好。如果您停留在JTree的该行上,并且不单击其他任何位置,而是在JToggleButton上单击,则可以正常工作。如果单击其他地方,所设置的值将丢失。

当单击其他地方时,如何保留JToggleButton的设置值?

MCVE

代码语言:javascript
复制
import java.awt.Color;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseEvent;
import java.util.EventObject;

import javax.swing.AbstractCellEditor;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.JTree;
import javax.swing.event.ChangeEvent;
import javax.swing.plaf.metal.MetalToggleButtonUI;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreePath;

@SuppressWarnings("serial")
public class DirectoryExplorer extends JFrame {
    private DirectoryExplorer() {
        super("Directory Explorer");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new GridLayout(1, 1));
        createPanel();
        setSize(800,600);
        setVisible(true);
    }

    private void createPanel() {
        DefaultMutableTreeNode colors = new DefaultMutableTreeNode("Colours");
        colors.add(new DefaultMutableTreeNode("Red"));
        colors.add(new DefaultMutableTreeNode("Green"));
        colors.add(new DefaultMutableTreeNode("Blue"));

        DefaultMutableTreeNode falvors = new DefaultMutableTreeNode("Flavours");
        falvors.add(new DefaultMutableTreeNode("Toffee"));
        falvors.add(new DefaultMutableTreeNode("Fudge"));
        falvors.add(new DefaultMutableTreeNode("Chocolate"));

        DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
        root.add(colors);
        root.add(falvors);
        root.add(new DefaultMutableTreeNode("Leafy"));

        JPanel panel = new JPanel(new GridLayout(1, 1));
        JTree tree = new JTree(root);

        FileNameRenderer fileRender = new FileNameRenderer();
        tree.setCellRenderer(fileRender);

        tree.setCellEditor(new CheckBoxNodeEditor(tree));
        tree.setEditable(true);

        tree.setShowsRootHandles(true);

        panel.add(new JScrollPane(tree));
        getContentPane().add(panel);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(() -> new DirectoryExplorer());
    }

    private class FileNameRenderer extends DefaultTreeCellRenderer {
        @Override
        public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
            JComponent c = (JComponent) super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);

            return new Holder((JLabel) c);
        }
    }

    private class CheckBoxNodeEditor extends AbstractCellEditor implements TreeCellEditor {
        FileNameRenderer renderer = new FileNameRenderer();
        ChangeEvent changeEvent = null;
        JTree t;
        TreePath path;

        public CheckBoxNodeEditor(JTree tree) {
            t = tree;
        }

        public Object getCellEditorValue() {
            Holder checkBoxNode = new Holder(new JLabel((((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject().toString())));
            return checkBoxNode;
        }

        public boolean isCellEditable(EventObject event) {
            if(event instanceof MouseEvent) {
                MouseEvent mouseEvent = (MouseEvent) event;
                path = t.getPathForLocation(mouseEvent.getX(), mouseEvent.getY());
                if (path != null) {
                    Object node = path.getLastPathComponent();
                    if ((node != null) && (node instanceof DefaultMutableTreeNode)) {
                        DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode) node;
                        Object userObject = treeNode.getUserObject();
                        return (userObject instanceof String);
                    }
                }
            }
            return false;
        }

        public Component getTreeCellEditorComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row) {
            Component editor = renderer.getTreeCellRendererComponent(tree, value, true, expanded, leaf, row, true);
            ItemListener itemListener = new ItemListener() {
                public void itemStateChanged(ItemEvent itemEvent) {
                    if (stopCellEditing())
                        fireEditingStopped();
                }
            };

            if (editor instanceof JToggleButton) {
                ((JToggleButton) editor).addItemListener(itemListener);
            }

            return editor;
        }
    }

    private class Holder extends JPanel {
        public Holder(Component c) {
            setLayout(new GridBagLayout());
            setBackground(Color.BLACK);
            setOpaque(false);
            addComponents(c);
        }

        private void addComponents(Component c) {
            GridBagConstraints gBC = new GridBagConstraints();

            gBC.insets = new Insets(0, 0, 0, 5);
            add(c, gBC);

            gBC.insets = new Insets(0, 0, 0, 0);
            add(new DefaultChkBx(), gBC);
            add(new FavouriteChkBx(), gBC);
        }
    }

    private class DefaultChkBx extends JToggleButton {
        public DefaultChkBx() {
            setUI(new MetalToggleButtonUI() {
                @Override
                protected Color getSelectColor() {
                    return new Color(242, 0, 255);
                }
            });
            setBorder(null);
            setForeground(Color.GRAY);
            setText("Default");
            setFocusPainted(false);
        }
    }

    private class FavouriteChkBx extends JToggleButton {
        public FavouriteChkBx() {
            setUI(new MetalToggleButtonUI() {
                @Override
                protected Color getSelectColor() {
                    return Color.RED;
                }
            });
            setBorder(null);
            setForeground(Color.GRAY);
            setText("Favourite");
            setFocusPainted(false);
        }
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-12-04 22:15:37

在我看来,您的问题在于您的“模型”:您正在为节点使用普通的DefaultMutableTreeNode对象,这个类无法保存最重要的数据--按钮的状态。

相反,考虑一下

  1. 使用一个从DefaultMutableTreeNode扩展的类(一个有两个布尔值),呈现器将使用这些值来告诉按钮要显示什么状态。
  2. 或者使用DefaultMutableTreeNode作为“包装器”,向DefaultMutableTreeNode中传递一个包含文本的对象以及两个布尔字段,这些字段是JToggleButtons用来显示其状态的字段。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40963828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档