Swing: что делать, если обновление JTree занимает слишком много времени и замораживает другие элементы GUI? - PullRequest
4 голосов
/ 07 апреля 2010

Я знаю, что код GUI в Java Swing должен быть помещен в SwingUtilities.invokeAndWait или SwingUtilities.invokeLater.Таким образом, многопоточность работает нормально.

К сожалению, в моей ситуации графический интерфейс обновляет его, что занимает гораздо больше времени, чем фоновые потоки.Более конкретно: я обновляю JTree всего с 400 записями, глубина вложения составляет максимум 4, так что ничего страшного не должно быть, верно?Но иногда это занимает одну секунду!Мне нужно убедиться, что пользователь может печатать в JTextPane без задержек.Ну, угадайте, что медленные обновления JTree do вызывают задержки для JTextPane во время ввода.Он обновляется только после обновления дерева.

Я использую Netbeans и эмпирически знаю, что приложение Java может обновлять большое количество информации, не блокируя остальную часть пользовательского интерфейса.

Как это можно сделать?

ПРИМЕЧАНИЕ 1. Все эти DefaultMutableTreeNode подготовлены за пределами invokeAndWait.
ПРИМЕЧАНИЕ 2. При заменеinvokeAndWait с invokeLater дерево не обновляется.
ПРИМЕЧАНИЕ 3. Обратите внимание, что рекурсивное расширение дерева занимает гораздо больше времени.
ПРИМЕЧАНИЕ 4: Я использую пользовательское средство рендеринга ячеек дерева, попробую без него и сообщу.
ПРИМЕЧАНИЕ 4a: Мой рендерер ячеек дерева использует карту для кэширования и повторного использования созданных JTextComponent s, в зависимости от узла дерева (как ключ).

КЛИВ 1 : Ух ты! Без настройки пользовательского средства визуализации ячеек это в 10 раз быстрее .Думаю, мне понадобятся несколько хороших руководств по написанию пользовательских средств визуализации древовидных ячеек.К сожалению, мне нужно пользовательское средство визуализации ячеек.

Этот учебник, включающий отложенную загрузку, может помочь, я разберусь с этим.

Ответы [ 2 ]

2 голосов
/ 07 апреля 2010

[Отсутствуют некоторые детали, такие как: какой тип обработки происходит каждый раз, когда пользователь обновляет JTextPane? Целое дерево восстанавливается?]

В любом случае, что работало для меня в прошлом (когда я испытывал значительное замедление из-за обновлений JTree), так это то, что я развернул собственную TreeModel.

Большинство программистов предпочитают использовать DefaultTreeModel. Это действительно готовое решение, которое хорошо работает в большинстве случаев. Тем не менее, это довольно медленно, когда важные части дерева должны быть обновлены. Очевидно, что написание вашей собственной TableModel - это больше работы, чем использование готового решения, но это гораздо менее болезненно, чем вы думаете.

В частности, моя пользовательская модель дерева быстрая, потому что она сама по себе не строит никаких деревьев. Он просто наблюдает за моей моделью предметной области и вычисляет ответы на вызываемый для нее метод (getChild (), getParent (), ...), извлекая соответствующую информацию из этой модели. Попытайся. Это работает как шарм.

1 голос
/ 07 апреля 2010

Я не знаю, почему он работает только с invokeAndWait() (это странно), но простой способ - вызвать этот метод в новом фоновом потоке.

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

...