我有一个列表视图,可以在其中选择将显示在主窗格中的不同窗格。现在,对于特定的窗格,我需要一些对象来使用每个功能。在列表视图上,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
}
});
}
答案 0 :(得分:0)
这是第一个代码段中的一个可运行示例,第二个代码段是程序中的外观
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
}
});
});
答案 1 :(得分:0)
在这种情况下,您应该使用自定义选择模型来防止选择某些项目。
简化了以下实现。它不处理项目列表的更改。此外,它仅实现单一选择,但希望它显示了通用方法:
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();
}