我有一个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
?
我该如何解决这个问题?
答案 0 :(得分:0)
您的问题与Java内存模型的工作方式有关。主线程中的循环将检查陈旧值check
。
当你进入调试器时,会强制更新内存,以便它在那时开始工作。
如果将变量标记为volatile
,则会强制JVM确保所有线程都使用最新值:
volatile boolean check;
您可以在documentation中阅读有关volatile
和Java内存模型的更多信息。
答案 1 :(得分:0)
看起来你正在使用JFrame,你应该使用模态JDialog。如果您使用模态JDialog作为输入窗口,您将确切知道它何时“完成”,因为代码流将在对话框设置为可见之后立即从调用代码恢复。
或者如果您尝试交换视图,然后使用CardLayout交换视图,并使用观察者类型模式来监听状态的更改。