且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何获得带有空JLabel的JPanel来占用GridBagLayout中的空间

更新时间:2023-12-05 11:14:58

好,基本上,GridBagLayout将组件放置在网格中的矩形(单元格)中,然后使用组件的 preferred sizes 进行确定细胞应该多大. 采用这种布局:

  • 如果容器的大小小于首选大小 ,则仅使用最小大小.
  • 带空("")文本如果未使用setPreferredSize(size)或覆盖getPreferredSize(size)显式给出首选大小提示,则JLabel\JTextFeild\JButton的首选大小在(2,2)左右.

在他看来,最小尺寸将不起作用,因为带有空白文本的首选尺寸在(2,2)左右,并且容器的尺寸已经大于首选尺寸. GridBagLayout使用首选大小,根本不用担心最小大小.

您实际上需要使用GridBagLayout设置首选尺寸和最小尺寸,因为:

如果尝试仅将 设置为首选大小,则缩小窗口的大小最终将导致容器面板的大小缩小.容器的面板尺寸将小于组件的首选尺寸 ,并且JLabel\JTextFeild\JButton会缩小到其最小尺寸.如果此时您还没有给出最小尺寸提示,则使用默认的最小尺寸:可能在(2,2)左右. 通过下面给出的工作示例,您会更好地理解.

需要注意的其他事项:

   c.gridx = 1;
    c.gridy = 0;
    c.fill = GridBagConstraints.BOTH;

   // filesPanel.add(calibrationFileSelection,c);
    filesPanel.add(calibrationFileSelectionValuePanel,c);

您要添加包含calibrationFileSelectionValueLabelpanel.您不需要使用额外的面板,只需通过设置将calibrationFileSelectionValueLabel直接添加到网格中即可(相反,***覆盖getPreferedSize(Size))preferredSize.但是,请尝试将插图设置为GridBagConstraints,以使您的第一个panel更好看:

   gridBagCnst.insets = new Insets(3, 3, 3, 3); 

最适合您的示例:

如果您听不懂我们在说什么,在此示例中,我仅为解决您的问题设置了首选大小.但由于我尚未设置最小尺寸,请尝试调整窗口大小以与上述说明匹配.

源代码:

import java.awt.*;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.SwingUtilities;
import javax.swing.border.*;


/**
 *
 * @author Rashed
 */
 class GridBagLayoutDemo extends JFrame{


    public JLabel createLabel(String txt, int width, int height, Color color)
    {
        JLabel label = new JLabel(txt);
        label.setOpaque(true);
        label.setBackground(color);
        label.setPreferredSize(new Dimension(width, height));
        return label;
    }

    public GridBagLayoutDemo() throws HeadlessException {
      // setSize(400,400);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       JPanel panel = new JPanel(new java.awt.GridBagLayout());
       panel.setBorder(new EmptyBorder(10, 10, 10, 10));
       GridBagConstraints labCnst = new GridBagConstraints();

       Dimension preferredSize = new Dimension(140,20);

       labCnst.insets = new Insets(3, 3, 3, 3);

       JLabel title = new JLabel("My Title");
       JLabel title2 = new JLabel("My Title");
       JLabel title3 = new JLabel("My Title");

       JLabel selectionLabel1 = new JLabel("");
       selectionLabel1.setBorder(new LineBorder(Color.BLACK));
       JLabel selectionLabel2 = new JLabel("");
       selectionLabel2.setBorder(new LineBorder(Color.BLACK));
       JLabel selectionLabel3 = new JLabel("");
       selectionLabel3.setBorder(new LineBorder(Color.BLACK));

       selectionLabel1.setPreferredSize(preferredSize);
       selectionLabel2.setPreferredSize(preferredSize);
       selectionLabel3.setPreferredSize(preferredSize);

       JButton browse1 = new JButton("Browse");
       JButton browse2 = new JButton("Browse");
       JButton browse3 = new JButton("Browse");


        labCnst.gridx = 0;
        labCnst.gridy = 0;
        panel.add(title, labCnst);
        labCnst.gridy = 1;
        panel.add(title2, labCnst);
        labCnst.gridy = 2;
        panel.add(title3, labCnst);

        labCnst.gridx = 1;
        labCnst.gridy = 0;
        panel.add(selectionLabel1, labCnst);
        labCnst.gridy = 1;
        panel.add(selectionLabel2, labCnst);
        labCnst.gridy = 2;
        panel.add(selectionLabel3, labCnst);

        labCnst.gridx = 3;
        labCnst.gridy = 0;
        panel.add(browse1, labCnst);
        labCnst.gridy = 1;
        panel.add(browse2, labCnst);
        labCnst.gridy = 2;
        panel.add(browse3, labCnst);


       //labCnst.anchor = GridBagConstraints.LINE_END;


       add(panel);
       pack();

    }


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

            @Override
            public void run() {
                new GridBagLayoutDemo().setVisible(true);
            }
        });
    }
}

