为什么这个摇摆应用程序挂起?

时间:2015-03-08 00:17:05

标签: java swing awt

当我等待构造函数返回的引用被设置时,程序在尝试构造自己的另一个实例后挂起。

如果我点击按钮,程序将会挂起。

编辑:删除了愚蠢的第二个等待循环。

编辑2:调用构造函数时将true更改为false。程序似乎现在有效。

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.InvocationTargetException;
import javax.swing.*;
public class Problem extends JPanel {
    public Problem(boolean wait) {
        frame=new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());
        if(wait) try {
            System.out.println("calling invoke and wait");
            SwingUtilities.invokeAndWait(new Runnable() {
                public void run() {
                    Problem.this.run();
                }
            });
        } catch(InvocationTargetException|InterruptedException e) {
            throw new RuntimeException(e);
        }
        else {
            System.out.println("calling invoke later");
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    Problem.this.run();
                }
            });
        }
    }
    public String title() {
        return "title";
    }
    public void addContent() {
        JButton button=new JButton("click");
        add(button,BorderLayout.CENTER);
        button.addActionListener(new ActionListener() {
            @Override public void actionPerformed(ActionEvent arg0) {
                Runnable runnable=new Runnable() {
                    @Override public void run() {
                        System.out.println("before new "+Thread.currentThread());
                        problem=new Problem(false);
                        System.out.println("after new "+Thread.currentThread());
                    }
                };
                new Thread(runnable).start();
                System.out.println("before first wait "+Thread.currentThread());
                while (problem==null)
                    ;
            }
        });
    }
    void run() {
        frame.setTitle(title());
        frame.getContentPane().add(this,BorderLayout.CENTER);
        addContent();
        frame.pack();
        frame.setVisible(true);
    }
    public static void main(String[] args) {
        new Problem(false);
    }
    Problem problem;
    public final JFrame frame;
    private static final long serialVersionUID=1;
}

1 个答案:

答案 0 :(得分:1)

p1 =来自主要功能的问题实例

  1. 状态1:创建 - p1已初始化。 p1.problem为空
  2. 状态2:用户点击按钮。最后,在另一个线程中,创建了p1.problem。但是,p1.problem.problem从未初始化,并且在用户点击按钮之前不会被激活,这将永远不会发生。我不确定你要做什么,但好像你的程序挂在了while (problem.problem==null);