【问题标题】:How to make an event for left & right click at the same time?如何同时为左键和右键单击事件?
【发布时间】:2015-07-14 10:47:36
【问题描述】:

我知道如何分别处理左键或右键单击、拖动、双击,但是如果用户同时单击鼠标左键和右键而不干扰/引起其他操作,我不知道该怎么做要触发的事件。

@Override
public void handle(Event event) {
    if (event.getSource() instanceof Tile) {
        Tile tile = (Tile) event.getSource();
        if (event.getEventType().equals(MouseEvent.MOUSE_CLICKED)) {
            if (((MouseEvent) event).getButton().equals(MouseButton.SECONDARY))
                tile.toggleFlag();
            else if (((MouseEvent) event).getClickCount() == 2)
                mineField.massClick(tile);
        }
        if (event.getEventType().equals(MouseEvent.DRAG_DETECTED))
            if (!((MouseEvent) event).getButton().equals(MouseButton.SECONDARY))
                tile.startFullDrag();
        if (event.getEventType().equals(MouseDragEvent.MOUSE_DRAG_ENTERED))
            tile.arm();
        if (event.getEventType().equals(MouseDragEvent.MOUSE_DRAG_EXITED))
            tile.disarm();
        if (event.getEventType().equals(MouseDragEvent.MOUSE_DRAG_RELEASED))
            mineField.clickedTile(tile);
        if (event.getEventType().equals(ActionEvent.ANY))
            mineField.clickedTile(tile);
    }
}

此外,如果您发现我的代码存在问题,请随时指出,并始终寻求改进。

