but why swing does not paint my component? - java

I have a working version of the simplest java gui with a button and a circle which works fine:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
//a gui element shares its events only with classes that implement Actionlistener interface
public class SimpleGui1 implements ActionListener {
JButton button;
JFrame frame;
ppanel mypanel;
public static void main (String[] args) {
SimpleGui1 mywindow = new SimpleGui1();
mywindow.renderWindow();
}
public void renderWindow(){
frame = new JFrame();
button = new JButton("click me");
mypanel = new ppanel();
//register my interest to catch button events
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, mypanel);
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
//button will call this method when clicked (its the callback)
public void actionPerformed(ActionEvent event)
{
frame.repaint();
button.setText("Clicked!!");
}
}
//i need this to override paintComponent
public class ppanel extends JPanel {
//draw something silly
public void paintComponent(Graphics g) {
//super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70,70,startColor, 150,150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70,70,100,100);
}
}
And then, just for fun, i tried to aggregate the two classes to one like this:
public class SimpleGui1 extends JPanel implements ActionListener {
private JButton button;
private JFrame frame;
private JPanel mypanel;
public static void main (String[] args) {
SimpleGui1 mywindow = new SimpleGui1();
mywindow.renderWindow();
}
public void renderWindow(){
frame = new JFrame();
button = new JButton("click me");
mypanel = new JPanel();
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
// register my interest to catch button events
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, mypanel);
//without this i see only the button
//frame.add(this);
}
//button will call this method when clicked (its the callback)
public void actionPerformed(ActionEvent event)
{
frame.repaint();
button.setText("Clicked!!");
}
public void paintComponent(Graphics g) {
//super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70,70,startColor, 150,150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70,70,100,100);
}
}
The new class compiles successfully but at run time it draws only the button. For some reason paintComponent is not called and the only way to work correctly is to add the following in renderwindow():
frame.add(this);
my question is why this behaviour ... why do i have to add explicitly
the object to my frame for this version to work properly?
Tried repaint() and validate() almost everywhere. Does not change much
Also i know that i shouldnt be drawing things off EDT and a version with inner classes also alleviates the problem

