私が取り組んでいるプロジェクトでは、JTree
を各行にJToggleButton
、実際には各2行に作成する必要がありました。 MCVEで見るように、この作業を行うには、DefaultTreeCellRenderer
カスタムとAbstractCellEditor
カスタムを書きました。JToggleButtonの選択を保存する
ただし、JToggleBox
が選択されているかどうかの編集に問題があります。最初は、変更する最初の値を選択すると正常に動作します。そして、あなたがJTree
の行にとどまっていて、他の場所をクリックしないでくださいが、JToggleButton
の場合はうまくいきます。他の場所をクリックすると、設定した値が失われます。
他の場所をクリックしたときに、JToggleButton
の設定値はどのように保持できますか?
MCVE
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);
}
}
}
答えをいただきありがとうございます – Dan