0

我有一个使用 JavaFX 的应用程序。它包含一个 ListView(它使用一个 ObservableList)。我添加了一个 ChangeListener 使用

list.getSelectionModel().selectedItemProperty().addListener(new ChangeListener...

它工作正常。每次我选择其他项目时,都会调用侦听器。

但是当我从 ObservableList 中删除一个元素时也会调用它。移除元素后,会自动选择列表中的另一个元素并调用侦听器。

我怎样才能防止这种行为?

谢谢!

4

3 回答 3

1

以防我的评论太神秘;

package listchange;

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class ListChange extends Application {

    @Override
    public void start(Stage primaryStage) {
        ObservableList<String> data = FXCollections.observableArrayList();
        data.addAll("one","two","three","four");

        ChangeListener changeListener = new ChangeListener() {
            @Override
            public void changed(ObservableValue observable, Object oldValue, Object newValue) {
                System.out.println("new val "+newValue);
            }
        };

        ListView lv = new ListView(data);
        lv.getSelectionModel().selectedItemProperty().addListener(changeListener);

        data.addListener(new ListChangeListener<String>() {
            @Override
            public void onChanged(ListChangeListener.Change<? extends String> c) {
                c.next();
                if (c.wasRemoved()){
                    lv.getSelectionModel().selectedItemProperty().removeListener(changeListener);
                }
            }
        });

        Button b = new Button("delete");
        b.setOnAction(new EventHandler<ActionEvent>() {
            @Override
            public void handle(ActionEvent event) {
                //you can remove listener here or in data ListChangeListener
                //lv.getSelectionModel().selectedItemProperty().removeListener(changeListener);
                if (data.size() > 0) data.remove(0);
                //you have to re-add the listener after removing
                lv.getSelectionModel().selectedItemProperty().addListener(changeListener);
            }
        });

        VBox root = new VBox();
        root.getChildren().addAll(lv,b);

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

}

这样,在使用键遍历时,您仍然会获得选择更改事件。如果您知道删除发生的位置,则很容易删除然后重新添加侦听器。

于 2014-02-24T20:44:48.467 回答
0

I found a solution that works, but it is not a good solution.

Instead of using a listener for selection changes, i only handle mouse click events on the list. When I receive a click event, I request the selected element from the ListView. This is not called when I remove or add an element. Just when clicking on the list.

于 2014-02-24T18:00:32.610 回答
0

尝试这个:

final ObservableList<String> fruits = FXCollections.observableArrayList("Apple", "Banana", "Pear", "Strawberry", "Peach", "Orange", "Plum", "Melon", "Cherry", "Blackberry", "Melon", "Cherry", "Blackberry");
final ComboBox fruit = new ComboBox(fruits);

fruit.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<String>() {
    public void changed(ObservableValue<? extends String> ov, String old_val, String new_val) {
        //TODO: your remove method
    }
});
于 2014-02-24T17:19:56.000 回答