I am working on a GUI for a project at school. I am using a GridBagLayout in swing.

I want to have a label indicating the input(a type of file @ x = 0, y = 0), followed by another label(the actual file name once selected @ x = 1, y = 0), followed by a browse button for a file chooser( @ x = 2, y = 0). The label at (1,0) is initially blank, however I want the area that the text will occupy to take up some space when the label contains no text. I also want the space between the label at (0,0) and the button at (2,0) to remain constant.

To achieve this, I'm trying to put the label onto a panel and then play with the layouts. However I can't seam to achieve the desired results. Could anyone offer some suggestions? The next three rows of the GridBagLayout will be laid out exactly the same way.

Here is a link to a screen shot of the GUI.

    calibrationFileSelectionValueLabel = new JLabel("",Label.LEFT);
    calibrationFileSelectionValueLabel.setName("calibrationFileSelection");
    calibrationFileSelectionValueLabel.setMinimumSize(new Dimension(100,0));



    calibrationFileSelectionValuePanel = new JPanel();
    calibrationFileSelectionValuePanel.setBorder(BorderFactory.createEtchedBorder());
    calibrationFileSelectionValuePanel.add(calibrationFileSelectionValueLabel);

    c.gridx = 0;
    c.gridy = 0;
    c.fill = GridBagConstraints.NONE;

    filesPanel.add(calibrationFileLabel,c);

    c.gridy = 1;
    filesPanel.add(frequencyFileLabel,c);

    c.gridy = 2;
    filesPanel.add(sampleFileLabel,c);

    c.gridy = 3;
    filesPanel.add(outputFileLabel,c);

    c.gridx = 1;
    c.gridy = 0;
    c.fill = GridBagConstraints.BOTH;

   // filesPanel.add(calibrationFileSelection,c);
    filesPanel.add(calibrationFileSelectionValuePanel,c);

    c.gridy = 1;
   // filesPanel.add(frequencyFileSelection,c);
    filesPanel.add(frequencyFileSelectionValueLabel,c);

    c.gridy = 2;
   // filesPanel.add(sampleFileSelection,c);
    filesPanel.add(sampleFileSelectionValueLabel,c);

    c.gridy = 3;
   // filesPanel.add(outputFileSelection,c);
    filesPanel.add(outputFileSelectionValueLabel,c);

    c.gridx = 2;
    c.gridy = 0;
    c.fill = GridBagConstraints.NONE;
    filesPanel.add(calibrationFileSelectionButton,c);

    c.gridy = 1;
    filesPanel.add(frequencyFileSelectionButton,c);      

    c.gridy = 2;
    filesPanel.add(sampleFileSelectionButton,c);

    c.gridy = 3;
    filesPanel.add(createOutputFileButton,c);       

    panelForFilesPanelBorder = new JPanel();
    panelForFilesPanelBorder.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(5,10,5,10), BorderFactory.createEtchedBorder()));
    panelForFilesPanelBorder.add(filesPanel);

    buttonsPanel = new JPanel();
    buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER));
    buttonsPanel.setBorder(BorderFactory.createCompoundBorder(new EmptyBorder(5,10,10,10), BorderFactory.createEtchedBorder()));
    buttonsPanel.add(startButton);
    buttonsPanel.add(stopButton);
    basePanel.add(panelForFilesPanelBorder);
    basePanel.add(numericInputPanel); 
    basePanel.add(buttonsPanel); 

Well, Essentially, GridBagLayout places components in rectangles (cells) in a grid, and then uses the components' preferred sizes to determine how big the cells should be. With this layout:

  • if the container's size is smaller than the preferred size only then the minimum size gets used.
  • With empty("") text A JLabel\JTextFeild\JButton's preferred size is around (2,2), if no preferred size hints is given to it explicitly using setPreferredSize(size) or overriding getPreferredSize(size).