Indeed, you have to explicitly add the this object to the content pane. I compiled and tested the following:
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
//a gui element shares its events only with classes that implement Actionlistener interface
public class SimpleGui1 extends JPanel implements ActionListener {
JButton button;
JFrame frame;
ppanel mypanel;
public void paintComponent(Graphics g)
{
//super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70,70,startColor, 150,150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70,70,100,100);
}
public static void main (String[] args) {
SimpleGui1 mywindow = new SimpleGui1();
mywindow.renderWindow();
}
public void renderWindow(){
frame = new JFrame();
button = new JButton("click me");
//register my interest to catch button events
button.addActionListener(this);
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, this);
frame.setSize(300,300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
//button will call this method when clicked (its the callback)
public void actionPerformed(ActionEvent event)
{
frame.repaint();
button.setText("Clicked!!");
}
}
You need to explicitly add the components in order for this to be painted, it doesn't matter that the component is the object itself!

It's likely that this is your problem:
public void renderWindow(){
//where everything is the same except ofcourse:
mypanel = new JPanel();
}
Because the mypanel is of type JPanel you are adding a generic panel to the frame and not the object with your overrides.
Try:
public void renderWindow(){
//where everything is the same except ofcourse:
mypanel = new SimpleGui1(); // or possibly 'this'
}
This way your SimpleGui1 class will be added to the frame and can participate in the Swing message queue.
To answer your question about 'why', it is because when you attach a panel to the frame the panel has to have the code to handle messages and overrides. When you include a JPanel object you don't get any of the custom behavior. To tell the frame that it should send messages to your class you have to tell the frame about, essentially registering it with the frame.

Related

Minimizing/Maximizing java swing gui executes actionPerformed method

So I'm a complete beginner in Java swing gui. I am going through Head First Java as the starting book. I made a simple gui in which a button is there and pressing it creates different gradient on a circle above it. The code is all in the book. It works fine when i click the button. However, when i maximize/minimize the gui, it acts as if the button is pressed and gradient changes. Why does this happen?
GUI code:
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class SimpleGuiC implements ActionListener {
JFrame frame;
public static void main(String[] args) {
SimpleGuiC gui=new SimpleGuiC();
gui.go();
}
public void go(){
frame=new JFrame();
frame.setTitle("Gradient changer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button=new JButton("Change colors");
button.addActionListener(this);
MyDrawPanel drawPanel=new MyDrawPanel();
frame.getContentPane().add(BorderLayout.SOUTH,button);
frame.getContentPane().add(BorderLayout.CENTER,drawPanel);
frame.setSize(300,300);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
frame.repaint();
}
}
Random gradient generating code:
import java.awt.*;
import javax.swing.*;
public class MyDrawPanel 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 startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70,70,startColor, 150,150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70,70,100,100);
}
}
Here's the implementation suggested in my comments:
public final class MyDrawPanel extends JPanel {
private Color startColor;
private Color endColor;
public MyDrawPanel() {
this.changeColors();
}
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
GradientPaint gradient = new GradientPaint(70, 70, startColor, 150, 150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70, 70, 100, 100);
}
public void changeColors() {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
this.startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
this.endColor = new Color(red, green, blue);
this.repaint();
}
}
As you can see, the panel has a state (i.e. fields), containing the colors that the circle must have. These colors don't change in paintComponent(). They only change when the changeColors() method is called.
public class SimpleGuiC implements ActionListener {
private JFrame frame;
private MyDrawPanel drawPanel;
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
SimpleGuiC gui = new SimpleGuiC();
gui.go();
});
}
public void go() {
frame = new JFrame();
frame.setTitle("Gradient changer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Change colors");
button.addActionListener(this);
this.drawPanel = new MyDrawPanel();
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.setSize(300, 300);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
this.drawPanel.changeColors();
}
}
And, as you can see here, the actionPerformed() method changes the state of the panel (i.e. the colors it must display). It does what the button says it does: change the colors. Each time the panel is repainted, it will always use the colors that were set the last time changeColors() has been called.
People in the comments told you why it happens. All you now have to do is create a boolean that will tell if it was pressed or not and then check.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class SimpleGuiC implements ActionListener {
JFrame frame;
MyDrawPanel drawPanel;
public static void main(String[] args) {
SimpleGuiC gui=new SimpleGuiC();
gui.go();
}
public void go(){
frame=new JFrame();
frame.setTitle("Gradient changer");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button=new JButton("Change colors");
button.addActionListener(this);
drawPanel = new MyDrawPanel();
frame.getContentPane().add(BorderLayout.SOUTH,button);
frame.getContentPane().add(BorderLayout.CENTER,drawPanel);
frame.setSize(300,300);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
drawPanel.buttonPressed = true;
frame.repaint();
}
}
DrawPanel:
import java.awt.*;
import javax.swing.*;
public class MyDrawPanel extends JPanel{
public boolean buttonPressed = false;
private GradientPaint gradient;
public MyDrawPanel () {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
gradient = new GradientPaint(70, 70, startColor, 150, 150, endColor);
}
public void paintComponent(Graphics g) {
if (buttonPressed) {
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
gradient = new GradientPaint(70, 70, startColor, 150, 150, endColor);
buttonPressed = false;
}
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(gradient);
g2d.fillOval(70, 70, 100, 100);
}
}
Basically what this does is every time the button is pressed, the boolean will be set to true. Then when repainting, it will check if it's true and if yes, it will paint it and set it back to false so it can go again. Good Luck!
EDIT:
To make it not disappear. You need to separate the code for changing the gradient and for painting. So, paint every single time, but only change the gradient when the button is pressed. I hope this code I just updated will work.
EDIT 2:
Don't forget to encapsulate that variable, I didn't because I was in hurry, but just make it private and add getters and setters!

JAVA swing gui window gets jarred after repaint method is run

