How to add a tooltip to a TableView header cell in JavaFX 8

后端 未结 3 1830
时光说笑
时光说笑 2021-02-13 20:34

Does anyone know how to add a tooltip to a column header in a TableView ?

There are many places where are explained how to add the tooltip to data cells, but I didn\'t f

相关标签:
3条回答
  • 2021-02-13 21:30

    The solution

    Alternatively, you can look up the label that's already there and just give it a tool tip.

    In order to .lookup() an element the table needs to be rendered already. To be sure that your code runs after the table is rendered, just wrap your code in a Platform.runlater().

    // We need to do this after the table has been rendered (we can't look up elements until then)
    Platform.runLater(() -> {
        // Prepare a tooltip
        Tooltip tooltip = new Tooltip("This is a super cool control; here's how to work it...");
        tooltip.setWrapText(true);
        tooltip.setMaxWidth(200);
    
        // Get column's column header
        TableColumnHeader header = (TableColumnHeader) historyTable.lookup("#" + column.getId());
    
        // Get column header's (untooltipped) label
        Label label = (Label) header.lookup(".label");
    
        // Give the label a tooltip
        label.setTooltip(tooltip);
    
        // Makes the tooltip display, no matter where the mouse is inside the column header.
        label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    }
    

    The solution at scale

    If you want to do this for your whole set of columns, you might put them all in a LinkedHashMap (this will just help you organizationally by keeping your columns associated with their messages):

    // We'll use this to associate columns with messages for right now.
    LinkedHashMap<TableColumn<Person, String>, String> tableColumns = new LinkedHashMap<>();
    
    // Each column gets a helpful message
    tableColumns.put(numberOfBoxesColumn, "The total number of boxes that have arrived");
    tableColumns.put(backordersColumn, "Use these columns as a measure of how urgently the Purchase Order needs to be processed.");
    /*... put each column in along with it's message */
    

    ... then use a for-each loop to loop through and give each column a tooltip ...

    // Make a tooltip out of each message. Give each column('s label) it's tooltip.
    for (Map.Entry<TableColumn<Person, String>, String> pair : tableColumns.entrySet()) {
        
        TableColumn<Person, String> column;
        String message;
    
        // Get the column and message
        column = pair.getKey();
        message = pair.getValue();
    
        // Prepare a tooltip
        Tooltip tooltip = new Tooltip(message);
        tooltip.setWrapText(true);
        tooltip.setMaxWidth(200);
    
        // Get column's column header
        TableColumnHeader header = (TableColumnHeader) historyTable.lookup("#" + column.getId());
    
        // Get column header's (untooltipped) label
        Label label = (Label) header.lookup(".label");
    
        // Give the label a tooltip
        label.setTooltip(tooltip);
    
        // Makes the tooltip display, no matter where the mouse is inside the column header.
        label.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
    }
    

    NOTE: I tried the combination of Jesper and James' solutions before coming up with this one. Sadly, when I did, the CSS caused all of my labels to disappear when I look at my .fxml layout in SceneBuilder. And we just can't have that, can we? (okay maybe I just couldn't have that).

    0 讨论(0)
  • 2021-02-13 21:39
        TableColumn<Person, String> firstNameCol = new TableColumn<>();
        Label firstNameLabel = new Label("First Name");
        firstNameLabel.setTooltip(new Tooltip("This column shows the first name"));
        firstNameCol.setGraphic(firstNameLabel);
    
    0 讨论(0)
  • 2021-02-13 21:41

    This is an extended answer to James_D. (I don't have the reputation to comment):

    To make the label connect with textProperty of the column and just hide the original text, so it does not mess up the rest of the table functionality:

    nameLabel.textProperty().bindBidirectional(textProperty());
    nameLabel.getStyleClass().add("column-header-label");
    nameLabel.setMaxWidth(Double.MAX_VALUE); //Makes it take up the full width of the table column header and tooltip is shown more easily.
    

    css:

    .table-view .column-header .label{
        -fx-content-display: graphic-only;
    }
    .table-view .column-header .label .column-header-label{
        -fx-content-display: text-only;
    }
    
    0 讨论(0)
提交回复
热议问题