我有一个 Java 应用程序,它在树中显示用户文件系统。我用复选框、图标和文本显示文件夹。为此,我必须为树单元创建一个自定义组件。该组件是 JLabel 的子类,并包含 JCheckBox 和 JLabel。我编写了自己的渲染器和编辑器来显示和编辑组件。当您第一次单击该复选框时,它会进入编辑模式,但关闭编辑的代码不会发生。复选框上的所有后续点击都可以正常工作。我做了很多搜索,无法解决这个问题。
这是我的渲染器和编辑器的代码。树已设置为允许编辑,并且设置了渲染器和编辑器。
class MyRenderer implements TreeCellRenderer
{
private CheckBoxPanel m_panel;
public MyRenderer()
{
m_panel = new CheckBoxPanel();
}
@Override
public Component getTreeCellRendererComponent(JTree tree,
Object value,
boolean selected,
boolean expanded,
boolean leaf,
int row,
boolean hasFocus) {
DefaultMutableTreeNode node = (DefaultMutableTreeNode)value;
MyState state = (MyState)node.getUserObject();
m_panel.setState(state);
return m_panel;
}
}
class MyEditor extends AbstractCellEditor implements TreeCellEditor
{
private CheckBoxPanel m_panel;
private JCheckBox m_checkbox;
private MyState m_state;
public MyEditor()
{
m_panel = new CheckBoxPanel();
// m_panel.setColor(Color.red);
}
@Override
public Component getTreeCellEditorComponent(JTree tree,
Object value,
boolean isSelected,
boolean expanded,
boolean leaf,
int row) {
DefaultMutableTreeNode treeNode = (DefaultMutableTreeNode)value;
m_state = (MyState)treeNode.getUserObject();
m_panel.setState(m_state);
m_checkbox = m_panel.getCheckBox();
m_checkbox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent e)
{
fireEditingStopped();
m_checkbox.removeItemListener(this);
}
});
return m_panel;
}
@Override
public Object getCellEditorValue()
{
m_state.setSelected(m_checkbox.isSelected());
return m_state;
}
@Override
public boolean isCellEditable(EventObject anEvent)
{
if (anEvent instanceof MouseEvent)
{
return true;
}
return false;
}
}
class CheckBoxPanel extends JPanel
{
private JCheckBox m_checkBox;
private JLabel m_label;
public CheckBoxPanel()
{
m_checkBox = new JCheckBox();
m_checkBox.setBackground(UIManager.getColor("Tree.background"));
m_checkBox.setBorder(null);
m_checkBox.setFocusable(true);
m_label = new JLabel();
m_label.setFont(UIManager.getFont("Tree.font"));
m_label.setFocusable(false);
setOpaque(false);
setLayout(new BorderLayout());
add(m_checkBox, BorderLayout.WEST);
add(m_label, BorderLayout.CENTER);
}
public JCheckBox getCheckBox()
{
return m_checkBox;
}
public void setState(MyState _state)
{
m_label.setText(_state.getText());
m_checkBox.setSelected(_state.isSelected());
}
public void setColor(Color _color)
{
m_label.setForeground(_color);
}
}
class MyState
{
private String m_text;
private boolean m_selected;
public MyState(String _text, boolean _selected)
{
m_text = _text;
m_selected = _selected;
}
public String getText()
{
return m_text;
}
public void setText(String _text)
{
m_text = _text;
}
public boolean isSelected()
{
return m_selected;
}
public void setSelected(boolean _selected)
{
m_selected = _selected;
}
}