刷新 JTree 而不折叠
Refresh JTree without collapsing
我有一个以 JButton 作为节点的树。
我希望能够在两组值之间切换按钮名称及其调用的方法。
我认为如果树在每次单击按钮后都会刷新,这会很好用。
This method 似乎可行,但它会在刷新时折叠树,我需要树保持打开状态。
我不是 adding/deleting 节点,所以我在网上看到的许多其他方法都不适用。
public void valueChanged(TreeSelectionEvent e)
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
tree.getLastSelectedPathComponent();
/* if nothing is selected */
if (node == null) return;
/* retrieve the node that was selected */
Object obj = node.getUserObject();
if (obj instanceof EmployeeButton)
EmployeeButton eb = (EmployeeButton) obj;
if (eb.getText().contains("Add Employee"));
{
eb.setText("Remove Employee");
addEmp(eb.point);
}
if (eb.getText().contains("Remove Employee"));
{
eb.setText("Add Employee");
delEmployee(eb.point);
}
};
使用 Jakub Zaverka to a somewhat similar question (Compound JTree Node allowing events to pass through to objects underneath) 的优秀答案,你可以这样做:
// Class RefreshTree.java:
import javax.swing.*;
import javax.swing.tree.*;
public class RefreshTree {
public static final String ADD_EMPLOYEE = "Add Employee";
public static final String REMOVE_EMPLOYEE = "Remove Employee";
public static void main(final String[] arguments) {
new RefreshTree().launchGui();
}
private void launchGui() {
final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("root");
rootNode.add(new DefaultMutableTreeNode(ADD_EMPLOYEE));
rootNode.add(new DefaultMutableTreeNode(ADD_EMPLOYEE));
rootNode.add(new DefaultMutableTreeNode(ADD_EMPLOYEE));
final JTree tree = new JTree(rootNode);
tree.setEditable(true);
tree.setCellRenderer(new ButtonCellRenderer());
tree.setCellEditor(new ButtonCellEditor());
final JFrame frame = new JFrame("Refresh JTree with JButton");
frame.getContentPane().add(new JScrollPane(tree));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setBounds(400, 200, 600, 600);
frame.setVisible(true);
}
}
// Class ButtonCellEditor.java:
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class ButtonCellEditor extends AbstractCellEditor implements TreeCellEditor {
private JButton button;
public ButtonCellEditor() {
button = new JButton(RefreshTree.ADD_EMPLOYEE);
button.addActionListener(actionEvent -> {
final boolean add = RefreshTree.ADD_EMPLOYEE.equals(button.getText());
if (add)
System.out.println("Call addEmp(eb.point)");
else
System.out.println("Call delEmployee(eb.point)");
button.setText(add ? RefreshTree.REMOVE_EMPLOYEE : RefreshTree.ADD_EMPLOYEE);
stopCellEditing();
});
}
@Override
public Object getCellEditorValue() {
return button.getText();
}
@Override
public Component getTreeCellEditorComponent(final JTree tree,
final Object value,
final boolean isSelected,
final boolean expanded,
final boolean leaf,
final int row) {
button.setText(value.toString());
return button;
}
}
// Class ButtonCellRenderer.java:
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class ButtonCellRenderer extends JButton implements TreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(final JTree tree,
final Object value,
final boolean selected,
final boolean expanded,
final boolean leaf,
final int row,
final boolean hasFocus) {
setText(value.toString());
return this;
}
}
我有一个以 JButton 作为节点的树。
我希望能够在两组值之间切换按钮名称及其调用的方法。
我认为如果树在每次单击按钮后都会刷新,这会很好用。
This method 似乎可行,但它会在刷新时折叠树,我需要树保持打开状态。
我不是 adding/deleting 节点,所以我在网上看到的许多其他方法都不适用。
public void valueChanged(TreeSelectionEvent e)
{
DefaultMutableTreeNode node = (DefaultMutableTreeNode)
tree.getLastSelectedPathComponent();
/* if nothing is selected */
if (node == null) return;
/* retrieve the node that was selected */
Object obj = node.getUserObject();
if (obj instanceof EmployeeButton)
EmployeeButton eb = (EmployeeButton) obj;
if (eb.getText().contains("Add Employee"));
{
eb.setText("Remove Employee");
addEmp(eb.point);
}
if (eb.getText().contains("Remove Employee"));
{
eb.setText("Add Employee");
delEmployee(eb.point);
}
};
使用 Jakub Zaverka to a somewhat similar question (Compound JTree Node allowing events to pass through to objects underneath) 的优秀答案,你可以这样做:
// Class RefreshTree.java:
import javax.swing.*;
import javax.swing.tree.*;
public class RefreshTree {
public static final String ADD_EMPLOYEE = "Add Employee";
public static final String REMOVE_EMPLOYEE = "Remove Employee";
public static void main(final String[] arguments) {
new RefreshTree().launchGui();
}
private void launchGui() {
final DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("root");
rootNode.add(new DefaultMutableTreeNode(ADD_EMPLOYEE));
rootNode.add(new DefaultMutableTreeNode(ADD_EMPLOYEE));
rootNode.add(new DefaultMutableTreeNode(ADD_EMPLOYEE));
final JTree tree = new JTree(rootNode);
tree.setEditable(true);
tree.setCellRenderer(new ButtonCellRenderer());
tree.setCellEditor(new ButtonCellEditor());
final JFrame frame = new JFrame("Refresh JTree with JButton");
frame.getContentPane().add(new JScrollPane(tree));
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.setBounds(400, 200, 600, 600);
frame.setVisible(true);
}
}
// Class ButtonCellEditor.java:
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class ButtonCellEditor extends AbstractCellEditor implements TreeCellEditor {
private JButton button;
public ButtonCellEditor() {
button = new JButton(RefreshTree.ADD_EMPLOYEE);
button.addActionListener(actionEvent -> {
final boolean add = RefreshTree.ADD_EMPLOYEE.equals(button.getText());
if (add)
System.out.println("Call addEmp(eb.point)");
else
System.out.println("Call delEmployee(eb.point)");
button.setText(add ? RefreshTree.REMOVE_EMPLOYEE : RefreshTree.ADD_EMPLOYEE);
stopCellEditing();
});
}
@Override
public Object getCellEditorValue() {
return button.getText();
}
@Override
public Component getTreeCellEditorComponent(final JTree tree,
final Object value,
final boolean isSelected,
final boolean expanded,
final boolean leaf,
final int row) {
button.setText(value.toString());
return button;
}
}
// Class ButtonCellRenderer.java:
import java.awt.*;
import javax.swing.*;
import javax.swing.tree.*;
public class ButtonCellRenderer extends JButton implements TreeCellRenderer {
@Override
public Component getTreeCellRendererComponent(final JTree tree,
final Object value,
final boolean selected,
final boolean expanded,
final boolean leaf,
final int row,
final boolean hasFocus) {
setText(value.toString());
return this;
}
}