代码之家  ›  专栏  ›  技术社区  ›  Arceus

带有ChangeListener的JavaFX表格视图,可进行多种选择

  •  3
  • Arceus  · 技术社区  · 9 年前

    我想在JavaFX 8中侦听表视图上的选择更改 selectedItemProperty (或selectedIndexProperty)在以下情况下不触发: 已经选择了多条线,现在我选择了一条新的单线。如果这条线是之前选择的最后一条线,它不会做出反应。这是因为selectedItemProperty只包含一个项目,而不是所有选定项目的列表。但不幸的是,没有选择 项目 属性很奇怪,因为方法 getSelectedItems() 存在。我不知道在哪里添加监听器以使其在任何情况下都能工作。

    下面是一个示例代码:

    import java.util.stream.Collectors;
    import javafx.application.Application;
    import javafx.beans.property.SimpleStringProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.control.ListView;
    import javafx.scene.control.SelectionMode;
    import javafx.scene.control.TableColumn;
    import javafx.scene.control.TableView;
    import javafx.scene.layout.HBox;
    import javafx.stage.Stage;
    
    public class MultipleSelectionTest extends Application
    {
        private ListView<Integer> list = new ListView<>();
        private TableView<String> table = new TableView<>();
        private TableColumn<String, String> column1 = new TableColumn<>("Numbers");
    
        @Override
        public void start(Stage primaryStage) throws Exception
        {
            HBox box = new HBox(list, table);
            primaryStage.setScene(new Scene(box, 300, 500));
            initializeTable();
            initializeList();
            primaryStage.show();
        }
    
        private void initializeTable()
        {
            table.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
            table.getColumns().add(column1);
            column1.setCellValueFactory(s -> new SimpleStringProperty(s.getValue()));
            table.setItems(FXCollections.observableArrayList("One", "Two", "Three", "Four", "Five", "Six", "Seven"));
        }
    
        private void initializeList()
        {
            table.getSelectionModel().selectedItemProperty().addListener((property, oldValue, newValue) ->
            {
                ObservableList<Integer> convertedItems = FXCollections.observableList(
                    table.getSelectionModel().getSelectedItems()
                    .stream()
                    .map(this::convertNumber)
                    .collect(Collectors.toList()));
    
                list.setItems(convertedItems);
            });
        }
    
        private int convertNumber(String expression)
        {
            switch (expression)
            {
                case "One": return 1;
                case "Two": return 2;
                case "Three": return 3;
                case "Four": return 4;
                case "Five": return 5;
                case "Six": return 6;
                case "Seven": return 7;
                default: throw new IllegalArgumentException();
            }
        }
    
        public static void main(String[] args)
        {
            launch();
        }
    }
    

    请注意,此示例中的ListView仅用于视觉目的。

    2 回复  |  直到 7 年前
        1
  •  4
  •   Itai    9 年前

    你不需要 selectedItemsProperty - getSelectedItems 返回一个 ObservableList 您可以向其中添加侦听器。

    为此设置一个属性将意味着列表对象已更改,但实际上发生的是列表保持不变 对象 ,但内容发生了变化。

        2
  •  1
  •   Andrew S    9 年前

    这是一个更完整的解决方案,这要归功于SillyFly的回应。

    在我的示例中,假设表被设置为使用任意类Person,该类定义了名字、姓氏和电子邮件。

    //Set the table to multi selection mode
    table.getSelectionModel().setSelectionMode( SelectionMode.MULTIPLE);
    
    //Regiseter the listener on the ObervableList<Person>
    table.getSelectionModel().getSelectedItems().addListener(multiSelection);
    
    
      /**A listener for list selections, multiple selections in the TableView**/
         ListChangeListener< Person> multiSelection = new ListChangeListener<Person>(){
            @Override
            public void onChanged(  ListChangeListener.Change<? extends Person> changed){
                for( Person p : changed.getList())
                    System.out.println(p);
            } 
         };