1

ユーザーが特定のキーを押したときに、コンテキスト メニューを開きたいと思います。そのため、Key EventHandler を登録し、contextmenu を開くことに成功しましたが、残念ながら contextmenu の正しい位置を特定できません。

現在選択されているセルのすぐ下で開きたい:

ここに画像の説明を入力

コンテキストメニューを表示する正しい位置を決定できません:

//Showcase Code:
treeTableView.setOnKeyPressed( new EventHandler<KeyEvent>()
{
   @Override
   public void handle( final KeyEvent keyEvent )
   {
    final TreeItem<Item> selectedItem = treeTableView.getSelectionModel().getSelectedItem();

    if ( selectedItem != null )
    {
      if ( keyEvent.getCode().equals( KeyCode.INSERT ) )
      {
        final ContextMenu rowMenu = new ContextMenu();

        Menu deleteMenu = new Menu( "Delete" );
        final MenuItem deleteItem = new MenuItem( selectedItem.getValue().getName() );
        deleteMenu.getItems().add( deleteItem );
        rowMenu.getItems().add( deleteMenu );
        rowMenu.show( treeTableView.getScene().getWindow() );//How to get X and Y of current selected cell/row?
      }
    }
   }
 }

現在選択されている行/セルの左下隅のtreeTableViewsから正しいXとYの位置を特定するのを手伝ってくれる人はいますか?

編集:

小さな例を追加:

public class TreeTableViewKeyListenerOnRow 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> item2 = new TreeItem<>( new Item( "Item2" ) );
    TreeItem<Item> item3 = new TreeItem<>( new Item( "Item3" ) );

    root.getChildren().add( item1 );
    item1.getChildren().add( item2 );
    root.getChildren().add( item3 );

    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<>();
        row.setFocusTraversable( true );

        row.setOnKeyPressed( new EventHandler<KeyEvent>()
        {
          @Override
          public void handle( final KeyEvent keyEvent )
          {
            System.out.println( "FIRE!" );//Not Fireing?

            final TreeItem<Item> selectedItem = row.getTreeItem();

            if ( selectedItem != null )
            {
              if ( keyEvent.getCode().equals( KeyCode.INSERT ) )
              {
                final ContextMenu menu = new ContextMenu();

                Menu deleteMenu = new Menu( "Delete" );
                final MenuItem deleteItem = new MenuItem( selectedItem.getValue().getName() );
                deleteMenu.getItems().add( deleteItem );
                menu.getItems().add( deleteMenu );

                // compute bounds of row in screen:
                Bounds boundsInScreen = row.localToScreen( row.getBoundsInLocal() );
                double x = boundsInScreen.getMinX();
                double y = boundsInScreen.getMinY();

                menu.show( treeTableView.getScene().getWindow(), x, y );
              }
            }
          }
        } );

        return row;
      }
    } );

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

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

1 に答える 1

2

個々の にコンテキスト メニューを登録しますTreeTableRow。次に、呼び出しrow.getBoundsInLocal()て行の境界を取得し、row.localToScreen(...)画面座標に変換できます。

treeTableView.setRowFactory(ttv -> {
    TreeTableRow<Item> row = new TreeTableRow<>();
    row.setOnKeyPressed( new EventHandler<KeyEvent>() {
       @Override
       public void handle( final KeyEvent keyEvent ) {
           final TreeItem<Item> selectedItem = row.getTreeItem();

           if ( selectedItem != null ) {
               if ( keyEvent.getCode().equals( KeyCode.INSERT ) ) {
                   final ContextMenu rowMenu = new ContextMenu();

                   Menu deleteMenu = new Menu( "Delete" );
                   final MenuItem deleteItem = new MenuItem( selectedItem.getValue().getName() );
                   deleteMenu.getItems().add( deleteItem );
                   rowMenu.getItems().add( deleteMenu );

                   // compute bounds of row in screen:
                   Bounds boundsInScreen = row.localToScreen(row.getBoundsInLocal());
                   double x = boundsInScreen.getMinX();
                   double y = boundsInScreen.getMinY();

                   rowMenu.show( treeTableView.getScene().getWindow() );//How to get X and Y of current selected cell/row?
               }
           }
       }
   }    
   return row ;
});
于 2015-03-23T15:59:33.163 に答える