【问题标题】:JavaFX ObservableList prevent auto selectionJavaFX ObservableList 防止自动选择
【发布时间】:2014-02-24 16:43:56
【问题描述】:

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

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

而且效果很好。每次我选择其他项目时,都会调用侦听器。

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

如何防止这种行为?

谢谢!

【问题讨论】:

  • 您必须移除监听器,删除项目,然后重新添加监听器。在哪里执行此操作取决于您的代码,但可能在哪里删除项目或使用 getRemoved() 在列表更改侦听器中。

标签: java javafx observablelist


【解决方案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();
    }

}

这样,您在使用键遍历时仍会收到选择更改事件。如果您知道删除发生的位置,则只需删除然后重新添加侦听器即可。

【讨论】:

  • 谢谢我知道了。我找到了另一个非常适合我的解决方案。我在从列表中删除一个元素之前设置了一个标志。在选择处理程序方法中,我检查此标志,如果它是真的,我将忽略该事件(并将标志设置回flase)。
【解决方案2】:

试试这个:

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

【讨论】:

  • 任何可以用于ComboBox 的组件,而不是ListViewfinal lv = new ...
【解决方案3】:

我找到了一个可行的解决方案,但它不是一个好的解决方案。

我只处理列表上的鼠标单击事件,而不是使用侦听器进行选择更改。当我收到点击事件时,我从 ListView 请求选定的元素。 当我删除或添加元素时不会调用它。就在点击列表时。

【讨论】:

    猜你喜欢
    • 2017-05-01
    • 2023-03-29
    • 1970-01-01
    • 2014-10-30
    • 2011-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多