6

我正在为学校的一个项目开发 GUI。我在摇摆中使用 GridBagLayout。

我想要一个指示输入的标签(一种文件@ x = 0,y = 0),然后是另一个标签(选择后的实际文件名@ x = 1, y = 0),然后是文件选择器的浏览按钮(@ x = 2, y = 0) . 处的标签(1,0)最初是空白的,但是当标签不包含文本时,我希望文本将占据的区域占用一些空间。我还希望标签 at(0,0)和按钮 at之间的空间(2,0)保持不变。

为此,我尝试将标签放在面板上,然后使用布局。但是我无法缝合以达到预期的效果。有人可以提供一些建议吗?GridBagLayout 的接下来三行将以完全相同的方式布局。

这是指向 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); 
4

4 回答 4

6

令人讨厌的是,没有文本的标签不会占用垂直空间。您可以通过" "在它为空时使用来解决此问题。

JLabel fileNameLabel = new JLabel(" ");
于 2013-11-02T03:11:34.920 回答
4

好吧,本质上,GridBagLayout 将组件放置在网格中的矩形(单元格)中,然后使用组件preferred sizes来确定单元格的大小。使用这种布局

  • 如果容器的尺寸小于首选尺寸,使用最小尺寸。
  • 使用 empty( "") 文本 AJLabel\JTextFeild\JButton的首选大小约为(2,2),如果没有明确使用setPreferredSize(size)或覆盖的首选大小提示getPreferredSize(size)

此时设置最小尺寸将不起作用,因为带有空文本的首选尺寸在附近(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);

您正在添加panel包含您的calibrationFileSelectionValueLabel. 您不需要使用额外的面板,而只需calibrationFileSelectionValueLabel通过设置直接将其添加到网格中(而不是覆盖getPreferedSize(Size)更可取)preferredSize。但是尝试将 inset 设置为使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);
            }
        });
    }
}
于 2013-11-02T06:51:48.940 回答
1

我使用 John 的技巧修改了 Sage 的程序" ",并添加了一点我自己的GridBagConstraint风格,以使对话框在折叠和展开时更自然地调整大小。

public class GridBagLayoutDemo extends JFrame {

    public GridBagLayoutDemo() throws HeadlessException {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        this.setLayout(new BorderLayout());

        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, 1);

        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");

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

        setPreferredWidth(selectionLabel1, 120);
        setPreferredWidth(selectionLabel2, 120);
        setPreferredWidth(selectionLabel3, 120); 

        JButton browse1 = new JButton(new AbstractAction("Browse 1") {
            public void actionPerformed(ActionEvent arg0) {
                selectionLabel1.setText("C:\\Documents and Settings\\jsmith\\My Documents\\Studio 2014\\Projects\\1");
            }
        });
        JButton browse2 = new JButton(new AbstractAction("Browse 2") {
            public void actionPerformed(ActionEvent arg0) {
                selectionLabel2.setText("C:\\Documents and Settings\\jsmith\\My Documents\\Studio 2014\\Projects\\2");
            }
        });
        JButton browse3 = new JButton(new AbstractAction("Browse 3") {
            public void actionPerformed(ActionEvent arg0) {
                selectionLabel3.setText("C:\\Documents and Settings\\jsmith\\My Documents\\Studio 2014\\Projects\\3");
            }
        });

        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.weightx = 1;
        labCnst.fill = GridBagConstraints.HORIZONTAL;
        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.weightx = 0;

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

        add(panel, BorderLayout.CENTER);
        pack();

    }

    private void setPreferredWidth(JComponent c, int w) {
        Dimension d = c.getPreferredSize();
        d.width = w;
        c.setPreferredSize(d);
    }

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

            @Override
            public void run() {
                GridBagLayoutDemo demo = new GridBagLayoutDemo();
                demo.setLocationRelativeTo(null);
                demo.setVisible(true);
            }
        });
    }
}
于 2013-11-02T10:23:13.340 回答
-1

正如约翰所说,在标签中放置一个空格和/或将其设置为setMinimumSize().

如果打算稍后在 UI 活动上填充标签,则最小尺寸很有用。当最初没有选择任何内容时,可以防止 UI 压缩成丑陋的状态。

于 2013-11-02T03:12:29.377 回答