TITLE:JCheckBox付きJTreeでディテクトリ構造を表示
Posted by at 2011-08-15

JCheckBox付きJTreeでディテクトリ構造を表示

編集可能なJCheckBoxをノードに追加したJTreeでディテクトリ構造を表示します。
  • category: swing folder: FileSystemTreeWithCheckBox title: JCheckBox付きJTreeでディレクトリ構造を表示 tags: [JTree, JCheckBox, TreeCellRenderer, TreeCellEditor, File, TreeModelListener, SwingWorker] author: aterai pubdate: 2011-08-15T15:43:03+09:00 description: 編集可能なJCheckBoxをノードに追加したJTreeでディレクトリ構造を表示します。 image: https://lh6.googleusercontent.com/-5ihZ2R-e4Ug/Tki-blUTxaI/AAAAAAAABA0/5KCjlm9CkSY/s800/FileSystemTreeWithCheckBox.png hreflang:
       href: https://java-swing-tips.blogspot.com/2011/08/filesystemtree-with-jcheckbox.html
       lang: en

概要

編集可能なJCheckBoxをノードに追加したJTreeでディレクトリ構造を表示します。
FileSystemTreeWithCheckBox.png

サンプルコード

#spanend
#spanadd
* サンプルコード [#sourcecode]
#spanend
#spanadd
#code(link){{
#spanend
class CheckBoxNodeEditor extends TriStateCheckBox implements TreeCellEditor {
  private final FileSystemView fileSystemView;
  private final JPanel panel = new JPanel(new BorderLayout());
  private DefaultTreeCellRenderer renderer = new DefaultTreeCellRenderer();
  private File file;
#spanadd

#spanend
  public CheckBoxNodeEditor(FileSystemView fileSystemView) {
    super();
    this.fileSystemView = fileSystemView;
    this.addActionListener(new ActionListener() {
      @Override public void actionPerformed(ActionEvent e) {
        stopCellEditing();
      }
    });
    panel.setFocusable(false);
    panel.setRequestFocusEnabled(false);
    panel.setOpaque(false);
    panel.add(this, BorderLayout.WEST);
    this.setOpaque(false);
  }
#spanadd

#spanend
  @Override public Component getTreeCellEditorComponent(
      JTree tree, Object value, boolean isSelected, boolean expanded,
      boolean leaf, int row) {
    JLabel l = (JLabel)renderer.getTreeCellRendererComponent(
        tree, value, true, expanded, leaf, row, true);
    JLabel l = (JLabel) renderer.getTreeCellRendererComponent(
      tree, value, true, expanded, leaf, row, true);
    l.setFont(tree.getFont());
    setOpaque(false);
    if(value != null && value instanceof DefaultMutableTreeNode) {
    if (value instanceof DefaultMutableTreeNode) {
      this.setEnabled(tree.isEnabled());
      this.setFont(tree.getFont());
      Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
      if(userObject!=null && userObject instanceof CheckBoxNode) {
        CheckBoxNode node = (CheckBoxNode)userObject;
        if(node.status==Status.INDETERMINATE) {
      Object userObject = ((DefaultMutableTreeNode) value).getUserObject();
      if (userObject instanceof CheckBoxNode) {
        CheckBoxNode node = (CheckBoxNode) userObject;
        if (node.status == Status.INDETERMINATE) {
          setIcon(new IndeterminateIcon());
        }else{
        } else {
          setIcon(null);
        }
        file = node.file;
        l.setIcon(fileSystemView.getSystemIcon(file));
        l.setText(fileSystemView.getSystemDisplayName(file));
        setSelected(node.status==Status.SELECTED);
        setSelected(node.status == Status.SELECTED);
      }
      //panel.add(this, BorderLayout.WEST);
      // panel.add(this, BorderLayout.WEST);
      panel.add(l);
      return panel;
    }
    return l;
  }
#spanadd

#spanend
  @Override public Object getCellEditorValue() {
    return new CheckBoxNode(file, isSelected()?Status.SELECTED:Status.DESELECTED);
    return new CheckBoxNode(file, isSelected() ? Status.SELECTED : Status.DESELECTED);
  }
#spanadd

#spanend
  @Override public boolean isCellEditable(EventObject e) {
    if(e != null && e instanceof MouseEvent && e.getSource() instanceof JTree) {
      MouseEvent me = (MouseEvent)e;
      JTree tree = (JTree)e.getSource();
    if (e instanceof MouseEvent && e.getSource() instanceof JTree) {
      MouseEvent me = (MouseEvent) e;
      JTree tree = (JTree) e.getSource();
      TreePath path = tree.getPathForLocation(me.getX(), me.getY());
      Rectangle r = tree.getPathBounds(path);
      if(r==null) return false;
      if (r == null) {
        return false;
      }
      Dimension d = getPreferredSize();
      r.setSize(new Dimension(d.width, r.height));
      if(r.contains(me.getX(), me.getY())) {
        if(file==null && System.getProperty("java.version").startsWith("1.7.0")) {
          System.out.println("XXX: Java 7, only on first run\n"+getBounds());
          setBounds(new Rectangle(0,0,d.width,r.height));
        }
      if (r.contains(me.getX(), me.getY())) {
        // if (file == null && System.getProperty("java.version").startsWith("1.7.0")) {
        //   System.out.println("XXX: Java 7, only on first run\n" + getBounds());
        //   setBounds(new Rectangle(0, 0, d.width, r.height));
        // }
        return true;
      }
    }
    return false;
  }
#spanadd

#spanend
  @Override public void updateUI() {
    super.updateUI();
    if(panel!=null) panel.updateUI();
    //1.6.0_24 bug??? @see 1.7.0 DefaultTreeCellRenderer#updateUI()
    if (panel != null) {
      panel.updateUI();
    }
    // 1.6.0_24 bug??? @see 1.7.0 DefaultTreeCellRenderer#updateUI()
    renderer = new DefaultTreeCellRenderer();
  }
#spandel
//......
#spanend
#spanadd
// ...
#spanend

解説

このサンプルは、FileSystemViewを使ってディテクトリ構造をJTreeに表示すると、JTreeの葉ノードをJCheckBoxにするを組み合わせて作成しています。

解説

このサンプルは、FileSystemViewを使ってディレクトリ構造をJTreeに表示すると、JTreeの葉ノードをJCheckBoxにするを組み合わせて作成しています。
TreeCellEditor#isCellEditable(...)をオーバーライドして、JCheckBox付近をクリックした場合のみ編集可能(チェックの有無を切り替えることができる)にし、ラベールやアイコンなどをクリックした場合は、編集状態にせずノードの展開や折り畳みができるように設定しています。
  • TreeCellEditor#isCellEditable(...)をオーバーライドしてJCheckBoxの領域内をクリックした場合のみ編集可能(チェックの有無を切り替えることができる)に設定
  • ラベルやアイコンなどをクリックした場合は編集状態にせずノードの展開や折り畳みができるように設定

参考リンク

参考リンク

コメント

コメント