Java TreeCeleditor的fireEditingStopped()方法
我有一些swing教程中的示例代码。在代码中,我们向面板添加一个JTree,然后定制渲染和编辑树。我们希望树的叶子是JCheckbox,所以用户可以选中或取消选中每一个 作为一个自定义TreeCellEditor,我创建了一个实现TreeCellEditor并扩展AbstractCellEditor的类,因此在我的类中,我只覆盖这些树方法:Java TreeCeleditor的fireEditingStopped()方法,java,swing,jtree,Java,Swing,Jtree,我有一些swing教程中的示例代码。在代码中,我们向面板添加一个JTree,然后定制渲染和编辑树。我们希望树的叶子是JCheckbox,所以用户可以选中或取消选中每一个 作为一个自定义TreeCellEditor,我创建了一个实现TreeCellEditor并扩展AbstractCellEditor的类,因此在我的类中,我只覆盖这些树方法: public boolean isCellEditable(EventObject e) public Object getCellEditorValue(
public boolean isCellEditable(EventObject e)
public Object getCellEditorValue()
public Component getTreeCellEditorComponent(JTree arg0, Object arg1, boolean arg2, boolean arg3, boolean arg4, int arg5)
在最后一个类中,它检查用户是否尝试编辑叶,它调用复选框的ItemListener中的fireEditingStopped()方法(叶被呈现为复选框)。是威德!我们仍然没有编辑任何内容,fire编辑停止了!那么这个方法到底是什么呢
脚注:我们将每个叶的UserObject设置为ServerInfo类的一个实例,其中有3个字段:name、id和checked
import java.awt.BorderLayout;
import java.awt.Component;
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.ImageIcon;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTree;
import javax.swing.SwingUtilities;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeCellRenderer;
import javax.swing.tree.TreeCellEditor;
import javax.swing.tree.TreeCellRenderer;
import javax.swing.tree.TreePath;
public class Main extends JFrame{
private MPanel mPanel;
public Main() {
mPanel = new MPanel();
this.setSize(400,400);
this.setLayout(new BorderLayout());
this.add(mPanel,BorderLayout.CENTER);
this.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new Main();
}
});
}
}
class MPanel extends JPanel{
private JTree serverTree;
public MPanel() {
serverTree = new JTree(createTree());
serverTree.setCellRenderer(new ServerTreeCellRenderer());
serverTree.setCellEditor(new ServerTreeCellEditor());
this.setLayout(new BorderLayout());
this.add(serverTree, BorderLayout.CENTER);
}
private DefaultMutableTreeNode createTree() {
DefaultMutableTreeNode top = new DefaultMutableTreeNode("Servers");
DefaultMutableTreeNode branch1 = new DefaultMutableTreeNode("USA");
DefaultMutableTreeNode server1 = new DefaultMutableTreeNode(new ServerInfo("New York",1,true));
branch1.add(server1);
DefaultMutableTreeNode branch2 = new DefaultMutableTreeNode("UK");
DefaultMutableTreeNode server4 = new DefaultMutableTreeNode(new ServerInfo("London", 4, false));
branch2.add(server4);
top.add(branch1);
top.add(branch2);
return top;
}
}
////////////////////////////////////////////
class ServerInfo{
private String name;
private int id;
private boolean selected;
public ServerInfo(String name, int id, boolean selected) {
this.name = name;
this.id = id;
this.selected=selected;
}
public String getName() {
return name;
}
public boolean isChecked() {
return selected;
}
public void setChecked(boolean selected) {
this.selected = selected;
}
public String toString() {
return id + " : " + name + "-->" + selected;
}
}
////////////////////////////////
class ServerTreeCellRenderer implements TreeCellRenderer {
private JCheckBox leafRenderer;
private DefaultTreeCellRenderer nonLeafNode;
public ServerTreeCellRenderer() {
}
@Override
public Component getTreeCellRendererComponent(JTree tree, Object node, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
DefaultMutableTreeNode theNode = (DefaultMutableTreeNode)node;
if(leaf) {
ServerInfo info = (ServerInfo)theNode.getUserObject();
leafRenderer = new JCheckBox(info.getName());
leafRenderer.setSelected(info.isChecked());
return leafRenderer;
}else {
nonLeafNode = new DefaultTreeCellRenderer();
//nonLeafNode.setClosedIcon(new ImageIcon(getClass().getResource("/images/earthplus.gif")));
//nonLeafNode.setOpenIcon(new ImageIcon(getClass().getResource("/images/earth.gif")));
return nonLeafNode.getTreeCellRendererComponent(tree, node, selected, expanded, leaf, row, hasFocus);
}
}
}
/////////////////////////////////////////
class ServerTreeCellEditor extends AbstractCellEditor implements TreeCellEditor {
private ServerTreeCellRenderer renderer;
private ServerInfo info;
private JCheckBox checkBox;
@Override
public Object getCellEditorValue() {
info.setChecked(checkBox.isSelected());
return info;
}
@Override
public boolean isCellEditable(EventObject e) {
if(!(e instanceof MouseEvent)) return false;
MouseEvent me = (MouseEvent)e;
JTree tree = (JTree)e.getSource();
TreePath path = tree.getPathForLocation(me.getX(),me.getY());
if(path==null) return false;
Object lastComp = path.getLastPathComponent();
if(lastComp==null) return false;
DefaultMutableTreeNode node = (DefaultMutableTreeNode )lastComp;
return node.isLeaf();
}
@Override
public Component getTreeCellEditorComponent(JTree tree, Object value, boolean isSelected, boolean expanded, boolean leaf,int row) {
Component comp = renderer.getTreeCellRendererComponent(tree,value,isSelected,expanded,leaf,row, true);
if(leaf){
DefaultMutableTreeNode treeNode=(DefaultMutableTreeNode)value;
info = (ServerInfo)treeNode.getUserObject();
checkBox = (JCheckBox)comp;
ItemListener itemListener = new ItemListener(){
public void itemStateChanged(ItemEvent e){
fireEditingStopped();
checkBox.removeItemListener(this);
}
};
checkBox.addItemListener(itemListener);
}
return comp;
}
}
你能发布一个可复制的最小示例吗?@vincenzopalazzo我能,但在我的代码中我不能编辑复选框,我想这可能是因为这个fireEditingStopped方法!无论如何,我在这里放了一个可运行的最小代码,谢谢
ItemListener
,当JCheckBox
的状态更改(选中/取消选中)时,将调用ItemListener
,我个人会使用ActionListener
,副作用更少,但这就是我。因此,在调用itemStateChanged
时,您已经编辑了值的状态,因此调用stop editing是一项有效的任务,这将迫使JTree
调用getCellEditorValue
并修改模型状态。好吧,您会因为这一点而讨厌您自己(我知道当我意识到这一点时,我不禁呻吟)。添加serverTree.setEditable(true)代码>给你MPanel
构造函数。这将使表格可编辑-但您将在编辑器中得到一个NullPointerException
,但我很确定您应该能够修复它;)@非常感谢