java swing - how to change window background

2020-04-21 03:40发布

问题:

I was trying to make a button that switches the window background from default to red. I haven't found any preset colors to match the default so i tried to get it from panel.getBackground when i created it. I have an error at line 11, i don't know how to check the current background color.

JPanel panel = new JPanel();
    panel.setBounds(0, 0, 434, 262);
    frame.getContentPane().add(panel);
    panel.setLayout(null);
    panel.setVisible(true);
    Color c=panel.getBackground();

    JButton btnRed = new JButton("Red");
    btnRed.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            if(panel.getBackground(c));{
                panel.setBackground(Color.RED);
            }
            else{
                panel.setBackground(c);
            }
        }
    });

回答1:

You want to compare the Color, this is an Object so equals() is the way... also an if expects a boolean and will finish when ; is found, so this:

if(panel.getBackground(c));{
// ↑ not a boolean        ↑
//                        ↑
//                        ; is wrong

must be

if(panel.getBackground().equals(c)){


回答2:

if(panel.getBackground(c));{ isn't correct, it won't even compile. It should be if (c.equals(panel.getBackground()) {

Note, the lack of ; at the end of the statement.

Also, there is no such method as getBackground(Color), so, along with the else statement, your code basically wouldn't compile.

Don't use null layouts, you don't control the aspects of the UI which will change the components required sizes on different systems or look and feel settings

  import java.awt.Color;
  import java.awt.Dimension;
  import java.awt.EventQueue;
  import java.awt.GridBagLayout;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import javax.swing.JButton;
  import javax.swing.JFrame;
  import javax.swing.JPanel;
  import javax.swing.UIManager;
  import javax.swing.UnsupportedLookAndFeelException;

  public class Test {

    public static void main(String[] args) {
      new Test();
    }

    public Test() {
      EventQueue.invokeLater(new Runnable() {
        @Override
        public void run() {
          try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
          } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
            ex.printStackTrace();
          }

          JFrame frame = new JFrame("Testing");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.setContentPane(new TestPane());
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
        }
      });
    }

    public class TestPane extends JPanel {

      private Color baseColor;

      public TestPane() {
        baseColor = getBackground();
        setLayout(new GridBagLayout());

        JButton btn = new JButton("Click");
        btn.addActionListener(new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent e) {
            if (baseColor.equals(getBackground())) {
              setBackground(Color.RED);
            } else {
              setBackground(baseColor);
            }
          }
        });

        add(btn);
      }

      @Override
      public Dimension getPreferredSize() {
        return new Dimension(200, 200);
      }

    }

  }

An alternative to checking the current color, which might cause some issues on some systems/look and feels would be to use a simple counter...

public class TestPane extends JPanel {

  private int tick;

  public TestPane() {
    setLayout(new GridBagLayout());

    JButton btn = new JButton("Click");
    btn.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        tick++;
        if ((tick % 2) != 0) {
          setBackground(Color.RED);
        } else {
          setBackground(null);
        }
      }
    });

    add(btn);
  }

  @Override
  public Dimension getPreferredSize() {
    return new Dimension(200, 200);
  }

}

This would allow you to flip the state independently of the current the color which would generally be safer