【问题标题】:Layouts in java Swing specifying sizejava Swing中的布局指定大小
【发布时间】:2016-08-10 00:07:51
【问题描述】:

我的问题是如何指定布局中部件的大小?
我需要以某种方式设置“部分”的大小,而不是使用preferedSize,也许在布局管理器中,不管在哪里 - 我只需要稳定的大小。

我想为游戏创建布局。我已经创建了一个,但我正在处理组件大小的问题。所以我认为最好对我的布局做出更好的概念。
让我们看看我的草稿。

+-----------+ |上 | +-----+-----+ |一个 | | +-----+ C | |乙| | +-----+-----+ |页脚 | +-----------+ A+B+C 共同构成中心。

主要部分由这个树部分组成:
上层-会有菜单。
中心 - 这包括 3 个部分 A、B、C
页脚 - 会有状态栏


我的想法是能够设置每个组件的大小。 所有布局都取决于 C 部分,它的大小可能为 450x450 像素或 600x600 像素。
对于 A 部分和 B 部分,我只需要指定宽度,因为只有一些文本信息 - 它应该是大约 300 像素。
我尝试将 GridBagLayout 用于中心部分,但用于 C 的 setSize 效果不佳。
我在 Containers (java.awt.Container) 中制作零件 - 我在其中添加每个零件的内容,然后将 Container 添加到上层。

【问题讨论】:

  • 你不应该设置组件的大小。组件应该知道它们的首选大小并在调用 getPreferredSize() 时返回它。大多数布局使用组件的首选大小来相应地布置它们。
  • 好的,我发现这是布局管理器的工作……我不想设置组件的首选大小。可以在Layout manager(managers)中严格设置组件的大小吗?
  • 您不能手动设置控件的大小,除非您完全不使用布局管理器,而是手动全部进行。恐怕没有中间道路。
  • 我会在 GUI 上设置Cpack() 的首选大小并在框架上调用setResizable(false)
  • 嗨......我自己目前正在努力解决这个问题。我在我的 gui 中处于早期阶段,并且我已经对应该“扩展”以填充(剩余)可用区域的主面板提出了挑战。这很烦人。我还从本质上认为“布局”必须填充可用的已发布空间——正如该术语的印刷起源来自出版一样,布局是“页面(作为一个整体)如何布局”!

标签: java swing layout layout-manager


【解决方案1】:

最简单的方法:对 contentPane 使用 BorderLayout(已经是) - 上面板向北 - 页脚面板向南 - 面板 A 和 B 使用 GridLayout(2,1) 进入面板 ab - 面板 ab 和 C 进入具有 GridLayout(1,2) 的面板 abc - 面板 abc 进入中心 和你的 A、B、C 的 setPreferedSize()

【讨论】:

  • 对不起,但这不是我的问题的答案......如何设置零件的尺寸。
  • 设置C 组件的首选大小是创建逻辑大小的GUI 所需要的(除了xyz 的整体策略)。如果您想稍微“填充”一下,请在需要的地方添加边框。我打算创建一个基本上遵循 xyz 概述的公式的 GUI,直到 a) 我看到它已经说过,并且 b) 你声称它不是所需要的!
  • 我不同意,因为这导致ab 的大小(resp 宽度,heignt 也相同但不是问题)将与C 的大小相同。 (在 ab 上设置首选大小也不起作用......)。
  • 你说得对。那么你应该在将面板 ab 和 C 添加到另一个面板时使用 GridBagLayout,当然还有 C 的 setPreferredSize。
  • @xyz 当我使用 GridBagLayout 时,在C 处停止使用preferedSize,你不能只看到A、B、C 部分的部分......这是魔术圈......跨度>
【解决方案2】:

一般来说,GridBagLayout 会忽略您为带有setSize 的控件设置的值,而是询问控件的首选 大小(通过调用getPreferredSize)并使用它来计算整体布局.不建议您自己简单地设置首选大小,因为大多数控件倾向于在触发布局时重新计算这些值,因此您很难让它们“粘住”。

如果您真的想确保 UI 元素 C 具有一定的大小,请将其实现为从合适的基(例如 JPanel)派生的自定义类并覆盖 getPreferredSize 方法让它返回你想要/需要的 UI 部分的大小。

