2017-11-13 18 views
1

私のプロジェクトでは、5つの列を持つTreeTableViewがあります。 すべての列に異なるコンテキストメニューが必要です。 すべての列(この例では「値」列の1つしか表示されません)に対してContextMenuをソースビルダで作成しましたが、menuは列ヘッダーを右クリックすると表示されますが、menùは右クリックして表示する必要がありますセル値JavaFX TreeTableViewとContextMenu

 <TreeTableView fx:id="valueTable" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER"> 
    <columns> 
     <TreeTableColumn fx:id="context" prefWidth="483.20001524686813" sortable="false" text="Context" /> 
     <TreeTableColumn fx:id="tag" minWidth="50.0" prefWidth="90.0" sortable="false" text="Tag" /> 
     <TreeTableColumn fx:id="offset" minWidth="50.0" prefWidth="90.0" sortable="false" text="OffSet" /> 
     <TreeTableColumn fx:id="lenght" minWidth="50.0" prefWidth="90.0" sortable="false" text="Lenght" /> 
     <TreeTableColumn fx:id="value" prefWidth="367.99993896484375" sortable="false" text="Value"> 
      <contextMenu> 
       <ContextMenu fx:id="contextMenuValue" > 
       <items> 
        <MenuItem mnemonicParsing="false" text="Action 1" /> 
        <MenuItem mnemonicParsing="false" text="Action 2" /> 
        <MenuItem mnemonicParsing="false" text="Action 3" /> 
        <MenuItem mnemonicParsing="false" text="Action 4" /> 
       </items> 
       </ContextMenu> 
      </contextMenu> 
     </TreeTableColumn> 
    </columns> 
    </TreeTableView> 

私はMouseClickとイベントをチェックするためにこのコードを追加しようとしますが、イベントがTreeTableColumn「値」に「valueTable」のみTreeTableViewに傍受されていません。

 value.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> { 
       System.out.println("Work Cell"); 
     }); 
     valueTable.addEventHandler(MouseEvent.MOUSE_CLICKED, (MouseEvent e) -> { 
      System.out.println("Work Table"); 
     }); 

私を助けてくれますか? Reg35。

答えて

2

そのあとのような代わりに、列のセルにContextMenuを追加するカスタムTreeTableCellを実装することによってそれを行うことができます:それは設定されているとあなたは同じ第二カラムごとに異なるメニューを設定することができます。もちろん、

public class Controller implements Initializable { 

    @FXML 
    private TreeTableView<MyModel> table; 
    @FXML 
    private TreeTableColumn<MyModel, String> first; 
    @FXML 
    private TreeTableColumn<MyModel, Boolean> second; 

    @Override 
    public void initialize(URL location, ResourceBundle resources) { 

     first.setCellValueFactory(data -> data.getValue().getValue().nameProperty()); 
     first.setCellFactory(cell -> new MyCell()); 
     second.setCellValueFactory(data -> data.getValue().getValue().selectedProperty()); 

     MyModel john = new MyModel("John"); 
     MyModel andrew = new MyModel("Andrew"); 

     table.setRoot(new TreeItem<>()); 
     table.setShowRoot(false); 
     table.getRoot().getChildren().add(new TreeItem<>(john)); 
     table.getRoot().getChildren().add(new TreeItem<>(andrew)); 

    } 

    private class MyModel { 

     private StringProperty name; 
     private BooleanProperty selected; 

     MyModel(String name) { 
      this.name = new SimpleStringProperty(name); 
      this.selected = new SimpleBooleanProperty(false); 
     } 

     StringProperty nameProperty() { 
      return name; 
     } 

     BooleanProperty selectedProperty() { 
      return selected; 
     } 
    } 

    private class MyMenu extends ContextMenu { 
     MyMenu() { 
      getItems().add(new MenuItem("Test")); 
      getItems().add(new MenuItem("Item")); 

     } 
    } 

    private class MyCell extends TreeTableCell<MyModel, String> { 
     MyCell() { 
      // Here you can set the same menu for each cell. Then the column is having the same cell for every row 
      setContextMenu(new MyMenu()); 
     } 

     // Overridden just to show the text of the cell. 
     @Override 
     protected void updateItem(String item, boolean empty) { 
      super.updateItem(item, empty); 
      if (empty) { 
       setText(null); 
      } else { 
       contextMenuProperty().bind(Bindings 
        // here you can define your own condition 
        .when(getTreeTableRow().getTreeItem().getValue().selectedProperty()) 
        .then(new MyMenu()) 
        .otherwise((MyMenu) null)); 
       setText(item); 
      } 
     } 
    } 

} 

最初のもののために。

+0

で解決なかった:「機能を追加することなく、拡張しない」==のContextMenuのサブの必要性を、代わりのMenuItemを追加することによって、それを設定 – kleopatra

+0

はいます」彼はそれをカスタマイズしたいのであれば拡張しましたが、あなたが言いましたように、あなたが私のようにこの方法を使用しているならば、それを拡張することは役に立たないのです。 – Sunflame

+0

ありがとう、仕事。 しかし、質問:TreeItemのマウスクリックを傍受する方法は? セル値に基づいてメニュー項目を無効/有効にするには、これを傍受する必要があります。 – SirLancillotto

0

私は

問題/解決策とは無関係の
  value.setCellFactory(tc -> { 
      TreeTableCell<MyModel, String> cell = new TreeTableCell<MyModel, String>() { 
       @Override 
       protected void updateItem(String item, boolean empty) { 
        super.updateItem(item, empty) ; 
        setText(empty ? null : item); 
       } 
      }; 
      cell.setOnMouseClicked(e -> { 
       if (! cell.isEmpty()) { 
        String userId = cell.getItem(); 
        System.out.println("Work!"); 
       } 
      }); 
      return cell ; 
     });