Окно JAVA Swing Gui зависает

У меня проблема с графическим интерфейсом SWING, или, по крайней мере, я думаю, что это графический интерфейс Swing.

Вот мой основной файл кода:

/**
 * 
 */
package com.tda.t2.ctas.slasher;

import javax.swing.SwingUtilities;

import com.tda.t2.ctas.slasher.gui.mainFrame;
import com.tda.t2.ctas.slasher.utils.MyCloseListener;



public class SLASHer {

    public SLASHer () {
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        //EventQueue.invokeLater(new Runnable() {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                ConfigData myconfig = new ConfigData();
                try {
                    //TdaUrlHelper window = new TdaUrlHelper();
                    //window.tdaFrame.setVisible(true);
                    mainFrame tdaFrame = new mainFrame();
                    tdaFrame.setVisible(true);

                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

}

Простой вызов для создания фрейма и открытия его. Есть и другие файлы, которые я не поместил сюда для места. Но проблема, которая у меня есть (а я пробовал на нескольких машинах и операционных системах), заключается в том, что кнопки на окне как бы зависают. Я могу выбрать окно и нажать на кнопки, и они подсвечиваются, как будто их нажали, но ничего не происходит. У меня есть плоскость с вкладками, и нажатие на другие вкладки также ничего не делает. Иногда это длится около 15 секунд, а иногда несколько минут. Но в конце концов он всегда возвращается и будет реагировать на новый ввод (т.е. он не помнит все щелчки, которые я сделал до того, как он вернулся). Приложение в целом простое в том смысле, что оно ждет, пока пользователь что-то не сделает, прежде чем оно что-то сделает, поэтому я не понимаю, почему оно зависает.

Любая помощь будет оценена по достоинству.

Спасибо


person Patrick Aquilone    schedule 28.11.2012    source источник
comment
Ваша проблема в коде, который не показан. Скорее всего, вы не соблюдаете правила потоковой передачи Swing, вполне возможно, в ActionListeners для ваших JButtons, но кто знает, пока мы не увидим код нарушения.   -  person Hovercraft Full Of Eels    schedule 28.11.2012
comment
Похоже, что либо поток GUI печатает трассировку стека ( :\. ), либо вы что-то неправильно сделали в многопоточности.   -  person Zéychin    schedule 28.11.2012
comment
Обратите внимание, что класс mainFrame следует переименовать в MainFrame. Все имена классов должны начинаться с заглавной буквы. Это важно, если вы хотите, чтобы другие (например, мы!) могли понять ваш код и помочь вам.   -  person Hovercraft Full Of Eels    schedule 28.11.2012
comment
Опубликованный код не имеет отношения к проблеме — вам нужно проверить ваше приложение, чтобы выяснить, где находится узкое место: используйте отладчик или идите грязным путем, пытаясь распечатать материал на каждом уровне приложения, каждый раз продвигаясь дальше. .   -  person moonwave99    schedule 28.11.2012
comment
Звучит как ActionListener, прикрепленный к кнопке, которая запускает тяжелую задачу на EDT iso с использованием рабочего потока. Ознакомьтесь с руководством по параллелизму в Swing.   -  person Robin    schedule 28.11.2012
comment
Проблема в том, что у меня на этой панели 81 кнопка (и еще на другой панели с вкладками) и ВСЕ они зависают. Когда я нажимаю на окно, и ничего не работает, НИЧЕГО не работает. Ни одна кнопка не будет работать, пока не перестанет зависать.   -  person Patrick Aquilone    schedule 28.11.2012
comment
Конечно. Когда EDT занят, весь ваш пользовательский интерфейс зависает. Вот почему длительные задачи не должны выполняться в EDT, как объясняется в руководстве, на которое я ссылался в своем предыдущем комментарии.   -  person Robin    schedule 28.11.2012
comment
Вы должны попытаться изолировать ошибку в небольшой программе. Затем, пожалуйста, не стесняйтесь публиковать оскорбительный код в любое время, когда вам нужна дополнительная помощь. В противном случае все, что мы можем сделать, это обсудить теоретические возможности, и пока это, кажется, не очень вам помогает.   -  person Hovercraft Full Of Eels    schedule 28.11.2012


Ответы (1)


Какой оскорбительный код прикрепить к кнопке, которая висит? Проверьте свою консоль на наличие исключений и поместите некоторые операторы System.out.println() вверху и внизу этого кода. Посмотрите, видите ли вы, что эти операторы печати распечатываются. Посмотрите, сколько времени требуется для печати верхнего и нижнего. Если вы видите оба оператора, то вы знаете, что выполняется весь блок, но если требуется некоторое время, чтобы отобразить последний оператор, вы знаете, что вы зависаете в потоке Swing (также известном как EDT — поток диспетчеризации событий). Правило номер один в Swing: пользовательский интерфейс не может перерисовываться во время выполнения вашего ActionListener.

Чтобы сделать отзывчивый пользовательский интерфейс, вы должны увидеть, как первый и последний оператор появляются на консоли менее чем за 10-100 мс (визуально почти мгновенно). Если вы действительно хотите пофантазировать, вы можете использовать System.currentTimeMillis() в конце и внизу. Вычтите два значения и выполните println(). Это скажет вам точно, как долго этот слушатель работал. Если оно превышает 100 мс, вам необходимо реструктурировать код, улучшив алгоритм или отключив загрузку длинных вычислений в потоке (см. этот руководство по SwingWorker).

public void actionPerformed(ActionEvent event) {
    System.out.println("Starting SomeProcess");
    long start = System.currentTimeMillis();

    // all your code belongs here

    long duration = System.currentTimeMillis() - start;
    System.out.printf("SomeProcess took %,d ms%n", duration );
}
person chubbsondubs    schedule 28.11.2012
comment
Я не добавлял код кнопки, потому что всего на панели 81 кнопка. И при этом не имеет значения, какую кнопку я нажму. При зависании все кнопки не работают, пока не снимется зависание. Это похоже на то, что он не осознавал, что теперь у него есть фокус, поэтому я опубликовал то, что сделал. - person Patrick Aquilone; 28.11.2012
comment
Ну, это зависит от вас, сколько помощи вы хотите. Вы можете сделать то, что я предлагаю, и выяснить специфику вашей проблемы самостоятельно, или просто опубликовать код для одной из тех кнопок, которые зависают в пользовательском интерфейсе. Вы правы, я не буду просматривать слушатели с 81 кнопкой, но я посмотрю на прослушиватель с 1 кнопкой. Я думаю, если вы сделаете то, что я предложил, вы поймете, в чем проблема. Если вы не можете понять это, опубликуйте еще немного кода. - person chubbsondubs; 28.11.2012
comment
Я согласен. По какой-то причине @JesterHawk, похоже, не хочет публиковать код прослушивателя. Пока он этого не сделает, все, что мы можем сделать, это задаться вопросом, что происходит. Скорее всего, будет достаточно одного слушателя. - person Hovercraft Full Of Eels; 28.11.2012
comment
Ну, мы все знаем, что он делает на высоком уровне. Он зависает в потоке EDT с длительным вычислением, которое следует выгрузить в поток. Скорее всего, какой-то вызов сетевой службы непосредственно из потока EDT, но пока он не опубликует код, мы действительно не можем сказать ему, что именно не так. :-) - person chubbsondubs; 28.11.2012
comment
Я довольно удивлен простотой моего ответа, смею сказать, горжусь. :-) Слишком легко попасть в сорняки, когда речь идет о потоках, но это держит планку на низком уровне, обучая приему отладки для повышения производительности. @JesterHawks Я немного обновил свой ответ, добавив несколько ссылок, которые должны вам помочь. - person chubbsondubs; 28.11.2012
comment
Я согласен; ты отвечаешь прилично. 1+ голос. Я не очень уверен в таймере, поскольку время может быть коротким во время создания программы и тестовых прогонов, но долгим в реальном мире. Существуют определенные ситуации, когда фоновый поток требуется независимо от времени в вашей тестовой программе. Одними из таких являются файловый ввод-вывод и методы базы данных. - person Hovercraft Full Of Eels; 28.11.2012