In this illustration, the header of the column labeled "Long Last Name" overlaps into the adjacent column's space.
overlapping.css
.column-header.left-header > .label {
-fx-alignment: baseline-left;
}
.column-header.overlap-header > .label {
-fx-alignment: baseline-right;
-fx-padding: 0 3 0 0;
}
Code snippet implementing the overlap effect
TableColumn<Person, String> lastNameCol = new TableColumn<>();
lastNameCol.setMinWidth(80);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<>("lastName"));
lastNameCol.getStyleClass().add("overlap-header");
Label headerLabel = new Label("Long Last Name");
headerLabel.setMinWidth(Control.USE_PREF_SIZE);
lastNameCol.setGraphic(headerLabel);
To achieve this workaround:
- Use CSS to adjust alignment properties.
- Utilize a label graphic for the overlapping effect.
By providing a label graphic, you can customize the minimum width to prevent truncation if the header text is too lengthy.
Executable code example
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.*;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class TableViewOverlapHeader extends Application {
private TableView<Person> table = new TableView<>();
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob", "Smith", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0e646f6d616c207d63677a664e6b766f637e626b206d6163">[email protected]</a>"),
new Person("Isabella", "Johnson", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="244d574546414848450a4e4b4c4a574b4a64415c45495448410a474b49">[email protected]</a>"),
new Person("Ethan", "Williams", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="7a1f0e121b14540d131616131b17093a1f021b170a161f54191517">[email protected]</a>"),
new Person("Emma", "Jones", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="0b6e66666a256164656e784b6e736a667b676e25686466">[email protected]</a>"),
new Person("Michael", "Brown", "<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="d4b9bdb7bcb5b1b8fab6a6bba3ba94b1acb5b9a4b8b1fab7bbb9">[email protected]</a>")
);
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
table.setPrefHeight(200);
final Label label = new Label("Address Book");
label.setFont(new Font("Arial", 20));
TableColumn<Person, String> firstNameCol = new TableColumn<>("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(
new PropertyValueFactory<>("firstName"));
firstNameCol.getStyleClass().add("left-header");
TableColumn<Person, String> lastNameCol = new TableColumn<>();
lastNameCol.setMinWidth(80);
lastNameCol.setCellValueFactory(
new PropertyValueFactory<>("lastName"));
lastNameCol.getStyleClass().add("overlap-header");
Label headerLabel = new Label("Long Last Name");
headerLabel.setMinWidth(Control.USE_PREF_SIZE);
lastNameCol.setGraphic(headerLabel);
TableColumn<Person, String> emailCol = new TableColumn<>("Email");
emailCol.setMinWidth(100);
emailCol.setCellValueFactory(
new PropertyValueFactory<>("email"));
table.setItems(data);
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10));
vbox.getChildren().addAll(label, table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
scene.getStylesheets().add(getClass().getResource("overlap.css").toExternalForm());
stage.setScene(scene);
stage.show();
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}