4

I have a JTable in which I want to call a function when a cell is double-clicked and call another function when the cell is triple-clicked.

When the cell is triple-clicked I do not want to call the double-click-function.

What I have right now is (mgrdAlarm is the JTable) :

mgrdAlarm.addMouseListener(new MouseAdapter()
{
  public void mouseClicked(MouseEvent e)
  {
    System.out.println("getClickCount() = " + e.getClickCount());
    if (e.getClickCount()==2)
    {
      doubleClick();
      System.out.println("Completed : doubleClick()");
    }
    if (e.getClickCount()==3)
    {
      tripleClick();
      System.out.println("Completed : tripleClick()");
    }
  }
});

When double-clicked the console shows :

getClickCount() = 1
getClickCount() = 2
Completed : doubleClick()

When triple-clicked the console shows :

getClickCount() = 1
getClickCount() = 2
Completed : doubleClick()
getClickCount() = 3
Completed : tripleClick()

When triple-clicked I want the console to show :

getClickCount() = 1
getClickCount() = 2
getClickCount() = 3
Completed : tripleClick()

So I do not want to call the function doubleClick() when the cell is triple-clicked, but I do want to call the function doubleClick() when the cell is double-clicked.

[EDIT]

As all replies suggest the solution seems to be to delay the double-click-action and wait a certain time for the triple-click.

But as discussed here that might lead to a different type of problem : The user might have set his double-click-time quite long, which might overlap with the timeout of my triple-click.

It is no real disaster if my double-click-action is executed before my triple-click-action, but it does generate some extra overhead, and especially some extra data traffic which I would like to prevent.

As the only solution so far might lead to other problems, which might actually be worse than the original problem, I will leave it as it is right now.

5
  • Hmm... delay the execution? Commented Jan 16, 2013 at 7:52
  • 2
    A rather interesting topic, yet not (so) simple to solve. You might want to start reading stackoverflow.com/questions/1067464/… . Single and double clicking provide the same problem. You will need to implement a bit of time tracking in your code. Commented Jan 16, 2013 at 7:54
  • What about implement custom EventQueue and detect one, two or triple click here? Commented Mar 24, 2013 at 11:10
  • @KMaertens thanks for your answer. It seemed the way to go, but after reading another topic I think that might cause extra problems. See my edit to my post. Commented Mar 25, 2013 at 8:07
  • @LadislavDANKO Sorry, I am not that experienced in Java yet. What exactly do you mean, and how would I do that? Commented Mar 25, 2013 at 8:12

7 Answers 7

4
  public class TestMouseListener implements MouseListener {    
  private boolean leftClick;
  private int clickCount;
  private boolean doubleClick;
  private boolean tripleClick;
  public void mouseClicked(MouseEvent evt) {
    if (evt.getButton()==MouseEvent.BUTTON1){
                leftClick = true; clickCount = 0;
                if(evt.getClickCount() == 2) doubleClick=true;
                if(evt.getClickCount() == 3){
                    doubleClick = false;
                    tripleClick = true;
                }
                Integer timerinterval = (Integer)Toolkit.getDefaultToolkit().getDesktopProperty("awt.multiClickInterval");

                         Timer  timer = new Timer(timerinterval, new ActionListener() {
                            public void actionPerformed(ActionEvent evt) { 

                                if(doubleClick){
                                    System.out.println("double click.");                                    
                                    clickCount++;
                                    if(clickCount == 2){
                                        doubleClick();   //your doubleClick method
                                        clickCount=0;
                                        doubleClick = false;
                                        leftClick = false;
                                    }

                                }else if (tripleClick) { 

                                    System.out.println("Triple Click.");
                                    clickCount++;
                                    if(clickCount == 3) {
                                       tripleClick();  //your tripleClick method
                                        clickCount=0;
                                        tripleClick = false;
                                        leftClick = false;
                                    }

                                } else if(leftClick) {                                      
                                    System.out.println("single click.");
                                    leftClick = false;
                                }
                            }               
                        });
                        timer.setRepeats(false);
                        timer.start();
                        if(evt.getID()==MouseEvent.MOUSE_RELEASED) timer.stop();
            }           
      }


          public static void main(String[] argv) throws Exception {

            JTextField component = new JTextField();
            component.addMouseListener(new TestMouseListener());
            JFrame f = new JFrame();

            f.add(component);
            f.setSize(300, 300);
            f.setVisible(true);

            component.addMouseListener(new TestMouseListener());
          }
   }
Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for your answer. It seems the same as the other answer suggest? Which has the same problem as I don't know the configured double click time of the user..
2

