1

Consider a javax.swing.JPanel with the following as its MouseListener

new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                var count = e.getClickCount();
                switch (count) {
                    case 1 -> Helper.sop("single count");
                    case 2 -> Helper.sop("double  count");
                    default -> Helper.sop("more than double count %d".formatted(count));
                }
            }
        }

Upon double-clicking, I am getting the following puzzling output

single count
double  count

instead of the expected

double  count

Apparently, during a double click, a single click precedes the said double click. Why is this so?


rough.java


import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.UUID;

public class rough {


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


        //Helper.sop=System.out.println
        //Helper.launch=launch a JPanel in a JFrame (new,pack,EXIT_ON_CLOSE,<Screen_Size,UUIDTitle,SystemLAF,EDTThread)

        JPanel pn = new JPanel();
        pn.setPreferredSize(new Dimension(500, 500));

        ///////////////////THIS IS ALL THAT MATTERS HERE//////////////////////
        pn.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
                super.mouseClicked(e);
                var count = e.getClickCount();

                switch (count) {
                    case 1 -> Helper.sop("single count");
                    case 2 -> Helper.sop("double  count");
                    default -> Helper.sop("more than double count %d".formatted(count));
                }

            }
        });
        /////////////////////////////////////////////////////////////////////


        Helper.launch(pn);


    }


    private static class Helper {

        static public int frameNo = 0;

        public static void sop(Object o) {

            System.out.println(o);
        }

        public static void launch(JPanel pnMain, String frameTitle, String lafClassName) {

            try {
                UIManager.setLookAndFeel(lafClassName);
                f.sop("set laf to " + lafClassName);
            } catch (Exception e) {
                System.err.println("err: couldn't apply laf");
            }

            final var screenSize = Toolkit.getDefaultToolkit().getScreenSize();
            final var pnSize = pnMain.getPreferredSize();


            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {

                    JFrame frame = new JFrame(frameTitle);

                    if (pnSize.width > screenSize.width || pnSize.getHeight() > screenSize.getHeight())
                        frame.setPreferredSize(new Dimension((int) (screenSize.width * 0.75), (int) (0.75 * screenSize.height)));


                    frame.setContentPane(pnMain);
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.pack();
                    frame.setVisible(true);

                }
            });

        }

        public static void launch(JPanel pnMain, String frameTitle) {

            launch(pnMain, frameTitle, UIManager.getSystemLookAndFeelClassName());

        }


        public static void launch(JPanel pnMain) {

            String title = "Frame no: " + ++frameNo + "\t (" + UUID.randomUUID() + ")";
            launch(pnMain, title);

        }


    }

}

Env:
openjdk 15.0.2 2021-01-19
OpenJDK Runtime Environment (build 15.0.2+7-27)
OpenJDK 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)
Windows 10

lineage
  • 792
  • 1
  • 8
  • 20
  • If you want to handle both single and double clicks you can rely on the *click interval* (see [here](https://stackoverflow.com/a/4577475)). – gthanop Apr 03 '21 at 21:06
  • @gthanop I am just surprised that the age-old click counting check actually fires a single click too! This is regardless of how fast one does it...I do know about using timeout...thought this would work fine – lineage Apr 03 '21 at 21:11
  • Consume the click until you get the count you want: `e.consume();` – DevilsHnd - 退職した Apr 04 '21 at 00:56
  • 1
    *Apparently, during a double click, a single click precedes the said double click* - this is normal and expected behaviour. Typically you use the single click to "select" something and then double click to "process" something. For example when you edit your question. If you single click the caret moves. If you double click the caret moves AND the word is selected. This is because the first click moves the caret and the double click selects the word. The normal issue is that you get two single clicks instead of a single and double, because you don't click fast enough or the mouse moves. – camickr Apr 04 '21 at 02:01
  • @camickr so, and maybe this is not java specific, the events generated by the API for an *n-click* are n 1-clicks as they occur (with an updated click count) rather than a single 1-click after click count reaches n .... is this correct? – lineage Apr 05 '21 at 21:35
  • @gthanop I do wish to detect both single and double clicks. Any API builtins to differentiate? – lineage Apr 05 '21 at 21:38
  • @DevilsHnd this won't work to differentiate between a single click and an ongoing double click, would it? – lineage Apr 05 '21 at 21:39
  • @lineage Not understanding your question. If you click slowly you will get multiple single clicks. If you click fast (within the multiClickInverval) you will get a single click and a double click. If you really click fast you could get a single, double, triple click as determined by the click count. As I stated in my answer you would generally have code to handle both the single and double click. You can't generate a double click without a single click. This is standard processing on all OS. – camickr Apr 06 '21 at 00:09
  • @lineage I am not currently aware of any builtins to differentiate when the user intends to perform double click and you don't want the single click first. But you can follow the link I gave you in my first comment and see an implementation of just that behaviour. – gthanop Apr 06 '21 at 08:52
  • @camickr thnx..your original comment clarified my doubt..i'll accept if you post. – lineage Apr 06 '21 at 16:04

1 Answers1

0

Apparently, during a double click, a single click precedes the said double click

This is normal and expected behaviour.

The OS defines the "click interval". If you click multiple times within the interval the click count will increase.

If you click slowly you will get multiple single clicks.

If you click fast, within the "click interval", you will get a single click and a double click.

If you really click fast you could get a single, double and triple click as determined by the click count.

Typically you use the:

  1. single click to "select" something and
  2. the double click to "process" something.

Think a list of files in Windows explorer. A single click will select the item. A double click will do something with the selected item. If it is a text file it will open it in the default editor. If it is a .mp3 file it will play the song in the default music player.

camickr
  • 321,443
  • 19
  • 166
  • 288