Почему мое окно Swing продолжает закрываться через несколько секунд? - PullRequest
3 голосов
/ 16 сентября 2011

Редактировать: Если несколько тегов сбивают с толку, я работаю в Jython.

Вот мой SSCCE :

from javax.swing import JFrame

window = JFrame('Test', 
                defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
                size = (800, 600))
window.visible = True

Окно открывается, сидит там несколько секунд, а затем закрывается. Пока единственное решение, которое я нашел, это добавить while True: pass в конец, что, похоже, указывает на то, что проблема в том, что window выходит из области видимости, поэтому он очищается и должен закрываться. На самом деле это может быть еще одним симптомом той же проблемы, с которой я столкнулся ранее .

Однако я не думаю, что тратить циклы в бесконечном цикле - лучшее решение. Я думаю, я мог бы сделать это менее проблематичным, поспав несколько секунд в каждом цикле, но я все же хотел бы решить эту проблему правильно .

Правильное поведение, создание окна в EDT дает точно такое же поведение:

from javax.swing import JFrame, SwingUtilities
from java.lang import Runnable

class Foo(Runnable):
    def run(self):
        window = JFrame('Test', 
                        defaultCloseOperation = JFrame.EXIT_ON_CLOSE,
                        size = (800, 600))
        window.visible = True

foo = Foo()
SwingUtilities.invokeLater(foo)

В предыдущих приложениях это не было проблемой, потому что я все равно нуждался в бесконечном цикле для других задач (мониторинг сокетов и т. Д.). Однако мое текущее приложение управляется исключительно пользовательским вводом, поэтому мне ничего не нужно / не нужно после того, как я invokeLater().

Обновление: Основываясь на ответе Кинго, я попытался создать один из них:

class JFrameTest(JFrame):
    def addNotify(self):
        print 'In addNotify()'
        JFrame.addNotify(self)

    def removeNotify(self):
        print "In removeNotify()"
        JFrame.removeNotify(self)

«В addNotify ()» печатается, но не «В removeNotify ()», и окно ведет себя так же. Почему бы removeNotify() не позвонить?

Кроме того, я попытался сделать window.setVisible(True) вместо window.visible = True, и это тоже не имеет никакого эффекта.

1 Ответ

0 голосов
/ 16 сентября 2011

Я предлагаю следующую стратегию, чтобы узнать больше о проблеме:

sun.awt.AWTAutoShutdown - это класс, который предотвращает отключение JVM, если в инструментарии зарегистрирован собственный оконный узел.Любой компонент регистрируется при вызове addNotify().Для фрейма это делается, когда вы звоните setVisible(true).

Единственный способ, которым одноранговый узел может остаться незарегистрированным, - это если кто-то звонит dispose() на одноранговый узел.Единственное место, dispose(), которое вызывается на одноранговом узле в JRE, - это Component#removeNotify().

Вы можете переопределить этот метод в своем классе фреймов и распечатать трассировку стека, чтобы понять, почему это происходит.

...