【问题标题】:Why did JFrame originally require getContentPane() for adding components为什么 JFrame 最初需要 getContentPane() 来添加组件
【发布时间】:2012-02-07 01:32:49
【问题描述】:

我知道,as of Java 1.5,可以像这样向 JFrame 添加组件:

myFrame.add(myButton);

代替:

myFrame.getContentPane().add(myButton);

为什么并非总是如此?

【问题讨论】:

  • 我问的原因是我在教Intro CS,书中的例子都使用旧的符号。我希望能够给学生一些理由,说明为什么曾经有必要进行额外的步骤。

标签: java swing jframe


【解决方案1】:

正如JFrame API 中所述,两者都做同样的事情:向 contentPane 添加一个组件。就在最近(可能是 Java 1.5?)Swing 添加了语法糖/便利方法以允许您直接在 JFrame(或任何其他 Swing 顶级容器)上进行此调用,但您仍在向 contentPane 添加。 remove(...)setLayout(...) 相同,如果您尝试通过 myJFrame.setBackground(Color.green); 设置 JFrame 的背景颜色并且没有任何反应,这将变得非常清楚。正因为如此,我对这种变化不太满意。那也是因为我一定是个老脾气。

【讨论】:

  • 你能告诉我为什么你对改变不满意吗?我试图理解反对它的论点。
  • 这个概念让新手相信 JFrame 实际上是获取组件的东西。 再次尝试在 JFrame 上调用 setBackground(...)。
  • @espertus:请阅读 Swing tutorial section on JFrames and other top-level windows,特别是如果您要教授这些内容。在那里您会明白为什么——Swing 在创建 JFrame 或其他顶级窗口(包括 JFrame、JRootPane、contentPane、glassPane 等)时使用对象的结构化层次结构......每个都有自己的功能。这是非常重要的东西,不能在论坛中很好地解释,无论如何都没有教程那么好。
  • 这是一种分而治之的哲学。 JFrame 本身同意创建一个必须包含本机代码并建立在本机 GUI 组件上的窗口。顶层窗口中的所有其他组件都是轻量级的,并且每个都执行自己的角色 - contentPane 用于保存添加到 GUI 的所有组件并进行布局,菜单栏用于保存菜单,glasspane 用于覆盖所有内容和根窗格以容纳所有内容。
  • 知道了。谢谢,@HovercraftFullOfEels。
【解决方案2】:

4753342:Swing 的顶级组件应该重定向添加/删除 ContentPane 的方法

说明:

与 AWT 编程相反, JFrame/JDialg/JWindow/JApplet/JInternalFrame不允许你添加 Components 给它,而不是你必须了解 JRootPane 并添加 孩子们Components 给它。这给新的 开发人员。

在 5.0 之前,尝试从其中之一添加或删除 Component 这些顶级Components 将导致抛出异常。在 5.0,不会抛出异常,而是将在内容窗格中添加或删除Component。这导致了多次修订 到JFrameJDialogJWindowJAppletJInternalFrame。这已在 RootPaneContainer 的 文档:

 * For conveniance
 * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>,
 * <code>JApplet</code> and <code>JInternalFrame</code>, by default,
 * forward all calls to <code>add</code> and its variants,
 * <code>remove</code> and <code>setLayout</code> to the
 * <code>contentPane</code>. This means rather than writing:
 * <pre>
 * rootPaneContainer.getContentPane().add(component);
 * </pre>
 * you can do:
 * <pre>
 * rootPaneContainer.add(component);
 * </pre>
 * <p>
 * The behavior of <code>add</code> and its variants and
 * <code>setLayout</code> for
 * <code>JFrame</code>, <code>JDialog</code>, <code>JWindow</code>,
 * <code>JApplet</code> and <code>JInternalFrame</code> is controlled by
 * the <code>rootPaneCheckingEnabled</code> property. If this property is
 * true, the default, then <code>add</code> and its variants and
 * <code>setLayout</code> are
 * forwarded to the <code>contentPane</code>, if it is false, then these
 * methods operate directly on the <code>RootPaneContainer</code>. This
 * property is only intended for subclasses, and is therefor protected.

另外,这里有一个相关的错误:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-02
    • 2016-12-27
    • 1970-01-01
    • 2014-06-02
    • 1970-01-01
    • 2019-03-16
    相关资源
    最近更新 更多