如何在 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 JPanelFlowLayout 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?

如何将 JPanel 放在 JFrame 的前面

如何在JFrame上显示带有图像的两个JPanel,并且两个img都可见?

如何在 JFrame/JPanel 中可视化控制台 java

java中jframe 和jpanel的区别

在 JFrame 中将图像绘制到 JPanel