很抱歉打扰如此广泛的解释主题。 我一直在创建对话框,从一个列表中选择字符串值到另一个列表。一开始就有选项列表。 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());
}
}
});
提前致谢。
答案 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);
}