2014-02-28 160 views
2

我一直在想,为什么JavaFX MenuItems设计为在右击时执行指定的操作?通常,任何Windows应用程序中的菜单项都应该用鼠标左键单击,但在JavaFX中,它看到两个单击操作均等。JavaFX:右键点击菜单项

另一个想法是,有没有办法阻止MenuItems的右击?我尝试了下面的代码,但它失败了。

它看起来像事件处理程序根本没有得到注册。

import javafx.application.Application; 
import javafx.event.EventHandler; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.Label; 
import javafx.scene.control.MenuItem; 
import javafx.scene.input.MouseButton; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class ContextMenuDemo extends Application 
{ 

@Override 
public void start(Stage primaryStage) 
{ 

    final ContextMenu cm = new ContextMenu(); 


    MenuItem menuItem1 = getMenuItemForLine("line 1"); 
    MenuItem menuItem2 = getMenuItemForLine("line 2"); 
    MenuItem menuItem3 = getMenuItemForLine("line 3"); 

    menuItem1.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() 
    { 
     @Override 
     public void handle(MouseEvent e) 
     { 
      if (e.getButton() == MouseButton.SECONDARY) 
      { 
       System.out.println("Desired Click"); 
      } 
      else 
      { 
       System.out.println("No right click"); 
      } 
      e.consume(); 
     } 
    }); 

    menuItem2.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() 
    { 
     @Override 
     public void handle(MouseEvent e) 
     { 
      if (e.getButton() == MouseButton.SECONDARY) 
      { 
       System.out.println("Desired Click"); 
      } 
      else 
      { 
       System.out.println("No right click"); 
      } 
      e.consume(); 
     } 
    }); 

    menuItem3.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() 
    { 
     @Override 
     public void handle(MouseEvent e) 
     { 
      if (e.getButton() == MouseButton.SECONDARY) 
      { 
       System.out.println("Desired Click"); 
      } 
      else 
      { 
       System.out.println("No right click"); 
      } 
      e.consume(); 
     } 
    }); 


    cm.getItems().add(menuItem1); 
    cm.getItems().add(menuItem2); 
    cm.getItems().add(menuItem3); 

    final Rectangle rectangle = new Rectangle(70, 70, Color.TAN); 
    rectangle.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() 
    { 
     @Override 
     public void handle(MouseEvent e) 
     { 
      if (e.getButton() == MouseButton.SECONDARY) 
      { 
       cm.show(rectangle, e.getScreenX(), e.getScreenY()); 
      } 
      else 
      { 
       System.out.println("No right click"); 
      } 
     } 
    }); 

    Group root = new Group(); 
    root.getChildren().addAll(rectangle); 
    Scene scene = new Scene(root, 350, 250); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

private MenuItem getMenuItemForLine(String menuName) 
{ 
    Label menuLabel = new Label(menuName); 
    MenuItem menuItem = new MenuItem(); 
    menuItem.setGraphic(menuLabel); 
    return menuItem; 
} 

public static void main(String[] args) 
{ 
    launch(args); 
} 
} 

回答

6

你有很多多余的代码。我删除了一些。停止事件的方式在过滤中。你必须找出什么时候一个事件被触发,选择似乎发生在按下和onAction发生在释放。两个事件一起在一个节点上点击。

无需为每个菜单项添加处理程序,甚至可以重新使用相同的处理程序。父菜单获取onAction事件。

package contextmenudemo; 

import javafx.application.Application; 
import javafx.event.ActionEvent; 
import javafx.event.EventHandler; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.ContextMenu; 
import javafx.scene.control.MenuItem; 
import javafx.scene.input.MouseButton; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.paint.Color; 
import javafx.scene.shape.Rectangle; 
import javafx.stage.Stage; 

public class ContextMenuDemo extends Application { 

    @Override 
    public void start(Stage primaryStage) { 

     final ContextMenu cm = new ContextMenu(); 
     cm.addEventFilter(MouseEvent.MOUSE_RELEASED, new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent event) { 
       if (event.getButton() == MouseButton.SECONDARY) { 
        System.out.println("consuming right release button in cm filter"); 
        event.consume(); 
       } 
      } 
     }); 
     cm.setOnAction(new EventHandler<ActionEvent>() { 
      @Override 
      public void handle(ActionEvent event) { 
       System.out.println("right gets consumed so this must be left on "+ 
         ((MenuItem)event.getTarget()).getText()); 
      } 
     }); 

     MenuItem menuItem1 = new MenuItem("line 1"); 
     MenuItem menuItem2 = new MenuItem("line 2"); 
     MenuItem menuItem3 = new MenuItem("line 3"); 

     cm.getItems().addAll(menuItem1, menuItem2, menuItem3); 

     final Rectangle rectangle = new Rectangle(70, 70, Color.TAN); 
     rectangle.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() { 
      @Override 
      public void handle(MouseEvent e) { 
       if (e.getButton() == MouseButton.SECONDARY) { 
        cm.show(rectangle, e.getScreenX(), e.getScreenY()); 
       } else { 
        System.out.println("No right click"); 
       } 
      } 
     }); 

     Group root = new Group(); 
     root.getChildren().addAll(rectangle); 
     Scene scene = new Scene(root, 350, 250); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static void main(String[] args) { 
     launch(args); 
    } 
} 
+0

太棒了。正是我想要的。谢谢。 – Aspirant

+0

出于好奇,为什么不把活动代码运行在MouseEvent的EventHandler中? –

1

你有没有试图把

e.consume(); 
+0

我试过了。但没有改变。 – Aspirant