Java Swing Program-从GUI到Main的输入卡住了

时间:2014-07-14 10:35:53

标签: java eclipse swing user-interface user-input

我有一个Java程序,我计划从GUI获取输入,稍后使用该输入在main()中进行处理。我正在使用Eclipse 我将HW对象(称为HWObj)发送到GUI JFrame,并检查对象中的boolean字段以继续在main()中处理。

InputWindow是扩展JPanel实现ActionListener的自定义对象 它包含对当前JFrame(parentFrame)的引用。点击InputWindow中的JButton后,我编写了一个自定义ActionListener,用于设置HWObj的值。检查为true并配置parentFrame。这应该导致执行在main()中恢复 HW类的代码如下:

import java.awt.*;
import javax.swing.*;
public class HW {

    //globals
    boolean check;
    public HW() {
        //initialisations
        check = false;
    }

    public static void main(String args[]) { 
        final HW problem = new HW();
        try {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    //Create and set up the window.
                    JFrame frame = new JFrame("Select folders");
                    frame.setPreferredSize(new Dimension(640, 480));
                    frame.setResizable(false);
                    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                    InputWindow Directories = new InputWindow(problem, frame);
                    Directories.setOpaque(true);
                    frame.add(Directories);
                    //Display the window.
                    frame.pack();
                    frame.setVisible(true);
                }
            });
        } catch(Exception e) {
            System.out.println("Exception:"+e.getLocalizedMessage());
        }
        while(!problem.finish);
        //Do processing on problem
        System.out.println("Done");
    } 
}

gui中的Actionlistener如下:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class InputWindow extends JPanel
                implements ActionListener {

    private static final long serialVersionUID = 4228345704162790878L;

    HW problem;
    JFrame parentFrame;
    //more globals

    public InputWindow(HW problem, JFrame parentFrame) {
        super();
        this.setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();

        this.parentFrame = parentFrame;
        this.problem = problem;

        JButton finishButton = new JButton("Finish");
        finishButton.setActionCommand("fin");
        finishButton.addActionListener(this);
        gbc.gridx = 0;
        gbc.gridy = 0;
        this.add(finishButton, gbc);

        //Initialize buttons and text areas and labels
        //Code removed for ease of reading

    }

    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if(command.equals("fin")) {
            //Do a lot of stuff, then   
            this.removeAll();
            parentFrame.dispose();
            problem.check = true;
        }
    }
}

我已经检查过了,按下这个按钮时,对此功能的控制正常。

现在,我希望它返回main,退出while循环,然后继续处理。 这不会发生。 eclipse中的调试器只显示正在运行的主线程,当我尝试暂停它时,我看到线程卡在while循环中。但是如果我尝试单步执行,它会按预期退出while循环,然后继续。但是,在我手动尝试调试它之前,它仍会卡在while循环中 问题是什么?为什么不按预期恢复main thread? 我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您的问题与Java内存模型的工作方式有关。主线程中的循环将检查陈旧值check

当你进入调试器时,会强制更新内存,以便它在那时开始工作。

如果将变量标记为volatile,则会强制JVM确保所有线程都使用最新值:

volatile boolean check;

您可以在documentation中阅读有关volatile和Java内存模型的更多信息。

答案 1 :(得分:0)

看起来你正在使用JFrame,你应该使用模态JDialog。如果您使用模态JDialog作为输入窗口,您将确切知道它何时“完成”,因为代码流将在对话框设置为可见之后立即从调用代码恢复。

或者如果您尝试交换视图,然后使用CardLayout交换视图,并使用观察者类型模式来监听状态的更改。