Java GridBagLayout调整大小和固定大小

3

这是我想要实现的目标。

------------------------| 150px |
|                       | width |
|                       |   p2  |
|                       |       |
|      Fill frame       |       |
|      p1               |       |
|                       |       |
|                       |       |
------------------------|       |
150px height            |       |
|       p3              |       |
---------------------------------

'填充框架'必须按比例缩放,但其他两个正方形具有固定的宽度/高度。

我的代码确实生成了这个布局,但是p1没有扩展到填满整个框架。请问有谁能告诉我如何使p1动态变化?

先行致谢。

这是我目前的代码:

    setTitle(Rolit.TITLE);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    mainPanel = new JPanel();
    mainPanel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();

//P1    FILL P1 WITH 64 BUTTONS
    p1 = new JPanel();
    p1.setLayout(new GridLayout(8, 8));

    p1.setMinimumSize(new Dimension(600, 600));
    p1.setMaximumSize(new Dimension(600, 600));
    p1.setPreferredSize(new Dimension(600, 600));

    for(int y = 0; y < 8; y++){
        for(int x = 0; x < 8; x++){
            JButton btn = new JButton(x + " , " + y);
            p1.add(btn);
        }
    }

//P2    FILL P2 WITH 4 BUTTONS
    p2 = new JPanel();
    p2.setLayout(new GridLayout(4, 1));
    p2.setMinimumSize(new Dimension(150, 100));
    p2.setMaximumSize(new Dimension(150, 100));
    p2.setPreferredSize(new Dimension(150, 100));

    for(int i = 0; i < 4; i++){
        p2.add(new JButton("Button"));
    }

//P3
    p3 = new JPanel();
    p3.setMinimumSize(new Dimension(100, 150));
    p3.setMaximumSize(new Dimension(100, 150));
    p3.setPreferredSize(new Dimension(100, 150));
    p3.setBackground(Color.BLUE);


//ADD ALL TO mainPanel

    c.gridx = 0;
    c.gridy = 0;
    c.fill = GridBagConstraints.BOTH; 
    mainPanel.add(p1, c);        

    c.gridx = 1;
    c.gridheight = 2;  
    c.fill = GridBagConstraints.VERTICAL;
    mainPanel.add(p2, c);

    c.gridx = 0;
    c.gridy = 1;
    c.gridheight = 1;        
    c.gridwidth = 2;
    c.fill = GridBagConstraints.HORIZONTAL;
    mainPanel.add(p3, c);

    setContentPane(mainPanel);
    pack();
    setLocationRelativeTo(null);
    setVisible(true);
2个回答

4
你需要在 GridBagConstraints 中提供 weightxweighty 值,它们会影响组件对父容器大小变化的反应以及在给定单元格内占用多少“权重”。
更多详情请参考如何使用GridBagLayout
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestGridBagLayout {

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

    private JPanel mainPanel;
    private JPanel p1;
    private JPanel p2;
    private JPanel p3;

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

                mainPanel = new JPanel();
                mainPanel.setLayout(new GridBagLayout());
                GridBagConstraints c = new GridBagConstraints();

                //P1    FILL P1 WITH 64 BUTTONS
                p1 = new JPanel();
                p1.setLayout(new GridLayout(8, 8));

                p1.setMinimumSize(new Dimension(600, 600));
                p1.setMaximumSize(new Dimension(600, 600));
                p1.setPreferredSize(new Dimension(600, 600));

                for (int y = 0; y < 8; y++) {
                    for (int x = 0; x < 8; x++) {
                        JButton btn = new JButton(x + " , " + y);
                        p1.add(btn);
                    }
                }

                //P2    FILL P2 WITH 4 BUTTONS
                p2 = new JPanel();
                p2.setLayout(new GridLayout(4, 1));
                p2.setMinimumSize(new Dimension(150, 100));
                p2.setMaximumSize(new Dimension(150, 100));
                p2.setPreferredSize(new Dimension(150, 100));

                for (int i = 0; i < 4; i++) {
                    p2.add(new JButton("Button"));
                }

                //P3
                p3 = new JPanel();
                p3.setMinimumSize(new Dimension(100, 150));
                p3.setMaximumSize(new Dimension(100, 150));
                p3.setPreferredSize(new Dimension(100, 150));
                p3.setBackground(Color.BLUE);

                //ADD ALL TO mainPanel
                c.gridx = 0;
                c.gridy = 0;
                c.fill = GridBagConstraints.BOTH;
                c.weightx = 1;
                c.weighty = 1;
                mainPanel.add(p1, c);

                c.gridx = 1;
                c.gridheight = 2;
                c.weighty = 1;
                c.weightx = 0;
                c.fill = GridBagConstraints.VERTICAL;
                mainPanel.add(p2, c);

                c.gridx = 0;
                c.gridy = 1;
                c.gridheight = 1;
                c.gridwidth = 2;
                c.fill = GridBagConstraints.HORIZONTAL;
                c.weighty = 0;
                c.weightx = 1;
                mainPanel.add(p3, c);

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(mainPanel);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

}

4
我建议使用嵌套的JPanels,而这些JPanels应该使用边界布局(BorderLayout)。例如:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;

public class EmielGui extends JPanel {
   protected static final int DELTA_DIMEN = 1;
   protected static final int MAX_DIMEN = 600;
   private static final int DELAY = 20;
   private JPanel rightPanel = new JPanel();
   private JPanel bottomPanel = new JPanel();
   private JPanel centerPanel = new JPanel();
   private int dimen = 100;

   public EmielGui() {
      JPanel tempCenterPanel = new JPanel(new BorderLayout());
      tempCenterPanel.add(centerPanel, BorderLayout.CENTER);
      tempCenterPanel.add(bottomPanel, BorderLayout.SOUTH);

      setLayout(new BorderLayout());
      add(rightPanel, BorderLayout.EAST);
      add(tempCenterPanel, BorderLayout.CENTER);

      rightPanel.setMinimumSize(new Dimension(150, 0));
      bottomPanel.setMinimumSize(new Dimension(0, 150));

      rightPanel.setPreferredSize(rightPanel.getMinimumSize());
      bottomPanel.setPreferredSize(bottomPanel.getMinimumSize());

      rightPanel.setBorder(BorderFactory.createLineBorder(Color.red));
      bottomPanel.setBorder(BorderFactory.createLineBorder(Color.blue));
      centerPanel.setBorder(BorderFactory.createLineBorder(Color.green));

      new Timer(DELAY, new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            dimen += DELTA_DIMEN;
            if (dimen < MAX_DIMEN) {
               centerPanel.setPreferredSize(new Dimension(dimen, dimen));
               SwingUtilities.getWindowAncestor(EmielGui.this).pack();

            } else {
               ((Timer) e.getSource()).stop();
            }
         }
      }).start();
   }

   private static void createAndShowGui() {
      EmielGui mainPanel = new EmielGui();

      JFrame frame = new JFrame("EmielGui");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

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

@MadProgrammer:谢谢。像往常一样,我因为你的回答非常出色而第一个点赞了你。 - Hovercraft Full Of Eels
1
个人而言,我更喜欢在可能的情况下使用复合布局而不是复杂的GridBagLayout,如果以后想要更改它,复合布局更容易处理 - 在我看来。 - MadProgrammer
这看起来非常动态! :) - In-young Choung
哇哇哇,我不得不筛选五年的帖子才能找到我需要的! - NoName

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接