1

クライアントである Swing アプリ (実行可能で署名された jar に常駐) があります。アプリはサーバーにも接続します。特定の条件が満たされると、GUI の更新を実行します (より具体的には、a のすべてのノードを削除してJTreeから再設定します)。このクライアントをそのまま (つまり、セキュリティ マネージャを使用せず、実行可能で署名付きの JAR に常駐させずに) 実行すると、ツリーは問題なく更新されます。

ただし、クライアントを署名付き JAR として (適切なポリシー ファイルと共に) パッケージすると、更新の問題が発生します。アプリを起動すると、JTree展開されません。一度クリックすると展開したように見えますが、子ノードが表示されません。ノードを表示するには、その後 2 回クリックする必要があります。また、更新 (すべてのノードを削除してから再設定) を実行すると、UI が適切に更新されません。GUI を更新するには、ルート ノードを 2 回クリックする必要があります。

ポリシー ファイルに AWT パーミッションを追加しようとしましたが、効果がありませんでした (そもそもパーミッション違反は見られませんでしたが、試してみようと思いました)。JARにすべての権限を与えようとさえしました。それも役に立たなかったようです。何が原因でしょうか?

リフレッシュを実行するコードは次のとおりです。

private void buildTree() throws IOException, ClassNotFoundException {
    setVisible(false);
    tree.removeTreeWillExpandListener(this);
    tree.removeTreeSelectionListener(this);

    DefaultTreeModel treeModel = (DefaultTreeModel) tree.getModel();
    DefaultMutableTreeNode root = (DefaultMutableTreeNode) treeModel.getRoot();
    root.removeAllChildren();

    root.setUserObject(base);

    Book[] bookArray = remoteLibraryService.getAllBooks();
    TreeBuilderService.buildTree(root, bookArray);
    treeModel.reload();

    for(int i = 0; i < tree.getRowCount(); i++) {
        tree.expandRow(i);
    }

    tree.addTreeSelectionListener(this);
    tree.addTreeWillExpandListener(this);
    setVisible(true);
}

ツリーを生成するコード (関連するスニペットのみを表示):

categoryNode = new DefaultMutableTreeNode(book.getGenre());
root.add(categoryNode);

課題に関する限り、これはおそらく取り決めを破るものではありませんが、本当に気になります。何が原因なのかを突き止めたいと思います。

4

2 に答える 2

2

GUIの更新サイクルでIOを実行しているため、結果としてGUIスレッドがブロック/ストールする可能性があります。代わりに、APIを介してSwingWorkerとツリーの非同期ポピュレーションを使用することを検討してください。

于 2010-11-12T07:31:57.157 に答える
2

初期スレッドで説明したように、Swing GUI コンポーネントはイベント ディスパッチ スレッドで作成する必要があります。経験的に、JTree別のスレッドから操作された場合に特に失敗しやすくなります。これSecurityManagerはおそらく偶発的です。タイミングの変更は、プラットフォームの変更であっても、欠陥を明らかにする可能性があります。

于 2010-11-12T08:55:15.623 に答える