import java.util.Objects;
import java.util.function.Predicate;
import javafx.application.Application;
import javafx.beans.binding.*;
import javafx.collections.*;
import javafx.collections.transformation.SortedList;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class Test extends Application {
class Connection {
int id;
String departure;
String arrival;
Integer distance;
public Connection(int id, String departure, String arrival) {
this(id, departure, arrival, null);
}
public Connection(int id, String departure, String arrival, Integer dist) {
this.id = id;
this.departure = departure;
this.arrival = arrival;
this.distance = dist;
}
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
TableColumn<Connection, Number> idCol = new TableColumn<>("ID");
TableColumn<Connection, String> depCol = new TableColumn<>("Von");
TableColumn<Connection, String> arrCol = new TableColumn<>("Nach");
TableColumn<Connection, Number> distCol = new TableColumn<>("Entfernung");
idCol.setCellValueFactory(cdf ->
Bindings.createIntegerBinding(() -> cdf.getValue().id));
depCol.setCellValueFactory(cdf ->
Bindings.createStringBinding(() -> cdf.getValue().departure));
arrCol.setCellValueFactory(cdf ->
Bindings.createStringBinding(() -> cdf.getValue().arrival));
distCol.setCellValueFactory(cdf ->
Bindings.createIntegerBinding(() -> cdf.getValue().distance));
depCol.setCellFactory(col -> new StyledCell<Connection, String>(
"-fx-background-color: lightgreen;", cell -> {
TableView<Connection> table = cell.getTableView();
SortedList<Connection> sl = (SortedList<Connection>)table.getItems();
int rowIndex = sl.getSourceIndex(cell.getTableRow().getIndex());
boolean result = rowIndex > 0 &&
Objects.equals(sl.getSource().get(rowIndex-1).arrival,
sl.getSource().get(rowIndex).departure);
return result;
}));
arrCol.setCellFactory(col -> new StyledCell<Connection, String>(
"-fx-background-color: lightgreen;", cell -> {
TableView<Connection> table = cell.getTableView();
SortedList<Connection> sl = (SortedList<Connection>)table.getItems();
int rowIndex = sl.getSourceIndex(cell.getTableRow().getIndex());
boolean result = rowIndex + 1 < sl.size() &&
Objects.equals(sl.getSource().get(rowIndex).arrival,
sl.getSource().get(rowIndex+1).departure);
return result;
}));
TableView<Connection> connectionTable = new TableView<>();
connectionTable.getColumns().addAll(idCol, depCol, arrCol, distCol);
ObservableList<Connection> connections = FXCollections.observableArrayList(
new Connection(1, "Hamburg", "Berlin", 200),
new Connection(2, "Berlin", "Hamburg", 200),
new Connection(3, "München", "Berlin", 0)
);
SortedList<Connection> sl = new SortedList<>(connections);
sl.comparatorProperty().bind(connectionTable.comparatorProperty());
connectionTable.setItems(sl);
primaryStage.setTitle("javafx-skeleton");
BorderPane panel = new BorderPane();
panel.setCenter(connectionTable);
Scene scene = new Scene(panel, 300, 200);
primaryStage.setScene(scene);
primaryStage.show();
}
private static class StyledCell<S,T> extends TableCell<S,T> {
private Predicate<TableCell<S,T>> predicate;
private String style;
public StyledCell(String style, Predicate<TableCell<S,T>> predicate) {
this.predicate = predicate;
this.style = style;
}
@Override
public void updateItem(T value, boolean empty) {
super.updateItem(value, empty);
setText(value == null || empty ? "" : value.toString());
setStyle("-fx-background-color: null;");
if (!empty && getTableRow() != null) {
if (predicate.test(this)) {
setStyle(style);
}
}
}
}
}