如何在 JPanel 和 JFrame 的 contentPane 之间添加间距?
Posted
技术标签:
【中文标题】如何在 JPanel 和 JFrame 的 contentPane 之间添加间距?【英文标题】:How to add spacing between JPanel and JFrame's contentPane? 【发布时间】:2021-06-04 16:51:56 【问题描述】:这是我要复制的图片
这就是我所拥有的(尚未添加图标图像)
我似乎找不到解决方案,盯着它看了很长时间。
我正在尝试复制下图,将GridLayout
用于按钮,其余部分则使用Java Swing 自行计算。此外,我已将按钮添加到 JPanel
中,现在我正在尝试在面板和窗格之间添加间距。
这就是我所拥有的,我该怎么做?
super(title);
this.setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));
Container pane = this.getContentPane();
JButton b1 = new JButton();
b1.setBackground(Color.white);
JButton b2 = new JButton();
b2.setBackground(Color.white);
JButton b3 = new JButton();
b3.setBackground(Color.white);
JButton b4 = new JButton();
b4.setBackground(Color.white);
JButton b5 = new JButton();
b5.setBackground(Color.white);
JButton b6 = new JButton();
b6.setBackground(Color.white);
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(2,3,10,10));
panel.setBackground(Color.black);
panel.add(b1);
panel.add(b2);
panel.add(b3);
panel.add(b4);
panel.add(b5);
panel.add(b6);
pane.add(panel);
this.setSize(500,500);
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
【问题讨论】:
可能是panel.setBorder(new EmptyBorder(..))
。我说“可能”,因为这与我愿意给出一个缺少minimal reproducible example 的问题一样多的关注。顺便说一句this.setSize(500,500);
最好是this.pack();
【参考方案1】:
最简单的方法是在您的 JPanel (see this post on empty borders) 中添加一个空边框:
JPanel panel = new JPanel();
panel.setLayout(new GridLayout(3, 2, 10, 10));
// ...
panel.setBorder(new EmptyBorder(50, 50, 50, 50));
另一种好方法(取决于您的应用程序需要),如果您设置了 JButton 首选大小,则将主 JPanel 的网格布局设置为两列一行,每列内有另一个 JPanel。在 Y_AXIS 模式下向内部 JPanel 添加一个 BoxLayout 并使用 setAlignmentX() 对齐按钮也可以很好地工作(注意这种方法不会使 JButtons 垂直居中)(请参阅How to use BoxLayout):
public class MyFrame extends JFrame
private String title = "Title";
public MyFrame()
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new GridLayout(1,2,10,10));
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
JPanel leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.Y_AXIS));
mainPanel.add(leftPanel);
mainPanel.add(rightPanel);
JButton b1 = new JButton();
b1.setBackground(Color.white);
//b1.setIcon(new ImageIcon(img1));
b1.setAlignmentX(Component.RIGHT_ALIGNMENT);
leftPanel.add(b1);
JButton b2 = new JButton();
b2.setBackground(Color.white);
//b2.setIcon(new ImageIcon(img2));
b2.setAlignmentX(Component.RIGHT_ALIGNMENT);
leftPanel.add(b2);
JButton b3 = new JButton();
b3.setBackground(Color.white);
//b3.setIcon(new ImageIcon(img3));
b3.setAlignmentX(Component.RIGHT_ALIGNMENT);
leftPanel.add(b3);
JButton b4 = new JButton();
b4.setBackground(Color.white);
//b4.setIcon(new ImageIcon(img4));
b4.setAlignmentX(Component.LEFT_ALIGNMENT);
rightPanel.add(b4);
JButton b5 = new JButton();
b5.setBackground(Color.white);
//b5.setIcon(new ImageIcon(img5));
b5.setAlignmentX(Component.LEFT_ALIGNMENT);
rightPanel.add(b5);
JButton b6 = new JButton();
b6.setBackground(Color.white);
//b6.setIcon(new ImageIcon(img6));
b6.setAlignmentX(Component.LEFT_ALIGNMENT);
rightPanel.add(b6);
add(mainPanel); //Adding our mainPanel to the contentPane of the JFrame
this.setSize(500,500); //or pack();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setTitle(title);
this.setVisible(true);
【讨论】:
“如果您设置了 JButton 首选尺寸” 请参阅 Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?(是的。)【参考方案2】:这是我制作的一个小演示。
所有 Swing 应用程序都必须以调用 SwingUtilities
invokeLater
方法开始。此方法确保所有 Swing 组件都在 Event Dispatch Thread 上创建和执行。
您不设置JFrame
的大小并尝试使Swing 组件适合。您让 JFrame
与所有 Swing 组件一起打包。
您在FlowLayout
JPanel
内部创建一个GridLayout
JPanel
。 FlowLayout
JPanel
使用适当大小的空边框。
我使用了 OP 提供的图像来获取图标。
这是完整的可运行代码。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class EmptySpaceDemo implements Runnable
public static void main(String[] args)
SwingUtilities.invokeLater(new EmptySpaceDemo());
private Image[] images;
public EmptySpaceDemo()
this.images = createImages();
private Image[] createImages()
BufferedImage image = readImage();
Image[] images = new Image[6];
images[0] = image.getSubimage(155, 113, 110, 90);
images[1] = image.getSubimage(276, 113, 110, 90);
images[2] = image.getSubimage(155, 217, 110, 90);
images[3] = image.getSubimage(276, 217, 110, 90);
images[4] = image.getSubimage(155, 321, 110, 90);
images[5] = image.getSubimage(276, 321, 110, 90);
return images;
@Override
public void run()
JFrame frame = new JFrame("Empty Space Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createMainPanel(), BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
private JPanel createMainPanel()
JPanel panel = new JPanel(new FlowLayout());
panel.setBackground(Color.BLACK);
panel.setBorder(BorderFactory.createEmptyBorder(40, 100, 40, 100));
JPanel innerPanel = new JPanel(new GridLayout(0, 2, 10, 10));
innerPanel.setBackground(Color.BLACK);
for (int i = 0; i < images.length; i++)
JButton button = new JButton(new ImageIcon(images[i]));
innerPanel.add(button);
panel.add(innerPanel);
return panel;
private BufferedImage readImage()
try
return ImageIO.read(getClass().getResourceAsStream("/icons.png"));
catch (Exception e)
e.printStackTrace();
return null;
【讨论】:
以上是关于如何在 JPanel 和 JFrame 的 contentPane 之间添加间距?的主要内容,如果未能解决你的问题,请参考以下文章
如何在JFrame上显示带有图像的两个JPanel,并且两个img都可见?