【问题讨论】:

    标签: java user-interface events javafx event-handling


    【解决方案1】:

    简单的版本是这样的:

    public class Main extends Application {
    
        @Override
        public void start(Stage primaryStage) {
            try {
    
                StackPane root = new StackPane();
    
                root.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
    
                    if( e.isPrimaryButtonDown() && e.isSecondaryButtonDown()) {
                        System.out.println( "Both down");
                    } else if( e.isPrimaryButtonDown()) {
                        System.out.println( "Primary down");
                    } else if( e.isSecondaryButtonDown()) {
                        System.out.println( "Secondary down");
                    }
    
                });
    
                Scene scene = new Scene(root,400,400);
                primaryStage.setScene(scene);
                primaryStage.show();
    
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    如果您希望在按下两个按钮时发生自己的事件,您可以这样尝试:

    public class Main extends Application {
    
        BooleanProperty primaryMouseButtonDown = new SimpleBooleanProperty();
        BooleanProperty secondaryMouseButtonDown = new SimpleBooleanProperty();
    
        @Override
        public void start(Stage primaryStage) {
            try {
    
                StackPane root = new StackPane();
    
                root.addEventFilter(MouseEvent.MOUSE_PRESSED, e -> {
                    primaryMouseButtonDown.setValue( e.isPrimaryButtonDown());
                    secondaryMouseButtonDown.setValue( e.isSecondaryButtonDown());
                });
    
                root.addEventFilter(MouseEvent.MOUSE_RELEASED, e -> {
                    primaryMouseButtonDown.setValue( e.isPrimaryButtonDown());
                    secondaryMouseButtonDown.setValue( e.isSecondaryButtonDown());
                });
    
                BooleanBinding binding = Bindings.and(primaryMouseButtonDown, secondaryMouseButtonDown);
                binding.addListener( new ChangeListener<Boolean>() {
    
                    @Override
                    public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
                        System.out.println( "Mouse Button Event: " + oldValue + " -> " + newValue);
                    }
                });
    
    
                Scene scene = new Scene(root,400,400);
                primaryStage.setScene(scene);
                primaryStage.show();
    
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    有 2 个布尔属性,一个用于主按钮按下,一个用于辅助按钮按下。这两个属性都通过 BooleanBinding 连接。每当通过鼠标事件更改属性之一时,就会触发一个事件。所以剩下要做的就是检查 newValue 是否为真并触发处理代码。

    【讨论】:

      【解决方案2】:

      做更多的事情,注意鼠标按下,并在鼠标左/右键调用 mousePressed 事件时将布尔值设置为 true。然后稍后在事件中查看左右的布尔值是否为真。如果它们是,就如同同时按下两者一样对其进行操作。

      boolean mouse_1, mouse_2 = false;
      
      public void mousePressed(MouseEvent e){
          //The numbers are just made up I don't remember the actual codes for the buttons but it's simple enough to figure out.
          if(e.getButton()==1){
              mouse_1  = true;
          }
          if(e.getButton()==2){
              mouse_2  = true;
          }
      
          if(mouse_1&&mouse_2){
          //Your code here
          }
      }
      
      public void mouseReleased(MouseEvent e){
          if(e.getButton() == 1){
              mouse_1 = false;
          }
          if(e.getButton() == 2){
              mouse_2 = false;
          }
      }
      

      假设这是某种处理程序类...但这是如何实现它的缩写。

      【讨论】:

      • 这些是布尔值类字段吗?不然就不行了?
      • 对不起,我没有在答案中定义它们我认为很明显它们在更高的地方被预先初始化..让我编辑我的答案@jpdemko
      • @TheJavaCoder16 你能把这个 AWT 代码转换成 JavaFX 代码吗?
      【解决方案3】:

      我可能迟到了回答这个问题,但我将发布我的解决方案,以演示如何分别处理单按钮点击和同时点击两个按钮

      现有答案已经解释了如何检测同时单击的两个鼠标按钮。但是鼠标事件(单击、按下和释放)仍然由单个按钮触发,之前的海报没有说明如何避免这些事件相互干扰。

      我的解决方案是跟踪鼠标按下时按下的两个按钮,并在鼠标释放时检测任何类型的鼠标点击:

      //flag to track both buttons being pressed
      private boolean wereBothButtonsPressed = false;
      
      private void onMousePressed(MouseEvent e) {
          //single button press sets flag to false
          wereBothButtonsPressed = e.isPrimaryButtonDown() && e.isSecondaryButtonDown();
      }
      
      private void onMouseReleased(MouseEvent e) {
          if (e.isPrimaryButtonDown() || e.isSecondaryButtonDown()) {
              //do nothing if user is still holding the button
              return;
          }
          if (wereBothButtonsPressed) {
              System.out.prinln("Both buttons");
          } else if (e.getButton() == MouseButton.PRIMARY) {
              System.out.prinln("Only primary");
          } else if (e.getButton() == MouseButton.SECONDARY) {
              System.out.prinln("Only secondary");
          }
      }
      

      您可以为特定控件上的特定事件设置这些处理程序或将它们放入您的方法中:

      private boolean wereBothButtonsPressed = false;
      
      @Override
      public void handle(Event event) {
          ...
      
          if (event.getEventType().equals(MouseEvent.MOUSE_PRESSED)) {
              MouseEvent me = (MouseEvent) event;
              wereBothButtonsPressed = me.isPrimaryButtonDown() && me.isSecondaryButtonDown();
          } else if (event.getEventType().equals(MouseEvent.MOUSE_RELEASED)) {
              MouseEvent me = (MouseEvent) event;
              if (!me.isPrimaryButtonDown() && !me.isSecondaryButtonDown()) {
                  if(wereBothButtonsPressed) {
                      mineField.massClick(tile);
                  } else if(me.getButton() == MouseButton.PRIMARY) {
                      mineField.clickedTile(tile);
                  } else if(me.getButton() == MouseButton.SECONDARY) {
                      tile.toggleFlag();
                  }
              } 
          ...
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-05-03
        • 1970-01-01
        • 1970-01-01
        • 2017-11-04
        • 2015-10-11
        • 2015-03-03
        • 1970-01-01
        相关资源
        最近更新 更多