Приложение Swing с менеджером безопасности, вызывающее странные проблемы обновления GUI - PullRequest
1 голос
/ 12 ноября 2010

У меня есть приложение Swing (находящееся в исполняемом, подписанном фляге), которое является клиентом.Приложение также подключается к серверу.Когда определенные условия выполняются, я выполняю обновление графического интерфейса (точнее, удаляю все узлы JTree и затем заново заполняю его).Когда я запускаю этот клиент как есть (то есть без менеджера безопасности и без наличия исполняемого файла с подписанным JAR), дерево обновляется и обновляется без каких-либо проблем.

Однако, когда я упаковываю свой клиент какподписанный JAR (с соответствующим файлом политики), я получаю проблемы обновления.Когда приложение запускается, я JTree не расширяется.Когда я щелкаю его один раз, он выглядит как расширенный, но дочерние узлы не отображаются.Я должен дважды щелкнуть по нему, чтобы отобразились узлы.Кроме того, когда я выполняю обновление (удаляя все узлы и затем снова заполняя), пользовательский интерфейс не обновляется надлежащим образом.Я (снова) должен дважды щелкнуть по корневому узлу, чтобы обновить графический интерфейс.

Я попытался добавить разрешения 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);

Это, вероятно, не нарушает договоренности, что касается назначения, но это действительно беспокоит меня;Я хотел бы выяснить, что является причиной этого.

Ответы [ 2 ]

2 голосов
/ 12 ноября 2010

Как обсуждено в Исходные потоки , компоненты Swing GUI должны быть созданы в потоке диспетчеризации событий.Опытным путем JTree особенно подвержен ошибкам при манипулировании из другого потока.SecurityManager, вероятно, случайный;любое изменение в сроках, даже смена платформ, может выявить недостаток.

2 голосов
/ 12 ноября 2010

Хорошо, вы выполняете ввод-вывод в цикле обновления графического интерфейса, поэтому поток графического интерфейса может быть в результате заблокирован / остановлен.Вместо этого рассмотрите возможность использования SwingWorker и асинхронного заполнения дерева через его API.

...