我想在JavaFX应用程序中创建一个表, 所以我创建了一个定义数据模型的类,并提供了进一步使用表的方法和字段。 这是代码:
import java.util.ArrayList;
import java.util.List;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class Item {
private final SimpleStringProperty id;
private final SimpleStringProperty serial_number ;
private final SimpleStringProperty description;
private final BooleanProperty check;
private final IntegerProperty language;
private final SimpleStringProperty cpvCode=new SimpleStringProperty("");
private final SimpleStringProperty replaceItem=new SimpleStringProperty("");
private final SimpleStringProperty includeInContract=new SimpleStringProperty("");
private final List<Attribute> listOfAttrs=new ArrayList();
public Item(String id1,String num,String des,Boolean bool,int lang) {
this.description = new SimpleStringProperty(des);
this.id = new SimpleStringProperty(id1);
this.serial_number= new SimpleStringProperty(num);
this.check=new SimpleBooleanProperty(bool);
this.language=new SimpleIntegerProperty(lang);
this.listOfAttrs.add(new Attribute("Yoo"));
}
public StringProperty cpvCodeProperty() {
return cpvCode;
}
public StringProperty replaceItemProperty() {
return replaceItem;
}
public StringProperty includeInContractProperty() {
return includeInContract;
}
public IntegerProperty languageProperty(){
return language;
}
public BooleanProperty checkProperty(){
return check;
}
public StringProperty idProperty() {
return id;
}
public StringProperty serial_numberProperty() {
return serial_number;
}
public StringProperty descriptionProperty() {
return description;
}
public void setLanguage(int lang){
this.language.set(lang);
}
public void setId(String fid) {
this.id.set(fid);
}
public void setSerial_number(String fnumber) {
this.serial_number.set(fnumber);
}
public void setDescription(String fdesc) {
this.description.set(fdesc);
}
public void setCheck(Boolean checking) {
this.check.set(checking);
}
public void setCpvCode(String cpv) {
this.cpvCode.set(cpv);
}
public void setReplaceItem(String replace) {
this.replaceItem.set(replace);
}
public void setIncludeInContract(String include) {
this.includeInContract.set(include);
}
public synchronized void setListOfAttrs(Attribute attrs) {
listOfAttrs.add(attrs);
}
public synchronized StringProperty getListOfAttrs(int index) {
return listOfAttrs.get(index).nameCodeProperty();
}
}
我还创建了一个带有场景构建器的桌面视图
<AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" style="-fx-background-color: #F0F0F0;">
<children>
<TableView fx:id="tableForItems" editable="true" pickOnBounds="true" prefHeight="463.0" prefWidth="901.0" tableMenuButtonVisible="true" AnchorPane.bottomAnchor="129.0" AnchorPane.leftAnchor="14.0" AnchorPane.rightAnchor="41.0" AnchorPane.topAnchor="55.0">
<columns>
<TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="33.0" text="Id" fx:id="tID" />
<TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="82.0" style=" .table-view:focused .table-row-cell:filled .invalid-table-cell:selected:focused { /* Works! */ } .table-view:focused .table-row-cell:filled .invalid-table-cell:focused:selected:hover { /* Works! */ }" text="%prompt.column.item.serial.number" fx:id="tSer" />
<TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="105.0" text="%prompt.column.item.description" fx:id="tDes" />
<TableColumn maxWidth="5000.0" minWidth="0.0" prefWidth="121.0" text="%prompt.column.item.keywords" fx:id="checkId" />
<TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="62.0" text="%prompt.column.item.url" fx:id="langId" />
<TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="71.0" text="%prompt.column.item.cpv" fx:id="cpvId" />
<TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="131.0" text="%prompt.column.item.replacesItem" fx:id="replaceItem" />
<TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="155.0" text="%prompt.column.item.includedInContract" fx:id="includedInContract" />
</columns>
</TableView>
</children>
</AnchorPane>
我已将数据与表格列相关联。
tID.setCellValueFactory(new PropertyValueFactory("id"));
tDes.setCellValueFactory(new PropertyValueFactory("description"));
tSer.setCellValueFactory(new PropertyValueFactory("serial_number"));
checkId.setCellValueFactory(new PropertyValueFactory("check"));
langId.setCellValueFactory(new PropertyValueFactory("language"));
cpvId.setCellValueFactory(new PropertyValueFactory("cpvCode"));
replaceItem.setCellValueFactory(new PropertyValueFactory("replaceItem"));
我想将列与arraylist listOfAttrs中的第一个值相关联。我做到了:
lastNameCol.setCellFactory(new Callback<TableColumn<Item,String>, TableCell<Item,String>>() {
@Override
public TableCell call(TableColumn p) {
return new TableCell() {
@Override
protected void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (this.getTableRow() != null && item != null) {
Item current =(Item) this.getTableRow().getItem();
String s=current.getListOfAttrs(0).getValue();
setText(s);
}
else {
setText("");
}
}
};
}
});
lastNameCol.setEditable(true);
lastNameCol.setOnEditCommit(
new EventHandler<CellEditEvent<Item, String>>() {
@Override
public void handle(CellEditEvent<Item, String> t) {
((Item) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setListOfAttrs(new Attribute(t.getNewValue()));
}
});
我在列中有第一个值,但是我无法编辑列,或者如果我更改了arraylist中的值,它就不会改变。有人能帮助我吗?
答案 0 :(得分:0)
我的代码中有很多我不理解的东西,因为有些东西丢失了。您应该尽可能简单地运行并显示问题的示例。我复制了你的代码块,并添加了一些使其工作所需的东西。现在您拥有嵌套列表结构,该表响应列表中的更改和编辑。
包表;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
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.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Callback;
public class Table extends Application {
private final ObservableList<Item> items = FXCollections.observableArrayList();
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("add ids");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
items.addAll(new Item("id1"), new Item("id2"));
}
});
VBox root = new VBox();
root.getChildren().add(btn);
TableColumn tID = new TableColumn("ID");
tID.setCellValueFactory(new PropertyValueFactory("id"));
TableColumn lastNameCol = new TableColumn("last name");
lastNameCol.setCellValueFactory(new Callback<CellDataFeatures<Item, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<Item, String> p) {
return p.getValue().getListOfAttrs();
}
});
lastNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
lastNameCol.setOnEditCommit(new EventHandler<CellEditEvent<Item, String>>() {
@Override
public void handle(CellEditEvent<Item, String> t) {
((Item) t.getTableView().getItems().get(
t.getTablePosition().getRow())).setListOfAttrs(t.getNewValue());
}
});
TableView tv = new TableView(items);
tv.setEditable(true);
tv.getColumns().addAll(tID, lastNameCol);
root.getChildren().add(tv);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Nested Obs list test");
primaryStage.setScene(scene);
primaryStage.show();
}
public class Item {
private final SimpleStringProperty id;
private final ObservableList<Attribute> listOfAttrs = FXCollections.observableArrayList();
public Item(String id1) {
this.id = new SimpleStringProperty(id1);
this.listOfAttrs.add(new Attribute("Yoo " + id1));
}
public StringProperty idProperty() {
return id;
}
public void setId(String fid) {
this.id.set(fid);
}
public synchronized void setListOfAttrs(String attrs) {
listOfAttrs.get(0).nameCode.set(attrs);
}
public synchronized StringProperty getListOfAttrs() {
return listOfAttrs.get(0).nameCodeProperty();
}
}
public class Attribute {
private SimpleStringProperty nameCode;
public Attribute(String s) {
this.nameCode = new SimpleStringProperty(s);
}
public StringProperty nameCodeProperty() {
return nameCode;
}
}
}