【问题标题】:Effect of setMaximumSize on JPanels arranged in a boxlayoutsetMaximumSize 对 boxlayout 中排列的 JPanel 的影响
【发布时间】:2012-07-13 22:09:04
【问题描述】:

我注意到在 boxlayout 中设置最大尺寸有些奇怪。

我需要在窗口右侧运行一列面板,我尝试将其设置为框式布局。可能有 8-10 或 30-40,所以我给它们足够的空间来容纳 30-40,但如果只有 8-10,它们会分散开来占用所有可用空间,看起来很奇怪。所以我想我会为他们设置MaximumSize 以阻止这种情况发生......

...最后我发现它们中的大多数都消失了。

所以我把它分解成一堆非常基本的彩色面板,试图看看发生了什么,我已经想出了如何继续,但我不喜欢它。

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

public class BoxLayoutDemo extends JFrame {


  public BoxLayoutDemo() {
    super("JScrollPane Demonstration");
    setSize(800, 600);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    init();
    setVisible(true);
  }

  public void init() {
    setLayout(null);

    JPanel rightPanel = new JPanel();
    rightPanel.setBounds(400,0,400,600);
    rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS));

    JPanel greenPanel = new JPanel();
    JPanel bluePanel = new JPanel();
    JPanel yellowPanel = new JPanel();
    greenPanel.setBackground(Color.GREEN);
    bluePanel.setBackground(Color.BLUE);
    yellowPanel.setBackground(Color.YELLOW);

    rightPanel.add(greenPanel);
    rightPanel.add(bluePanel);
    rightPanel.add(yellowPanel);

    add(rightPanel);



  }

  public static void main(String args[]) {
    new BoxLayoutDemo();
  }
}

...这正是我所期望的:三个彩色框占据了屏幕的右半部分。

如果我添加类似:

greenPanel.setMaximumSize(new Dimension(400,100));
bluePanel.setMaximumSize(new Dimension(400,100));
yellowPanel.setMaximumSize(new Dimension(400,100));

然后,三个彩色框每个都只有 100 像素高,只占据屏幕的上半部分左右,这也是我所期望的。

但如果我这样做......

greenPanel.setMaximumSize(new Dimension(400,100));
yellowPanel.setMaximumSize(new Dimension(400,100));

蓝色面板将另外两个压扁到只有几个 px 高。

这可能不会成为问题,我可以为所有内容设置一个最大大小,但是在这并不可行的假设情况下,有没有办法改变这种行为,或者这只是盒子布局有什么作用?

编辑:

好的,所以我们将 test1 称为:

greenPanel.setMinimumSize(new Dimension(400,100));
yellowPanel.setMinimumSize(new Dimension(400,100));

...这对任何东西都没有影响,因为绿色和黄色面板无论如何都大约 200 px 高。

测试2:

greenPanel.setMaximumSize(new Dimension(400,100));
yellowPanel.setMaximumSize(new Dimension(400,100));

...如最初描述的那样,使蓝色面板挤出绿色和黄色面板。

测试3:

greenPanel.setMinimumSize(new Dimension(400,100));
greenPanel.setMaximumSize(new Dimension(400,100));
yellowPanel.setMinimumSize(new Dimension(400,100));
yellowPanel.setMaximumSize(new Dimension(400,100));

...应该生成 100 px 高的绿色和黄色面板,正如您所描述的,但实际上实际发生的情况与 test2 中的完全相同。

【问题讨论】:

  • 永远不要硬编码大小。永远不要考虑空布局或干扰组件的大小提示 (stackoverflow.com/questions/7229226/…)。选择一个满足您的需求并允许微调的 LayoutManager,f.i. MigLayout(或者如果你被核心管理器卡住了,GridBagLayout)。
  • 是的,是的,Java 俱乐部的第一条规则。除了布局管理器实际上不会使视觉内容很好地缩放,除非我采取额外措施使其无论如何都可以与空布局一起使用。我对编程约定的宗教态度不感兴趣。
  • 耸耸肩,现在是你的时间浪费在坚持做错误的事情上......

标签: java swing layout jpanel sizing


【解决方案1】:

问题是,bluePane 的默认最大尺寸现在是 32767x32767...

布局管理器基本上会尝试为蓝色提供最大的空间(默认的最小尺寸在我的 PC 上似乎是 10x10(默认的首选尺寸也是如此))

如果不使用 setMaximumSize,我将您的代码更改为使用 minimumSize

greenPanel.setMinimumSize(new Dimension(400,100));
yellowPanel.setMinimumSize(new Dimension(400,100));

