Swing/FileSystemTreeWithCheckBox のバックアップの現在との差分(No.4)
- バックアップ一覧
- 差分 を表示
- 現在との差分 - Visual を表示
- ソース を表示
- バックアップ を表示
- Swing/FileSystemTreeWithCheckBox へ行く。
- 1 (2011-08-15 (月) 15:43:03)
- 2 (2012-04-13 (金) 20:12:08)
- 3 (2012-04-17 (火) 17:29:13)
- 4 (2012-04-19 (木) 19:50:07)
- 5 (2012-05-16 (水) 15:15:04)
- 6 (2012-07-31 (火) 18:15:44)
- 7 (2012-11-23 (金) 04:41:06)
- 8 (2012-12-19 (水) 01:58:58)
- 9 (2013-09-20 (金) 04:28:45)
- 10 (2013-12-25 (水) 14:11:08)
- 11 (2013-12-25 (水) 16:31:22)
- 12 (2013-12-25 (水) 18:57:06)
- 13 (2013-12-26 (木) 13:36:28)
- 14 (2013-12-26 (木) 21:55:24)
- 15 (2014-02-18 (火) 15:25:48)
- 16 (2014-03-04 (火) 13:55:30)
- 17 (2014-03-05 (水) 18:23:39)
- 18 (2014-06-03 (火) 21:07:01)
- 19 (2014-09-06 (土) 02:23:37)
- 20 (2014-10-04 (土) 03:44:12)
- 21 (2014-12-02 (火) 01:33:06)
- 22 (2015-02-06 (金) 11:58:24)
- 23 (2015-02-09 (月) 17:21:46)
- 24 (2016-09-11 (日) 15:02:35)
- 25 (2017-10-20 (金) 14:46:06)
- 26 (2018-02-24 (土) 19:51:30)
- 27 (2018-03-30 (金) 16:08:02)
- 28 (2018-09-25 (火) 15:38:51)
- 29 (2019-05-22 (水) 19:34:28)
- 30 (2020-09-29 (火) 18:30:23)
- 31 (2022-05-29 (日) 11:45:35)
- 追加された行はこの色です。
- 削除された行はこの色です。
TITLE:JCheckBox付きJTreeでディテクトリ構造を表示 #navi(../) RIGHT:Posted by &author(aterai); at 2011-08-15 *JCheckBox付きJTreeでディテクトリ構造を表示 [#w66e4684] 編集可能な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 --- * 概要 [#summary] 編集可能な`JCheckBox`をノードに追加した`JTree`でディレクトリ構造を表示します。 //-&jnlp; -&jar; -&zip; #download(https://lh6.googleusercontent.com/-5ihZ2R-e4Ug/Tki-blUTxaI/AAAAAAAABA0/5KCjlm9CkSY/s800/FileSystemTreeWithCheckBox.png) //#screenshot #ref(https://lh6.googleusercontent.com/-5ihZ2R-e4Ug/Tki-blUTxaI/AAAAAAAABA0/5KCjlm9CkSY/s800/FileSystemTreeWithCheckBox.png) **サンプルコード [#i1700889] #code{{ * サンプルコード [#sourcecode] #code(link){{ 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; 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); } @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; } @Override public Object getCellEditorValue() { return new CheckBoxNode(file, isSelected()?Status.SELECTED:Status.DESELECTED); return new CheckBoxNode(file, isSelected() ? Status.SELECTED : Status.DESELECTED); } @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; } @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(); } //...... // ... }} **解説 [#r3f14f2c] このサンプルは、[[FileSystemViewを使ってディテクトリ構造をJTreeに表示する>Swing/DirectoryTree]]と、[[JTreeの葉ノードをJCheckBoxにする>Swing/CheckBoxNodeTree]]を組み合わせて作成しています。 * 解説 [#explanation] このサンプルは、[[FileSystemViewを使ってディレクトリ構造をJTreeに表示する>Swing/DirectoryTree]]と、[[JTreeの葉ノードをJCheckBoxにする>Swing/CheckBoxNodeTree]]を組み合わせて作成しています。 ---- TreeCellEditor#isCellEditable(...)をオーバーライドして、JCheckBox付近をクリックした場合のみ編集可能(チェックの有無を切り替えることができる)にし、ラベールやアイコンなどをクリックした場合は、編集状態にせずノードの展開や折り畳みができるように設定しています。 ---- %%[[JTableHeaderにJCheckBoxを追加してセルの値を切り替える>Swing/TableHeaderCheckBox]]のように親ノードをチェックすると子ノードのチェックをすべて切り替える機能には今のところ対応していません。%% - 対応済み - `TreeCellEditor#isCellEditable(...)`をオーバーライドして`JCheckBox`の領域内をクリックした場合のみ編集可能(チェックの有無を切り替えることができる)に設定 - ラベルやアイコンなどをクリックした場合は編集状態にせずノードの展開や折り畳みができるように設定 **参考リンク [#v001ce9d] - [[FileSystemViewを使ってディテクトリ構造をJTreeに表示する>Swing/DirectoryTree]] * 参考リンク [#reference] - [[FileSystemViewを使ってディレクトリ構造をJTreeに表示する>Swing/DirectoryTree]] - [[JTreeの葉ノードをJCheckBoxにする>Swing/CheckBoxNodeTree]] **コメント [#b9b92412] - [[JTreeのすべてのノードにJCheckBoxを追加する>Swing/CheckBoxNodeEditor]] で使用しているTreeModelListenerを追加してJCheckBoxの状態を変更するように修正。 -- [[aterai]] &new{2012-04-13 (金) 20:12:08}; * コメント [#comment] #comment - [[JTreeのすべてのノードにJCheckBoxを追加する>Swing/CheckBoxNodeEditor]] で使用している`TreeModelListener`を追加して`JCheckBox`の状態を変更するように修正。 -- &user(aterai); &new{2012-04-13 (金) 20:12:08}; - チェックされたノード(最上位となる)の一覧をコンソールに表示する`JButton`を追加(スクリーンショットなどは面倒なので更新しない)。 -- &user(aterai); &new{2012-04-19 (木) 19:50:07}; - ノードをチェックしてから、そのディレクトリを開いても子ディレクトリにチェックが反映されない。 -- &user(aterai); &new{2012-07-31 (火) 18:15:44}; - いつも勉強させていただいております。サンプルでは`root`はデスクトップとなっていますが、もし例えば`Z:\`または`Z:\aaa`と`TOP`にしたい場合、どこを修正すれば宜しいでしょうか?ご教示をお願いいたします。 -- &user(Tiger); &new{2013-12-25 (水) 14:11:08}; -- こんばんは。このサンプルでは、`fileSystemView.getRoots()`で`Desktop`フォルダ(`Windows`の場合)を取得しているので、この箇所を、例えば`File fileSystemRoot = new File("Z:/"); /* for(File fileSystemRoot: fileSystemView.getRoots()) */ {`のように変更するのはどうでしょうか。 -- &user(aterai); &new{2013-12-25 (水) 16:34:38}; - ご教示、ありがとうございました。ご指摘のところを見落としました。やり方は理解できました。ついでに、もし`root`はデスクトップにしておいて、`C:\`を表示させないで(または展開させないで)、`X:\`,`Y:\`のみ操作させるには、どこを弄れば宜しいでしょうか?ありがとうございました。来年もよろしくお願いします。 -- &user(Tiger); &new{2013-12-26 (木) 13:36:28}; -- `fileSystemView.getRoots()`で`Desktop`フォルダを取得すると、 マイコンピュータとか、`Desktop`フォルダが`C:\`にある場合はマイドキュメントなどを選択不可にするのが、面倒な気がします。以下のように`new File(System.getProperty("user.home")+"/Desktop")`とデスクトップを決め打ちにしてノードを作ってしまうのが簡単かもしれません。 -- &user(aterai); &new{2013-12-26 (木) 21:55:24}; #code{{ final FileSystemView fileSystemView = FileSystemView.getFileSystemView(); DefaultMutableTreeNode root = new DefaultMutableTreeNode(); final DefaultTreeModel treeModel = new DefaultTreeModel(root); File desktopFile = new File(System.getProperty("user.home")+"/Desktop"); DefaultMutableTreeNode desktop = new DefaultMutableTreeNode(new CheckBoxNode(desktopFile, Status.DESELECTED)); root.add(desktop); for (File file: fileSystemView.getFiles(desktopFile, true)) { if (file.isDirectory()) { desktop.add(new DefaultMutableTreeNode(new CheckBoxNode(file, Status.DESELECTED))); } } for (File fileSystemRoot: Arrays.asList(new File("X:/"), new File("Y:/"))) { DefaultMutableTreeNode node = new DefaultMutableTreeNode(new CheckBoxNode(fileSystemRoot, Status.DESELECTED)); desktop.add(node); for (File file: fileSystemView.getFiles(fileSystemRoot, true)) { System.out.println(file.getAbsolutePath()); if (file.isDirectory()) { node.add(new DefaultMutableTreeNode(new CheckBoxNode(file, Status.DESELECTED))); } } } treeModel.addTreeModelListener(new CheckBoxStatusUpdateListener()); }} - いつも勉強させていただいております。チェックしたファイルまたはフォルダーのチェックマークの外し方を教えていただけませんか? -- &user(Tiger); &new{2014-03-04 (火) 13:55:30}; -- こんばんは。マウスを使わずにチェックを外したいということですよね。このサンプルの場合、`MutableTreeNode#setUserObject(...)`でチェックを外した`new CheckBoxNode(node.file, Status.DESELECTED)`を設定し、そのあと[https://docs.oracle.com/javase/jp/8/docs/api/javax/swing/tree/DefaultTreeModel.html#nodeChanged-javax.swing.tree.TreeNode- DefaultTreeModel#nodeChanged(...)]メソッドを呼べばいいと思います。 -- &user(aterai); &new{2014-03-05 (水) 18:23:39}; #code{{ //例えば、すべてのチェックを外す場合... private static void deselectedAll(DefaultTreeModel model, TreePath path) { Object o = path.getLastPathComponent(); if (!(o instanceof DefaultMutableTreeNode)) { return; } DefaultMutableTreeNode node = (DefaultMutableTreeNode) o; o = node.getUserObject(); if (!(o instanceof CheckBoxNode)) { return; } CheckBoxNode check = (CheckBoxNode) o; if (check.status == Status.SELECTED) { node.setUserObject(new CheckBoxNode(check.file, Status.DESELECTED)); model.nodeChanged(node); //or: model.valueForPathChanged(path, new CheckBoxNode(check.file, Status.DESELECTED)); } else if (!node.isLeaf()) { // Java 9: Enumeration<TreeNode> e = node.children(); Enumeration<?> e = node.children(); while (e.hasMoreElements()) { deselectedAll(model, path.pathByAddingChild(e.nextElement())); } } } }} #comment