Pix*_*xel 3 java swing actionlistener mouseclick-event
我有一个带有MenuItem"maddbound3"的窗口,其中包含以下ActionListener:
maddbound3.addActionListener
(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
menu_addbound3();
}
}
);
Run Code Online (Sandbox Code Playgroud)
单击菜单时,此侦听器调用下面的menu_addbound3():
void menu_addbound3()
{
while(getEditMode() != EditMode.NONE)
{
System.out.println("!... " + getEditMode());
synchronized(this)
{
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
MouseClicked事件改变编辑模式的值并发出notifyAll(),以便while循环退出.但是,测试表明,当系统通过while循环运行时,单击鼠标时不会发生MouseClicked事件.
ActionListener是否阻止了MouseClicked事件?我该如何解决这个问题?
谢谢
没有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
}
Run Code Online (Sandbox Code Playgroud)