2011-07-26 14 views
3

私は、ツリー内のノードの表示文字列を任意に変更することをサポートする、DefaultMutableTreeNodeのオーバーライドが設定されたDefaultTreeModelを使用しています。下のコードに示すように、私のフォームでは、ツリーを別のクラスに作成し、メインデータ型のラッパークラスを介して渡すことで、新しいノードをツリーに挿入します。手順は、新しいオーバーライドDefaultMutableTreeNodeを作成し、それに子を追加します(各AccessPointは複数の子ノードを持つノードで表されます)。その後、UIで後で使用できるように保存します。TreeModelで新しいノードが追加されたときにJTreeが更新されないのはなぜですか?

このようにノードを初めて追加すると、美しく動作します。次のコードで追加された後続のノードは、実際にはDefaultTreeModelに格納されますが、JTreeは新しいノードで更新されていません。

なぜ、JTreeに最初の子が追加された後にデータが取り込まれないのですか?

private void populateAccessPointTreeModel(AccessPointDataWrapper wrapper) { 
    //the pre-created DefaultMutableTreeNode subclass instance is 
    // stored in the wrapper 
    DefaultMutableTreeNode accessPointNode = 
      wrapper.getAccessPointTreeNode(); 
    //this line updates the accessPointTree with the new node (I've looked at the 
    // value in debug mode, and it does in fact add the node 
    ((DefaultMutableTreeNode) accessPointTree.getRoot()).add(accessPointNode); 
    //unrelated logic happens down here... 
} 

必要に応じてノードを作成するコードを含めることができますが、問題ではないと思います。

+0

コンポーネントまたはその親を再描画しようとしましたか? – Bitmap

答えて

7

DefaultMutableTreeNodeは、子どもが更新されたことをDefaultTreeModelに通知しないという問題があります。これを行うには、テーブルモデル(nodesChangedまたは類似のもの)の適切なメソッドを呼び出すか、(好ましくは)DefaultTreeModel.insertNodesIntoメソッドを使用します。

DefaultTreeModel model = (DefaultTreeModel)accessPointTree.getModel(); 
DefaultMutableTreeNode root = model.getRoot(); 
model.insertNodeInto(accessPointNode, root, root.getChildCount()); 
+0

+1、Swingコモプナントの更新は常にモデルを使用して行う必要があります。 – camickr

+0

それは理にかなっています。以前はUIクラスに保存したDefaultTreeModelを使って更新していましたが、DefaultMutableTreeNodeの追加は短くて済みました。ありがとう。 –

+0

私は、root.getChildCount()は、insertNodeIntoの範囲外の例外(信じて、私が経験から知っていることを意味する)を捨てると信じています。 スレッド "アルゴリズムスレッド"での例外java.lang.ArrayIndexOutOfBoundsException:1> 0 at java.util.Vector.insertElementAt(Vector.java:571) at javax.swing.tree.DefaultMutableTreeNode.insert(DefaultMutableTreeNode.java:195) ) at javax.swing.tree.DefaultTreeModel.insertNodeInto(DefaultTreeModel.java:234) –

0

スレッドの問題がある可能性があります。あなたのJTreeはいくつかのスレッドで更新されていますが、Swingイベントディスパッチスレッド(EDT)に表示されるJTreeの重要なコピーは、それらの変更を何も知らない。

このような場合は、あなたが使用してスイングEDTでJTreeのを更新する必要があります。

SwingUtilities.invokeLater(new Runnable() { 
    @Override public void run() { ... update jTree here } 
}); 

を私がJTreeのことは知らない...多分それはあなたがSwingで更新する必要がありますTreeModelのですEDT。

関連する問題