ユーザーのファイルシステムをツリーで表示する 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;
}
}