【问题标题】:java an object that is set in EventQueue.invokeLater is nulljava 在EventQueue.invokeLater中设置的对象为null
【发布时间】:2011-10-13 21:22:11
【问题描述】:

我有一个 MyClass 类,它在运行时通过调用 GUI 的 main 方法来初始化 GUI awt 框架(“Launch.java”)。 在这个主要方法中,我有 EventQueue.invokeLater,它的 runnable 实际上做了所有的初始化。初始化的一部分是设置一个名为“controller”的对象。

从MyClass调用GUI的main方法后,想getController()控制器,结果返回null,不知道为什么。

当我调试它时,我在 Launch.java 中的创建控制器的行上放置了一个断点 (controller = new Controller(textArea)),我注意到它当时不为空,但是回到 MyClass 中,当我调用 Launcher.getController() 时它为空。

我做错了什么??谢谢!

我的班级:

public class MyClass{

private static boolean isInitialized = false;
private Controller control;

public static void main(String[] args){

    if (!isInitialized)
    {
        Launch.main(new String[1]);
        control = Launch.getControl(); //here control is null!
        isInitialized = true;
    }
    //irrelevant code here      
}
}}

Launch.java:

public class Launch {

private JFrame frame;
private JTextField inputField;
DefaultListModel model;
private static Controller controller;
JSpinner spinner;

public static Controller getControl()
{
    return controller;
}


/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Launch window = new Launch();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public Launch() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {
        //some code here... (here controller is null)

        controller = new Controller(textArea);

        //some code here...  (here controller is not null - during debug)
    }
}

【问题讨论】:

  • 我对 _controller 与控制器感到困惑。您发布的这段代码是否可编译?
  • 另外,为什么控制器变量是静态的?
  • 另外,为什么要在 servlet 中嵌入 GUI?
  • @Hovercraft Full Of Eels:我编辑了 _controller/controller 错误
  • 您仍然需要回答另外两个关于不恰当使用静态和将 Swing 与 Servlet 混合的问题。

标签: java multithreading user-interface awt


【解决方案1】:

您的代码存在几个问题。最明显的是您在 servlet 线程上同步调用 main()getControl()。然而,创建控制器的代码会在未来某个不确定的时间被调用,假设存在 AWT 调度程序线程和系统事件队列。在您调用 getControl() 时,Launch 对象很可能尚未实例化。

假设您的其余代码执行您想要的操作,您需要做的是将getControl() 的调用移动到您使用其返回值之前。

我只回答您提出的问题...但是您的应用程序设计(从 servlet 启动 AWT 应用程序、缺少 AWT 事件循环代码等)看起来有问题。

【讨论】:

  • 仅将getControl() 移动到稍后将调用它的其他位置是否足够安全?根据你所说的,我仍然没有受让人在它被称为 Launch 对象时将被实例化。在我调用getControl()之前没有其他方法可以确保 Launch 被实例化?
  • 如果在 Launch 实例化时没有显式控制,并且不能保证 doPost 发生在 Launch 之后,那么就无法保证 getControl() 不会返回 null。您需要修改设计,以免发生这种情况。
  • 您似乎编辑了帖子并更改了代码,消除了 servlet 和对 getControl() 的调用,因此代码不再匹配问题。
猜你喜欢
  • 2020-07-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-05
  • 2012-10-18
相关资源
最近更新 更多