不要while(true)
在 Swing 事件线程上使用,同样不要wait()
在 Swing 事件线程上调用——您将冻结整个 GUI,使其完全无响应。您需要了解主 Swing 事件线程或“事件调度线程”负责所有 Swing 绘图和用户交互,因此如果您将其与长时间运行或冻结的代码捆绑在一起,您就会锁定整个 GUI。
相反,改变你的程序的状态——也许通过设置一个或两个变量,让你的程序的行为依赖于这个状态。如果您需要更具体的建议,请告诉我们您想要实现的行为,我们或许可以为您提供更好的方法。
有关 Swing 事件线程的更多信息,请阅读:课程:Swing 中的并发
编辑
你状态:
当用户单击菜单项时,我想通过窗口中的一系列“离散”鼠标单击来获取信息。因此,在单击菜单时,将提示用户“在窗口中选择一个点”。所以,我需要的是我的 ActionListener 函数(menu_addbound3)然后等待鼠标点击。因此等待/通知设置。鼠标单击更改 edit_mode 和 notifyAll() 导致 while 循环中的等待退出,然后导致 while 循环退出,然后我可以在 menu_addbound3 函数中提示我的下一点信息,根据需要重复此操作.
感谢您的澄清,现在我可以肯定地告诉您,您做错了,您绝对不想使用 while 循环或等待或通知。有很多方法可以解决这个问题,一种是使用一些布尔变量或枚举变量来给程序一个状态,然后根据状态改变它的行为。您可以在 MouseListener 中使用您的 EditMode 枚举以使其知道其处于活动状态,然后您还可以为 MouseListener 类提供一个布尔变量 windowPointSelected,设置为 false,然后仅在第一次单击后将其设置为 true。
编辑 2
例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class ProgState extends JPanel {
private static final int PREF_W = 400;
private static final int PREF_H = PREF_W;
private static final Color EDIT_COLOR = Color.red;
private EditMode editMode = EditMode.NONE;
private boolean firstPointSelected = false;
private JMenuBar jMenuBar = new JMenuBar();
private JTextField firstPointField = new JTextField(15);
private JTextField secondPointField = new JTextField(15);
public ProgState() {
add(firstPointField);
add(secondPointField);
JMenu menu = new JMenu("Menu");
menu.add(new JMenuItem(new AbstractAction("Edit") {
@Override
public void actionPerformed(ActionEvent arg0) {
setEditMode(EditMode.EDITING);
setFirstPointSelected(false);
}
}));
jMenuBar.add(menu);
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent mEvt) {
if (getEditMode() == EditMode.EDITING) {
Point p = mEvt.getPoint();
String pStr = String.format("[%d, %d]", p.x, p.y);
if (!isFirstPointSelected()) {
firstPointField.setText(pStr);
setFirstPointSelected(true);
} else {
secondPointField.setText(pStr);
setEditMode(EditMode.NONE);
}
}
}
});
}
public void setEditMode(EditMode editMode) {
this.editMode = editMode;
Color c = editMode == EditMode.NONE ? null : EDIT_COLOR;
setBackground(c);
}
public EditMode getEditMode() {
return editMode;
}
public void setFirstPointSelected(boolean firstPointSelected) {
this.firstPointSelected = firstPointSelected;
}
public boolean isFirstPointSelected() {
return firstPointSelected;
}
@Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
public JMenuBar getJMenuBar() {
return jMenuBar;
}
private static void createAndShowGui() {
ProgState progState = new ProgState();
JFrame frame = new JFrame("EditMode");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(progState);
frame.setJMenuBar(progState.getJMenuBar());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
enum EditMode {
NONE, EDITING
}