我可以得到想要的结果,因为布局管理器无法再为蓝色窗格分配更多空间。

更新

那我错过了什么。

如果我使用您的默认代码,我会正常设置所有三个面板。 如果我只使用绿色和黄色(最大尺寸),那么它们会像你描述的那样被压扁 如果我设置绿色和黄色的最小尺寸,我会正常设置三个面板

这是我使用的代码。

public void init() {

    setLayout(null);

    JPanel rightPanel = new JPanel();
    rightPanel.setBounds(400,0,400,600);
    rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.PAGE_AXIS));

    JPanel greenPanel = new JPanel();
    JPanel bluePanel = new JPanel();
    JPanel yellowPanel = new JPanel();

      Dimension size = new Dimension(400, 100);

      // Default
    //    greenPanel.setMaximumSize(size);
    //    bluePanel.setMaximumSize(size);
    //    yellowPanel.setMaximumSize(size);

      // Test 1
    //    greenPanel.setMaximumSize(size);
    //    yellowPanel.setMaximumSize(size);

      // Test 2
      greenPanel.setMinimumSize(size);
      yellowPanel.setMinimumSize(size);

    greenPanel.setBackground(Color.GREEN);
    bluePanel.setBackground(Color.BLUE);
    yellowPanel.setBackground(Color.YELLOW);

    rightPanel.add(greenPanel);
    rightPanel.add(bluePanel);
    rightPanel.add(yellowPanel);

    add(rightPanel);

  }

您的默认设置

仅限绿色和黄色最大(蓝色默认尺寸)

仅限绿色和黄色最小(蓝色默认尺寸)

现在认真想想发生了什么。

在默认测试下,布局管理器已确定它可以按比例布局所有面板(因为高度相同)。它必须这样做,因为已经设置了最大尺寸并且它有空间这样做。事实上,如果我根本没有设置任何尺寸(全部默认),它们会以这种方式布局

在测试 1 中,确定蓝色窗格比绿色和黄色需要更多的空间(蓝色 MAX 高度 = 32767,绿色和黄色 MAX 高度 = 100) ,因此它会将它们压扁(绿色和黄色的最小高度为 10 像素)

在测试 2 中,决定蓝色窗格应该接收最大的大小(因为它的 MAX 大小是 32767,但最小和首选大小是 10),但也发现绿色和黄色窗格不能小于 100 像素,因此它将剩余空间分配给蓝色(在本例中约为 100 像素)。

更新 2

好的,这就是我的工作:P。基本上,仅使用最小值或仅使用最大值之间的区别在于这些尺寸的默认尺寸(最小/最大/首选项)。

当您只使用最小值时,总组合的最大高度为 98301(每个组件的最大值为 32767)。这需要在组件之间进行划分。布局使用分解方法(根据需要为所有组件提供 % 的空间)。为此,它使用了 max 和 pref 大小的组合。

当我只使用最小尺寸时,实际分配了 200 像素的绿色和黄色 - 这归结为最大尺寸值。仅使用最大尺寸,绿色和黄色分配了 11 个像素(因为蓝色获得了最大份额)。

...所以是的,最小尺寸被忽略了...在这种情况下。

如果分配的空间量 (600) >= 总首选空间 (30),布局管理器将使用此路径。如果分配的空间 (600) 小于总首选空间,布局管理器将使用 pref/min 大小的组合来计算因数...

文档实际上说布局管理器可能会忽略这些 (max/min/pref) 值中的一个或多个,因为它们只是一个指导方针。

但是,如果改用 pref 大小,蓝色和绿色分配 229 像素(蓝色仅获得 140)。

在这种情况下,我会选择 max 和 pref 大小的组合,或者使用 GridBagLayout 之类的东西。

我没用过,但很多人都对 MigLayout 发誓。

嘿,谢谢你提出一个有趣的问题;)

【讨论】:

  • 即使这样可行,它也不是一个理想的解决方案,但它不起作用。为绿色和黄色设置这些最小值会产生与根本不设置任何尺寸完全相同的结果,因为无论如何它们都比这大。如果我将绿色和黄色的最小值和最大值都设置为 400,100,但对蓝色不做任何事情,那么我会得到与以前相同的结果。蓝色面板排挤了其他两个,显然它们的最小尺寸被忽略了。
  • 查看编辑,cmets 中没有段落结构使阅读变得困难。
  • 干杯,还有更多信息可以参考
猜你喜欢
  • 2012-07-28
  • 2010-10-19
  • 1970-01-01
  • 2014-10-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 2013-04-13
相关资源
最近更新 更多