I'm beginning to learn Java Swing. I was trying to create a GUI in which there are 2 buttons, changeColor on the bottom and changeLabel on right. It has a label on right and at the center a JPanel which shows a gradient colored oval.
When I click on changeLabel, it works fine and changes the label on left. But when I click on changeColor, a new oval appears and the whole layout breaks, with some new panels superimposing. I am following a book in which the same thing is given, but it uses random color generation in the paintComponent method, which I learned from here, isn't a good thing to do. That method works fine, but I tried to avoid that and make a separate method. This is not working though.
GUI class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TwoButtons {
public JFrame frame;
private JLabel label;
private MyDrawPanel panel;
private boolean clicked = false;
public static void main(String[] args) {
TwoButtons gui = new TwoButtons();
gui.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton labelButton = new JButton("Change Label");
labelButton.addActionListener(new LabelListener());
JButton colorButton = new JButton("Change color");
colorButton.addActionListener(new ColorListener());
label = new JLabel("I'm a label");
panel = new MyDrawPanel();
frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
frame.getContentPane().add(BorderLayout.CENTER, panel);
frame.getContentPane().add(BorderLayout.EAST, labelButton);
frame.getContentPane().add(BorderLayout.WEST, label);
frame.setSize(300, 300);
frame.setVisible(true);
}
class LabelListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
if (!clicked) {
label.setText("Ouch!! (Click again to revert)");
clicked = true;
} else {
clicked = false;
label.setText("Change Label");
}
}
}
class ColorListener implements ActionListener {
#Override//
public void actionPerformed(ActionEvent e) {
//frame.repaint();
panel.changeColors();
}
}
}
Coloring class:
import javax.swing.*;
import java.awt.*;
public class MyDrawPanel extends JPanel{
private Color startColor,endColor;
public MyDrawPanel(){
this.changeColors();
}
public void paintComponent(Graphics g){
Graphics2D g2D=(Graphics2D)g;
GradientPaint gradient=new GradientPaint(70,70,startColor,150,150,endColor);
g2D.setPaint(gradient);
g2D.fillOval(70,70,100,100);
}
public void changeColors(){
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
endColor = new Color(red, green, blue);
this.repaint();
}
}
Before clicking change color
After clicking on change color
To avoid rendering artifacts:
public void paintComponent(Graphics g){ ..
Should be:
public void paintComponent(Graphics g){
super.paintComponent(g); ..
By calling the super method, it will automatically repaint the background and borders etc., thus erasing the earlier drawing.

Why the subclass "TwoButtons" of JPanel didn't display on screen

It's my first post on StackOverflow. I'm a beginner in Java and I'm reading Head First Java recently. I have searched google for many times but I still can't find an answer to fix my doubt.
On chapter 12, I copy the code to Eclipse. My codes are executable, but after I click the button to change color of the circle, there's no any circle showed on the window. And another class "SimpleAnimation" has the same problem too. There is no any circle on the window. It has bothered me for two days. Please help this poor kid(TAT). Thanks!
Run TwoButtons
Here are the codes.
This is class TwoButtons:
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class TwoButtons {
JFrame frame;
JLabel label;
public static void main(String[] args) {
TwoButtons gui = new TwoButtons();
gui.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton labelButton = new JButton("Change label");
labelButton.addActionListener(new LabelListener());
JButton colorButton = new JButton("Change circle");
colorButton.addActionListener(new ColorListener());
label = new JLabel("I'm a label");
MyDrawPanel drawPanel = new MyDrawPanel();
frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.getContentPane().add(BorderLayout.EAST, labelButton);
frame.getContentPane().add(BorderLayout.WEST, label);
frame.setSize(500, 500);
frame.setVisible(true);
}
class LabelListener implements ActionListener{
public void actionPerformed(ActionEvent event) {
label.setText("Ouch!");
}
}
class ColorListener implements ActionListener{
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
}
}
This is class MydrawPanel:
import javax.swing.JPanel;
import java.awt.*;
public class MyDrawPanel extends JPanel {
public void paintConponent(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 startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70, 70, startColor, 150, 150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70, 70, 100, 100);
}
}
Run SimpleAnimation
This is class SimpleAnimation:
import javax.swing.*;
import java.awt.*;
public class SimpleAnimation {
int x = 70;
int y = 70;
public static void main(String[] args) {
SimpleAnimation gui = new SimpleAnimation();
gui.go();
}
public void go() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyDrawPanel drawPanel = new MyDrawPanel();
frame.getContentPane().add(drawPanel);
frame.setSize(300, 300);
frame.setVisible(true);
for(int i = 0; i < 130; i++) {
x++;
y++;
drawPanel.repaint();
try {
Thread.sleep(50);
} catch(Exception ex) {
}
}
}
class MyDrawPanel extends JPanel{
public void paintConponent(Graphics g) {
g.setColor(Color.green);
g.fillOval(x, y, 40, 40);
}
}
}
Thanks again!
For starters:
public void paintConponent(Graphics g) {
Should be:
#Override
public void paintComponent(Graphics g) {
Always use #Override notation when changing methods, to ensure the method name is spelled correctly and uses the correct method arguments. Or to put that another way, use the compiler flag to check that code is actually overriding a parent method, rather than defining a new one!
Other tips
Any custom painted component should:
Call the super method before custom painting, to ensure that older paints are erased & the BG color (etc.) of the component is painted.
Override the getPreferredSize() method to provide a hint to the layout manager.
You have not overridden the paintComponent method. There is a typo in the name. Please note the M in paintComponent. Your method, in each case, is named paintConponent.
The compiler will warn you if you try to override a method from a superclass but get the method signature wrong (the name or the number and types of parameters) if you use the #Override annotation on your method:
#Override
public void paintComponent(Graphics g) {
// . . .
}
You're missing the annulation override
import javax.swing.JPanel;
import java.awt.*;
public class MyDrawPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70, 70, startColor, 150, 150, endColor);
g2d.setPaint(gradient);
g2d.fillOval(70, 70, 100, 100);
this.setVisible(true);
}
}

