Java: ¿ignorar un solo clic con doble clic?
events click (4)
¿Alguien puede pensar en una buena forma de ignorar el solo clic que viene con un doble clic en Java?
Estoy buscando tener diferentes comportamientos para cada uno de los siguientes:
- un solo clic pinta puntos de mira en el punto de clic
- hacer doble clic selecciona un objeto en la pantalla, pero no debe pintar puntos de mira en el punto de clic
... ¿alguien puede pensar en una forma de hacer esto? Algún tipo de configuración de temporizador tal vez? Una idea apreciada :-)
<descargo de responsabilidad> ... y sí, sé que estoy cometiendo un faux pas de usabilidad / UI más atroz. </ disclaimer>
EDIT # 2:
Aunque esto funciona, la demora debida al temporizador es enloquecedora. Estoy abandonando esta solución y haciendo clic con el botón central para seleccionar en lugar de hacer doble clic ...
EDITAR:
Gracias cgull : esto es lo que pude obtener dada su confirmación de que no hay una manera fácil de hacerlo (tenga en cuenta que si configuro el temporizador <200 carreras impares se ve entre el clic y el temporizador, pero siempre y cuando establezca esto en un valor> 200 cosas que funcionen solo amelocotonado):
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();
}
}
¿Ya has intentado implementar la interfaz MouseListener?
Creo que MouseEvent tiene un método de recuento de clics (o propiedad) para saberlo.
Apuesto a que ya has pasado por eso, ¿cuál es el problema que estás enfrentando allí?
Probablemente lo que puede hacer es codificar el intervalo de tiempo transcurrido entre un simple y doble clic con un hilo o algo.
Por lo tanto, un solo clic solo será válido si no se emite otro clic, digamos 300 ms. (algo configurable)
La idea es:
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
O algo así.
De hecho, necesitará configurar un temporizador en su método reemplazado por mouse () sobre mouseAdapter para detectar el intervalo de tiempo entre los dos clics. El intervalo predeterminado en ms se puede encontrar mediante la consulta de Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval")
. Si se detecta otro clic en el mouse antes de que el temporizador expire, entonces tiene un doble clic, de lo contrario, una vez que el temporizador caduque, puede procesar el solo clic.
Una solución alternativa:
Descubrí esto antes de encontrar la solución en esta pregunta. La idea es la misma, usa un temporizador, aunque es más complicado :).
Use 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;
}
}
En el método mouseClicked()
puedes hacer algo como esto:
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
}
Espero que sea útil.
En realidad, creo que hay una solución más simple (use el método getWhen () de 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();
}
}
}