如何刷新JavaFX中的ListView

时间:2016-11-21 13:44:10

标签: listview javafx refresh

很抱歉打扰如此广泛的解释主题。 我一直在创建对话框,从一个列表中选择字符串值到另一个列表。一开始就有选项列表。 get / setSourceItems和get / setTargetItems是ObservableLists的getter和setter

private ListView<String> sourceListView;
private ObservableList<String> sourceItems;
private ListView<String> targetListView;
private ObservableList<String> targetItems;

        List<String> options = getSelectedMetaDataList();
        setSourceItems(FXCollections.observableArrayList(options));
        sourceListView = new ListView(getSourceItems());
        setTargetItems(FXCollections.observableArrayList(new ArrayList()));
        targetListView = new ListView(getTargetItems());

对话框在开始时显示listViews。源填充选项,目标为空。 但是当我使用按钮时,UI上没有任何反应。 例如,当我将所有项目从源移动到目标时,我可以在targetItems observableList中看到项目,但在UI上的targetListView中没有任何内容。

        Button selectAllBtn = new Button(">>");
            selectAllBtn.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    if (getSourceItems().size() > 0) {
                        setTargetItems(getSourceItems());
                        targetListView.refresh();
                        setSourceItems(null);
                        sourceListView.refresh();
                        System.out.println("selectAllBtn target: " + getTargetItems().toString());
                    }
                }
            });

选择模型也有问题。因为当我尝试移动所选项目时,SourceListView.getSelectionModel()。即使我突出显示项目,getSelectedItems()也是空的。我试图不仅通过observableList移动​​项目,而且使用targetListView.getItems()。addAll(movingItems); 用户界面仍然没有变化。

        Button selectOneBtn = new Button(">");
            selectOneBtn.setOnAction(new EventHandler<ActionEvent>() {
                @Override
                public void handle(ActionEvent event) {
                    ObservableList<String> movingItems = sourceListView.getSelectionModel().getSelectedItems();
                    System.out.println("selectOneBtn: " + sourceListView.getSelectionModel().getSelectedItems().size());
                    System.out.println("selectOneBtn: " + targetListView.getSelectionModel().getSelectedItems().size());
                    if (movingItems.size() > 0) {
                    System.out.println("selectOneBtn: " + movingItems.toString());
                    sourceListView.getSelectionModel().clearSelection();
                    sourceListView.getItems().removeAll(movingItems);
                    sourceListView.refresh();
                    targetListView.getItems().addAll(movingItems);
                    targetListView.refresh();
                    System.out.println("selectOneBtn source: " + getSourceItems().toString());
                    System.out.println("selectOneBtn target: " + getTargetItems().toString());
                    }
                }
            });

提前致谢。

3 个答案:

答案 0 :(得分:0)

您更改了基础可观察列表,但您从未告诉列表视图使用新列表:

Button selectAllBtn = new Button(">>");

selectAllBtn.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        if (getSourceItems().size() > 0) {
            setTargetItems(getSourceItems());

            targetListView.setItems(getTargetItems());

            // use an empty list, not null:
            setSourceItems(FXCollections.observableArrayList());

            sourceListView.setItems(getSourceItems());

            System.out.println("selectAllBtn target: " + getTargetItems().toString());
        }
    }
});

或者,只需更改现有列表的内容,而不是更改为新列表。由于列表是可观察的,因此列表视图将自动查看更改:

Button selectAllBtn = new Button(">>");

selectAllBtn.setOnAction(new EventHandler<ActionEvent>() {
    @Override
    public void handle(ActionEvent event) {
        if (getSourceItems().size() > 0) {

            getTargetItems().setAll(getSourceItems());

            getSourceItems().clear();

            System.out.println("selectAllBtn target: " + getTargetItems().toString());
        }
    }
});

对于您的选择问题,您将获得所选项目列表的参考:

 ObservableList<String> movingItems = sourceListView.getSelectionModel().getSelectedItems();

然后清除选择:

 sourceListView.getSelectionModel().clearSelection();

当然会将所选项目列表清空。

所以现在当你做

 sourceListView.getItems().removeAll(movingItems);
 targetListView.getItems().addAll(movingItems);

每次都会传入一个空列表,所以什么都不会改变。

而是复制所选项目:

List<String> movingItems = new ArrayList<>(sourceListView.getSelectionModel().getSelectedItems());

然后

sourceListView.getItems().removeAll(movingItems);
targetListView.getItems().addAll(movingItems);

会产生预期的效果(无需拨打refresh())。

这是一个SSCCE(注意我将这两种行为统一到一个方法中,因为它们基本相同):

import java.util.ArrayList;
import java.util.List;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class MoveItemsBetweenListViews extends Application {

    private ObservableList<String> sourceItems;
    private ObservableList<String> targetItems;



    @Override
    public void start(Stage primaryStage) {
        sourceItems = FXCollections.observableArrayList("One", "Two", "Three", "Four");
        targetItems = FXCollections.observableArrayList();

        ListView<String> sourceListView = new ListView<>(sourceItems);
        ListView<String> targetListView = new ListView<>(targetItems);

        Button moveAllButton = new Button(">>");
        Button moveSelectedButton = new Button(">");

        moveAllButton.setOnAction(e -> moveItems(sourceItems));
        moveSelectedButton.setOnAction(e -> moveItems(sourceListView.getSelectionModel().getSelectedItems()));

        VBox buttons = new VBox(10, moveAllButton, moveSelectedButton);
        buttons.setAlignment(Pos.CENTER);

        BorderPane root = new BorderPane(buttons, null, targetListView, null, sourceListView);
        Scene scene = new Scene(root, 600, 600);
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private void moveItems(List<String> itemsToMove) {
        List<String> movingItems = new ArrayList<>(itemsToMove);
        sourceItems.removeAll(movingItems);
        targetItems.addAll(movingItems);
    }

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

答案 1 :(得分:0)

我可能会错误地看待你的问题,但对我来说,似乎你做了一个复杂的简单任务。 ListView和ObservableList设计简单,简化了ListView的更新/刷新。我认为你应该让你的getSelectedMetaDataList()方法返回一个ArrayList,然后你应该创建一个ObservableList用你的ArrayList引导它。然后你应该相应地使用ObservableList和ListView。从那里你应该使用ObservableList方法来完成你想要做的事情。

        ArrayList<String> options = getSelectedMetaDataList();//Make this method return an ArrayList
        ObservableList<String> items = FXCollections.observableArrayList(options);
        ListView targetListView = new ListView();
        targetListView.setItems(items); 

答案 2 :(得分:0)

我猜你正在尝试做类似的事情。

@FXML ListView lv1, lv2;

ArrayList options = new ArrayList();
ObservableList<String> items;

ObservableList<String> items2;


//This is used to get the selected item from lv1 and add it to lv2
@FXML
private void handleButtonAction(ActionEvent event) {
    items2.add(lv1.getSelectionModel().getSelectedItem().toString());             
}

//This is used to get all items from lv1 and add them to lv2
@FXML 
private void handleGetAllButtonAction(ActionEvent event)
{
    for(String entry : items)
    {
       items2.add(entry);
    }
}

@Override
public void initialize(URL url, ResourceBundle rb) {
    // TODO

   options.add("hello");
   options.add("bye");
   options.add("hola");
   items = FXCollections.observableArrayList(options);
   items2 = FXCollections.observableArrayList();

   System.out.println(items.size());
   lv1.setItems(items);
   lv2.setItems(items2);

}