2012-10-13 5 views
5

JDreeノードに使用するJTreeノードの可視性に問題があります。 モデルに新しいノードを追加したいとき、Jtreeはリフレッシュされません。JDialog - 動的に追加されたノードをJTreeで更新する

setRootVisible(true)を設定した場合と同じようにノードが更新されていますか。

ここにコードがあります。事前のおかげで

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JDialog; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 
import javax.swing.JTree; 
import javax.swing.tree.DefaultMutableTreeNode; 
import javax.swing.tree.DefaultTreeModel; 

public class TestClass { 

JTree tree; 
DefaultTreeModel dm; 
JDialog dialog; 

public TestClass(){ 
    JFrame frame = new JFrame("title"); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 

    JPanel showPane = new JPanel(); 
    showPane.setLayout(new BorderLayout()); 

    dm = new DefaultTreeModel(new DefaultMutableTreeNode("root")); 
    tree = new JTree(dm); 
    tree.setRootVisible(false); 

    JButton button = new JButton("add node"); 
    button.addActionListener(new ActionListener(){ 

     public void actionPerformed(ActionEvent arg0) { 
      DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot();   
      dm.insertNodeInto(new DefaultMutableTreeNode("Node " + (root.getChildCount() + 1)), root, root.getChildCount()); 

      int c = root.getChildCount(); 
      System.out.println("child count: " + c); 

      for(int i=0; i<c; i++){ 
       DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i); 
       System.out.println("has node:" + node.getUserObject().toString()); 
      } 
     } 

    }); 

    showPane.add(tree, BorderLayout.CENTER); 
    showPane.add(button, BorderLayout.PAGE_END); 

    JComponent[] inputComponents = new JComponent[] {showPane}; 

    Object[] opButtons = {"OK"}; 

    JOptionPane optPane = new JOptionPane(inputComponents  
      , JOptionPane.PLAIN_MESSAGE    
      , JOptionPane.CLOSED_OPTION    
      , null          
      , opButtons        
      , opButtons[0]);        

    optPane.setPreferredSize(new Dimension(400 ,250)); 

    dialog = optPane.createDialog(null, "Create new Application Node"); 
    dialog.setLocationRelativeTo(frame); 
    dialog.setVisible(true); 

    if(optPane.getValue() != null){ 
     System.exit(0); 
    } 

} 

public static void main(String arg[]){ 
    TestClass myClass = new TestClass(); 
} 

}

+1

追加されたノードを非表示にする2つの要素があります。 1)ルートは表示されません。 2)モデルが更新された後、ノードは拡張されません。 –

答えて

7

ルートに新しい子ノードを追加するたびに、新しいノードの親からのパスを拡張することを確認します:

DefaultMutableTreeNode newChild = new DefaultMutableTreeNode("Node " + (root.getChildCount() + 1)); 
dm.insertNodeInto(newChild, root, root.getChildCount()); 
tree.expandPath(new TreePath(dm.getPathToRoot(newChild.getParent()))); 
+0

それはまだ私を混乱させるけれども、それは魅力のように働く。私はJFrameのためにこれを行う必要はありません。ありがとう。 – bioMind

+1

@ user1503578通常、JTreeのルートノードが展開されますが、ツリーが作成されるとルートノードには子がないため、展開できません。ルートノードが表示されていない場合でも、その展開状態は引き続きその子ノードの可視性を制御します。後で新しいノードを追加すると、ルートは折りたたまれて表示されません。 –

+0

@GeoffReedyは基本的には真ですが、私には嫌な思いをします。それはモデルの実装の詳細です:-) – kleopatra

3

もチェックしてください別の解決策:

DefaultTreeModel model = (DefaultTreeModel) (tree.getModel()); 
    model.reload(); 

APIは言う:

この モデルが依存するTreeNodeを変更した場合は、reloadメソッドを呼び出す。モデルは、モデルが変更されたことをすべてのリスナーに通知します( )。迅速な検証のために

次のことを試してください。

public void actionPerformed(ActionEvent arg0) { 
    DefaultMutableTreeNode root = (DefaultMutableTreeNode) tree.getModel().getRoot(); 
    dm.insertNodeInto(new DefaultMutableTreeNode("Node " + (root.getChildCount() + 1)), root, root.getChildCount()); 

    int c = root.getChildCount(); 
    System.out.println("child count: " + c); 

    DefaultTreeModel model = (DefaultTreeModel) (tree.getModel()); // !!! 
    model.reload(); // !!! 

    for (int i = 0; i < c; i++) { 
     DefaultMutableTreeNode node = (DefaultMutableTreeNode) root.getChildAt(i); 
     System.out.println("has node:" + node.getUserObject().toString()); 
    } 
} 

詳細については、以下の回答を参照してください:@JBNizetによって答えが正しいか

+0

単純な変更でリロードを使用せず、モデルが適切なものであることを確認してください(defaultTreeModelはinsertNodeIntoになります) – kleopatra

3

を要約すると、

012ノードを挿入
  • はとても新しく挿入された子が表示されていることを確認するために、親が少しで投げるために

を拡大しなければならない親

  • の拡張状態には自動的に効果がありません

    :@Geoffリーディ(私が太字)によるコメントについて

    dm.makeVisible(new TreePath(newChild.getPath()); 
    

    :子供が目に見えるようにする代替API

    は通常JTreeののルートノードが展開されますが、ツリーが作成されると、ルートノードははそれほど厳密ではないことはできません

    を展開することができない、それように、すべての子どもを持っていませんか実際にはモデルのisLeafの実装に依存します。間違いなく、ルートは(ルート見えたりしない)その本質は、このような実装で

    final DefaultTreeModel model = new DefaultTreeModel(root) { 
    
        @Override 
        public boolean isLeaf(Object node) { 
         if (isRoot(node)) { 
          return false; 
         } 
         return super.isLeaf(node); 
        } 
    
        private boolean isRoot(Object node) { 
         return node != null && node == getRoot(); 
        } 
    
    }; 
    

    で達成することができる:-)ではないことですので、根が常に展開されている(でも子供なし)の葉ではありません新たに挿入された直接的な子供たちは、明示的に見えることなく現れます。

  • 関連する問題