【问题标题】:Layout Manager preferredSize Java布局管理器首选大小 Java
【发布时间】:2011-10-26 10:19:25
【问题描述】:

我仍在尝试了解布局管理器的工作原理。我用两个 JPanel 制作了一个框架。 第一个包含一个带有 boxLayout 的 textArea。 第二个包含一个带有按钮的流布局。

我相应地设置了每个面板的preferredSize,将它们打包,但得到了意想不到的结果。

import java.awt.*;
import javax.swing.*;

public class LayoutMgrTest
{
    public static void main(String[] args)
    {
        TableBasic frame = new TableBasic();
        frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
        frame.setVisible(true);


        frame.getContentPane().setLayout(new GridLayout(2,1));

        JPanel controlPane = new JPanel();
        JPanel buttonPane = new JPanel();

        controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.PAGE_AXIS));
        controlPane.setPreferredSize(new Dimension(200, 200));
        controlPane.add(new JScrollPane(new JTextArea()));

        buttonPane.setLayout(new FlowLayout(FlowLayout.LEFT));
        buttonPane.setPreferredSize(new Dimension(100,20));
        buttonPane.add(new JButton("Button1"));
        buttonPane.add(new JButton("Button2"));

        frame.getContentPane().add(controlPane, BorderLayout.NORTH);
        frame.getContentPane().add(buttonPane, BorderLayout.SOUTH);
        frame.setSize(new Dimension(500,500));
        frame.pack();
    }
}

无论我做什么,如果我使用网格布局,它似乎总是为每个控件分配一半的可用空间。有人告诉我:

每一行的高度取决于每个组件的高度 在每一行中添加。

按钮窗格的高度是 20。它分配的远不止于此:

这段代码有什么问题?
我想保留这两个 JPanel 完好无损。将文本框和按钮直接添加到框架很容易,但我需要使用 JPanel 来完成(因为我将添加边框和其他东西)。

【问题讨论】:

    标签: java swing layout


    【解决方案1】:

    如果您使用 LayoutManager,则不应在除框架之外的组件上设置大小。

    组件的大小由不同的布局管理器计算得出。

    您可以在http://download.oracle.com/javase/tutorial/uiswing/layout/howLayoutWorks.html找到更多信息

    在您的代码中,您可以将带有文本区域的面板添加到 BorderLayout.CENTER。这应该可以解决您的问题。 BorderLayout.CENTER 中的组件占用整个空间,除了 NORTH、EAST、SOUTH 和 WEST 中的组件所需的空间。

    【讨论】:

      【解决方案2】:

      我相应地设置了每个面板的preferredSize,

      这是另一个问题。您不应该设置首选尺寸。这是布局管理器的工作。只需将您的组件添加到面板中,然后让布局管理器完成它的工作。

      大多数组件都有默认的首选大小。对于某些人来说,你需要给它一点小费。 例如,当使用文本区域时,您可以通过以下方式给出“建议的”首选大小:

      JTextArea textArea = new JTextArea(rows, columns);
      

      【讨论】:

      • 好主意,我会尽量避免。这次我在做实验。
      • 不正确; preferredSize 是布局管理器基于其计算的值之一(尽管不是全部)。他们计算的结果是 size 属性,而不是 preferredSize。
      • @Michael,我支持我的评论。海报不应设置controlPane 或buttonPane 的首选尺寸。布局管理器将根据添加到它们的组件确定这些面板的首选大小。然后,此信息将用于根据添加到框架的所有面板的首选大小来打包()框架。是的,然后布局管理器将设置每个面板的大小/位置。
      • @camickr:嗯,你说得对:设置具有布局管理器的容器的首选大小没有用;我的陈述对于常规组件是正确的。
      • @Michael 你不应该为独立组件设置大小(最小、最大、首选项或实际),因为大多数 Swing 组件都知道如何根据他们的内容;那么 LayoutMnager 的工作就是计算设置它们的实际大小(和位置)。
      【解决方案3】:

      这就是使用 GridLayout 作为布局管理器的结果。将其更改为 BorderLayout:

      frame.getContentPane().setLayout(new BorderLayout());
      

      例如,这段代码(我在原来的基础上做了一点改动):

      import java.awt.*;
      import javax.swing.*;
      
      public class LayoutMgrTest
      {
          public static void main(String[] args)
          {
              JFrame frame = new JFrame();
              frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
              //frame.setVisible(true);   
              //frame.getContentPane().setLayout(new BorderLayout());
      
              JPanel controlPane = new JPanel();
              JPanel buttonPane = new JPanel();
      
              controlPane.setLayout(new BoxLayout(controlPane, BoxLayout.PAGE_AXIS));
              controlPane.setPreferredSize(new Dimension(200, 200));
              controlPane.add(new JScrollPane(new JTextArea()));
      
              buttonPane.setLayout(new FlowLayout(FlowLayout.LEFT));
              buttonPane.setPreferredSize(new Dimension(100,40));
              buttonPane.add(new JButton("Button1"));
              buttonPane.add(new JButton("Button2"));
      
              frame.add(controlPane, BorderLayout.NORTH);
              frame.add(buttonPane, BorderLayout.SOUTH);
              //frame.setSize(new Dimension(500,500));
              frame.pack();
              frame.setVisible(true);
          }
      }
      

      生成此帧:

      【讨论】:

      • @mKorbel - 谢谢。我的方法总是尽可能少地改变,但我认为你的更好:)
      • 感谢您的回答。这次有点晚了 mKorbel :P 你通常总是对 Swing GUI 很有帮助:)
      • @David 请阅读 (@camickr) 的一些加密建议 == 不要,永远不要设置 setSize(), setBounds() +1
      • 另请参阅How do I create a screenshot to illustrate a post?,了解有关制作出色屏幕截图的一些技巧。
      • 对于上面的屏幕截图,您运行的是什么操作系统。
      猜你喜欢
      • 2016-06-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多