miniHessel
miniHessel

Reputation: 834

TableColumn.setGraphic underneath the Column label

When I use the following code to add a TextField to each column:

      tableColumn.setGraphic(textField);

The textfield gets placed on the left side of the label, making the columns look like this:

enter image description here

If I drag the column width out, I see that the label is still there

enter image description here

Is there any way to make the Column use it's original label, and place the textfield underneath? I have tried with adding my own label in a VBox together with the textfield, but then you loose the auto width functionality.

After James_D's answer, the label is correct, but the column style is still a bit strange?

enter image description here

MVCE:

public class TableViewTEST extends Application {

List<TableColumn> listOfColumns = new ArrayList();
TableView tableView = new TableView();


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


public void buildData() {

    TableColumn myColumn = new TableColumn("asd");
    TableColumn myColumn2 = new TableColumn("qq");
    listOfColumns.add(myColumn);
    listOfColumns.add(myColumn2);
    //add columns dynamically
    int counter = 0;
    for (TableColumn col : listOfColumns) {
        final int j = counter;

  col.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<MyTableRow, String>, ObservableValue<String>>() {
            public ObservableValue<String> call(TableColumn.CellDataFeatures<MyTableRow, String> param) {
                return new SimpleStringProperty(param.getValue().rowData.get(j));

            }
        });

        counter++;
        TextField txtField = new TextField();
        VBox vbox = new VBox();
        vbox.getChildren().add(txtField);
        col.setGraphic(vbox);
        tableView.getColumns().add(col);

    }

    tableView.setRowFactory(tv -> {

        MyTableRow rowz = new MyTableRow();

        rowz.setOnMouseClicked(event -> {
            if (event.getClickCount() == 2 && (!rowz.isEmpty())) {

            }
        });

        return rowz;

    });

}

@Override
public void start(Stage stage) throws Exception {
    FlowPane flowpane = new FlowPane();
    flowpane.getChildren().add(tableView);

    buildData();
    Scene scene = new Scene(flowpane);

    scene.getStylesheets().add(TableViewTEST.class.getResource("css.css").toExternalForm());
    stage.setScene(scene);
    stage.show();

}

}

Upvotes: 0

Views: 1166

Answers (1)

James_D
James_D

Reputation: 209225

Use an external css file with the following:

.table-column .label {
    -fx-content-display: bottom ;
}

Here is a complete example:

import java.util.List;

import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

public class TableWithTextFieldColumnHeaders extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<List<String>> table = new TableView<>();

        table.getColumns().add( createColumn("A", 0) );
        table.getColumns().add( createColumn("B", 1) );

        BorderPane root = new BorderPane(table);
        Scene scene = new Scene(root, 600, 400);
        scene.getStylesheets().add("table-text-field.css");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private TableColumn<List<String>, String> createColumn(String title, int index) {

        TableColumn<List<String>, String> col = new TableColumn<>(title);

        col.setCellValueFactory(cellData -> 
            new ReadOnlyStringWrapper(cellData.getValue().get(index)));

        TextField textField = new TextField();
        col.setGraphic(textField);

        double textFieldPadding = 8 ;
        textField.prefWidthProperty().bind(
                col.widthProperty().subtract(textFieldPadding));

        return col ;
    }

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

with the css file table-text-field.css:

.table-column .label {
    -fx-content-display: bottom ;
}

Upvotes: 1

Related Questions