The previous answers are correct: you have to account for the timing and delay recognizing it as a double click until a certain amount of time has passed. The challenge is that, as you have noticed, the user could have a very long or very short double click threshold. So you need to know what the user's setting is. This other Stack Overflow thread ( Distinguish between a single click and a double click in Java ) mentions the awt.multiClickInterval desktop property. Try using that for your threshold.

Comments

1

You can do something like that, varying delay time:

public class ClickForm extends JFrame {

final static long CLICK_FREQUENTY = 300;

static class ClickProcessor implements Runnable {

    Callable<Void> eventProcessor;

    ClickProcessor(Callable<Void> eventProcessor) {
        this.eventProcessor = eventProcessor;
    }

    @Override
    public void run() {
        try {
            Thread.sleep(CLICK_FREQUENTY);
            eventProcessor.call();
        } catch (InterruptedException e) {
            // do nothing
        } catch (Exception e) {
            // do logging
        }
    }
}

public static void main(String[] args) {
    ClickForm f = new ClickForm();
    f.setSize(400, 300);
    f.addMouseListener(new MouseAdapter() {
        Thread cp = null;
        public void mouseClicked(MouseEvent e) {
            System.out.println("getClickCount() = " + e.getClickCount() + ", e: " + e.toString());

            if (cp != null && cp.isAlive()) cp.interrupt();

            if (e.getClickCount() == 2) {
                cp = new Thread(new ClickProcessor(new Callable<Void>() {
                    @Override
                    public Void call() throws Exception {
                        System.out.println("Double click processed");
                        return null;
                    }
                }));
                cp.start();
            }
            if (e.getClickCount() == 3) {
                cp =  new Thread(new ClickProcessor(new Callable<Void>() {
                    @Override
                    public Void call() throws Exception {
                        System.out.println("Triple click processed");
                        return null;
                    }
                }));
                cp.start();
            }
        }
    });
    f.setVisible(true);
}
}

1 Comment

thanks for your answer. It seemed the way to go, but after reading another topic I think that might cause extra problems. See my edit to my post.
0

You need to delay the execution of double click to check if its a tripple click.

Hint.

if getClickCount()==2 then put it to wait.. for say like 200ms?

1 Comment

thanks for your answer. It seemed the way to go, but after reading another topic I think that might cause extra problems. See my edit to my post.
0

It's exactly the same problem as detecting double-click without firing single click. You have to delay firing an event until you're sure there isn't a following click.

2 Comments

I had same problem here
@EJP thanks for your answer. It seemed the way to go, but after reading another topic I think that might cause extra problems. See my edit to my post.
0

There's a tutorial for this here

Edit: It fires click events individually though, so you would get: Single Click THEN Double Click THEN Triple Click. So you would still have to do some timing trickery.

The code is:

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.JFrame;
import javax.swing.JTextField;

public class Main {
  public static void main(String[] argv) throws Exception {

    JTextField component = new JTextField();
    component.addMouseListener(new MyMouseListener());
    JFrame f = new JFrame();

    f.add(component);
    f.setSize(300, 300);
    f.setVisible(true);

    component.addMouseListener(new MyMouseListener());
  }
}

class MyMouseListener extends MouseAdapter {
  public void mouseClicked(MouseEvent evt) {
    if (evt.getClickCount() == 3) {
      System.out.println("triple-click");
    } else if (evt.getClickCount() == 2) {
      System.out.println("double-click");
    }
  }
}

3 Comments

thanks for the answer ... detecting the clicks isnt that hard, detecting just a double click or a triple click (without firing the lesser-click events) is the issue ... timing trickery might work, but is trickery .. for the time being i made it so that the lesser-click events do fire, but have no drastic negative effect (other than some extra data traffic)
Yeah. One of the most mainstream triple click events is in text editors to select a line. They fire single, and double click events before executing the triple click code, too.
thats true ... my double click though fires an event which send some data to a device which might be heavy loaded already .. so i would want to send as little as possible (the triple click sends other data) .. but so far its working and not crashing (yet :))
0

Here is what i have done to achieve this, this actually worked fine for me. A delay is necessary to detect the type of click. You can choose it. The following delays if a triple click can be happened within 400ms. You can decrease it to the extent till a consecutive click is not possible. If you are only worrying about the delay, then this is a highly negligible delay which must be essential to carry this out.

Here flag and t1 are global variables.

public void mouseClicked(MouseEvent e)
{
int count=e.getClickCount();
                    if(count==3)
                    {
                        flag=true;
                        System.out.println("Triple click");
                    }
                    else if(count==2)
                    {
                        try
                        {
                        t1=new Timer(1,new ActionListener(){
                            public void actionPerformed(ActionEvent ae)
                            {
                                if(!flag)
                                System.out.println("Double click");
                                flag=false;
                                t1.stop();
                            }
                        });
                        t1.setInitialDelay(400);
                        t1.start();
                        }catch(Exception ex){}
                    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.