编辑:这是一个包装器的小例子,它可以包含另一个 UI 元素并且可以设置为固定大小(使用已被覆盖的 setSize 方法),应该遵守由布局管理器:

import java.awt.BorderLayout;
import java.awt.Dimension;

import javax.swing.JComponent;
import javax.swing.JPanel;

public class FixedSizeComponent extends JPanel {
    private Dimension size;
    private final JComponent content;

    public FixedSizeComponent(JComponent content) {
        super(new BorderLayout());
        this.content = content;
        super.add(content, BorderLayout.CENTER);
    }

    @Override
    public void setSize(Dimension d) {
        size = d;
    }

    @Override
    public void setSize(int width, int height) {
        size = new Dimension(width, height);
    }

    @Override
    public Dimension getSize() {
        if (size != null) return size;
        return content.getSize();
    }

    @Override
    public Dimension getSize(Dimension rv) {
        if (size != null) {
            if (rv == null) rv = new Dimension();
            rv.height = size.height;
            rv.width = size.width;
            return rv;
        }
        return content.getSize(rv);
    }

    @Override
    public Dimension getPreferredSize() {
        if (size != null) return size;
        return content.getPreferredSize();
    }

    @Override
    public Dimension getMaximumSize() {
        if (size != null) return size;
        return content.getMaximumSize();
    }

    @Override
    public Dimension getMinimumSize() {
        if (size != null) return size;
        return content.getMinimumSize();
    }
}

【讨论】:

  • 哦,为了确保真的,真的确定,最好也覆盖 getMaximumSizegetMinimumSize 方法...
  • “如果你真的想确保 UI 元素 C 具有一定的大小,.. 覆盖 getPreferredSize” 一些布局管理器不会尊重首选大小。而且我从来没有理解覆盖setPreferredSize() 的优势,当您可以简单地从构造函数中调用它并让开发人员选择 default 首选大小是否是他们想要的大小时.
  • 根据我的经验,每当有任何东西使当前布局无效时,往往会重新计算控件的首选大小,因此如果您在构建 UI 期间只设置了一次,重新计算将导致您手动设置首选尺寸被覆盖,您精心布置的布局被破坏。
  • 我发现这是非常值得怀疑的。在设置组件的首选大小时(在构造函数或重写方法之外),无论在 GUI 中发生什么其他情况,该首选大小都会保持不变(缺少对组件本身的另一个显式调用 setPreferredSize())。布局可能会忽略它,但这是完全不同的事情。
【解决方案3】:

我遇到了类似的问题,底部的状态工具栏包含许多其他组件。我的问题是它会变得更高。所以我所做的就是覆盖最大尺寸,将最大高度设置为最小高度。

JPanel status = new JPanel( new SpringLayout() ) {
  @Override
  public Dimension getMaximumSize() {
    Dimension max = super.getMaximumSize();
    Dimension min = getMinimumSize();
    return new Dimension( max.width, min.height );
  }
};

【讨论】:

    【解决方案4】:

    这个答案太少而且太晚了,

    (可能在问这个问题的时候还没有这个方法)

    就像getPreferredSize 一样,还有一个setPreferredSize 方法接受Dimension 对象。

    默认情况下,您的布局将忽略您的组件尺寸(您可能已使用setSize 设置),而是使用首选尺寸。

    通过使用setPreferredSize,您将能够覆盖组件的默认首选大小

    【讨论】:

      【解决方案5】:

      希望我的回答能对你有所帮助。根据设置 JPanel 或 JFrame 大小的经验,我一直使用setPreferredSize(new Dimension(WIDTH,HEIGHT));

      【讨论】:

      • 别误会,使用空布局是不好的做法;但作为最后的手段,当您在决定要使用的最佳布局管理器时遇到困难时,他们似乎都没有按照您的意愿行事?
      • 空布局永远不是答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-01-29
      • 2019-04-04
      • 2018-05-03
      • 2014-12-20
      • 1970-01-01
      • 2014-03-06
      • 1970-01-01
      相关资源
      最近更新 更多