我正在实现扫雷,处理鼠标事件时遇到了一点问题。我希望在 mouseRelease(而不是 mousePressed)上执行操作,因此用户可以在按下鼠标按钮后改变主意。有三种可能的操作:
- LMB 发布 - 揭示当前领域
- 人民币释放 - 在当前领域放置一个标志
- LMB 和 RMB 均已发布 - 突出显示或显示相邻字段
动作并不重要,我的问题是如何触发它们。
在情况 1 和 2 中,没有其他按钮处于关闭状态 - 这很容易检查。
问题是释放两个按钮会导致两次调用 mouseRelease 方法。如果两个按钮释放之间的延迟太大,我宁愿不触发动作。换句话说,只有在大约同时释放两个按钮时才会触发。
当按钮 1 被释放时,我可以很容易地检查按钮 3 是否按下,但这并没有真正的帮助。
目前我没有其他想法,然后存储释放第一个按钮的时间,然后将其与释放另一个按钮的时间进行比较 - 如果差异足够小,则触发一个动作。
我真的不喜欢玩 System.currentTimeMillis() 或 System.nanoTime() 的想法,我想知道是否有更好的方法?
解决方案:
极大简化了问题的是不允许用户将鼠标指针拖动到另一个字段(并因此更改“选定”字段)。释放两个按钮之间的延迟无关紧要。如果鼠标指针转到另一个字段,则所有内容都将被清除。这是代码片段:
private static final int B1DM = MouseEvent.BUTTON1_DOWN_MASK;
private static final int B3DM = MouseEvent.BUTTON3_DOWN_MASK;
private boolean bothWereDown = false;
@Override
public void mousePressed(MouseEvent e) {
// action if single button pressed
// in my case this is a sub-action of pressing both buttons
int both = B1DM | B3DM;
bothWereDown = (e.getModifiersEx() & both) == both;
if (bothWereDown) {
// action if both buttons pressed
}
}
@Override
public void mouseDragged(MouseEvent e) {
// some other code
if ( /* if pointer leaves field where mouse was pressed */) {
// some other code
bothWereDown = false;
// some other code
}
}
@Override
public void mouseReleased(MouseEvent e) {
// some other code
if (e.getButton() == MouseEvent.BUTTON1) {
if (bothWereDown) {
if ((e.getModifiersEx() & B3DM) != B3DM) {
// action if both released
}
} else {
// action if left button released
}
} else if (e.getButton() == MouseEvent.BUTTON3) {
if (bothWereDown) {
if ((e.getModifiersEx() & B1DM) != B1DM) {
// action if both released
}
} else {
// action if right button released
}
}
}