0

コンテキストメニューをツリーテーブルビューに追加すると、残念ながら、コンテキストメニューによって消費されない KeyEvents に反応します。

ここに画像の説明を入力

たとえば、サブアイテム (Item22) をクリックしてそのコンテキスト メニューを開き、左矢印をクリックすると、コンテキスト メニューが選択されてフォアグラウンドにあり、(imo) イベントを消費する必要がありますが、ツリー テーブル ビューはバックグラウンドでサブアイテムの親 (Item2) を選択します。イベント自体を処理できない場合。

コンテキストメニューが開いている間にすべてのナビゲーションイベントを消費する簡単な方法はありますか? または、望ましい動作を得る方法について他に提案はありますか?

問題を示す小さな例:

public class TreeTableViewContextMenuKeyBehaviourMain extends Application
{
  @Override
  public void start( final Stage primaryStage )
  {
    TreeItem<Item> root = new TreeItem<>( new Item( "Root" ) );

    TreeItem<Item> item1 = new TreeItem<>( new Item( "Item1" ) );
    TreeItem<Item> item11 = new TreeItem<>( new Item( "Item11" ) );
    TreeItem<Item> item2 = new TreeItem<>( new Item( "Item2" ) );
    TreeItem<Item> item22 = new TreeItem<>( new Item( "Item22" ) );

    root.getChildren().add( item1 );
    item1.getChildren().add( item11 );
    root.getChildren().add( item2 );
    item2.getChildren().add( item22 );

    TreeTableColumn<Item, String> column = new TreeTableColumn<>( "Column" );

    column.setCellValueFactory( new TreeItemPropertyValueFactory<Item, String>( "name" ) );

    final TreeTableView<Item> treeTableView = new TreeTableView<>( root );
    treeTableView.getColumns().add( column );
    treeTableView.setShowRoot( false );
    treeTableView.setColumnResizePolicy( TreeTableView.CONSTRAINED_RESIZE_POLICY );

    treeTableView.setRowFactory( new Callback<TreeTableView<Item>, TreeTableRow<Item>>()
    {
      @Override
      public TreeTableRow<Item> call( final TreeTableView<Item> tableView )
      {
        final TreeTableRow<Item> row = new TreeTableRow<>();
        final ContextMenu rowMenu = new ContextMenu();

        rowMenu.setOnShowing( ( event ) ->
        {
          System.out.println( "OPEN!" );

          //Clear and Rebuild Contextmenu dynamically.
            rowMenu.getItems().clear();
            Menu deleteMenu = new Menu( "Delete" );
            final MenuItem deleteItem = new MenuItem( row.getItem().getName() );
            deleteMenu.getItems().add( deleteItem );
            rowMenu.getItems().add( deleteMenu );
          } );

        //If the contextmenu has no childs setOnShowing will not be called, so we need a placeholder for dynamic context menus.
        final Menu placeholder = new Menu( "Delete" );
        rowMenu.getItems().add( placeholder );

        // only display context menu for non-null items:
        row.contextMenuProperty().bind(
            Bindings.when( Bindings.isNotNull( row.itemProperty() ) ).then( rowMenu )
                .otherwise( (ContextMenu) null ) );

        return row;
      }
    } );

    BorderPane layout = new BorderPane();
    layout.setCenter( treeTableView );
    Scene scene = new Scene( layout, 400, 400 );
    scene.getStylesheets().add( getClass().getResource( "application.css" ).toExternalForm() );
    primaryStage.setScene( scene );
    primaryStage.show();
  }

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

public class Item
{
  private final StringProperty name = new SimpleStringProperty();

  public Item( final String name )
  {
    this.name.set( name );
  }

  public String getName()
  {
    return name.get();
  }

  public void setName( final String name )
  {
    this.name.set( name );
  }

  public StringProperty nameProperty()
  {
    return name;
  }
}
4

1 に答える 1

1

を追加して、シーン グラフをバックアップしようとしているを消費できEventHandlerます。ContextMenuKeyEvents

rowMenu.addEventHandler(KeyEvent.ANY, (KeyEvent t) ->
{
    t.consume();
});
于 2015-03-31T13:30:32.233 に答える