JAVA GUI code didn't run as expected

I typed this code from the book
public class SimpleGui3C {
JFrame frame;
public static void main (String[] args) {
SimpleGui3C gui = new SimpleGui3C();
gui.go();
}
public void go() {
frame = new JFrame("My own code");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyDrawPanel drawPanel = new MyDrawPanel();
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.setSize(420,300);
frame.setVisible(true);
}}
class MyDrawPanel extends JPanel {
public void painComponent(Graphics g) {
g.fillRect(0,0,this.getWidth(), this.getHeight());
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
g.fillOval(70,70,100,100);
}}
the result is:
Here is the original code of the book, I downloaded this code from the book's website
public class SimpleGui3C {
JFrame frame;
public static void main (String[] args) {
SimpleGui3C gui = new SimpleGui3C();
gui.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyDrawPanel drawPanel = new MyDrawPanel();
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.setSize(420,300);
frame.setVisible(true);
}}
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
g.fillRect(0,0,this.getWidth(), this.getHeight());
// make random colors to fill with
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
g.fillOval(70,70,100,100);
}}
the result goes like this:
I checked it again and again to make sure that they're the same, and it seems that they are the same. but why the GUIs are different?
please help, thanks in advance.
In your own code, the method name is painComponent when it should be paintComponent.
Hint: Add #Override to overriden methods, then the compiler will tell you about errors like this:
#Override
public void painComponent(Graphics g) {

Java Button Triggers Multiple Events

I'm learning some basic Java working on a task using inner classes to create a two button gui. One button changes the colour of a drawn circle and one changes the text of a label. The problem I'm having is that when I click the change label button the circle colour changes as well (on the first click, nothing happens thereafter). If I click the change colour button it operates as expected changing only the circle colour on each click. Basically I would like to try and understand why this happens.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TwoButtons {
JFrame frame;
JLabel label;
public static void main (String[] args) {
TwoButtons gui = new TwoButtons ();
gui.go();
}
public void go () {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton labelButton = new JButton("Change Label");
labelButton.addActionListener(new LabelListener());
JButton colorButton = new JButton("Change Colour");
colorButton.addActionListener(new ColorListener());
label = new JLabel("I'm a label");
MyDrawPanel drawPanel = new MyDrawPanel();
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
g.fillRect(0,0,this.getWidth(), this.getHeight());
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color randomColor = new Color(red, green, blue);
g.setColor(randomColor);
g.fillOval(140,140,300,300);
}
}
frame.getContentPane().add(BorderLayout.SOUTH, colorButton);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.getContentPane().add(BorderLayout.EAST, labelButton);
frame.getContentPane().add(BorderLayout.WEST, label);
frame.setSize(600, 600);
frame.setVisible(true);
}
class LabelListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
label.setText("Boom!");
}
}
class ColorListener implements ActionListener {
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
}
}
I guess whenever a Component of a JFrame is changed, the Frame repaints automatically. Because after you click the label button for the first time the text doesn't change anymore, repaint isn't automatically called after clicking the label button.
In you paintComponent method you get new value of color component each time.
Problem is that this method can be invoked for lots of reason not only when you invoke repaint.
I suggest you get field Color randomColor in your TwoButtons class and move code
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
randomColor = new Color(red, green, blue);
before frame.repaint(); in ColorListener

Categories