Java: игнорировать одиночный щелчок при двойном щелчке?

кто-нибудь может придумать хороший способ игнорировать один клик, который идет с двойным щелчком в Java?

Я ищу разные варианты поведения для каждого из них:

  • одиночный щелчок рисует перекрестие в точке щелчка
  • двойной щелчок выделяет объект на экране, но не рисует перекрестие в точке щелчка

... кто-нибудь может придумать, как это сделать? Может какой-то таймер настроен? Идеи оценили :-)

‹отказ от ответственности> ...и да, я знаю, что совершаю самую отвратительную оплошность в отношении юзабилити / пользовательского интерфейса. ‹/отказ от ответственности>

РЕДАКТИРОВАНИЕ № 2:

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

ИЗМЕНИТЬ:

Спасибо cgull - это то, что я смог придумать, учитывая ваше подтверждение того, что нет простого способа сделать это (примечание что, если я установлю таймер ‹ 200, между щелчком и таймером будут видны странные скачки, но пока я устанавливаю это значение> 200, все работает просто замечательно):

public void mouseClicked(MouseEvent e) {
    System.out.println( "Click at (" + e.getX() + ":" + e.getY() + ")" );
    if (e.getClickCount() == 2) {  
        System.out.println( "  and it's a double click!");
        wasDoubleClick = true;
    }else{
        Integer timerinterval = (Integer) 
          Toolkit.getDefaultToolkit().getDesktopProperty(
                      "awt.multiClickInterval");
        timer = new Timer(timerinterval.intValue(), new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                if (wasDoubleClick) {
                    wasDoubleClick = false; // reset flag
                } else {
                    System.out.println( "  and it's a simple click!");
                }
            }    
        });
        timer.setRepeats(false);
        timer.start();
    }
}

person Dave Carpeneto    schedule 14.02.2009    source источник
comment
как это может работать? wasDoubleClick не может быть окончательным, и он используется внутри другого класса (анонимного ActionListener)   -  person alessiop86    schedule 15.09.2012


Ответы (4)


Действительно, вам нужно настроить таймер в вашем переопределенном методе mouseClicked() вашего MouseAdapter, чтобы определить временной интервал между двумя щелчками. Интервал по умолчанию в мс можно найти, запросив Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval"). Если другой щелчок мыши обнаружен до истечения времени таймера, то у вас есть двойной щелчок, в противном случае, когда таймер истечет, вы можете обработать одиночный щелчок.

person cgull    schedule 14.02.2009

На самом деле я думаю, что есть более простое решение (используйте метод getWhen() InputEvent):

class DCListener extends MouseAdapter{

    private long maxTimeBetweenClicks; // in millis
    private long firstClickTime=0;
    private Runnable eventHandler;

    public DCListener(long maxTimeBetweenClicks,Runnable eventHandler){
        this.maxTimeBetweenClicks=maxTimeBetweenClicks;
        this.eventHandler=eventHandler;
    }

    public void mouseClicked(MouseEvent e){

        if((e.getWhen()-firstClickTime)<=maxTimeBetweenClicks){
            firstClickTime=0; // 3 clicks are not 2 double clicks
            eventHandler.run();
        }else{
            firstClickTime=e.getWhen();
        }

    }
}
person Bat0u89    schedule 01.11.2012

Вы уже пробовали реализовать интерфейс MouseListener?

Я думаю, что MouseEvent имеет метод подсчета кликов (или свойство), чтобы знать это.

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

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

Таким образом, один щелчок будет действительным только в том случае, если другой щелчок не будет выполнен, скажем, через 300 мс. (что-то настраиваемое)

Идея такова:

public void listen for the single click() 
    if (  in x time there has not been another click  ) 
    then 
        we have a single click
        proceed with your single click handling
    else 
        we have a double click
       proceed with your double click handling

Или что-то вроде того.

person OscarRyz    schedule 14.02.2009

Альтернативное решение:

Я понял это до того, как нашел решение в этом вопросе. Идея та же, использовать таймер, хотя и сложнее :).

Используйте 1_:

class BackgroundClickHandler extends SwingWorker<Integer, Integer> {
  @Override
  protected Integer doInBackground() throws Exception {
    Thread.sleep(200);
    // Do what you want with single click
    return 0;
  }

}

В методе mouseClicked() вы можете сделать что-то вроде этого:

 if (event.getClickCount() == 1) {
  // We create a new instance everytime since
  // the execute() method is designed to be executed once
  clickHandler = new BackgroundClickHandler();

  try {
    clickHandler.execute();
  } catch(Exception e) {
    writer.println("Here!");
  }
}

if (event.getClickCount() == 2) {
  clickHandler.cancel(true);

  //Do what you want with double click
}

Я надеюсь, что это будет полезно.

person rendon    schedule 23.10.2012