6

(これは、CarlDeaによる「JavaFX2.0byexample」という本のコードです。コード例は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();
    }
}

これは、一度に1つずつ、2つのリストビュー間で人を前後に移動するためのコードです。私がやりたいのは、ワンクリックで複数の人を選択して移動できるようにすることです。

私が変更したい関連する抜粋は次のとおりです。

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);

2つのリストのそれぞれの宣言の下。

最後に、イベントボタンの処理のコードを次のように変更します

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_に変更してから、1人を追加/削除するだけでなく、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 に答える