gpt4 book ai didi

java - ActionListener 调用阻止 MouseClick 事件

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:14:18 25 4
gpt4 key购买 nike

我有一个带有以下 ActionListener 的 MenuItem“maddbound3”的窗口:

maddbound3.addActionListener
(
new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
menu_addbound3();
}
}
);

当菜单被点击时,这个监听器调用下面的 menu_addbound3():

void menu_addbound3()
{
while(getEditMode() != EditMode.NONE)
{
System.out.println("!... " + getEditMode());

synchronized(this)
{
try
{
wait();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
}
}

MouseClicked 事件改变编辑模式的值并发出 notifyAll() 以便 while 循环退出。但是,测试表明,当系统运行while循环时,鼠标点击不会发生MouseClicked事件。

ActionListener 是否会阻止 MouseClicked 事件?我该如何解决这个问题?

谢谢

最佳答案

在 Swing 事件线程上不要有 while(true),同样不要在 Swing 事件线程上调用 wait() —— 你将卡住整个 GUI,使其完全无响应。您需要了解主 Swing 事件线程或“事件调度线程”负责所有 Swing 绘图和用户交互,因此如果您将其与长时间运行或卡住的代码捆绑在一起,就会锁定整个 GUI。

相反,更改程序的状态——可能通过设置一两个变量,并让程序的行为取决于此状态。如果您需要更具体的建议,请告诉我们您想要实现的行为,我们或许可以为您提供更好的方法。

有关 Swing 事件线程的更多信息,请阅读:Lesson: Concurrency in Swing

编辑
你声明:

When the user clicks the menu item I want to obtain information via a series of "discrete" mouse clicks from the window. Hence, on clicking the menu, the user would be prompted to "select a point in the window". So, what I need is for my ActionListener function (menu_addbound3) to then wait for a mouse click. Hence the wait/notify setup. A mouse click changes the edit_mode and notifyAll() causes the wait in the while loop to exit which then causes the while loop to exit and I can then prompt for my next bit of information within the menu_addbound3 function, repeating this as as I need to.

感谢您的澄清,现在我可以肯定地告诉您您做错了,您绝对不想使用 while 循环或等待或通知。有很多方法可以解决这个问题,一个可能是使用一些 boolean 或枚举变量来给程序一个状态,然后根据状态改变它的行为。您的 EditMode 枚举可以在 MouseListener 中使用,让它知道它处于 Activity 状态,然后您还可以为 MouseListener 类提供一个 boolean 变量 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
}

关于java - ActionListener 调用阻止 MouseClick 事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11032321/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com