0

good day!

I'm making an attendance-checking program that displays an orange button when clicked once, red button, for two clicks and black button for 3. I'm having problem as to how to accumulate getClickCount() values, because for the buttons to register 3 clicks, the buttons have to be clicked at 3 times quickly.

Here's the code

        button1.addMouseListener(new MouseAdapter(){
            public void mousePressed(MouseEvent a){

                if (a.getClickCount() == 1){
                button1.setBackground(Color.ORANGE);
                }

                else if (a.getClickCount() == 2){
                button1.setBackground(Color.RED);
                }

                else if (a.getClickCount() == 3){
                button1.setBackground(Color.BLACK);
                }
            }

        });

        frame.setVisible(true); 
        frame.pack();

    }
}
Aly
  • 3
  • 4
  • 2
    `MouseListener` is not a good choice for buttons. Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This will result in less confusion and better responses – MadProgrammer Nov 18 '14 at 23:24
  • I just ran your code and seems to work OK (not great). However, what you need to do is to make your `MouseListener` a class that every single button can use (you don't want to create multiple, identical, anonymous listeners that do the same thing). Then add independent instances of the listener to each button. – hfontanez Nov 18 '14 at 23:45
  • You should definitely create a method `createButton` which gets an `int` as parameter and returns the new subpanel with the button on it. You've currently copied that code 12 times. Also, please read this: [DRY](http://en.wikipedia.org/wiki/Don%27t_repeat_yourself). – Tom Nov 19 '14 at 00:07

2 Answers2

1

If I understand correctly, basically you want to change the color each time the button is pressed, based on the number of times the button has previously been pressed.

MouseListener is not a good choice for JButton, as buttons can be activated by the keyboard (via short cuts or focus activity) and programically, none of which the MouseListener will detect.

Instead, you should use a ActionListener

This example will change the color each time the button is clicked. I've used an array of Colors to make life simpler, but the general concept should work for if-else statements, you just need to reset the counter when it reaches its limit

Clicker

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class ButtonClicker {

    public static void main(String[] args) {
        new ButtonClicker();
    }

    public ButtonClicker() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public static class TestPane extends JPanel {

        private static final Color[] COLORS = new Color[]{Color.ORANGE, Color.RED, Color.BLACK};
        private int clickCount;

        public TestPane() {

            setLayout(new GridBagLayout());
            JButton clicker = new JButton("Color Changer");
            clicker.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    clickCount++;
                    setBackground(COLORS[Math.abs(clickCount % COLORS.length)]);
                }
            });
            setBackground(COLORS[clickCount]);
            add(clicker);

        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

    }

}

Take a look at How to Use Buttons, Check Boxes, and Radio Buttons and How to Write an Action Listeners for more details

MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • I'd do `clickCount = (clickCount + 1) % COLORS.length;`, y'know just in case. – Radiodef Nov 19 '14 at 00:47
  • @Radiodef Why? The array is 0 indexed? Or should it be `COLORS.length - 1`? – MadProgrammer Nov 19 '14 at 00:48
  • To prevent overflow, I mean. – Radiodef Nov 19 '14 at 00:49
  • 1
    If the user clicks the button enough times (say, they are using an auto-clicker), it will eventually wrap to `Integer.MIN_VALUE`. It will throw an exception since Java's modulo can yield a negative result. (Doesn't really matter for an MCVE.) – Radiodef Nov 19 '14 at 00:53
  • @Radiodef Wouldn't something like `Math.abs(clickCount % COLORS.length)` be more appropriate? I did try `Integer.MIN_VALUE % 3` and it gave `-2` and `((Integer.MIN_VALUE + 1) % 3)` just gives `-1` ;) – MadProgrammer Nov 19 '14 at 01:03
  • Sure, technically you could also do that. – Radiodef Nov 19 '14 at 01:09
0

Step 1: Create your own MouseListener class. In this case, I chose to create an external class that extends MouseAdapter.

public class MyMouseListener extends MouseAdapter
{
    public void mousePressed(MouseEvent event)
    {
        Object obj = event.getSource();
        if (obj instanceof JButton)
        {
            if JButton btn = (JButton)obj;

            if (a.getClickCount() == 1)
            {
                btn.setBackground(Color.ORANGE);
            }

            else if (a.getClickCount() == 2)
            {
                btn.setBackground(Color.RED);
            }

            else if (a.getClickCount() == 3)
            {
                btn.setBackground(Color.BLACK);
            }
        }
    }
}

Step 2: Add independent instances of this listener to each button

    button1.addMouseListener(new MyMouseListener());
    button2.addMouseListener(new MyMouseListener());
    button3.addMouseListener(new MyMouseListener());
    button4.addMouseListener(new MyMouseListener());
    button5.addMouseListener(new MyMouseListener());
    button6.addMouseListener(new MyMouseListener());
    button7.addMouseListener(new MyMouseListener());
    button8.addMouseListener(new MyMouseListener());
    button9.addMouseListener(new MyMouseListener());
    button10.addMouseListener(new MyMouseListener());
    button11.addMouseListener(new MyMouseListener());
    button12.addMouseListener(new MyMouseListener());

That should work for you. However, as I mentioned, this works OK, but not great.

hfontanez
  • 5,774
  • 2
  • 25
  • 37