javafx: оставляйте oldValue и newValue списка одинаковыми, когда условие не выполнено - PullRequest
0 голосов
/ 05 сентября 2018

У меня есть список, в котором я могу выбрать различные панели, которые будут отображаться на главной панели. Теперь для конкретной панели мне нужно несколько объектов, чтобы использовать каждую функцию. В просмотре списка есть слушатель на selectedItemProperty. Я хочу проверить, доступны ли нужные мне объекты, в противном случае объекты oldValue и newValue должны сохранять свое значение. Есть ли способ сделать это?

listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>()
{
    @Override
    public void changed(ObservableValue<? extends Object> observable, Object oldValue,
                            Object newValue)
    {
        if(obj == null)
        {
            // keep the oldValues for both
        }
    });
}

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

В этом случае вы должны использовать пользовательскую модель выбора, чтобы предотвратить выбор некоторых элементов.

Следующая реализация упрощена. Он не обрабатывает изменения списка элементов. Кроме того, он реализует только один выбор, но, надеюсь, он показывает общий подход:

public class CustomSelectionModel<T> extends MultipleSelectionModel<T> {

    private final ListView<T> listView;
    private final ObservableList<Integer> selectedIndices = FXCollections.observableArrayList();
    private final ObservableList<Integer> selectedIndicesUnmodifiable = FXCollections.unmodifiableObservableList(selectedIndices);
    private final ObservableList<T> selectedItems;

    private BiPredicate<Integer, T> leavePredicate;
    private BiPredicate<Integer, T> enterPredicate;

    public BiPredicate<Integer, T> getLeavePredicate() {
        return leavePredicate;
    }

    public void setLeavePredicate(BiPredicate<Integer, T> leavePredicate) {
        this.leavePredicate = leavePredicate;
    }

    public BiPredicate<Integer, T> getEnterPredicate() {
        return enterPredicate;
    }

    public void setEnterPredicate(BiPredicate<Integer, T> enterPredicate) {
        this.enterPredicate = enterPredicate;
    }

    public CustomSelectionModel(ListView<T> listView) {
        if (listView == null) {
            throw new IllegalArgumentException();
        }
        this.listView = listView;
        this.selectedItems = new TransformationList<T, Integer>(selectedIndices) {

            @Override
            protected void sourceChanged(ListChangeListener.Change<? extends Integer> c) {
                beginChange();
                while (c.next()) {
                    if (c.wasReplaced()) {
                        nextReplace(c.getFrom(), c.getTo(), c.getRemoved().stream().map(listView.getItems()::get).collect(Collectors.toList()));
                    } else if (c.wasRemoved()) {
                        nextRemove(c.getFrom(), c.getRemoved().stream().map(listView.getItems()::get).collect(Collectors.toList()));
                    } else if (c.wasAdded()) {
                        nextAdd(c.getFrom(), c.getTo());
                    }
                }
                endChange();
            }

            @Override
            public int getSourceIndex(int index) {
                return index;
            }

            @Override
            public T get(int index) {
                return listView.getItems().get(getSource().get(index));
            }

            @Override
            public int size() {
                return getSource().size();
            }

        };
    }

    @Override
    public ObservableList<Integer> getSelectedIndices() {
        return selectedIndicesUnmodifiable;
    }

    @Override
    public ObservableList<T> getSelectedItems() {
        return selectedItems;
    }

    @Override
    public void selectIndices(int index, int... indices) {
        clearAndSelect(index); // ignore all indices but the first
    }

    @Override
    public void selectAll() {
        selectFirst();
    }

    @Override
    public void selectFirst() {
        if (!listView.getItems().isEmpty()) {
            clearAndSelect(0);
        }
    }

    @Override
    public void selectLast() {
        if (!listView.getItems().isEmpty()) {
            clearAndSelect(listView.getItems().size() - 1);
        }
    }

