Как динамически обновлять ячейки ListView в JavaFX? - PullRequest
0 голосов
/ 11 декабря 2018

У меня есть большое OvervableList<Website>, которое получается при вызове mainApp.getWebsitData().

В этом контроллере я делаю 3 отдельных FilteredList<Websites>: keepData, deleteData и newData на основе2 логических свойства Website:

private final BooleanProperty keep;
private final BooleanProperty delete;

Эти 3 отфильтрованных списка отображаются в 3 различных ListView с.

У меня есть кнопки рядом с каждым элементом в списке newDataгде я делаю либо keep, либо delete true.Это должно переместить этот объект сайта либо в список хранения, либо в список удаления.Однако, когда я нажимаю кнопку, представления списка не обновляются соответствующим образом.

public class WebsiteOverviewController {


    @FXML
    private ListView<Website> deleteList;

    @FXML 
    private ListView<Website> keepList;

    @FXML
    private ListView<Website> newList;

    @FXML
    private JFXButton scanButton;

    @FXML
    private JFXButton pauseButton;

    @FXML
    private StackPane stackPane;

    private BooleanProperty isScanning = new SimpleBooleanProperty(false);

    private MainApp mainApp;

    private FilteredList<Website> keepData;

    private FilteredList<Website> deleteData;

    private FilteredList<Website> newData;

    private AtomicBoolean paused = new AtomicBoolean(false);

    private Thread thread;

    public WebsiteOverviewController() {

    }

    @FXML
    public void initialize() {
        scanButton.setContentDisplay(ContentDisplay.RIGHT);
    }

    public void setMainApp(MainApp mainApp) {
        this.mainApp = mainApp;

        keepData = new FilteredList<>(mainApp.getWebsiteData(), p -> (!p.getDelete() && p.getKeep()));
        deleteData = new FilteredList<>(mainApp.getWebsiteData(), p -> (p.getDelete() && !p.getKeep()));

        newData = new FilteredList<>(mainApp.getWebsiteData(), p -> (!p.getKeep() && !p.getDelete()));

        if (!deleteData.isEmpty()) {
            deleteList.setItems(deleteData);

            deleteList.setCellFactory(param -> new ListCell<Website>() {
                @Override
                protected void updateItem(Website item, boolean empty) {
                    super.updateItem(item,  empty);

                    if (empty || item == null) {
                        setText(null);
                    } else {
                        setText(item.getWebsite());
                    }
                }
            });
        }

        if (!keepData.isEmpty()) {
            keepList.setItems(keepData);

            keepList.setCellFactory(param -> new ListCell<Website>() {
                @Override
                protected void updateItem(Website item, boolean empty) {
                    super.updateItem(item,  empty);

                    if (empty || item == null) {
                        setText(null);
                    } else {
                        setText(item.getWebsite());
                    }
                }
            });
        }

        if (!newData.isEmpty()) {
            newList.setItems(newData);

            newList.setCellFactory(param -> new ListCell<Website>() {
                @Override
                protected void updateItem(Website item, boolean empty) {
                    super.updateItem(item, empty);

                    if (empty || item == null) {
                        setText(null);
                    } else {
                        HBox hBox = new HBox();
                        hBox.setAlignment(Pos.CENTER);
                        JFXButton keepBtn = new JFXButton("Keep");
                        JFXButton deleteBtn = new JFXButton("Delete");

                        Label label = new Label(item.getWebsite());
                        label.setAlignment(Pos.CENTER);

                        hBox.getChildren().addAll(keepBtn, label, deleteBtn);
                        setGraphic(hBox);

                        keepBtn.setOnAction(new EventHandler<ActionEvent>() {
                            @Override
                            public void handle(ActionEvent event) {
                                System.out.println(item.getWebsite());
                                item.setKeep(true);
                            }
                        });
                    }
                }
            });
        }
        scanButton.visibleProperty().bind(isScanning.not());
        pauseButton.visibleProperty().bind(isScanning);


    }

    @FXML
    public void handleScanInbox() {
        isScanning.set(true);

        if (thread == null) {
            thread = new Thread() {
                public void run() {
                    mainApp.handleScanInbox(paused);
                }
            };
            thread.setDaemon(true);
            thread.start();
        } else {
            synchronized (paused) {
                if (paused.get()) {
                    paused.set(false);
                    paused.notify();
                }
            }
        }

    }

    @FXML
    public void handlePauseScanInbox() {
        paused.compareAndSet(false,  true);
        isScanning.set(false);

    }



}

Есть идеи, как динамически обновлять списки?

Ответы [ 2 ]

0 голосов
/ 11 декабря 2018

Для обновления FilteredList должен быть запущен прослушиватель, добавленный к ObservableList.Изменение свойства элемента списка по умолчанию не сработает.

Если вы создаете список с использованием экстрактора для свойств элемента, которые должны вызывать изменения при обновлении, FilteredList также обновляется.

Пример

public class Item {
    private final int i;
    private final BooleanProperty keep = new SimpleBooleanProperty();

    public Item(int i) {
        this.i = i;
    }

    @Override
    public String toString() {
        return Integer.toString(i);
    }

    public BooleanProperty keepProperty() {
        return keep;
    }

    public boolean isKeep() {
        return keep.get();
    }

    public void setKeep(boolean value) {
        keep.set(value);
    }

}
ObservableList<Item> data = FXCollections.observableArrayList(new Callback<Item, Observable[]>() {

    @Override
    public Observable[] call(Item param) {
        return new Observable[] { param.keepProperty() };
    }

});
for (int i = 0; i < 10; i++) {
    data.add(new Item(i));
}
FilteredList<Item> filtered = new FilteredList<>(data, Item::isKeep);
filtered.addListener((Observable o) -> System.out.println(filtered));
data.get(3).setKeep(true);
data.get(6).setKeep(true);
data.get(7).setKeep(true);
data.get(3).setKeep(false);

Выход

[3]
[3, 6]
[3, 6, 7]
[6, 7]

Возвращение массива, содержащего несколько триггеров Observable sобновление, если какой-либо из этих Observable s изменен.

Я рекомендую двойную проверку, если keep и delete действительно свойства, связанные с типом элемента, или если вы просто добавили эти свойства, чтобывозможность разделить ваш список на 3 FilteredList с.Будет ли таблица базы данных, содержащая элемент, содержать столбцы для этих значений?Вы бы сохранили их в выходном файле, если бы вам пришлось сохранять элементы в файл?
Если ответ на эти вопросы "Нет" , вам следует использовать 3 отдельных ObservableList с.Перемещение элементов из одного списка в другой менее сложно, чем работа с двумя свойствами и фильтрация списка по ним.

0 голосов
/ 11 декабря 2018

Почему вы используете BooleanProperty для этого, есть ли причина?Потому что вы можете просто пойти с 3 списка.

Вы можете выбрать 2 опции, вы можете создать контекстное меню для представления списка или кнопку рядом с ним, я фанат контекстного меню.

В FXML вы можете указатьa setOnAction () - Метод, этот метод можно использовать для переноса модели выбора из одного узла в один из ваших списков сохранения или удаления.

После этого все должно работать нормально.

private ListView<String>list;
private ListView<String> deleteList;

@FXML
private final void deleteSetOnAction(ActionEvent event) {
    deleteList.getItems().addAll(list.getSelectionModel().getSelectedItems());
    list.getItems().removeAll(list.getSelectionModel().getSelectedItems());
}

DeleteSetOnActionMethod указан для кнопки или контекстного меню в этом примере.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...