user3015224
user3015224

Reputation: 27

Using JButton to change background color in JFrame

I'm writing a program that uses JButton. When the user clicks a button, the background should change color, but the JFrame can't be accessed from the actionPerformed() method. Can someone please tell me how to make it work?

import java.awt.event.*; 
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;
public class HandlerClass implements ActionListener{

  public static void main(String[] args){
    HandlerClass handler = new HandlerClass();
     final JFrame f = new JFrame("Testing out these JPanels");
     f.setSize(400, 100); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.setLocationRelativeTo(null); 
     f.setLayout(new GridLayout(2, 3));
     JButton b = new JButton("button 1");
     b.addActionListener(new HandlerClass());
     JButton butt = new JButton("button 2");

     JButton bug = new JButton("button 3");

     JButton button = new JButton("button 4");

     JButton button5 = new JButton("button 5");

     JButton button6 = new JButton("button 6");

     JPanel p = new JPanel();
     p.setVisible(true);
     JPanel pnl = new JPanel();
     p.add(b);
     p.add(butt);
     p.add(bug);
     pnl.add(button);
     pnl.add(button5);
     pnl.add(button6);
     f.add(p, BorderLayout.CENTER);
     f.add(pnl, BorderLayout.SOUTH);
     f.setVisible(true);
     f.setBackground(Color.RED);
   }
     public void actionPerformed(ActionEvent e){
        f.setBackground(Color.WHITE);
       }

     }

Upvotes: 0

Views: 4007

Answers (3)

Arijit
Arijit

Reputation: 1674

Your problem:

JFrame can't be accessed from the actionPerformed()

The solution is, You cannot access a local variable from another method Take a look at here and here

Now the important thing: You have two JPanels over your JFrame. So if you change the color of the JFrame, then you will not be able to see the color change. So my suggestion is change the color of the JPanel. Take the example of the code below:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import java.awt.GridBagLayout;
import javax.swing.JButton;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class HandlerClass extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    HandlerClass frame = new HandlerClass();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public HandlerClass() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        GridBagLayout gbl_contentPane = new GridBagLayout();
        gbl_contentPane.columnWidths = new int[]{0, 0, 0, 0, 0, 0, 0};
        gbl_contentPane.rowHeights = new int[]{0, 0, 0, 0};
        gbl_contentPane.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
        gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, Double.MIN_VALUE};
        contentPane.setLayout(gbl_contentPane);

        JButton btnRed = new JButton("Red");
        GridBagConstraints gbc_btnRed = new GridBagConstraints();
        gbc_btnRed.insets = new Insets(0, 0, 5, 5);
        gbc_btnRed.gridx = 3;
        gbc_btnRed.gridy = 1;
        contentPane.add(btnRed, gbc_btnRed);

        JButton btnBlue = new JButton("Blue");
        GridBagConstraints gbc_btnBlue = new GridBagConstraints();
        gbc_btnBlue.insets = new Insets(0, 0, 5, 0);
        gbc_btnBlue.gridx = 5;
        gbc_btnBlue.gridy = 1;
        contentPane.add(btnBlue, gbc_btnBlue);

        JButton btnWhite = new JButton("White");
        GridBagConstraints gbc_btnWhite = new GridBagConstraints();
        gbc_btnWhite.insets = new Insets(0, 0, 0, 5);
        gbc_btnWhite.gridx = 3;
        gbc_btnWhite.gridy = 2;
        contentPane.add(btnWhite, gbc_btnWhite);

        JButton btnGreen = new JButton("Green");
        GridBagConstraints gbc_btnGreen = new GridBagConstraints();
        gbc_btnGreen.gridx = 5;
        gbc_btnGreen.gridy = 2;
        contentPane.add(btnGreen, gbc_btnGreen);

        btnRed.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                contentPane.setBackground(Color.red);

            }
        });
        btnBlue.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                contentPane.setBackground(Color.blue);
            }
        });
        btnWhite.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                contentPane.setBackground(Color.WHITE);

            }
        });
        btnGreen.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {

                contentPane.setBackground(Color.green);
            }
        });

        pack();
    }

}

Screen shot: enter image description here

Upvotes: 0

David Yee
David Yee

Reputation: 3646

You have few choices:

  1. Move the JFrame instance outside the main body so that it becomes an instance variable as such:

    public class HandlerClass {
        private JFrame frame;
    
        public HandlerClass() {
            ...
        }
    }
    
  2. Move the ActionListener inside the same method as such:

    public class HandlerClass {
        public HandlerClass() {
            final JFrame frame = new JFrame();
            JButton button = new JButton();
            ...
            button.addActionListener(new ActionerListener() {
                @Override
                public void actionPerformed(ActionEvent e){
                    frame.setBackground(Color.WHITE);
                }
            }
        }
    }
    

    The only issue with this second choice is that you must make the reference to frame with the final modifier which means you can't change the reference later.

  3. Do both of the above.

Upvotes: 2

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

  1. Don't write all your code in a single huge main method. That's for rank beginner programs, and if you want your code to do more than hello world, you're going to have to make it a true OOPs program.
  2. Create a class with non-static fields and methods.
  3. Have your ActionListener call a method that in its body changes the background color of your main JPanel, the one that you add to the JFrame's contentPane.
  4. Consider using anonymous inner listener classes, and then off-load the meat of the listener code to a separate method, either in your GUI or in a control class.

Upvotes: 4

Related Questions