【问题标题】:JFrame does not show up in EclipseJFrame 没有出现在 Eclipse 中
【发布时间】:2014-07-04 21:59:07
【问题描述】:

我尝试在 Eclipse (OSX) 中执行以下代码:

public static void main(String[] args) {
            JFrame frame = new JFrame("Test");
            frame.setSize(new Dimension(400, 30));
            frame.add(new JButton("hello"));
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }

框架未显示,但我收到以下控制台消息:

2014-05-16 14:45:35.230 java[8685:903] [Java CocoaComponent compatibility mode]: Enabled
2014-05-16 14:45:35.232 java[8685:903] [Java CocoaComponent compatibility mode]: Setting timeout for SWT to 0.100000
2014-05-16 14:45:35.546 java[8685:903] *** __NSAutoreleaseNoPool(): Object 0x100612800 of class NSConcreteMapTableValueEnumerator autoreleased with no pool in place - just leaking
2014-05-16 14:45:35.547 java[8685:903] *** __NSAutoreleaseNoPool(): Object 0x100613f40 of class __NSCFDate autoreleased with no pool in place - just leaking
2014-05-16 14:45:35.547 java[8685:903] *** __NSAutoreleaseNoPool(): Object 0x100616e60 of class NSCFTimer autoreleased with no pool in place - just leaking
2014-05-16 14:45:35.550 java[8685:903] *** __NSAutoreleaseNoPool(): Object 0x10061d7c0 of class __NSCFDate autoreleased with no pool in place - just leaking
2014-05-16 14:45:35.550 java[8685:903] *** __NSAutoreleaseNoPool(): Object 0x10061e610 of class NSCFTimer autoreleased with no pool in place - just leaking

同时,如果我将代码放入我的 Eclipse 项目之外的 java 文件中并通过命令行编译和运行它,一切都很好并且框架显示出来。 有人可以帮我解决问题吗?

更新

现在的代码如下所示:

import javax.swing.*;

public class TestFrame {

    public static void main(String[] args) {

        javax.swing.SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI();
            }

            private void createAndShowGUI() {
                JFrame frame = new JFrame("Test");
                System.out.println(SwingUtilities.isEventDispatchThread());
                frame.getContentPane().add(new JButton("hello"));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.pack();
                frame.setVisible(true);
            }
        });

    }
}

这并不能解决问题(正如用户 DSquare 已经提到的)。我发现这似乎是那个特定的 Eclipse 项目的问题。如果我创建一个新的 Eclipse 项目(相同的 Eclipse),代码运行时不会出现错误消息,并且会显示框架。我仍然不知道哪个项目配置可能导致它。我的类路径中没有 swt.jar(尽管插件依赖项中有 org.eclipse.swt 和 org.eclipse.swt.cocoa.macosx.x86_64)。

【问题讨论】:

  • 如果您解释了为什么您可以通过快速搜索找到的多种解决方案不起作用,那将会很有用。您是如何这么快(不到 5 分钟)得出这个结论的,这样您的问题的核心就更清楚了,我们可以帮助解决它,而不是因为解决方案不成功而浪费时间。
  • 我找不到“多种解决方案”(我花了超过 5 分钟寻找它)。您提到我的 OSX 配置错误。如果你能帮我弄清楚我的 OSX 出了什么问题,那就太好了。
  • 这似乎是 OSX 中的线程特定的错误。那段代码本身很好,其他解决方案要么提到添加线程管理所需的某些代码的必要性,要么在 Java 配置中更改某些值。一些相关的答案是thisthisthis 等。
  • 另外,由于这与线程相关,请确保正确了解我提到的 EDT。您应该将invokeLater 放在您的主目录中并从那里开始工作。
  • 我已更改代码(请参阅更新)。除此之外,我还无法弄清楚哪些项目设置错误并导致此错误。

标签: java eclipse macos swing


【解决方案1】:

您的代码是正确的,并且可以在我自己的 Eclipse 中运行。

可能是您的 Eclipse 运行不正常。我认为更改您的 Eclipse 版本并重试。

顺便说一句,确保 jdk 版本在 eclipse 和控制台中是相同的。

【讨论】:

  • 他的代码不正确,但这不是他的问题的原因。见Swing's Hello World。他的示例代码存在一个根本性缺陷。
  • 这是 Swing 的示例和非常好的 hello world 应用程序,但这并不意味着他的代码不正确。
  • 他打破了swing的单线程规则,请阅读initial threads。这个简单的应用程序没有任何问题,但是一旦应用程序变得更大更复杂,就会出现多个不一致和不可重现的错误。这就是为什么 Swing 类的文档充满了“警告:Swing 不是线程安全的。有关更多信息,请参阅Swing's Threading Policy。”消息。
  • 我知道我现在 Swing 不是线程安全的,但这只是你好世界,他不需要考虑复杂的问题。
  • 再一次,看看官方的Hello World,他们确实打电话给invokeLater。 “这只是一个简单的程序”只是懒惰或无知的借口。如果你没有做好简单的程序,你有什么信心去进入更大更重要的程序。
【解决方案2】:

我认为您不能直接将组件添加到 JFrame。您必须使用以下语法:

frame.getContentPane().add(new JButton("hello"));

如@DSquare 所述。

你可以直接添加到其他swing组件中,但JFrame不行。

我做了更多研究,发现从 java 1.5 开始,您可以直接调用 add()JFrame 对象,它会隐式调用正确的窗格。这仅包括添加步骤。对内容窗格的所有其他调用都应明确完成。

【讨论】:

  • 我什么都没说,我指的是EDT问题,正如我稍后指定的那样。您可以直接添加到 JFrame,因为JFrame.add(...) 只是JFrame.getContentPane().add(...) 的商品方法,如documentation 中指定的那样。他是配置问题,不是代码问题。
【解决方案3】:

【讨论】:

  • 他“不需要”。当他的 GUI 更复杂时,他可能应该这样做,因为 setSize 是not recommended。然而,这与他的 OSX 配置错误问题无关。
【解决方案4】:

我不确定这是否是最终解决方案,但我学到了一些东西并想在这里分享:

非常欢迎任何评论/更正(因为我仍然是这一切的新手......)

【讨论】:

    【解决方案5】:

    我在使用 swing 和 java 1.8 时遇到了类似的问题。 @DSquare 提到了某种线程问题。

    我终于解决了这个问题,在 Run --> Run Configurations --> Arguments 中取消选中“使用 SWT 启动时使用 -XstartOnFirstThread 参数”

    希望这会有所帮助。

    【讨论】:

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