【问题标题】:Insets.top , left, bottom, right all zeroInsets.top , left, bottom, right 都为零
【发布时间】:2012-10-04 00:19:14
【问题描述】:

这是我用来实例化 JFrame 的代码示例:

public class TestFrame{
public static void main(String[] args){
    JFrame frame = new JFrame();
    Insets insets = frame.getInsets();
    frame.setSize(new Dimension(insets.right + insets.left + 400, insets.bottom + insets.top + 400));
    System.out.println(String.format("Top = %d \nBottom = %d \nLeft = %d \n Right
            = %d", insets.top, insets.bottom, insets.left, insets.right));

    frame.setResizable(false);
    frame.setVisible(true);
}
}

框架显示正常,但所有插图似乎都为零。我需要知道顶部标题栏的大小,因为我想要一个大小为 400x400 的内容窗格。

我在多个平台上对其进行了测试,在 windows 和 mac 上发生了同样的事情。

我做错了什么?

【问题讨论】:

    标签: java swing layout layout-manager insets


    【解决方案1】:
    1. 如果您希望内容窗格精确为 400x400,那么我会考虑将其 preferredSize 设置为 400x400(虽然我不喜欢在内容窗格上强制使用首选尺寸,但在某些情况下它可能是可以接受的)。
    2. 设置首选尺寸后,在显示框架之前,在框架上调用pack()

    这是最干净、最简单的解决方案,您不必关心边框插图。

    【讨论】:

    • 考虑覆盖getPreferredSize();以前投票过。
    • @trashgod 出于好奇,为什么覆盖比设置首选大小更好?
    • @trashgod 我已经阅读了那个答案,但我的问题更多的是“为什么覆盖比设置更好?”最后都是一样的。据我了解引用链接的建议,我们应该避免在嵌套组件上设置首选大小,但在 root 上,这不是问题
    • @Guillaume:你是对的;我可能对太多 this 的应用程序感到厌烦。
    【解决方案2】:

    如果 contentPane 应该正好是 400 x 400,则创建一个类,将其重新调整为它的 preferredSize 并将其用作 contentPane:

    class MyContentPane extends JPanel {
       public static final int PREF_W = 400;
       public static final int PREF_H = 400;
    
       public Dimension getPreferredSize() {
         return new Dimension(PREF_W, PREF_H);
       }
    }
    

    或者更好:

    class MyContentPane extends JPanel {
       public int prefW;
       public int prefH;
    
    public MyContentPane(int prefW, int prefH) {
       this.prefW = prefW;
       this.prefH = prefH;
    }
    
       public Dimension getPreferredSize() {
         return new Dimension(prefW, prefH);
       }
    }
    

    正如其他海报所提到的,您必须在顶级窗口上使用 pack() 并使用布局管理器。

    我自己不喜欢这样做,而是让各种组件的实际首选大小和容器的布局管理器为我做所有这些决定。

    【讨论】:

    • +1,我们得出了相同的结论。虽然简单地设置首选大小也可以,并且不需要扩展 JPanel。
    • @Guillaume:我同意,但我讨厌被 kleopatra/Jeanette 扇耳光设置首选大小,所以我尝试通过方法覆盖来做到这一点。
    • 我也讨厌这样 ;-) 但在这种情况下,这似乎是解决问题的一种非常有效的方法。最后,结果是一样的,这才是最重要的:-)
    • @guillaume:我自己喜欢的方法,我也敢打赌你的,是尽量避免这整个业务,让组件告诉布局管理器他们喜欢的尺寸,然后让布局管理器确定应用程序的最佳大小。
    • 当然。在使用嵌套的 LayoutManager 时尤其如此。
    【解决方案3】:

    您误解了您正在处理的内容,因此看起来“错误”。

    插图不是内容窗格之外“东西”的尺寸。它们类似于内容窗格周围的“边框”,不允许进行绘图。与边框不同,插图不重叠。

    装饰周围窗口的大小不是由程序决定的。它由处理焦点和窗口导航的不同程序确定。该程序称为窗口管理器。它是处理“顶部标题栏”及其高度、字体等的窗口管理器。

    要获得“精确大小”的程序,您需要向窗口管理器询问无框窗口,这可以在 Java 中完成。它不会在顶部有标题栏,也不会在边缘附近调整大小手柄、窗口命令菜单、要关闭的红色“x”或在桌面上移动窗口的方法(尽管您的程序可以重新定位自己如果这样写)。

    另一种方法是在适当的尺寸和根窗格窗口中请求一个独占的“屏幕”,这有时是在游戏中完成的。这是一种限制性更强的处理方式,并且分辨率仅限于支持的屏幕尺寸。

    如果您确实希望内容窗格具有特定大小,而不是整个窗口具有特定大小,请查看其他处理内容窗格首选大小的优秀答案。

    【讨论】:

      【解决方案4】:
      1. 在面板中制作您的用户界面。
      2. 设置面板的首选大小。
      3. 将面板添加到框架并调用pack()

      【讨论】:

      • 那行不通。尝试运行它并检查会发生什么:JFrame frame = new JFrame(); JLabel label = new JLabel("Some label"); frame.getContentPane().add(label); frame.getContentPane().setSize(400, 400); frame.pack(); frame.setVisible(true);
      • 我说的不是内容窗格,而是直接在我们设置大小的框架上添加另一个面板
      • 在框架上添加面板与添加到内容面板完全相同。而且即使你添加了一个中间面板,它仍然不起作用。
      • 看这个。 www.java.net/node/650887
      • 这不是您在此处详述的内容。在那个论坛中,这家伙直接设置了 JFrame 的大小。你说“设置面板的大小”。这些是不同的东西。无论如何,调用 pack() 会导致将内容窗格设置为 getPreferredSize() 返回的大小。在您的情况下,您没有设置任何内容,因此这将依赖于 LayoutManagers,它将根据面板内的内容返回一个值。看看其他答案并尝试您的解释:您会发现它不起作用。
      【解决方案5】:
      • BorderLayout(在JFrame API中预实现)忽略Insets

      • 大部分LayoutManager 也忽略Insets,仅AbsoluteLayout 需要,

      基本和常见的东西

      • JFrame(以及大部分Containers)只能返回InsetsBoundsSize

        a) 来自已经可见的容器

        b) 通话后JFrame(e.i.)#pack()

      • 那么在大多数情况下,设置为InsetsBoundsSizeXxxSize 超过了反效果,因为

        a) 大多数JComponents 可以返回自己的和正确的PreferredSize 给它的父级,

      • 但不包括

        a) Graphics(2D),

        b) 用于空容器

        c) JScrollPane & JList / JTable,在 JScrollPane 可以通过其容器调整大小的情况下生成自己的代码怪物会产生矛盾

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多