我有一个带有项目列表(事务)的TableView,并希望它进行排序,以便所有正值都高于负值。这是唯一的要求。
到目前为止我所拥有的:
expensesTableView.sortPolicyProperty().set(
new Callback<TableView<Transaction>, Boolean>() {
@Override
public Boolean call(TableView<Transaction> param) {
Comparator<Transaction> c = (a, b) -> {
if (a.getValue().contains("-") ^ b.getValue().contains("-")) { //getValue() returns a String
return a.getValue().contains("-") ? 1 : -1;
}
return 0;
};
FXCollections.sort(expensesTableView.getItems(), c);
return true;
};
});
这不是我的想法,我在网上发现了这个,所以不要问它是否是一种奇怪的方式来实现这一目标。真正的问题是,当添加/编辑/删除新项目时,表格不会自行排序。我需要点击标题3次然后它做我想要的。 如何才能获得始终正确排序的列表?
我尝试添加ChangeListener并对更改进行排序。但除此之外,这是一种丑陋的方式,它甚至不起作用......我在思想的最后。
答案 0 :(得分:1)
比较器中的按位OR在我的测试中不起作用,因此我将其更改为正常值,并且它也没有检查列表中项目值的变化。
我想知道进行数字检查而不是字符串检查是否更有效,但负面数据仍然可以在下面排序,但我想转换可能会花费更多?
我在评论中对SortedList的第一个想法实际上与保持原始排序顺序有关,在用户更改排序后要恢复,因此不合适。
编辑添加:为了澄清,这是保持源列表排序以保持表列表排序的行为。
public class TestApp extends Application {
private int c;
private ObservableList<TestTransaction> sortedOL;
private final Comparator<TestTransaction> comp = (TestTransaction a, TestTransaction b) -> {
if (a.getValue().contains("-") || b.getValue().contains("-")) {
return a.getValue().contains("-") ? 1 : -1;
}
return 0;
};
private TableView<TestTransaction> tableView;
@Override
public void start(Stage primaryStage) {
ArrayList<TestTransaction> rawList = new ArrayList<>();
for (int i = 1; i < 20; i++) {
int v = i * 3;
if (v % 2 > 0) {
v = v * -1;
}
c = i;
rawList.add(new TestTransaction(Integer.toString(v), "Item " + c));
}
sortedOL = FXCollections.observableArrayList(rawList);
sortedOL.addListener((ListChangeListener.Change<? extends TestTransaction> c1) -> {
if (c1.next() && (c1.wasAdded() || c1.wasRemoved())) {
FXCollections.sort(sortedOL, comp);
}
});
FXCollections.sort(sortedOL, comp);
tableView = new TableView<>(sortedOL);
TableColumn<TestTransaction,String> valCol = new TableColumn<>("Value");
valCol.setCellValueFactory(new PropertyValueFactory("value"));
TableColumn<TestTransaction,String> nameCol = new TableColumn<>("Name");
nameCol.setCellValueFactory(new PropertyValueFactory("name"));
tableView.getColumns().setAll(valCol, nameCol);
BorderPane tpane = new BorderPane();
Button btnAdd = new Button("Add");
btnAdd.setOnAction(a -> {addTransaction();});
ToolBar tb = new ToolBar(btnAdd);
tpane.setTop(tb);
tpane.setCenter(tableView);
tpane.setPrefSize(600, 600);
Scene scene = new Scene(tpane, 600, 600);
primaryStage.setTitle("Test");
primaryStage.setScene(scene);
primaryStage.show();
}
private void addTransaction() {
c++;
int v = (int) Math.floor(Math.random() * 50);
if (v % 2 > 0) {
v = v * -1;
}
sortedOL.add(new TestTransaction(Integer.toString(v), "New Item " + c));
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
public class TestTransaction {
private String value;
private String name;
public TestTransaction(String value, String name) {
this.value = value;
this.name = name;
}
/**
* @return the value
*/
public String getValue() {
return value;
}
/**
* @return the name
*/
public String getName() {
return name;
}
}
如果你想使用SortedList,意味着你可以内联比较器:
sortedOL = FXCollections.observableArrayList(rawList);
SortedList sorted = new SortedList(sortedOL, comp);
tableView = new TableView<>(sorted);