Java: игнорировать один клик по двойному клику?
может ли кто-нибудь подумать о хорошем способе игнорировать единственный клик, который поставляется с двойным щелчком мыши на Java?
Я ищу, чтобы у каждого было по-разному поведение, например:
- однократное нажатие красок перекрестия в точке щелчка
- двойной щелчок выбирает объект на экране, но должен не рисовать перекрестие в точке щелчка
... может ли кто-нибудь подумать о способе сделать это? Может быть, какая-то настройка таймера? Идеи оценили: -)
<disclaimer> ... и да, я знаю, что я совершаю самый отвратительный юзабилити /UI faux pas. </отказ от ответственности >
РЕДАКТИРОВАТЬ № 2:
Несмотря на то, что это работает, задержка из-за таймера сходит с ума - я отказываюсь от этого решения и используя средний щелчок для выбора вместо двойного щелчка...
EDIT:
Спасибо 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 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 a simple click!");
}
}
});
timer.setRepeats(false);
timer.start();
}
}
Ответы
Ответ 1
Действительно, вам нужно настроить таймер в вашем переопределенном методе mouseClicked() вашего MouseAdapter, чтобы определить временной интервал между двумя щелчками мыши. Интервал по умолчанию в мс может быть найден путем запроса
Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval")
. Если до истечения срока действия таймера обнаружен другой щелчок мыши, у вас есть двойной щелчок, иначе по истечении таймера вы можете обработать один клик.
Ответ 2
На самом деле я думаю, что есть более простое решение (используйте метод InputEvent getWhen()):
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();
}
}
}
Ответ 3
Вы уже пытались реализовать интерфейс 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
Или что-то в этом роде.
Ответ 4
Альтернативное решение:
Я понял это, прежде чем нашел решение в этом вопросе. Идея такая же, используйте таймер, хотя и сложнее:).
Используйте SwingWorker
:
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
}
Надеюсь, это будет полезно.