【问题标题】:JavaFX list databindingJavaFX 列表数据绑定
【发布时间】:2016-06-03 16:14:20
【问题描述】:

我有一个在单独线程中运行的模型类(实现任务)。它有一个在无限循环期间更新的ArrayList

private List<ClientSession> clientSessions = new ArrayList<>();

在控制器类中,我需要对该列表进行单向绑定,该列表具有 ChangeListener 并显示在 TableView 中。

您能帮我了解如何以最佳方式(绑定)吗?

我已经弄清楚如何进行内容绑定了。

在我添加的模型类中:

public ObservableList<ClientSession> clientSessions = FXCollections.observableArrayList();

在我添加的控制器类中:

private ListProperty<ClientSession> clientSessionListProperty = new SimpleListProperty<>(FXCollections.observableArrayList());
clientSessionListProperty.bindContent(commandCenterNio.clientSessions);

但这并不能解决 tableview 的问题。在这个例子中如何使用TableView

【问题讨论】:

    标签: java javafx data-binding


    【解决方案1】:

    实际上您不需要中间属性,ObservableList 默认是“可绑定的”,因为它会告诉您每当对列表执行更改时:

    允许侦听器在更改发生时跟踪更改的列表。

    您只需调用setItems,直接为列表视图提供模型的ObservableList

    我准备了一个例子:

    该示例有一个实现 Runnable 的模型(但请注意,它在无限循环中更新其列表这一事实在解决方案方面绝对没有区别),它有一个ObservableListToDo 对象,必须 Property 才能显示在 TableView 上。在Main 中,模型填充了一些初始数据,并显示了带有数据的ListView。 GUI 还具有一些控件,可通过其缓冲区向模型添加新项目。

    SampleModel.java

    public class SampleModel implements Runnable{
    
        // Listen to this list
        public ObservableList<ToDo> toDoList = FXCollections.observableArrayList();
    
        // Buffer to be used to store new elements until the thread wakes up
        private BlockingQueue<ToDo> queue = new ArrayBlockingQueue<ToDo>(1000);
    
        @Override
        public void run() { 
            while(true){
                // Drain the buffer to the ObservableList
                queue.drainTo(toDoList);
    
                // Sleep a bit
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
    
            } 
            }
    
        public void updateBuffer(ToDo newItem){
            queue.offer(newItem);
        }
    }
    

    ToDo.java

    public class ToDo {
    
        private StringProperty task = new SimpleStringProperty();
        public StringProperty taskProperty() {return task;}
    
        private ObjectProperty<Importance> importance = new SimpleObjectProperty<Importance>();
        public ObjectProperty<Importance> importanceProperty() {return importance;}
    
        public ToDo(String task, Importance importance){
            this.task.set(task);
            this.importance.set(importance);
        }
    
    
        enum Importance {
            DONTCARE, SHALL, MUST, FIRSTPRIO;
    
              @Override
              public String toString() {
                switch(this) {
                  case DONTCARE: return "I don't care";
                  case SHALL: return "It shall be done";
                  case MUST: return "It must be done";
                  case FIRSTPRIO: return "I will die if I do not do it";
                  default: throw new IllegalArgumentException();
                }
              }
        }
    
    }
    

    Main.java

    public class Main extends Application {
        @Override
        public void start(Stage primaryStage) {
            try {
                VBox root = new VBox();
                Scene scene = new Scene(root,400,400);
                scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
    
                SampleModel model = new SampleModel();
                model.toDoList.addAll(new ToDo("Brooming", ToDo.Importance.DONTCARE),
                        new ToDo("Taking a nap", ToDo.Importance.FIRSTPRIO),
                        new ToDo("Cooking", ToDo.Importance.MUST),
                        new ToDo("Wash the car", ToDo.Importance.DONTCARE),
                        new ToDo("Pay the bills", ToDo.Importance.SHALL));
    
                TableView<ToDo> tableView = new TableView<ToDo>();
    
                TableColumn<ToDo, String> colTask = new TableColumn<ToDo, String>();
                colTask.setCellValueFactory(new PropertyValueFactory<>("task"));
    
                TableColumn<ToDo, String> colImportance = new TableColumn<ToDo, String>();
                colImportance.setCellValueFactory(cellData -> new SimpleStringProperty(cellData.getValue().importanceProperty().get().toString()));
    
                tableView.getColumns().addAll(colTask, colImportance);
    
                tableView.setItems(model.toDoList);
    
                HBox hbox = new HBox();
                TextArea textArea = new TextArea();
                textArea.setPrefSize(180, 15);
                ComboBox<ToDo.Importance> cb = new ComboBox<ToDo.Importance>();
                cb.setItems(FXCollections.observableArrayList(ToDo.Importance.FIRSTPRIO, ToDo.Importance.DONTCARE, ToDo.Importance.MUST));
    
                Button btnAdd = new Button("Add");
                btnAdd.setOnAction(e -> model.updateBuffer(new ToDo(textArea.getText(), cb.getValue())));
    
                hbox.getChildren().addAll(textArea, cb, btnAdd);
                root.getChildren().addAll(hbox, tableView);
    
                Thread thread = new Thread(model);
                thread.setDaemon(true);
                thread.start();
    
    
                primaryStage.setScene(scene);
                primaryStage.show();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-02-28
      • 1970-01-01
      • 2011-01-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-28
      相关资源
      最近更新 更多