6

(这是 Carl Dea 所著的“JavaFX 2.0 by example”一书中的代码——代码示例可在 Apress 上免费获得,所以我相信他们不介意我在这里使用它)

我有完美运行的示例代码

package javafx2introbyexample.chapter1.recipe1_11;

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
 *
 * @author cdea
 */
public class CreatingAndWorkingWithObservableLists extends Application {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Application.launch(args);
    }

    @Override
    public void start(Stage primaryStage) {
        primaryStage.setTitle("Chapter 1-11 Creating and Working with ObservableLists");
        Group root = new Group();
        Scene scene = new Scene(root, 400, 250, Color.WHITE);

        // create a grid pane
        GridPane gridpane = new GridPane();
        gridpane.setPadding(new Insets(5));
        gridpane.setHgap(10);
        gridpane.setVgap(10);

        // candidates label
        Label candidatesLbl = new Label("Candidates");
        GridPane.setHalignment(candidatesLbl, HPos.CENTER);
        gridpane.add(candidatesLbl, 0, 0);

        Label heroesLbl = new Label("Heroes");
        gridpane.add(heroesLbl, 2, 0);
        GridPane.setHalignment(heroesLbl, HPos.CENTER);

        // candidates
        final ObservableList<String> candidates = FXCollections.observableArrayList("Superman",
                "Spiderman",
                "Wolverine",
                "Police", 
                "Fire Rescue", 
                "Soldiers", 
                "Dad & Mom", 
                "Doctor", 
                "Politician", 
                "Pastor", 
                "Teacher");
        final ListView<String> candidatesListView = new ListView<String>(candidates);
        candidatesListView.setPrefWidth(150);
        candidatesListView.setPrefHeight(150);

        gridpane.add(candidatesListView, 0, 1);

        // heros
        final ObservableList<String> heroes = FXCollections.observableArrayList();
        final ListView<String> heroListView = new ListView<String>(heroes);
        heroListView.setPrefWidth(150);
        heroListView.setPrefHeight(150);

        gridpane.add(heroListView, 2, 1);


        // select heroes
        Button sendRightButton = new Button(">");
        sendRightButton.setOnAction(new EventHandler<ActionEvent>() {

            public void handle(ActionEvent event) {
                String potential = candidatesListView.getSelectionModel().getSelectedItem();
                if (potential != null) {
                    candidatesListView.getSelectionModel().clearSelection();
                    candidates.remove(potential);
                    heroes.add(potential);
                }
            }
        });

        // deselect heroes
        Button sendLeftButton = new Button("<");
        sendLeftButton.setOnAction(new EventHandler<ActionEvent>() {

            public void handle(ActionEvent event) {
                String notHero = heroListView.getSelectionModel().getSelectedItem();
                if (notHero != null) {
                    heroListView.getSelectionModel().clearSelection();
                    heroes.remove(notHero);
                    candidates.add(notHero);
                }
            }
        });

        VBox vbox = new VBox(5);
        vbox.getChildren().addAll(sendRightButton,sendLeftButton);

        gridpane.add(vbox, 1, 1);
        GridPane.setConstraints(vbox, 1, 1, 1, 2,HPos.CENTER, VPos.CENTER);

        root.getChildren().add(gridpane);        
        primaryStage.setScene(scene);
        primaryStage.show();
    }
}

它是用于在两个列表视图之间来回移动人员的代码,一次一个。我想要做的是可以一键选择和移动几个人。

我要更改的相关摘录是:

final ListView<String> candidatesListView = new ListView<String>(candidates);
    candidatesListView.setPrefWidth(150);
    candidatesListView.setPrefHeight(150);

    gridpane.add(candidatesListView, 0, 1);

    // heros
    final ObservableList<String> heroes = FXCollections.observableArrayList();
    final ListView<String> heroListView = new ListView<String>(heroes);

...

// select heroes
    Button sendRightButton = new Button(">");
    sendRightButton.setOnAction(new EventHandler<ActionEvent>() {

        public void handle(ActionEvent event) {
            String potential = candidatesListView.getSelectionModel().getSelectedItem();
            if (potential != null) {
                candidatesListView.getSelectionModel().clearSelection();
                candidates.remove(potential);
                heroes.add(potential);
            }
        }
    });

    // deselect heroes
    Button sendLeftButton = new Button("<");
    sendLeftButton.setOnAction(new EventHandler<ActionEvent>() {

        public void handle(ActionEvent event) {
            String notHero = heroListView.getSelectionModel().getSelectedItem();
            if (notHero != null) {
                heroListView.getSelectionModel().clearSelection();
                heroes.remove(notHero);
                candidates.add(notHero);
            }
        }
    });

我尝试过的改变:

首先,我添加以下导入:

import javafx.scene.control.SelectionMode;

然后我添加行

candidatesListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
heroListView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);

在两个列表的各自声明下方。

最后,我将事件按钮的处理代码更改为

public void handle(ActionEvent event) {
            ObservableList<String> potential = candidatesListView.getSelectionModel().getSelectedItems();
            if (potential != null) {

                System.out.println(potential);
                candidates.removeAll(potential);
                heroes.addAll(potential);
                candidatesListView.getSelectionModel().clearSelection();
            }
        }

那就是 - 我将其更改为 getSelectedItem_s_,然后我 addAll 和 removeAll 而不是仅仅添加/删除一个人。当我尝试将几个人移过来时,这只会使 listView 留空。是什么赋予了?

附言。我还尝试通过迭代列表“潜在”来一次添加/删除几个人,但这也给出了错误的结果。

4

1 回答 1

6

不幸的是,您遇到了一个错误:http: //javafx-jira.kenai.com/browse/RT-24367

原始问题是下一个:ListView.getSelectionMode()返回它的可观察列表的一部分,但不返回副本。因此,从该列表中删除会导致各种问题。

在从中删除项目之前使用复制列表的下一个代码:

    sendRightButton.setOnAction(new EventHandler<ActionEvent>() {
        public void handle(ActionEvent event) {
            ObservableList<String> potential = 
                FXCollections.observableArrayList( //copy
                    candidatesListView.getSelectionModel().getSelectedItems());
            if (potential != null) {
                heroes.addAll(potential);
                candidates.removeAll(potential);
                candidatesListView.getSelectionModel().clearSelection();
            }
        }
    });
于 2012-08-26T19:56:18.147 回答