Yur*_*ura 0 java javafx arraylist
所有!
当我在Java上设计我的项目时遇到了以下主要问题:
我需要编写的程序是允许用户输入一些数据然后以特定格式保存的接口.在项目中我存储数据ArrayList<>.
public class CQuestionnaire
{
// fields
private final List<CQuestStage> m_lstStages;
…
}
Run Code Online (Sandbox Code Playgroud)
用户界面基于TableView.所以我需要ObservableList<>连接数据和TableView.我认为直接链接TableView列表是一个很好的决定CQuestionnaire.所以我getObservableList()为此目的实施:
public class CQuestionnaire
{
// fields
private final List<CQuestStage> m_lstStages;
public ObservableList<CQuestStage> getObservableList()
{
return FXCollections.observableArrayList(m_lstStages);
}
…
}
Run Code Online (Sandbox Code Playgroud)
这不起作用,因为FXCollections.observableArrayList()列表的返回副本和所有用户的操作不会更改CQuestionnaire成员.
现在的问题是:有没有什么办法如何链接TableView与ArrayList<>不改变其类型ObservableList<>(离开单独的数据和视图),并不会产生明显的列表所必需的TableView唯一?
当然我已经阅读了这个主题(JavaFX,Casting ArrayList to ObservableList).但问题是FXCollections.observableArrayList()副本列表中的源列表CQuestionnaire和之间没有链接TableView.
使用FXCollections.observableList(m_lstStages),返回由指定列表支持的可观察列表,而不是FXCollections.observableArrayList(m_lstStages)创建新的可观察数组列表并将集合的内容添加到其中.
这样,对表视图内容所做的更改将自动传播回原始列表.(但请注意,虽然对基础列表的更改将更改可观察列表,但由于基础列表不可观察,因此无法通知表格此类更改,因此无法自动更新.)
注意,没有必要将此功能添加到模型类中; 您可以FXCollections.observableList(...)在需要的时候包装列表.这可以防止您的模型依赖于JavaFX API,我认为这是目标的一部分.
这是一个简单的SSCCE.
import java.util.ArrayList;
import java.util.List;
import java.util.function.Function;
import javafx.application.Application;
import javafx.beans.value.ObservableValueBase;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Spinner;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class TableWithModelWithPlainList extends Application {
@Override
public void start(Stage primaryStage) {
Model model = new Model();
for (int i = 1 ; i <= 20 ; i++) {
model.getItems().add(new Item("Item "+i, i*i));
}
TableView<Item> table = new TableView<>();
// use observable list wrapping model data for table items:
table.setItems(FXCollections.observableList(model.getItems()));
// normal table setup:
table.getColumns().add(column("Item", Item::getName));
table.getColumns().add(column("Value", Item::getValue));
// controls to modify table data:
TextField itemNameField = new TextField();
Spinner<Integer> spinner = new Spinner<>(1, 1000, 200);
Button add = new Button("Add");
EventHandler<ActionEvent> addHandler = e -> {
table.getItems().add(new Item(itemNameField.getText(), spinner.getValue()));
itemNameField.clear();
};
add.setOnAction(addHandler);
itemNameField.setOnAction(addHandler);
Button remove = new Button("Remove");
remove.disableProperty().bind(table.getSelectionModel().selectedItemProperty().isNull());
remove.setOnAction(e -> table.getItems().remove(table.getSelectionModel().getSelectedIndex()));
// checks that model and table are in sync:
Button debug = new Button("Debug");
debug.setOnAction(e -> {
System.out.println("Model has "+model.getItems().size()+" items; table has "+table.getItems().size()+" items");
for (int i = 0 ; i < model.getItems().size() && i < table.getItems().size(); i++) {
Item modelItem = model.getItems().get(i);
Item tableItem = table.getItems().get(i);
System.out.printf("Index %d: model %s (%d); table %s (%d); equal: %s%n",
i, modelItem.getName(), modelItem.getValue(),
tableItem.getName(), tableItem.getValue(),
tableItem.getValue()==modelItem.getValue() && tableItem.getName().equals(modelItem.getName()));
}
System.out.println();
});
// layout stuff:
HBox controls = new HBox(2, itemNameField, spinner, add, remove, debug);
controls.setAlignment(Pos.CENTER);
controls.setPadding(new Insets(10));
BorderPane root = new BorderPane(table);
root.setBottom(controls);
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
private static <S,T> TableColumn<S,T> column(String title, Function<S,T> property) {
TableColumn<S,T> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> new ObservableValueBase<T>() {
@Override
public T getValue() {
return property.apply(cellData.getValue());
};
});
return col ;
}
public static class Model {
private List<Item> items ;
public Model() {
this.items = new ArrayList<>();
}
public List<Item> getItems() {
return items ;
}
}
public static class Item {
private String name ;
private int value ;
public Item(String name, int value) {
this.name = name ;
this.value = value ;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
public static void main(String[] args) {
launch(args);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5130 次 |
| 最近记录: |