25

I'm currently developing a program in Java where a certain event must be triggered only when the user clicks with both the left and the right click on a button.

Since it is a little unconventional, I decided to first test this. Here it is:

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;

public class GUI
{
    private JFrame mainframe;
    private JButton thebutton;

    private boolean left_is_pressed;
    private boolean right_is_pressed;

    private JLabel notifier;

    public GUI ()
    {
        thebutton = new JButton ("Double Press Me");
        addListen ();
        thebutton.setBounds (20, 20, 150, 40);

        notifier = new JLabel (" ");
        notifier.setBounds (20, 100, 170, 20);

        mainframe = new JFrame ("Double Mouse Tester");
        mainframe.setDefaultCloseOperation (JFrame.DISPOSE_ON_CLOSE);
        mainframe.setResizable (false);
        mainframe.setSize (400, 250);

        mainframe.setLayout (null);

        mainframe.add (thebutton);
        mainframe.add (notifier);

        mainframe.setVisible (true);

        left_is_pressed = right_is_pressed = false;
    }

    private void addListen ()
    {
        thebutton.addMouseListener (new MouseListener ()
        {
            @Override public void mouseClicked (MouseEvent e) { }
            @Override public void mouseEntered (MouseEvent e) { }
            @Override public void mouseExited (MouseEvent e) { }

            @Override public void mousePressed (MouseEvent e)
            {
                //If left button pressed
                if (e.getButton () == MouseEvent.BUTTON1)
                {
                    //Set that it is pressed
                    left_is_pressed = true;

                    if (right_is_pressed)
                    {
                        //Write that both are pressed
                        notifier.setText ("Both pressed");
                    }

                }
                //If right button pressed
                else if (e.getButton () == MouseEvent.BUTTON3)
                {
                    //Set that it is pressed
                    right_is_pressed = true;

                    if (left_is_pressed)
                    {
                        //Write that both are pressed
                        notifier.setText ("Both pressed");
                    }
                }
            }

            @Override public void mouseReleased (MouseEvent e)
            {
                //If left button is released
                if (e.getButton () == MouseEvent.BUTTON1)
                {
                    //Set that it is not pressed
                    left_is_pressed = false;

                    //Remove notification
                    notifier.setText (" ");
                }
                //If right button is released
                else if (e.getButton () == MouseEvent.BUTTON3)
                {
                    //Set that it is not pressed
                    right_is_pressed = false;

                    //Remove notification
                    notifier.setText (" ");
                }
            }
        });
    }
}

I tested it and it works, but there is a problem.

As you can see, the left mouse button is represented by MouseEvent.BUTTON1 and the right mouse button by MouseEvent.BUTTON3.

If the user has a mouse which doesn't have a scroll wheel (apparently such mice still exist), then only two buttons are set in MouseEvent. Does that mean that the right button will be represented by MouseEvent.BUTTON2 instead of MouseEvent.BUTTON3? If yes, how can I change my code to accomodate this? Is there any way I can detect something like this?

I read anything I could find on the MouseListener interface and on MouseEvent, but I couldn't find something about this.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Radu Murzea
  • 10,724
  • 10
  • 47
  • 69

3 Answers3

33

To determine which of the Mouse buttons is pressed, these three methods from SwingUtilities could help you:

  1. isLeftMouseButton
  2. isMiddleMouseButton
  3. isRightMouseButton
mKorbel
  • 109,525
  • 20
  • 134
  • 319
  • @mKorbel hmmm nice, didn't know these methods existed. So with this I can check if the mouse has a wheel. But what about my other question ? (if there is no wheel, should I check for `MouseEvent.BUTTON2` instead of `MouseEvent.BUTTON3` ?) – Radu Murzea Jan 23 '12 at 13:36
  • I think that no then (PS2 / Server Console) mouse have got two buttons LEFT & RIGHT – mKorbel Jan 23 '12 at 15:20
  • 1
    Be aware that isMiddleMouseButton will return TRUE if the user Alt-clicks with the Left button. Also, isRightMouseButton will return TRUE if the user Ctrl-clicks with the Left button. – texclayton Jul 27 '12 at 19:58
  • @texclayton: So you're saying that the methods are pretty unusable if you need multiple buttons with modifiers... any workaround? – maaartinus Dec 19 '13 at 13:26
  • These method's implementation just checks weather or not the button mask (1<<1)(1<<2)(1<<3) anded with the mods is unequal to 0 - or basically if the getButton() method == BUTTON1/2/3 – salbeira Jan 14 '14 at 12:32
  • @salbeira Mouse can has 5 buttons, don't to use numbers as constants in Swing – mKorbel Jan 14 '14 at 12:39
  • those methods are unreliable. I had a bug because of them. When you press the right mouse button and the left mouse button together.. the left mouse button is detected as the right button!!! This is on Windows Java 8. – Mordan Aug 11 '17 at 21:32
  • @Mordan please to create an SSCCE / MCVE, ask the question with this description, add the link to this thread, answer, maybe bug, maybe feature – mKorbel Aug 12 '17 at 14:16
14

You can use the utilities methods from SwingUtilties:

SwingUtilities.isLeftMouseButton(MouseEvent anEvent)   
SwingUtilities.isRightMouseButton(MouseEvent anEvent) 
SwingUtilities.isMiddleMouseButton(MouseEvent anEvent)
Alex
  • 2,405
  • 4
  • 23
  • 36
2

There is also MouseEvent.isPopupTrigger(). This method should return true, if the right mouse button is pressed.

henrik
  • 708
  • 7
  • 14
  • 1
    The only downside to this is that release events return false for this function, so it's not valid in that context. – tay10r Mar 02 '20 at 20:24