Java: Как прервать программу на полпути путем выполнения щелчком мыши - PullRequest
0 голосов
/ 28 января 2012

Как можно было бы реализовать средство для создания мыши (или другим способом, неважно), которое будет обрабатывать событие щелчка мыши в ЛЮБОЙ части программы? Предпочтительно вернуться к той строке, на которой он остановился, когда завершится метод обработчика события click.

Я использую свинг. «Контекст» - это графический интерфейс, который постоянно обновляется, но должен реагировать на щелчок мыши пользователем в любое время без задержки. Действительно, у меня есть опыт работы с событиями, использования и перезаписи их обработчиков и т. Д., Я полагаю, не слишком углубленно, но то, что я знаю, было достаточно во всем до сих пор.

Ответы [ 2 ]

1 голос
/ 28 января 2012

Я не мог понять ваш первый параграф, поэтому мой ответ идет на ваш второй параграф, если я правильно понял.;)

Swing следует модели с одним потоком.Итак, вы должны обновлять пользовательский интерфейс из Thread Dispatch Thread (EDT).Этот поток также отвечает за доставку событий в ваш код, отсюда и название.Если вы постоянно обновляете пользовательский интерфейс в цикле, то это приведет к тому, что EDT будет занят и заблокирован.Конечным эффектом будет пользовательский интерфейс, который не отвечает на пользовательские события.Это происходит потому, что события становятся в очередь, и EDT может выбрать их и доставить в свой код, когда он станет бесплатным.

Игры обычно сталкиваются с подобным сценарием.Вы могли заметить, что игры обычно имеют одну фиксированную частоту обновления, которую они называют FPS (Frames Per Second).Обычно поддержание 60 FPS достаточно хорошо.То есть вам нужно рисовать ваш пользовательский интерфейс 50 раз в секунду, но сейчас кажется, что ваш цикл рендеринга (который обновляет пользовательский интерфейс) работает непрерывно.

Вы должны иметь непрерывно работающий отдельный поток, который отвечает задля рисования пользовательского интерфейса.Это должно нарисовать в буфер (Image).А затем вызовите repaint() в обновляемом элементе пользовательского интерфейса.Этот элемент пользовательского интерфейса paintComponent() необходимо переопределить, чтобы он мог скопировать изображение в буфер Image и нарисовать его в графическом контексте.

Теперь наступает настоящий трюк.Цикл, который вызывает repaint(), должен выполнить некоторую арифметику, чтобы убедиться, что он не выходит за пределы рисования 60 раз, то есть зацикливается 60 раз в секунду.Если и когда это происходит, то он должен вызвать Thread.sleep(sleepTime), где sleepTime - это количество миллисекунд, оставшихся в секунде после цикла 60 раз.Иногда может случиться, что вашему циклу может потребоваться больше секунды, чтобы завершить 60 итераций, затем не просто перейти к следующей итерации, а вызвать Thread.yield().Это даст другим потокам возможность использовать процессор, например, ваш EDT.Чтобы усложнить задачу, не продолжайте давать урожай всегда, поэтому, возможно, вы захотите применить некоторую логику, чтобы убедиться, что доходность составляет только х раз подряд.Этот последний сценарий должен быть очень редким, если вообще.Этот сценарий означает, что система находится под большой нагрузкой.

Помните, что repaint() является потокобезопасным и может вызываться из любого потока.Он планирует paint() вызов на EDT.Таким образом, вызов repaint() не гарантирует краски.Итак, вы можете поэкспериментировать с различными значениями FPS, чтобы найти то, что подходит вам.

Кстати, уловка рендеринга в оперативную память Image технически называется Двойным буфером.Это дает нам возможность визуализировать приятные плавные анимации.

Дополнительная информация: -

1 голос
/ 28 января 2012

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

...