Переполнение стека Java / Swing в методе preferenceChanged - PullRequest
2 голосов
/ 26 февраля 2009

В настоящее время я работаю над проектом Java, и у меня возникла проблема с ошибкой переполнения стека. Происходит следующее: сначала программа читает файл из 1 500 000 слов и добавляет его в массив. Затем он читает небольшой файл из 600 слов и добавляет его в массив. Он проверяет, сколько слов в файле из 600 слов содержится в другом файле. Каждое слово в большом файле связано с числом. Поэтому, когда он находит слово в большом файле, он берет копию слова и связанного с ним целого числа и добавляет его в массив. Моя проблема в том, что я получаю ошибку переполнения стека:

"AWT-EventQueue-0" java.lang.StackOverflowError

Дело в том, что когда маленький файл составляет около 200 слов, программа работает нормально. Последняя строка, которую должна выполнить программа:

result.setPage("file:file for gui NEW.html");

(где результат - JEditorPane)

По какой-то причине я получаю ошибку переполнения стека, когда небольшой файл состоит из 600 слов, но работает нормально, когда он содержит 200 слов. Он запускает последнюю строку и создает этот файл, но не выводит его на панель редактора, поскольку это происходит при возникновении исключения.

Может ли кто-нибудь помочь мне сказать, почему это может произойти и как я мог это исправить? Спасибо.


Ошибка в консоли полностью:

Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError
    at sun.awt.SunToolkit.getSystemEventQueueImplPP(Unknown Source)
    at sun.awt.SunToolkit.getSystemEventQueueImpl(Unknown Source)
    at java.awt.Toolkit.getEventQueue(Unknown Source)
    at java.awt.EventQueue.isDispatchThread(Unknown Source)
    at javax.swing.SwingUtilities.isEventDispatchThread(Unknown Source)
    at javax.swing.JComponent.revalidate(Unknown Source)
    at javax.swing.plaf.basic.
             BasicTextUI$RootView.preferenceChanged(Unknown Source)
    at javax.swing.text.View.preferenceChanged(Unknown Source)
    at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
    at javax.swing.text.View.preferenceChanged(Unknown Source)
    at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
    at javax.swing.text.View.preferenceChanged(Unknown Source)
    at javax.swing.text.BoxView.preferenceChanged(Unknown Source)
    (... repeating forever ...)

РЕДАКТИРОВАТЬ: Таким образом, в принципе кажется, что два элемента управления в GUI продолжают вызывать метод preferenceChanged() друг друга.


Похоже, что графический интерфейс наиболее вероятен, потому что когда я запускаю программу без графического интерфейса и печатаю содержимое файла на консоль, вместо этого он работает нормально. Я понятия не имею, что на самом деле вызывает проблему. Я не использую предпочтения, изменил рутину. Только причины, такие как setSize (), setVisible () и т. Д. Могли бы вызвать это?

Ответы [ 8 ]

6 голосов
/ 26 февраля 2009

У вас есть где-нибудь рекурсивная функция? Обычно это источник переполнения стека.

Дополнительная информация здесь .

4 голосов
/ 26 февраля 2009

Я думаю, что вы столкнулись с вариантом этой проблемы:

http://www.jdocs.com/harmony/5.M5/javax/swing/text/BoxView.html#M-layout(int,int)

protected void layout ( int width, int height )

Этот метод может вызвать переполнение стека если на каждом макете попробуйте ребенка меняет свои предпочтения, т.е. preferenceChanged называется.

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

3 голосов
/ 26 февраля 2009

Переполнение стека происходит в подпрограмме preferenceChanged () объекта GUI. Виновник - это то, что делает ваш графический интерфейс, использование массива - всего лишь триггер.

Являетесь ли вы подклассами каких-либо объектов графического интерфейса, особенно объект с вашей собственной функцией preferenceChanged () где-нибудь? Лучше всего предположить, что это как-то связано с отображением полосы прокрутки, поскольку исключение зависит от того, сколько объектов вы добавляете в этот массив. Внимательно проверяйте документы на предмет объектов или событий GUI, с которыми вы работаете.

1 голос
/ 26 февраля 2009

Я бы проверил файл, который выводится, так как рекурсия, кажется, происходит в JEditorPane, а не в вашем коде - этот файл отображается в обычном веб-браузере, хорошо? Имейте в виду, что JEditorPane не является самым продвинутым компонентом в мире и может задохнуться, если вы пытаетесь показать что-то сложное.

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

Если вы изменяете размер окна во время загрузки файла, это может вызвать ошибки, которые вы описываете - я бы попытался просто загрузить файл в панель редактора, не изменяя его.

1 голос
/ 26 февраля 2009

Посмотрите на трассировку стека ошибки StackOverflowError. Он почти наверняка покажет вам один или два метода, неоднократно вызывающих себя / друг друга. Перепишите эти методы, чтобы этого не произошло (или не так часто).

0 голосов
/ 26 февраля 2009

Если это проблема рекурсии, вы можете попробовать изменить свой алгоритм на новый, который использует явный стек вместо неявного стека, например BFS или DFS

0 голосов
/ 26 февраля 2009

Предполагая, что вы можете подключить отладчик, в Eclipse (извините, я не знаю Netbeans / Idea) вы можете добавить точку останова исключения для StackOverflowError. На панели инструментов представления точки останова есть кнопка с синим J с восклицательным знаком - "J!" - щелкните по нему, затем введите StackOverflowError и выберите приостановку только для необработанных исключений.

Возможно, это обеспечит некоторый дополнительный контекст относительно того, что идет не так.

0 голосов
/ 26 февраля 2009

Вы должны проверить на рекурсию - как прямую рекурсию (когда функция вызывает себя), так и косвенную рекурсию (когда A вызывает B, а B снова вызывает A).

Самый простой способ сделать это - подключить отладчик и посмотреть на стек вызовов в момент переполнения стека.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...