简体   繁体   中英

Setting JPanel background while using BoxLayout

I am developing a simple application, and am currently working on the gui design using Swing. In my program I have a JPanel which I would like to have a background color black like so:

JPanel playerPanel = new JPanel();
playerPanel.setOpaque(true);
playerPanel.setBackground(Color.BLACK);

This code works fine. However, the problem is when I assign a Layout Manager to the panel:

JPanel playerPanel = new JPanel();
playerPanel.setOpaque(true);
playerPanel.setBackground(Color.BLACK);
playerPanel.setLayout(new BoxLayout(playerPanel, BoxLayout.PAGE_AXIS));

For some reason, this makes the black color of the panel go away. This happens no matter where I place the .setLayout(...) command, before or after the .setBackground(...) and .setOpaque(true) .

Why is this, and how do I work around this? How do I keep a black JPanel that uses a BoxLayout manager?

Verify that your panel's content is not obscuring the altered background. Resize the example below, which I've artificially enlarged, to see the effect.

图片

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.Random;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
  * @see https://stackoverflow.com/a/57785802/230513
  */
public class BoxTest {

     public static final Random random = new Random();

     public static void main(String[] args) {

         EventQueue.invokeLater(new Runnable() {
             public void run() {
                 new BoxTest().create();
             }
         });
     }

     void create() {
         JPanel panel = new JPanel();
         panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
         panel.setBackground(Color.BLACK);
         panel.add(Box.createVerticalGlue());
         for (int i = 0; i < 4; i++) {
             panel.add(new VariablePanel());
             panel.add(Box.createVerticalGlue());
         }

         JFrame f = new JFrame("BoxTest");
         f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         f.add(panel);
         f.pack();
         f.setLocationRelativeTo(null);
         f.setVisible(true);
         f.setSize(f.getWidth(), f.getHeight() + 64);
     }
}

/**
 * A VariablePanel has a label showing its current size,
 * as well as a variable number of text items.
 */
class VariablePanel extends JPanel {

    private static final String text = 
        "Sed ut perspiciatis unde omnis iste natus error sit.";
    private final JLabel sizeLabel = new JLabel("Size:");

    public VariablePanel() {
        this.setLayout(new GridLayout(0, 1));
        this.add(sizeLabel);
        int count = BoxTest.random.nextInt(5) + 1;
        for (int i = 0; i < count; i++) {
            this.add(new JLabel(text));
        }
        this.addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                int w = e.getComponent().getWidth();
                int h = e.getComponent().getHeight();
                sizeLabel.setText("Size: " + w + "\u00d7" + h);
            }
        });
    }
}

Swing components (except JLabel) are opaque by default. This means:

  1. you don't need playerPanel.setOpaque(true)
  2. most components you add to the panel will be opaque and cover the background of your playerPanel.

Also, the BoxLayout respects the maximum size of any component you add to the panel. So if you add a component:

  1. like a JButton which has a defined maximum size, you will see the button on top of the playerPanel and the background will surround the button.
  2. like a JPanel, which does not have a defined maximum size, the panel will be resized to fill the entire area of the playerPanel and you won't see the background of the playerPanel.

If you want to see the background of the playerPanel show through a component added to the playerPanel, then you need to use setOpaque(false) on the component. For example:

JPanel child = new JPanel();
child.setOpaque( false );
playerPanel.add( child );

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM