java - GridLayout 未填充 JPanel

标签 java swing

我在 GridLayout 和整个 JPanel 未填充时遇到问题。我有一个 N * M 网格,我用 N * M Tiles 填充它(它们扩展了 JPanel)。添加所有这些图 block 后,JPanel 的底部和右侧仍有空间。我认为 GridLayout 应该填满整个 JPanel,并使其中的所有内容大小均匀?

编辑:我不想发布所有代码,因为有多个类。我想也许有一个简单的解决方案。

public class MainFrame extends JFrame {

    private static final long serialVersionUID = 3985493842977428355L;
    private final int FRAME_HEIGHT = 800;
    private final int FRAME_WIDTH = 700;

    private MainPanel mainPanel;

    public MainFrame() {
        super("Test");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(FRAME_HEIGHT, FRAME_WIDTH);
        setLocationRelativeTo(null);    
        mainPanel = new MainPanel();
        getContentPane().add(mainPanel);
        setVisible(true);
    }
}

public class MainPanel extends JPanel {
    /**
     * 
     */
    private static final long serialVersionUID = 3421071253693531472L;

    private RoutePanel routePanel;
    private ControlPanel controlPanel;
    private GridBagConstraints gridBagConstraints;
    private GridBagLayout gridBagLayout;

    public MainPanel() {
        routePanel = new RoutePanel();
        controlPanel = new ControlPanel();
        setBackground(Color.black);
        gridBagLayout = new GridBagLayout();
        setLayout(gridBagLayout);
        gridBagConstraints = new GridBagConstraints();
        createLayout();
    }

    private void createLayout() {
        gridBagConstraints.weightx = 1;
        gridBagConstraints.weighty = 1;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 0;
        gridBagConstraints.anchor = GridBagConstraints.NORTH;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagLayout.setConstraints(routePanel, gridBagConstraints);
        add(routePanel);

        gridBagConstraints.weightx = 1;
        gridBagConstraints.weighty = .05;
        gridBagConstraints.gridx = 0;
        gridBagConstraints.gridy = 1;
        gridBagConstraints.anchor = GridBagConstraints.SOUTH;
        gridBagConstraints.fill = GridBagConstraints.BOTH;
        gridBagLayout.setConstraints(controlPanel, gridBagConstraints);
        add(controlPanel);
    }
}

public class RoutePanel extends JPanel{
    /**
     * 
     */
    private static final long serialVersionUID = 4366703088208967594L;
    private final int GRID_ROWS = 30;
    private final int GRID_COLS = 47;


    public RoutePanel() {
        setLayout(new GridLayout(GRID_ROWS, GRID_COLS, 0, 0));
        for(int i = 0; i < GRID_ROWS * GRID_COLS; i++) {
            add(new Tile());
        }
        setBackground(Color.orange);
    }
}

public ControlPanel() {

    }

public Tile() {
        setBackground(Color.gray);
        Border blackline;
        blackline = BorderFactory.createLineBorder(Color.black);
        setBorder(blackline);
    }

最佳答案

由于您没有发布代码,我们不得不猜测(这并不好)。

我的猜测:您可能正在设置某些组件或 GUI 的大小或首选大小,这会导致 GUI 边缘出现间隙。

解决方案:不要这样做。当在 GUI 上调用 pack() 时,让组件通过它们的首选大小和布局管理器自行调整大小。

要获得更多帮助,请创建并发布您的 sscce .对于这样的问题,代码确实是强制性的,实际上我有点惊讶你没有发布你的代码。


编辑 1

例如,注意生成的 GUI 的差异:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.*;

public class GapExample {
   private static final int M = 5;
   private static final int N = 6;
   private static final int PREF_W = 700;
   private static final int PREF_H = 500;

   @SuppressWarnings("serial")
   private static void createAndShowGui() {

      // *** attempt 1: set preferredSize of the mainPanel JPanel ***
      JPanel mainPanel = new JPanel(new GridLayout(M, N));
      mainPanel.setBorder(BorderFactory.createLineBorder(Color.red));
      mainPanel.setPreferredSize(new Dimension(PREF_W, PREF_H));

      for (int i = 0; i < M; i++) {
         for (int j = 0; j < N; j++) {
            String text = String.format("Foo [%d, %d]", i, j);
            JLabel label = new JLabel(text, SwingConstants.CENTER);
            label.setBorder(BorderFactory.createLineBorder(Color.blue));
            mainPanel.add(label);
         }
      }
      JOptionPane.showMessageDialog(null, mainPanel,
            "Attempt 1, setPreferredSize of mainPane",
            JOptionPane.PLAIN_MESSAGE);

      // *** attempt 2: override the getPreferredSize of the JLabel cells in the
      // grid ***
      mainPanel = new JPanel(new GridLayout(M, N));
      mainPanel.setBorder(BorderFactory.createLineBorder(Color.red));
      final Dimension labelPrefSize = new Dimension(PREF_W / N, PREF_H / M);
      for (int i = 0; i < M; i++) {
         for (int j = 0; j < N; j++) {
            String text = String.format("Foo [%d, %d]", i, j);
            JLabel label = new JLabel(text, SwingConstants.CENTER) {
               @Override
               public Dimension getPreferredSize() {
                  return labelPrefSize;
               }
            };
            label.setBorder(BorderFactory.createLineBorder(Color.blue));
            mainPanel.add(label);
         }
      }
      JOptionPane
            .showMessageDialog(null, mainPanel,
                  "Attempt 2, override getPreferredSize of the JLabel cells in the grid",
                  JOptionPane.PLAIN_MESSAGE);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

在第二个对话框中,我让 JLabel 返回一个首选大小,并让容纳它们的容器设置最佳大小以显示 GUI,第二次尝试时,网格会更适合。

这显示了第一次(错误的)尝试内部和外部组件之间的间隙:

enter image description here

第二次(好的)尝试显示没有这样的差距:

enter image description here

关于java - GridLayout 未填充 JPanel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17626760/

相关文章:

java - 如何使用 JPA 处理 INSERT 中的空值?

java 桌面应用程序 - JList 选择更改不会更新界面

java - 如何防止 JMenuItem 在单击 JMenuItem 时关闭菜单

java - 使用 Hibernate 将数据库从 mysql 更改为 oracle

java - Mule SFTP 文件监听器

java - System.setProperty 还是公共(public)静态变量?

java - 如何提交具有动态(未知)字段数的表单

java - 尽管我使用了 Swing Timer,但在 JPanel 上从动画绘制 Wave 时 GUI 卡住

java - 如何获得以另一个 JPanel 为中心的 JPanel 的边界?

java - AudioInputStream() 不会停止