【问题标题】:How do I get a JPanel with an empty JLabel to take up space in a GridBagLayout如何获得带有空 JLabel 的 JPanel 以占用 GridBagLayout 中的空间
【发布时间】:2013-11-13 08:10:58
【问题描述】:

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

我想要一个标签来指示输入(一种文件@x = 0,y = 0),然后是另一个标签(实际文件名一旦选择@x = 1, y = 0),然后是一个浏览按钮一个文件选择器(@x = 2, y = 0)。 (1,0) 的标签最初是空白的,但是当标签不包含文本时,我希望文本将占据的区域占用一些空间。我还希望(0,0) 处的标签和(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); 

【问题讨论】:

  • 拍张照片,上传到其他地方并添加到您的问题中,以便我们更好地理解
  • 您可以通过调用 setMinimumSize(Dimension d) 来设置 JLabel 的最小尺寸,这应该可以满足您的需求。
  • 嗯。好吧,我尝试添加图像。我显然需要 10 票。
  • 添加图片链接,我们可以为您将其添加到您的问题中。我的建议呢?
  • @HovercraftFullOfEels,在这种情况下,GridBagLayout 仅设置最小尺寸将不起作用。检查我的答案以获取详细信息,并指出我所解释的任何内容是否有误:)

标签: java swing gridbaglayout


【解决方案1】:

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

JLabel fileNameLabel = new JLabel(" ");

【讨论】:

    【解决方案2】:

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

    • 如果容器的尺寸小于比首选尺寸只有最小尺寸被使用。
    • 如果没有使用 setPreferredSize(size) 或覆盖 getPreferredSize(size) 明确给出首选大小提示,则使用空 ("") 文本 A 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);
                }
            });
        }
    }
    

    【讨论】:

    • 我希望你不介意,我在回答中偷了你的程序,并且(我认为)通过使标签在调整窗口大小时更自然地折叠和展开来对其进行了一些改进。我给了你荣誉。
    • @MikeClark,没关系,我不会,因为您的回答使我的解释更加清楚:)
    • 插图。您可以使用插图创建各种空白。
    【解决方案3】:

    我使用 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);
                }
            });
        }
    }
    

    【讨论】:

    • 有一点要提一下,Jhon 的想法更像是一种黑客投诉,它回避了实际情况。请不要误会我的意思,我个人不喜欢在不解释所有组件而不是任何特定类型的组件通用的逻辑推理的情况下推广这样的想法:)
    【解决方案4】:

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

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

    【讨论】:

    • 所以 setMinimumSize() 对第一个标签和按钮之间的空间没有影响。我可以将标签初始化为我需要的任何长度的空字符串,但是当我的标签被设置时,如果它的长度不同,那么第一个标签和按钮之间的间距可能会改变。我需要保持不变。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    相关资源
    最近更新 更多