2017-02-24 5 views
1

Gibt es eine Möglichkeit, einen Mausklick auf einen Header einer Tabelle zu bekommen?JavaFX TableView Klicken Sie auf Header

Warum brauche ich das?

Ich habe eine Tabelle mit vielen Spalten. Aber nur ein bestimmter Witz für den ganzen Tisch. Um Scrollen zu vermeiden, möchte ich jeder Spalte eine bestimmte Breite (50 oder so) geben, und nur wenn Sie auf eine Überschrift klicken, wird diese Spalte erweitert, so dass Sie den Inhalt lesen können. Wenn Sie auf eine andere Überschrift klicken, wird die vorherige ausgeblendet.

Hoffentlich kann mir jemand helfen :)

Antwort

1

Leider gibt es keine schöne Art und Weise, dies zu tun. Die einzige öffentliche API-Option besteht darin, die "Grafik" der Spalte durch ein eigenes Label zu ersetzen und dann einen Maus-Listener hinzuzufügen. Damit dies funktioniert, müssen Sie auch jeden vorhandenen Spaltentext löschen.

Beachten Sie, dass Spalten standardmäßig klicken Zuhörer haben zu implementieren sortieren, es scheint, dass Sie dieses Verhalten nicht wünschen, so können Sie auch column.setSortable(false)

@Override 
public void start(Stage primaryStage) throws Exception { 
    TableView<String> tableView = new TableView<>(); 
    TableColumn<String, Object> x = new TableColumn<>("x"); 
    tableView.getColumns().add(x); 
    TableColumn<String, Object> y = new TableColumn<>(""); 
    tableView.getColumns().add(y); 

    x.setSortable(false); 
    y.setSortable(false); 

    makeHeader(x, "X", 0); 
    makeHeader(y, "Y", 1); 

    EventHandler<? super MouseEvent> handler = event -> { 
     System.out.println("Column clicked " + ((Node)event.getTarget()).getProperties().get("index")); 
    }; 
    x.getGraphic().addEventFilter(MouseEvent.MOUSE_CLICKED, handler); 
    y.getGraphic().addEventFilter(MouseEvent.MOUSE_CLICKED, handler); 
    primaryStage.setScene(new Scene(tableView)); 
    primaryStage.show(); 
} 

private void makeHeader(TableColumn<?, ?> target, String name, int index) { 
    VBox vBox = new VBox(new Label(name)); 
    vBox.setAlignment(Pos.CENTER); 
    vBox.getProperties().put("index", index); 
    target.setGraphic(vBox); 
    target.setText(""); 
} 
+0

Isnt schön nennen müssen, aber funktionieren würde, . Das einzige Problem ist jetzt, dass ich kein Ereignis für jede Spalte machen möchte. Ist es möglich, den Spaltenindex innerhalb des Ereignisses zu erhalten? Statt "X angeklickt" brauche ich something.getIndex() + "clicked". – Hesk

+0

@Hesk Siehe aktualisierte Antwort. Ich habe einen Index in der benutzerdefinierten Eigenschaftenzuordnung gespeichert, die jeder Knoten hat und dann in einem geteilten Ereignishandler abgerufen ... – Adam

+0

Ich habe meine Tabelle auf andere Weise entworfen. Verwenden Sie dies jetzt: http://stackoverflow.com/questions/27739833/adapt-tableview-menu-button (Post vom Balage1551) – Hesk

0
// Step 1: Add a click listener to the table view. 
tableView.setOnMouseClicked(new EventHandler<>() { 

    @Override 
    public void handle(MouseEvent event) { 
    // Step 2: Get the height of the header. 
    double headerHeight = tableView.lookup(".column-header-background").getBoundsInLocal().getHeight(); 

    // Step 3: Check if the clicked position's Y value is less than or equal to the height of the header. 
    if (headerHeight <= event.getY()) { 
     // Clicked on the header! 
    } 
    } 
});