создание эффективной реализации этой логики Java MouseListener - PullRequest
3 голосов
/ 24 января 2012

У меня есть поток MouseListener, где этот метод вызывается каждый раз, когда происходит щелчок:

public void mousePressed(MouseEvent event){

    //my Logic here

}

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

Но происходит то, что во время обработки логики входящие клики ставятся в очередь, и даже когда щелчок останавливается, кликовые запросы продолжают вызывать этот метод mousePressed, в результате чего я выполняю несколько отложенных исполнений.

К сожалению, у меня нет контроля над Слушателем (почему он задает вопрос и продолжает посылать отложенные клики), поэтому в таком сценарии вы можете сказать мне, каков эффективный способ обработки, чтобы я не делалQue из-за задержки в моей обработке.

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

Ответы [ 2 ]

2 голосов
/ 24 января 2012

Обновления: См. Комментарии Филиппа о том, почему это не работает для Swing!

К сожалению, у вас нет доступа к eventListener.Идеальным решением было бы отменить регистрацию обратного вызова во время его выполнения.

Вот решение , которое эмулирует отмену регистрации функции обратного вызова во время ее выполнения , при условии, что вы хотите, чтобы щелчки в очереди исчезали:

private AtomicBoolean engaged = new AtomicBoolean(); // thread-safe boolean

public void mousePressed(MouseEvent event){
    if (!engaged.get()) {
        engaged.set(true);

        // your logic here

        engaged.set(false);
    }
}

AtomicBoolean действует как блокировка проверки и установки, предотвращающая одновременное выполнение несколькими потоками нажатого обратного вызова события.Прессы в очереди будут рассеяны во время блокировки.

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

Одним из решений было бы получить доступ к компоненту, на котором пользователь щелкнул, и отключить его во время обработки MouseListener. Таким образом, он не принимает новые клики. Это могло бы дать дополнительное преимущество, заключающееся в предоставлении пользователю визуальной обратной связи о том, что он не должен нажимать на компонент в данный момент.

Вы можете получить доступ к компоненту через MouseEvent:

public void mousePressed(MouseEvent event) {
  event.getComponent().setEnabled(false);
  try {

    // ....

  } finally {
    event.getComponent().setEnabled(true);
}

В общем, хотя вы не должны делать слишком много вычислений в потоке слушателя событий Swing, потому что Swing также нуждается в этом для обработки других событий и рисования. Вы должны использовать отдельные потоки для выполнения реальной работы и просто запустить их в MouseListener. Вы также можете использовать ExecutorService, чтобы упростить это. Было бы неплохо отключить компонент графического интерфейса на протяжении всего вычисления, чтобы предоставить обратную связь с пользователем.

Edit: Это решение, конечно, зависит от Swing. Любое подобное решение зависит от деталей вашей библиотеки GUI, поэтому, если вы используете свою собственную библиотеку GUI, вы - одна из своих.

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

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