Search code examples
javaswingjframejbuttonactionlistener

I'm trying to change the background color of a JPanel each time a button is pressed


I have looked at several of the similar questions and haven't been able to make this work. I am displaying the time and added a counter that counts to 4 and starts over, but I can only get it to set the beginning background color. What am I missing here? I've tried putting my if statements in a few places. Everything except the color change is working just fine.

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class TimeFrame extends JFrame {
        private static final int FRAME_WIDTH = 250;
        private static final int FRAME_HEIGHT = 200;
        private JButton CurrentTime;
        private JLabel CurrentTimeLabel;
        private JTextField CurrentTimeField;
        private int click;
        private JTextField clicktest;

        public TimeFrame() {
            CurrentTimeLabel = new JLabel("The Current Time is: ");

            createTextField();
            createButton();
            createPanel();

            setSize(FRAME_WIDTH, FRAME_HEIGHT);
            setSize(250, 200);
            initialize();


        }
        private void initialize()
        {
        click = 0;
        }

        private void createTextField()
        {
           final int FIELD_WIDTH = 10;
           CurrentTimeField = new JTextField(FIELD_WIDTH);
           Date now = new Date();
           DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
           CurrentTimeField.setText("" + dateFormat.format(now));

           clicktest = new JTextField(FIELD_WIDTH);
           clicktest.setText(" " + click);

        }
        private void createButton()
        {
            CurrentTime = new JButton("Display Current Time");

            ActionListener listener = new AddCurrentTimeListener();
            CurrentTime.addActionListener(listener);

        }
        private void createPanel()
        {
           JPanel panel = new JPanel();
           //panel.addActionListener(backgroundListener);
           panel.add(CurrentTimeLabel);
           panel.add(CurrentTimeField);
           panel.add(CurrentTime);
           panel.add(clicktest);
           //int click = 0;

           if (click == 0){
                panel.setBackground(Color.ORANGE);
            } 
           else if (click == 1) {
                panel.setBackground(Color.YELLOW);
            } 
           else if (click == 2) {
                panel.setBackground(Color.BLUE);
            } 
           else if (click == 3) {
                panel.setBackground(Color.GREEN);
            } 
           else if (click == 4) {
                panel.setBackground(Color.PINK);
            }

           add(panel);

        }

        class AddCurrentTimeListener implements ActionListener
        {
           public void actionPerformed(ActionEvent event){

               new java.util.Date();
               Date now = new Date();
               DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
               CurrentTimeField.setText("" + dateFormat.format(now));getClass();                                   
               if (click < 4){
                   click++;
               } else  {
                   click = click - 4;}

               clicktest.setText("" + click);getClass();

               /**
               if (click == 0){
                    panel.setBackground(Color.ORANGE);
                } 
               else if (click == 1) {
                    panel.setBackground(Color.YELLOW);
                } 
               else if (click == 2) {
                    panel.setBackground(Color.BLUE);
                } 
               else if (click == 3) {
                    panel.setBackground(Color.GREEN);
                } 
               else if (click == 4) {
                    panel.setBackground(Color.PINK);
                }
               */

               repaint();
               }


            }

}

Solution

  • By adding a JPanel to the frame, you are effetely blocking the frames contentPane, this, in of itself, is not a particular issue, except that in your ActionListener, you are trying to set the background color of the frame itself.

    Now, this doesn't work, as the frame is made up of a number overlapping components.

    The layers of a JFrame

    Any changes to the frame's background won't be shown, as it's hidden behind the contentPane.

    Instead, you should be changing the contentPane's background.

    Okay, but that takes us back to the first problem (the JPanel). Now, you could make the JPanel an instance field and change it's background colour in the ActionListener and this would work, or you could get rid of it and simply change the frame's contentPane, which you choose is up to you

    For my, overly simplified example, I've chosen to simply use the frame's contentPane as it demonstrates an important concept you need to learn about frames...

    import java.awt.Color;
    import java.awt.EventQueue;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.text.DateFormat;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JTextField;
    
    public class TimeFrame extends JFrame {
    
        public static void main(String args[]) {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new TimeFrame().setVisible(true);
                }
            });
        }
    
        private JButton currentTime;
        private JLabel currentTimeLabel;
        private JTextField currentTimeField;
        private int click;
        private JTextField clicktest;
    
        public TimeFrame() {
            currentTimeLabel = new JLabel("The Current Time is: ");
    
            createTextField();
            createButton();
            createPanel();
    
            pack();
            setLocationRelativeTo(null);
            initialize();
    
        }
    
        private void initialize() {
            click = 0;
        }
    
        private void createTextField() {
            final int FIELD_WIDTH = 10;
            currentTimeField = new JTextField(FIELD_WIDTH);
            Date now = new Date();
            DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
            currentTimeField.setText("" + dateFormat.format(now));
    
            clicktest = new JTextField(FIELD_WIDTH);
            clicktest.setText(" " + click);
    
        }
    
        private void createButton() {
            currentTime = new JButton("Display Current Time");
    
            ActionListener listener = new AddCurrentTimeListener();
            currentTime.addActionListener(listener);
    
        }
    
        private void createPanel() {
            setLayout(new FlowLayout());
            //panel.addActionListener(backgroundListener);
            add(currentTimeLabel);
            add(currentTimeField);
            add(currentTime);
            add(clicktest);
        }
    
        class AddCurrentTimeListener implements ActionListener {
    
            public void actionPerformed(ActionEvent event) {
    
                new java.util.Date();
                Date now = new Date();
                DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
                currentTimeField.setText("" + dateFormat.format(now));
                getClass();
                if (click < 4) {
                    click++;
                } else {
                    click = click - 4;
                }
    
                clicktest.setText("" + click);
    
                if (click == 0) {
                    getContentPane().setBackground(Color.ORANGE);
                } else if (click == 1) {
                    getContentPane().setBackground(Color.YELLOW);
                } else if (click == 2) {
                    getContentPane().setBackground(Color.BLUE);
                } else if (click == 3) {
                    getContentPane().setBackground(Color.GREEN);
                } else if (click == 4) {
                    getContentPane().setBackground(Color.PINK);
                }
                repaint();
            }
    
        }
    
    }
    

    Disclaimer:

    Personally, I would avoid extending directly from a JFrame, it locks you into a single use case and makes you reliant on the functionality of the frame (like having to use getContentPane)

    Personally, I'd start with a JPanel and then add this to what every container I wanted to