    private void moveSelection(int oldIndex, int newIndex) {
        if ((leavePredicate == null || leavePredicate.test(oldIndex, oldIndex == -1 ? null : listView.getItems().get(oldIndex)))
                && (enterPredicate == null || enterPredicate.test(newIndex, newIndex == -1 ? null : listView.getItems().get(newIndex)))) {
            setSelectedIndex(newIndex);
            if (newIndex == -1) {
                selectedItems.clear();
                setSelectedItem(null);
            } else {
                setSelectedItem(listView.getItems().get(newIndex));
                if (isEmpty()) {
                    selectedIndices.add(newIndex);
                } else {
                    selectedIndices.set(0, newIndex);
                }
            }
            listView.getFocusModel().focus(newIndex);
        }
    }

    @Override
    public void clearAndSelect(int index) {
        moveSelection(getSelectedIndex(), index);
    }

    @Override
    public void select(int index) {
        clearAndSelect(index);
    }

    @Override
    public void select(T obj) {
        int index = listView.getItems().indexOf(obj);
        if (index >= 0) {
            clearAndSelect(index);
        }
    }

    @Override
    public void clearSelection(int index) {
        if (getSelectedIndex() == index) {
            clearSelection();
        }
    }

    @Override
    public void clearSelection() {
        moveSelection(getSelectedIndex(), -1);
    }

    @Override
    public boolean isSelected(int index) {
        return selectedIndices.contains(index);
    }

    @Override
    public boolean isEmpty() {
        return selectedIndices.isEmpty();
    }

    @Override
    public void selectPrevious() {
        int index = getSelectedIndex() - 1;
        if (index >= 0) {
            clearAndSelect(index);
        }
    }

    @Override
    public void selectNext() {
        int index = getSelectedIndex() + 1;
        if (index < listView.getItems().size()) {
            clearAndSelect(index);
        }
    }

}
@Override
public void start(Stage primaryStage) throws Exception {
    ListView<Integer> listView = new ListView<>();

    for (int i = 0; i < 100; i++) {
        listView.getItems().add(i);
    }

    CustomSelectionModel<Integer> selectionModel = new CustomSelectionModel<>(listView);
    listView.setSelectionModel(selectionModel);

    CheckBox moveAllowed = new CheckBox("disallow movement");
    moveAllowed.selectedProperty().addListener((o, oldValue, newValue) -> selectionModel.setLeavePredicate(newValue ? (index, item) -> false : null));

    CheckBox enterOdd = new CheckBox("enter odd items disallowed");
    enterOdd.selectedProperty().addListener((o, oldValue, newValue) -> selectionModel.setEnterPredicate(newValue ? (index, item) -> (index & 1) == 0 : null));

    Scene scene = new Scene(new ScrollPane(new HBox(listView, new VBox(moveAllowed, enterOdd))));

    primaryStage.setScene(scene);
    primaryStage.show();
}
0 голосов
/ 05 сентября 2018

Вот исполняемый пример в первом фрагменте кода, второй фрагмент выглядит так, как в вашей программе

public class MainNoFXML extends Application {

    public static void main(String[] args) { launch(args); }

    @Override
    public void start(Stage primaryStage) {
        ListView<Object> listView = new ListView<>(FXCollections.observableArrayList(new String[]{"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"}));
        listView.getSelectionModel().selectedItemProperty().addListener((obs, oldVal, newVal)->{
            if(newVal != null && (!newVal.equals("Monday") && !newVal.equals("Tuesday")))
                Platform.runLater(() -> listView.getSelectionModel().select(oldVal));
        });

        Scene scene = new Scene(listView);
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

Ваша программа (я думаю, это правильно, я не совсем уверен, с чем вы работаете)

listView.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
        @Override
        public void changed(ObservableValue<? extends Object> observable, Object oldValue,
                            Object newValue)
        {
            if(obj == null)
            {
                Platform.runLater(() -> listView.getSelectionModel().select(oldValue));
                // keep the oldValues for both
            }
        });
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...