At his point setting minimum size will not work, as the preferred size with empty text is around (2,2) and container's size is already larger than the preferred size. GridBagLayout uses the preferred size not worrying about the minimum size at all.

You actually need to set both preferred and minimum size with GridBagLayout because:

If you try setting only the preferred size, shrinking the size of the window would eventually cause the container panel's size to get shrink. The container's panel size will be smaller than the preferred size of the component and the JLabel\JTextFeild\JButton shrink to their minimum size. If you haven't given minimum size hints at this point, the default minimum size: likely to be around (2,2) gets used. You will understand better with given working example below.

Some other things to note:

   c.gridx = 1;
    c.gridy = 0;
    c.fill = GridBagConstraints.BOTH;

   // filesPanel.add(calibrationFileSelection,c);
    filesPanel.add(calibrationFileSelectionValuePanel,c);

you are adding the panel which contains your calibrationFileSelectionValueLabel. You don't need to use an extra panel, rather just add the calibrationFileSelectionValueLabel directly to the grid by setting( instead overriding getPreferedSize(Size) is preferable) preferredSize. However try setting inset to the GridBagConstraints to look your first panel a little more nicer:

   gridBagCnst.insets = new Insets(3, 3, 3, 3); 

A minimal working example for you:

In case you are not getting what we are saying, this example i have set only preferred size for resolving your problem. But as i haven't set minimum size, try resizing the window to match with above explanation.

Source code:

import java.awt.*;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import javax.swing.*;
import javax.swing.SwingUtilities;
import javax.swing.border.*;


/**
 *
 * @author Rashed
 */
 class GridBagLayoutDemo extends JFrame{


    public JLabel createLabel(String txt, int width, int height, Color color)
    {
        JLabel label = new JLabel(txt);
        label.setOpaque(true);
        label.setBackground(color);
        label.setPreferredSize(new Dimension(width, height));
        return label;
    }

    public GridBagLayoutDemo() throws HeadlessException {
      // setSize(400,400);
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

       JPanel panel = new JPanel(new java.awt.GridBagLayout());
       panel.setBorder(new EmptyBorder(10, 10, 10, 10));
       GridBagConstraints labCnst = new GridBagConstraints();

       Dimension preferredSize = new Dimension(140,20);

       labCnst.insets = new Insets(3, 3, 3, 3);

       JLabel title = new JLabel("My Title");
       JLabel title2 = new JLabel("My Title");
       JLabel title3 = new JLabel("My Title");

       JLabel selectionLabel1 = new JLabel("");
       selectionLabel1.setBorder(new LineBorder(Color.BLACK));
       JLabel selectionLabel2 = new JLabel("");
       selectionLabel2.setBorder(new LineBorder(Color.BLACK));
       JLabel selectionLabel3 = new JLabel("");
       selectionLabel3.setBorder(new LineBorder(Color.BLACK));

       selectionLabel1.setPreferredSize(preferredSize);
       selectionLabel2.setPreferredSize(preferredSize);
       selectionLabel3.setPreferredSize(preferredSize);

       JButton browse1 = new JButton("Browse");
       JButton browse2 = new JButton("Browse");
       JButton browse3 = new JButton("Browse");


        labCnst.gridx = 0;
        labCnst.gridy = 0;
        panel.add(title, labCnst);
        labCnst.gridy = 1;
        panel.add(title2, labCnst);
        labCnst.gridy = 2;
        panel.add(title3, labCnst);

        labCnst.gridx = 1;
        labCnst.gridy = 0;
        panel.add(selectionLabel1, labCnst);
        labCnst.gridy = 1;
        panel.add(selectionLabel2, labCnst);
        labCnst.gridy = 2;
        panel.add(selectionLabel3, labCnst);

        labCnst.gridx = 3;
        labCnst.gridy = 0;
        panel.add(browse1, labCnst);
        labCnst.gridy = 1;
        panel.add(browse2, labCnst);
        labCnst.gridy = 2;
        panel.add(browse3, labCnst);


       //labCnst.anchor = GridBagConstraints.LINE_END;


       add(panel);
       pack();

    }


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

            @Override
            public void run() {
                new GridBagLayoutDemo().setVisible(true);
            }
        });
    }
}