繁体   English   中英

防止 MigLayout 为组件分配空间

[英]Prevent MigLayout from assigning space to a component

我有一个 JFrame,它由一组可能任意大的“标题”组成,可以单击以显示面板,每个标题一个(概念上类似于垂直排列的工具栏,标题是显示各种工具面板的选项卡) . 我希望标题有固定数量的垂直空间分配给它们,但水平增长以填充框架的宽度。 我希望标题暴露的面板消耗框架中所有多余的垂直空间——但前提是它们是可见的; 当不可见时,它们应该占用零空间。

不幸的是,无论我如何尝试调整布局,我都无法阻止它为标题和不可见面板分配额外的空间。 在演示应用程序中,只需将窗口放大即可。 期望的行为是蓝色的“Hello 0”面板应该变高,而所有其他组件保持“紧凑”; 实际上,我在两个“Compact label”标签周围和两个较低的“Click me”标题下方看到了空白区域。

谢谢你的时间!

public class Demo {
   public static void main(String[] args) {
      final JFrame frame = new JFrame("Inspector");
      frame.setLayout(new MigLayout("debug, fill, flowy, insets 0, gap 0"));
      frame.add(new JLabel("Compact label 1"));
      frame.add(new JLabel("Compact label 2"));
      for (int i = 0; i < 3; ++i) {
         JPanel wrapper = new JPanel(
               new MigLayout("debug, fill, flowy, insets 0, gap 0",
                  "", "0[]0[grow]0"));
         // Fixed-height header should grow horizontally only
         JPanel header = new JPanel(
               new MigLayout("flowx, fillx, insets 0, gap 0"));
         header.add(new JLabel("Click me!"), "growx, height 40!");
         header.setBackground(Color.RED);
         // Variably-sized body should fill any extra space.
         final JPanel body = new JPanel(new MigLayout("fill"));
         body.add(new JLabel("Hello, " + i), "grow");
         body.setBackground(Color.BLUE);
         body.setVisible(i == 0);
         wrapper.add(header, "growx");
         wrapper.add(body, "growy, hidemode 2");
         header.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
               boolean shouldShow = !body.isVisible();
               body.setVisible(shouldShow);
               frame.pack();
            }
         });
         frame.add(wrapper, "grow");
      }
      frame.pack();
      frame.setVisible(true);
   }
}

最好使用JTabbedPane获得所需的内容。

否则,您可以在组件上放置宽度和高度百分比约束。 因此,对于标题,您可以告诉他们使用以下宽度的100%:

wrapper.add(header, "growx , w 100%");

对于身体,您可以输入“ h 100%”(可以使用h或height)

wrapper.add(body, "growy, hidemode 2, h 100%");

它并不完美,但希望能有所帮助。

最终,我不得不诉诸于删除和重新添加组件到布局管理器,根据给定主体是否可见使用不同的约束。 这不是理想的,但确实会导致所需的行为。 MigLayout确实有一个setComponentConstraints()方法,您认为可以使用该方法,但是,就像Matt Hubbard的建议一样,当显示/隐藏物体时,它不会重新计算尺寸,从而导致可见物体的空间分布不均匀。

这是更新的演示程序:

public class Demo {
   public static void main(String[] args) {
      final JFrame frame = new JFrame("Inspector");
      final JPanel contents = new JPanel(
            new MigLayout("debug, fill, flowy, insets 0, gap 0"));
      contents.setBackground(Color.GRAY);
      frame.add(contents);
      final ArrayList<Component> components = new ArrayList<Component>();
      components.add(new JLabel("I should not grow"));
      components.add(new JLabel("I shouldn't grow either"));
      for (int i = 0; i < 3; ++i) {
         // Fixed-height header should grow horizontally only
         final JPanel header = new JPanel(
               new MigLayout("flowx, fillx, insets 0, gap 0"));
         header.add(new JLabel("Click me!"), "growx, height 40!");
         header.setBackground(Color.RED);
         components.add(header);
         // Variably-sized body should fill any extra space.
         final JPanel body = new JPanel(new MigLayout("fill"));
         body.add(new JLabel("Hello, " + i), "grow");
         body.setBackground(Color.BLUE);
         body.setVisible(i == 0);
         components.add(body);
         header.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseClicked(MouseEvent e) {
               boolean shouldShow = !body.isVisible();
               body.setVisible(shouldShow);
               refill(frame, contents, components);
            }
         });
      }
      refill(frame, contents, components);
      frame.setVisible(true); 
   } 
   private static void refill(JFrame frame, JPanel contents,
         ArrayList<Component> components) {
      contents.removeAll();
      for (int i = 0; i < components.size(); ++i) {
         Component component = components.get(i);
         // First two components don't grow at all.
         if (i < 2) {
            contents.add(component, "gap 0, grow 0, pushy 0");
         }
         // Even-numbered components are headers.
         else if (i % 2 == 0) {
            contents.add(component, "gap 0, growx, growy 0, pushy 0");
         }
         // Odd-numbered components are bodies, only if visible.
         else if (component.isVisible()) {
            contents.add(component, "gap 0, grow, pushy 100");
         }
      }
      Dimension curSize = frame.getSize();
      frame.pack();
      frame.setSize(curSize);
   }
}

我认为您正在寻找的是hidemode命令。 这将阻止 MigLayout 为尚不可见的组件分配空间。

我将把这个SO 问题留在这里,它解释了如何使用这个选项。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM