2

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

10
  • If you want to handle both single and double clicks you can rely on the click interval (see here). Commented Apr 3, 2021 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 Commented Apr 3, 2021 at 21:11
  • Consume the click until you get the count you want: e.consume(); Commented Apr 4, 2021 at 0: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. Commented Apr 4, 2021 at 2: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? Commented Apr 5, 2021 at 21:35

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

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.