Question

I am making a jFrame that represents a go board. I want a click of a given button to change the color to represent placing a piece on the board. In my code below, I show a method that should be able to change the color of a button (it only changes the background of the whole frame). First question: Why is the button color not changing (this is not my bigger problem about changing color after click occurs, my preliminary issue is that the button color will not change). I do not get any errors, the button color just never changes.

public static void showBoard()
{
    JFrame frame2 = new JFrame("Go Board");
    frame2.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    for(int i = 19*19; i > 0; i--)
    {
      JButton firstButton = new JButton("");

      firstButton.setBackground(Color.blue);
      firstButton.setVisible(true);
      firstButton.setContentAreaFilled(true);
      firstButton.setOpaque(true);

      firstButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e)
        {
          javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() 
            {
              System.out.println("ddsd");
              //int[] arr = findMove(0);
            }
          });
        }
      });
      frame2.getContentPane().add(firstButton);
    }
    frame2.setComponentOrientation(ComponentOrientation.LEFT_TO_RIGHT);
    frame2.setLayout(new GridLayout(19,19));
    frame2.pack();
    frame2.setVisible(true);
}

My second problem, getting the button to change color after being clicked, is presumably affected by the fact that I am not able to even change the button color. To get the button to change color after a click, I plan to put the button color change code inside the action listener.

So in summation, how can I change the color of the button after a click?

ANSWER:

The problem was the look and feel of my mac. Look to the checked answer for how to fix this if you have similar problem on your mac.

Was it helpful?

Solution

You don't need to call SwingUtilities.invokeLater inside your ActionListener, as the actionPerformed(ActionEvent) method will be invoked on the Event Thread already.

The following example demonstrates how to change a Button's background color when it's clicked on:

public class ChangeButtonColor implements Runnable {
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(new javax.swing.plaf.metal.MetalLookAndFeel());
        } catch (UnsupportedLookAndFeelException e) {
            System.err.println("Cannot set LookAndFeel");
        }
        SwingUtilities.invokeLater(new ChangeButtonColor());
    }

    @Override
    public void run() {
        JFrame frame = new JFrame();
        frame.setLayout(new FlowLayout());

        JButton button1 = new JButton("click me");
        JButton button2 = new JButton("click me too");
        ActionListener listener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Object source = e.getSource();
                if (source instanceof Component) {
                    ((Component)source).setBackground(Color.RED);
                }
            }
        };
        button1.addActionListener(listener);
        button2.addActionListener(listener);

        frame.add(button1);
        frame.add(button2);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
}

Please note that the ActionListener used here can be used for all buttons. There is no need to create a new instance of it for every button.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top