Arindam Arindam - 1 month ago 6
Java Question

Clicking on one button calls the actionListener of another button in JAVA Swing

I just started learning JAVA and Swing.
So, after reading from a book, I ran this code.
What it does it, there's a button for changing the color of a circle and a button for changing the text on a label. But when I click on the button made for changing the text of the label (for the 1st time), it changes the color of the circle too. Doesn't happen after the 1st time.
So, what can I do to avoid this problem and if you can explain why is it happening?
Here is the code:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

class DrawPanel extends JPanel
{
public void paintComponent(Graphics g)
{
Graphics2D g2D = (Graphics2D) g;
int red = (int)(Math.random() * 255);
int green = (int)(Math.random() * 255);
int blue = (int)(Math.random() * 255);
Color start = new Color(red, green, blue);

red = (int)(Math.random() * 255);
green = (int)(Math.random() * 255);
blue = (int)(Math.random() * 255);
Color end = new Color(red, green, blue);

GradientPaint gradient = new GradientPaint(60, 60, start, 170, 170, end);

g2D.setPaint(gradient);
g2D.fillOval(70, 70, 100, 100);
}
}

class TwoButton
{
private DrawPanel dp;
private JFrame frame;
private JLabel label;

public static void main(String[] args)
{
TwoButton gui = new TwoButton();
gui.go();
}
private void go()
{
frame = new JFrame();
label = new JLabel("I'm a label");
dp = new DrawPanel();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JButton colorButton = new JButton("Change color");
JButton labelButton = new JButton("Change label");
colorButton.addActionListener(new ColorListener());
labelButton.addActionListener(new LabelListener());

frame.setSize(400, 400);
frame.setVisible(true);
frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
frame.getContentPane().add(BorderLayout.CENTER, dp);
frame.getContentPane().add(BorderLayout.EAST, labelButton);
frame.getContentPane().add(BorderLayout.WEST, label);

}
class ColorListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
frame.repaint();
}
}
class LabelListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
label.setText("Good Job!");
}
}
}

Answer

This happens because setText eventually calls paintComponent, which changes the color to a random color. This happens because the text cannot be changed without redrawing the graphics, which is going to include calling paintComponent as that is the method used to draw the graphics.

But his only happens when the text is actually changed, so the second time you click the button nothing will happen, since you are not actually changing the text - it will still be "Good Job!".

So, basically the button does not call the action listener of the other button, but both action listeners eventually call paintComponent (at least on the first click, when the text of the label is actually changed).

If you want to fix this, move the part where color is randomized into the action listener and out of the paintComponent method.