首页 > 解决方案 > 为什么即使使用排序的可观察列表,我的组合框也没有排序?

问题描述

我正在尝试在 javafx 的组合框中显示排序的项目列表。

在我的控制器中,我的项目列表声明为 list this :

private final ObservableList<Profile> profiles = FXCollections.observableArrayList();
private final SortedList<Profile> sortedProfiles = new SortedList<>(profiles);

我的组合框是这样初始化的:

profiles.setItems(controller.getSortedProfiles());

然后,我的控制器中有一个方法可以添加项目:

profiles.add(new Profile(profileName));

组合框已更新,但未排序。为什么 ?我认为使用 sortedlist 包装器会使组合框保持排序?

示例代码:

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.SortedList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;

import java.util.Random;

public class Demo extends Application {
    public static void main(String[] args) {
        launch(args);
    }

    public void start(Stage primaryStage) throws Exception {
        final ObservableList<Item> items = FXCollections.observableArrayList();

        items.add(new Item(1));
        items.add(new Item(100));
        items.add(new Item(10));

        final SortedList<Item> itemSortedList = new SortedList<>(items);

        final BorderPane view = new BorderPane();

        final ComboBox<Item> profiles = new ComboBox<>();
        final Button add = new Button("add random");
        add.setOnAction(event -> items.add(new Item(new Random().nextInt(5000))));

        profiles.setItems(itemSortedList);

        view.setTop(profiles);
        view.setBottom(add);

        final Scene scene = new Scene(view, 400, 400);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private static final class Item implements Comparable<Item> {
        private Integer name;

        public Item(final int name) {
            this.name = name;
        }

        @Override
        public String toString() {
            return "Int : " + name;
        }

        @Override
        public int compareTo(final Item o) {
            return name.compareTo(o.name);
        }
    }
}

标签: sortingjavafxarraylistcombobox

解决方案


您永远不会设置comparator排序列表的属性。javadoc包含以下有关该comparator属性的声明:

表示此 SortedList 顺序的比较器。无序的 SortedList 为 Null。

即没有指定比较器,列表只是保持原始列表的顺序。只需指定比较器即可解决问题:

final SortedList<Item> itemSortedList = new SortedList<>(items, Comparator.naturalOrder());

或者,如果您添加适当的 getter,您可以轻松地按给定属性创建Comparator排序(假设此属性是可比较的):

final SortedList<Item> itemSortedList = new SortedList<>(items, Comparator.comparing(Item::getName));

推荐阅读