在鼠标按下事件中启动 "asyncExec" 会导致阻塞行为
Starting "asyncExec" in Mouse Down Event results in blocking behavior
有一个“下一个”按钮,当我在选择按钮的情况下按下键盘回车键时,按钮的 widgetSelected 事件被一次又一次地重复调用,并且下一个超级快。这正是我想要的行为,但只发生在键盘输入键上。
我希望在按住鼠标单击时具有鼠标单击的行为。当尝试用鼠标点击做同样的事情时,行为是不一样的,它只进行一次事件调用,当点击结束时(UP)。如何用鼠标点击来模拟同样的行为?
我试过这样做,但它会阻塞 UI(不明白为什么)并且 mouseUp 永远不会被调用,它永远阻塞在 while
:
button.addMouseListener(new MouseAdapter() {
boolean mouseDown;
@Override
public void mouseDown(MouseEvent e) {
System.out.println("mouseDown");
mouseDown = true;
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
while (mouseDown) {
System.out.println("Doing next in mouseDown");
next(composite, label_1);
synchronized(this){
try {
wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
}
@Override
public void mouseUp(MouseEvent e) {
System.out.println("mouseUp");
mouseDown = false;
}
});
您在 UI 线程中给 asyncExec
运行 的 Runnable
。您必须 永远不要 在 UI 线程中进行任何类型的等待,因为这会阻塞 UI 直到它完成。
所以你不能 运行 这样的循环,因为它只会阻塞 UI。由于循环从不 returns 到主 SWT readAndDispatch
循环没有 UI 操作完成。
而是使用 Display
的 timerExec
方法在给定时间间隔后安排 Runnable
到 运行。此 运行nable 应该执行操作的一个步骤,然后使用 timerExec
安排下一步。
我记得几天前还有一个关于鼠标长按行为的问题,但我找不到了。在我尝试在 UI 线程中使用 asyncExec 失败后,我将这段基于 greg-449 解决方案的代码用于使用 timerExec 方法。 :)
button.addMouseListener(new MouseAdapter() {
boolean mouseDown;
@Override
public void mouseDown(MouseEvent e) {
mouseDown = true;
Display.getCurrent().timerExec(1000, () -> {
if (mouseDown) {
button.notifyListeners(SWT.Selection, new Event());
button.notifyListeners(SWT.MouseDown, new Event());
}
});
}
@Override
public void mouseUp(MouseEvent e) {
mouseDown = false;
}
});
button.addSelectionListener(SelectionListener.widgetSelectedAdapter(
e -> System.out.println("Do next")));
有一个“下一个”按钮,当我在选择按钮的情况下按下键盘回车键时,按钮的 widgetSelected 事件被一次又一次地重复调用,并且下一个超级快。这正是我想要的行为,但只发生在键盘输入键上。
我希望在按住鼠标单击时具有鼠标单击的行为。当尝试用鼠标点击做同样的事情时,行为是不一样的,它只进行一次事件调用,当点击结束时(UP)。如何用鼠标点击来模拟同样的行为?
我试过这样做,但它会阻塞 UI(不明白为什么)并且 mouseUp 永远不会被调用,它永远阻塞在 while
:
button.addMouseListener(new MouseAdapter() {
boolean mouseDown;
@Override
public void mouseDown(MouseEvent e) {
System.out.println("mouseDown");
mouseDown = true;
Display.getDefault().asyncExec(new Runnable() {
@Override
public void run() {
while (mouseDown) {
System.out.println("Doing next in mouseDown");
next(composite, label_1);
synchronized(this){
try {
wait(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
});
}
@Override
public void mouseUp(MouseEvent e) {
System.out.println("mouseUp");
mouseDown = false;
}
});
您在 UI 线程中给 asyncExec
运行 的 Runnable
。您必须 永远不要 在 UI 线程中进行任何类型的等待,因为这会阻塞 UI 直到它完成。
所以你不能 运行 这样的循环,因为它只会阻塞 UI。由于循环从不 returns 到主 SWT readAndDispatch
循环没有 UI 操作完成。
而是使用 Display
的 timerExec
方法在给定时间间隔后安排 Runnable
到 运行。此 运行nable 应该执行操作的一个步骤,然后使用 timerExec
安排下一步。
我记得几天前还有一个关于鼠标长按行为的问题,但我找不到了。在我尝试在 UI 线程中使用 asyncExec 失败后,我将这段基于 greg-449 解决方案的代码用于使用 timerExec 方法。 :)
button.addMouseListener(new MouseAdapter() {
boolean mouseDown;
@Override
public void mouseDown(MouseEvent e) {
mouseDown = true;
Display.getCurrent().timerExec(1000, () -> {
if (mouseDown) {
button.notifyListeners(SWT.Selection, new Event());
button.notifyListeners(SWT.MouseDown, new Event());
}
});
}
@Override
public void mouseUp(MouseEvent e) {
mouseDown = false;
}
});
button.addSelectionListener(SelectionListener.widgetSelectedAdapter(
e -> System.out.println("Do next")));