как JTree реагирует на измененный DefaultMutableTreeNode?

Просто пытаемся выяснить, что произойдет с точки зрения потоков, если вы измените пользовательский объект DefaultMutableTreeNode в потоке, отличном от EDT?

Я не говорю о событиях DefaultTreeModel, а именно о insertNodeInto и removeNodeFromParent, которые, как я совершенно ясно, всегда должны запускаться в EDT... Я думаю...

В случае изменений в пользовательских объектах узлов оказывается, что JTree.TreeModelHandler — это вещь, которая «прослушивает» такие события... но есть ли основания ожидать, что слушатель будет уведомлен только о таком изменении в нить где произошло событие? И будет распространять свой ответ только в этом же потоке?

Очевидно, поэтому я предполагаю, что это довольно простой шаблон «наблюдатель».

Означает ли это, что большинство изменений в узлах JTree на самом деле должны происходить в EDT, с риском того, что в противном случае что-то произойдет не так, как и когда вы ожидаете?

В API для DefaultMutableTreeNode действительно говорится, что «вы должны выполнить собственную синхронизацию»...


person mike rodent    schedule 17.06.2012    source источник


Ответы (1)


Правила потоков Swing очень просты: Swing является однопоточным, и все операции с компонентами Swing должны выполняться в EDT.

Поэтому, как только ваш TreeModel, содержащий DefaultMutableTreeNodes, установлен на JTree, вам лучше убедиться, что любые изменения, которые вы вносите в модель (или узел), и соответствующие события, которые запускаются, происходят в EDT.

person Robin    schedule 17.06.2012
comment
JTree особенно чувствителен к этому важному принципу; см. также Начальные темы. - person trashgod; 18.06.2012
comment
спасибо... в некотором роде мне интересно, почему большинство/все методы JTree (и других JComponent) не включали тест isEventDispatchThread()... и запрещали вызовы, отличные от EDT... - person mike rodent; 18.06.2012
comment
@mikerodent В JavaFX об этом позаботились. Вы можете сделать это самостоятельно, установив собственный менеджер перерисовки (см. эту статья) - person Robin; 18.06.2012
comment
@Робин, спасибо, очень полезная ссылка. Мы собираемся упростить отладку Swing в Java 1.7. Тем временем изучу, что там сказано об этих двух возможных решениях. - person mike rodent; 18.06.2012
comment
@Robin Теперь я использую CheckThreadViolationRepaintManager ... но теперь я действительно не думаю, что все действия для JTree и DefaultTreeModel (например) всегда должны выполняться в EDT: если эти объекты отключены (т.е. не отображаются), это совершенно нормально, ИМХО, чтобы манипулировать ими в потоках, отличных от EDT. Вам просто нужно быть строгим в отношении того, когда они снова будут обрабатываться EDT. Если вы ошибетесь, RepaintManager обычно поймает вас. Но я думаю, что полное введение проверки EDT для всех методов всех объектов Swing ограничивает вполне законные проекты, включающие офлайн-манипуляции. - person mike rodent; 12.09.2012
comment
@mikerodent Как объяснялось в этой статье, ранее было разрешено создавать компоненты Swing в другом потоке, и было время, когда вам также разрешалось изменять невидимые компоненты в другом потоке. Однако в текущих рекомендациях говорится, что все создание и взаимодействие со всеми компонентами Swing (в том числе невидимыми) должно происходить в EDT. - person Robin; 12.09.2012
comment
@Robin извинения ... да, действительно ... к сожалению, ссылка на Oracle на интересной странице А. Поточкина, которая, возможно, однажды показала обоснование этого полного запрета, теперь не работает. Я имею в виду что-то вроде горячей замены предварительно подготовленных комбинаций JTree-TreeModel в качестве компонента JViewport. У меня работает, но я хотел бы знать, что стоит за этим общим запретом... - person mike rodent; 14.09.2012