can anyone think of a good way to ignore the single click that comes with a double-click in Java ?
任何人都可以想到一个很好的方法来忽略在Java中双击所带来的单击?
I'm looking to have different behaviors for each such that:
我希望每个人都有不同的行为:
- single-click paints crosshairs on the click point
- double-click selects an object on the screen, but should not paint crosshairs on the click point
单击点击点击点上的十字准线
双击选择屏幕上的对象,但不应在点击点上绘制十字准线
... can anyone think of a way to do this ? Some sort of timer set-up maybe ? An ideas appreciated :-)
......谁能想到办法做到这一点?某种计时器设置可能吗?一个想法赞赏:-)
<disclaimer> ...and yes, I know I'm committing a most heinous usability / UI faux pas. </disclaimer>
<免责声明> ......是的,我知道我犯了一个最令人发指的可用性/用户界面失礼。
EDIT #2:
Even though this works the delay due to the timer is maddening - I'm abandoning this solution, and using middle-click for selection instead of double-click...
虽然这可以解决由于计时器引起的延迟 - 我正在放弃这个解决方案,并使用中键单击进行选择而不是双击...
EDIT:
Thanks cgull - this is what I was able to come up with given your confirmation that there's no easy way to do this (note that if I set the timer < 200 odd racing is seen between the click & the timer, but as long as I set this to a value > 200 things work just peachy) :
谢谢cgull - 这是我能够想出的,因为你确认没有简单的方法来做到这一点(请注意,如果我设置计时器<200奇数赛车在点击和计时器之间看到,但只要我将此值设置为> 200件工作只是peachy):
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();
}
}
4 个解决方案
#1
Indeed you'll need to set up a Timer in your overridden mouseClicked() method of your MouseAdapter to detect the time interval between the two clicks. The default interval in ms can be found by querying Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval")
. If another mouse click is detected before the timer expires, then you have a double-click, else once the timer expires, you can process the single-click.
实际上,您需要在MouseAdapter的重写mouseClicked()方法中设置一个Timer,以检测两次点击之间的时间间隔。可以通过查询Toolkit.getDefaultToolkit()。getDesktopProperty(“awt.multiClickInterval”)找到以ms为单位的默认时间间隔。如果在计时器到期之前检测到另一次鼠标单击,则双击,否则计时器到期后,您可以单击一次。
#2
Actually I think there is a simpler solution (use InputEvent's getWhen() method):
实际上我认为有一个更简单的解决方案(使用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
Have you tried implementing the MouseListener interface already?
您是否尝试过实现MouseListener接口?
I think MouseEvent has a click count method ( or property ) to know that.
我认为MouseEvent有一个点击计数方法(或属性)来知道这一点。
I bet you have gone through that already, so what is the problem you're facing there?
我敢打赌你已经经历过了,所以你面临的问题是什么?
Probably what you can do is to code the time interval elapsed between a single and a double click with a thread or something.
你可以做的就是用线程或其他东西对单次和双击之间经过的时间间隔进行编码。
So a single click will only be valid if another click is not issued in let's say 300 ms. ( something configurable )
因此,单击一次只有在没有发出300毫秒的情况下才会发出有效点击。 (可配置的东西)
The idea is:
这个想法是:
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
Or something like that.
或类似的东西。
#4
An alternative solution:
另一种解决方案:
I figured out this before I found the solution in this question. The idea is the same, use a timer, although more complicated :).
在我在这个问题中找到解决方案之前,我想出了这一点。这个想法是一样的,使用计时器,虽然更复杂:)。
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;
}
}
In mouseClicked()
method you can do something like this:
在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
}
I hope it be useful.
我希望它有用。
#1
Indeed you'll need to set up a Timer in your overridden mouseClicked() method of your MouseAdapter to detect the time interval between the two clicks. The default interval in ms can be found by querying Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval")
. If another mouse click is detected before the timer expires, then you have a double-click, else once the timer expires, you can process the single-click.
实际上,您需要在MouseAdapter的重写mouseClicked()方法中设置一个Timer,以检测两次点击之间的时间间隔。可以通过查询Toolkit.getDefaultToolkit()。getDesktopProperty(“awt.multiClickInterval”)找到以ms为单位的默认时间间隔。如果在计时器到期之前检测到另一次鼠标单击,则双击,否则计时器到期后,您可以单击一次。
#2
Actually I think there is a simpler solution (use InputEvent's getWhen() method):
实际上我认为有一个更简单的解决方案(使用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
Have you tried implementing the MouseListener interface already?
您是否尝试过实现MouseListener接口?
I think MouseEvent has a click count method ( or property ) to know that.
我认为MouseEvent有一个点击计数方法(或属性)来知道这一点。
I bet you have gone through that already, so what is the problem you're facing there?
我敢打赌你已经经历过了,所以你面临的问题是什么?
Probably what you can do is to code the time interval elapsed between a single and a double click with a thread or something.
你可以做的就是用线程或其他东西对单次和双击之间经过的时间间隔进行编码。
So a single click will only be valid if another click is not issued in let's say 300 ms. ( something configurable )
因此,单击一次只有在没有发出300毫秒的情况下才会发出有效点击。 (可配置的东西)
The idea is:
这个想法是:
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
Or something like that.
或类似的东西。
#4
An alternative solution:
另一种解决方案:
I figured out this before I found the solution in this question. The idea is the same, use a timer, although more complicated :).
在我在这个问题中找到解决方案之前,我想出了这一点。这个想法是一样的,使用计时器,虽然更复杂:)。
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;
}
}
In mouseClicked()
method you can do something like this:
在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
}
I hope it be useful.
我希望它有用。