Как отсортировать свойство списка JavaFX

кажется, я столкнулся с проблемой ListProperties. ObservableLists реализуют интерфейс маркера SortableList, который позволяет эффективно сортировать их, запуская только одно событие. ListProperties не реализуют этот интерфейс (как они могли...?). Вместо этого они используют реализацию интерфейса List по умолчанию, запуская множество изменений.

Единственное решение, которое я вижу, - это напрямую вызвать sort() для базового List. Но это противоречит схеме возврата самого Property:

public ObservableList getSomeList()
{
    return someListProperty();
}

что гарантирует, что ListChangeListener останется зарегистрированным при обмене базового List.

Буду рад получить информацию, может я что-то пропустил?


person Grannath    schedule 27.11.2015    source источник


Ответы (1)


Я предполагаю, что SortableList, о котором вы говорите, используется в FXCollections.sort.

ListProperty может реализовать интерфейс SortableList.

Это действительно может быть хорошей идеей, поскольку это позволит вам выбрать способ сортировки обернутого списка, если, например. FXCollections.sort используется в свойстве. В этом случае вы можете использовать FXCollections.sort в содержащемся списке.

Как они могли? Как это:

class MyListProperty<T> extends ListPropertyBase<T> implements SortableList<T> {

    ...

    @Override
    public void sort() {
        ObservableList<T> list = getValue();
        if (list != null) {
            FXCollections.sort((ObservableList<Comparable>) list);
        }
    }

    @Override
    public void sort(Comparator<? super T> comparator) {
        ObservableList<T> list = getValue();
        if (list != null) {
            FXCollections.sort(list, comparator);
        }
    }

}

Единственная проблема заключается в том, что SortableList находится внутри пакета com.sun.javafx.collections (см. Использование проприетарных классов Java Sun является плохой практикой? ).

О вашем столкновении со схемой свойств: его нет, если вы определяете свойство предполагаемым образом, см. Использование свойств и привязки JavaFX раздел Понимание свойств

Свойство будет реализовано следующим образом:

private final ListProperty<MyClass> someList = ...;

public ObservableList<MyClass> getSomeList() {
    return someList.get();
}

public void setSomeList(ObservableList<MyClass> newList) {
    someList.set(newList);
}

public ListProperty<MyClass> someListProperty() {
    return someList;
}

ListProperty должен обеспечить, чтобы зарегистрированные в нем ListChangeListener получали события изменения из обернутого списка.

Возможно, вы запутались со свойствами списка только для чтения, используемыми в fxml, но ListProperty не предназначен только для чтения.

Вы по-прежнему можете использовать это свойство в файле fxml, но вам нужно будет использовать значение типа ObservableList:

<!-- imports -->

<ContainingClass xmlns:fx="http://javafx.com/fxml/1">
    <someList>
        <FXCollections fx:factory="observableArrayList">
            <!-- list content goes here -->
        </FXCollections>
    </someList>
</ContainingClass>
person fabian    schedule 27.11.2015
comment
Спасибо за обширный ответ. Мне всегда казалось более разумным возвращать свойство вместо обернутого списка в геттере. Таким образом, любой Listener останется подключенным, и вы сможете обойти кучу ошибок. Да, вы можете проверить любые методы свойства. Но если поведение геттера зависит от того, существует ли метод Property, это кажется плохой практикой. Во всяком случае, то, что ListProperty показывает другое поведение при сортировке, кажется мне реальной ошибкой. Он имеет тот же интерфейс, что указывает на то, что он работает как делегат (в документах API ничего не сказано), но не работает при сортировке. - person Grannath; 30.11.2015