-
Enhancement
-
Resolution: Unresolved
-
P4
-
None
-
generic
-
generic
A DESCRIPTION OF THE PROBLEM :
This is a typical table with two columns:
public class JavaFxTest10 extends Application {
public static class Employee {
private final SimpleStringProperty name;
private final SimpleDoubleProperty salary;
public Employee(String name, double salary) {
this.name = new SimpleStringProperty(name);
this.salary = new SimpleDoubleProperty(salary);
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public double getSalary() {
return salary.get();
}
public void setSalary(double salary) {
this.salary.set(salary);
}
}
@Override
public void start(Stage primaryStage) {
TableView<Employee> table = new TableView<>();
ObservableList<Employee> data = FXCollections.observableArrayList(
new Employee("Alice", 50000),
new Employee("Bob", 45000),
new Employee("Charlie", 70000)
);
TableColumn<Employee, String> nameColumn = new TableColumn<>("Name");
nameColumn.setMinWidth(100);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<Employee, Double> salaryColumn = new TableColumn<>("Salary");
salaryColumn.setMinWidth(100);
salaryColumn.setCellValueFactory(new PropertyValueFactory<>("salary"));
table.setItems(data);
table.getColumns().addAll(nameColumn, salaryColumn);
VBox vbox = new VBox();
vbox.getChildren().add(table);
Scene scene = new Scene(vbox, 300, 250);
primaryStage.setScene(scene);
primaryStage.setTitle("Employee Table Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
As you see there are two columns: name column with String value and salary column with Double value. Everything is clear and simple.
However, all this harmony will be disrupted if we complicate the table a bit by adding unconventional sorting. For example, if we need a 'Total' row that should always be last, regardless of the sorting type - ASCENDING / DESCENDING. The reason for this is that during sorting, we need to access not the cell value (which would be insufficient to determine its position in the sorting), but the actual item itself (to check if it's the 'total' item or not).
As a result, we will shift from TableColumn<Employee, String> nameColumn and TableColumn<Employee, Double> salaryColumn to TableColumn<Employee, Employee> nameColumn and TableColumn<Employee, Employee> salaryColumn, which will already be an unconventional solution with all the ensuing complexities. For instance, column.getCellData(rowIndex) will return the item, which is, of course, not what is needed.
To solve such problem I suggest to add item comparator to TreeTableView and TableView, so there would be two comparators:
ObjectProperty<java.util.Comparator<T>> comparator
ObjectProperty<java.util.Comparator<S>> itemComparator
and table will use that one, that is not null.
This is a typical table with two columns:
public class JavaFxTest10 extends Application {
public static class Employee {
private final SimpleStringProperty name;
private final SimpleDoubleProperty salary;
public Employee(String name, double salary) {
this.name = new SimpleStringProperty(name);
this.salary = new SimpleDoubleProperty(salary);
}
public String getName() {
return name.get();
}
public void setName(String name) {
this.name.set(name);
}
public double getSalary() {
return salary.get();
}
public void setSalary(double salary) {
this.salary.set(salary);
}
}
@Override
public void start(Stage primaryStage) {
TableView<Employee> table = new TableView<>();
ObservableList<Employee> data = FXCollections.observableArrayList(
new Employee("Alice", 50000),
new Employee("Bob", 45000),
new Employee("Charlie", 70000)
);
TableColumn<Employee, String> nameColumn = new TableColumn<>("Name");
nameColumn.setMinWidth(100);
nameColumn.setCellValueFactory(new PropertyValueFactory<>("name"));
TableColumn<Employee, Double> salaryColumn = new TableColumn<>("Salary");
salaryColumn.setMinWidth(100);
salaryColumn.setCellValueFactory(new PropertyValueFactory<>("salary"));
table.setItems(data);
table.getColumns().addAll(nameColumn, salaryColumn);
VBox vbox = new VBox();
vbox.getChildren().add(table);
Scene scene = new Scene(vbox, 300, 250);
primaryStage.setScene(scene);
primaryStage.setTitle("Employee Table Example");
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
As you see there are two columns: name column with String value and salary column with Double value. Everything is clear and simple.
However, all this harmony will be disrupted if we complicate the table a bit by adding unconventional sorting. For example, if we need a 'Total' row that should always be last, regardless of the sorting type - ASCENDING / DESCENDING. The reason for this is that during sorting, we need to access not the cell value (which would be insufficient to determine its position in the sorting), but the actual item itself (to check if it's the 'total' item or not).
As a result, we will shift from TableColumn<Employee, String> nameColumn and TableColumn<Employee, Double> salaryColumn to TableColumn<Employee, Employee> nameColumn and TableColumn<Employee, Employee> salaryColumn, which will already be an unconventional solution with all the ensuing complexities. For instance, column.getCellData(rowIndex) will return the item, which is, of course, not what is needed.
To solve such problem I suggest to add item comparator to TreeTableView and TableView, so there would be two comparators:
ObjectProperty<java.util.Comparator<T>> comparator
ObjectProperty<java.util.Comparator<S>> itemComparator
and table will use that one, that is not null.