GridBagLayout在尝试将消息JLabel添加到正方形网格下方时做了一些奇怪的事情



我正试图在显示的正方形网格下方显示消息的JLabel(每个正方形都是一个JLabel)。当我不尝试将消息添加到JPanel时,4x4正方形网格显示得很好。然而,当我尝试在网格下方或上方添加消息JLabel时,会发生的情况是,正方形网格一分为二(在第一列正方形之后),这样一列正方形显示在左侧,然后有一个间隙,然后显示其他三列正方形。消息显示在下面。为什么添加此消息会导致正方形网格像这样分裂?我已经把我的代码放在下面了。提前感谢您的帮助。

public void displayGrid(JButton button) {
    JLabel instructionsLabel = new JLabel ("Select the locations of the four objects that you saw previously. Be careful - when you select one box, you can't take it back.");
    try {
        squareImage = ImageIO.read(this.getClass().getResource("stimulus(0).gif"));  
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    for(int i = 0; i < 16; i++){
        c.gridx = i % 4;
        c.gridy = i / 4;
        squareLabels[i] = new JLabel(new ImageIcon(squareImage));
        panel.add(squareLabels[i], c);
        squareLabels[i].addMouseListener(this);
    }
    panel.validate();
    c.gridy += 1;
    c.gridx = 0;
    panel.add(instructionsLabel, c);
    panel.validate();
}

instructionsLabel添加到第五行的第一列,在JLabel s的4*4矩阵之后。

问题是因为instructionsLabel的长度比squareLabels[i]的长度长,所以GridBagLayout的默认行为会拉伸第一列以适应instructionsLabel

在添加instructionsLabel:之前,您需要为GridBagConstraints对象c设置gridWidth

c.gridy += 1;
c.gridx = 0;
constraint.gridwidth = 4;
panel.add(instructionsLabel, c);

通过设置constraint.gridwidth = 4;,您告诉布局管理器将instructionsLabel放置在多个列中。(这里我设置了4列。)

JLabel中添加一些LineBorder可以帮助您更好地理解GridBagLayout及其Constraints的行为。

[更新]您可以使用BorderLayout作为主布局,然后将带有JLabel和其他组件的JPanel添加到BorderLayout的中心。然后在该JPanel中使用GridBagLayout。参见此示例:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class TestGridBagLAyout extends JFrame {
    private static final long serialVersionUID = -392403850862179703L;
    private static final int FRAME_WIDTH = 200;
    private static final int FRAME_HEIGHT = 200;
    public TestGridBagLAyout() {
        setSize(FRAME_WIDTH, FRAME_HEIGHT);
        //
        setForeground(Color.RED);
        //
        setLayout(new BorderLayout());
        add(initCenterPanel());
    }
    private JPanel initCenterPanel() {
        GridBagLayout gridBagLayout = new GridBagLayout();
        JPanel centerPanel = new JPanel(gridBagLayout);
        centerPanel.setBackground(Color.WHITE);
        //
        GridBagConstraints constraint = new GridBagConstraints(0, 0, 1, 1, 0d, 0d, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0);
        //
        JLabel[] squareLabels = new JLabel[16];
        for(int i = 0; i < 16; i++){
            constraint.gridx = i % 4;
            constraint.gridy = i / 4;
            squareLabels[i] = new JLabel("Test");
            centerPanel.add(squareLabels[i], constraint);
        }
        //
        JLabel instructionsLabel = new JLabel("This is long instruction!");
        constraint.gridy += 1;
        constraint.gridx = 0;
        constraint.gridwidth = 4;
        centerPanel.add(instructionsLabel, constraint);
        //
        return centerPanel;
    }
}

祝你好运。

我认为您需要使用一个单独的GridBagConstraints对象——您不能像上面那样重用同一个实例。

最新更新