JavaFX:TableView 未显示在 GUI 中
JavaFX: TableView not showing up in GUI
我正在尝试将我的程序绑定到在 SceneBuilder 中设计的 GUI。
我已经设法让我的 'Accounts.class' ID 显示在最左边的列表中。
现在我需要让 TableView 正常工作,但我没有运气让它填充数据。
它应该包含来自 'Invoice.class' 字段的数据,
在每个帐户对象中都有一个集合 - 这个集合将显示在右侧 TableView 的不同行上。
非常感谢任何帮助!
p.s。原谅我,我知道之前已经被问过很多次了,但是所有其他解决方案似乎都不适合我我试过在参数中添加类型,比如;
tableAccount.setCellValueFactory(new PropertyValueFactory<Invoice, Account>("id"));
运气不好,这让我非常沮丧。从昨晚开始我就一直在胡闹,一点改进都没有,所以在这里发帖是我最后的选择。
Controller.class
public class Controller implements Initializable{
final ObservableList<Account> tableContent = FXCollections.observableArrayList(new Account("A", "B"));
@FXML
private TableView<?> tableView;
@FXML
private TableColumn<?, ?> tableAccount;
@FXML
private TableColumn<?, ?> tableDate;
@FXML
private TableColumn<?, ?> tableTime;
@FXML
private TableColumn<?, ?> tableTotal;
@FXML
private TableColumn<?, ?> tableNotes;
@FXML
private ListView<String> list;
@FXML
private TextArea invoiceView;
@FXML
private TextField amountField;
@FXML
private Button addAmount;
@FXML
private Button newInvoice;
@FXML
private Button saveInvoice;
@FXML
private Button deleteInvoice;
@FXML
private Label messageBar;
@Override
public void initialize(URL location, ResourceBundle resources) {
//list.setPlaceholder(new Label("No Content In List"));
setAccountsList();
//tableView = new TableView<>(names);
Account ac1 = new Account("A-02", "Tina", "96 Grove Vale", "London", "N1 8PT");
Invoice inv = ac1.newInvoice();
InvoiceCalculator calc = new InvoiceCalculator();
inv.add(4.50);
inv.add(4.50);
inv.add(3.00);
inv.add(15.00);
calc.calculateInvoice(inv);
setTableView(ac1);
}
private void setTableView(Account a) {
tableView = new TableView<>();
tableAccount.setCellValueFactory(new PropertyValueFactory<>("id"));
tableDate.setCellValueFactory(new PropertyValueFactory<>("date"));
tableTime.setCellValueFactory(new PropertyValueFactory<>("time"));
tableTotal.setCellValueFactory(new PropertyValueFactory<>("total"));
tableNotes.setCellValueFactory(new PropertyValueFactory<>("notes"));
//tableView.setItems(setTableAccounts());
}
@FXML
public void listViewSelected() {
list.getSelectionModel().getSelectedItem();
// newInvoice.setText(list.getSelectionModel().getSelectedItem());
}
@FXML
public void newInvoiceFired() {
System.out.println("new invoice button has been clicked");
}
@FXML
public void deleteInvoiceFired() {
System.out.println("delete invoice button has been clicked");
}
@FXML
public void saveInvoiceFired() {
System.out.println("save invoice button has been clicked");
}
public void setAccountsList(){
ObservableList<String> names = FXCollections.observableArrayList();
names.addAll(Main.getAllAccounts().stream().map(Account::getId).collect(Collectors.toList()));
list.setItems(names);
names.add("T-112");
}
public ObservableList<Account> setTableAccounts(){
ObservableList<Account> names = FXCollections.observableArrayList();
names.addAll(Main.getAllAccounts());
return names;
}
}
Account.class
public class Account {
private String id;
private String name;
private String address1;
private String address2;
private String postCode;
private Set<Invoice> invoiceArchive = new HashSet<>();
public Account(String id, String name, String address1, String address2, String postCode) {
this.id = id;
this.name = name;
this.address1 = address1;
this.address2 = address2;
this.postCode = postCode;
Main.addAccount(this);
}
public Account(String id, String name, String address1, String postCode) {
this.id = id;
this.name = name;
this.address1 = address1;
this.postCode = postCode;
}
public Account(String name, String id) {
this.name = name;
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getPostCode() {
return postCode;
}
public void setPostCode(String postCode) {
this.postCode = postCode;
}
public Set<Invoice> getInvoiceArchive() {
return invoiceArchive;
}
public Invoice newInvoice(){
Invoice i = new Invoice(this);
invoiceArchive.add(i);
return i;
}
@Override
public String toString(){
return this.getId();
}
}
Invoice.class
public class Invoice {
private Account id;
private ArrayList<Double> invoiceAmounts;
private double invoiceTotal;
private String date;
private String time;
private String notes;
private String modified;
DecimalFormat df = new DecimalFormat("#.00");
public Invoice(Account id) {
this.id = id;
this.invoiceAmounts = new ArrayList<>();
this.date = new SimpleDateFormat("dd/MM/yyyy HH:mm").format(Calendar.getInstance().getTime());
}
public String getDate() {
return date;
}
public void setModified(String date) {
this.modified = date;
}
public Account getId() {
return id;
}
public void setId(Account id) {
this.id = id;
}
public ArrayList<Double> getInvoiceAmounts() {
return invoiceAmounts;
}
public void setInvoiceAmounts(ArrayList<Double> invoiceAmounts) {
this.invoiceAmounts = invoiceAmounts;
}
public double getInvoiceTotal() {
return invoiceTotal;
}
public void setInvoiceTotal(double invoiceTotal) {
this.invoiceTotal = invoiceTotal;
}
public void add(Double d){
invoiceAmounts.add(d);
}
private String returnInvoiceAmounts(){
String result="";
for (Double d:invoiceAmounts){
result += "£"+df.format(d)+"\n";
}
return result;
}
@Override
public String toString(){
return "Account: "+id.getId()+
"\nCreated: "+getDate()+"\n"+returnInvoiceAmounts()
+"--------"+"\nTotal\n£"+df.format(invoiceTotal);
}
}
GUI.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="477.0" prefWidth="641.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
<children>
<SplitPane dividerPositions="0.24249999999999972" layoutY="50.0" prefHeight="427.0" prefWidth="641.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ListView fx:id="list" layoutX="-24.0" layoutY="62.0" onKeyPressed="#listViewSelected" onKeyReleased="#listViewSelected" onMouseClicked="#listViewSelected" prefHeight="425.0" prefWidth="151.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="445.0" prefWidth="411.0">
<children>
<SplitPane dividerPositions="0.30023640661938533" layoutX="143.0" layoutY="123.0" orientation="VERTICAL" prefHeight="445.0" prefWidth="480.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<TableView layoutX="128.0" layoutY="45.0" prefHeight="208.0" prefWidth="478.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="tableAccount" prefWidth="75.0" text="Account" />
<TableColumn fx:id="tableDate" prefWidth="75.0" text="Date" />
<TableColumn fx:id="tableTime" prefWidth="75.0" text="Time" />
<TableColumn fx:id="tableTotal" prefWidth="75.0" text="Amount" />
<TableColumn fx:id="tableNotes" prefWidth="75.0" text="Notes" />
</columns>
</TableView>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="286.0" prefWidth="478.0">
<children>
<SplitPane dividerPositions="0.4474789915966387" layoutX="168.0" layoutY="48.0" prefHeight="292.0" prefWidth="478.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TextArea fx:id="invoiceView" layoutX="5.0" layoutY="14.0" prefHeight="290.0" prefWidth="209.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TextField fx:id="amountField" layoutX="82.0" layoutY="86.0" prefHeight="27.0" prefWidth="104.0" promptText="0.00" />
<Button fx:id="addAmount" layoutX="195.0" layoutY="86.0" mnemonicParsing="false" text="Add" />
<Label layoutX="14.0" layoutY="91.0" text="Amount: : " />
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
<ImageView fitHeight="150.0" fitWidth="200.0" layoutX="14.0" layoutY="11.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@Icon/Logo.png" />
</image>
</ImageView>
<HBox alignment="CENTER_RIGHT" layoutX="462.0" layoutY="14.0" spacing="15.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<Button fx:id="newInvoice" mnemonicParsing="false" onAction="#newInvoiceFired" text="New" />
<Button fx:id="saveInvoice" mnemonicParsing="false" onAction="#deleteInvoiceFired" text="Save" />
<Button fx:id="deleteInvoice" mnemonicParsing="false" onAction="#deleteInvoiceFired" text="Delete" />
</children>
</HBox>
</children>
</AnchorPane>
首先,为您的字段使用正确的类型。由于 table 中的每一行都是 Invoice
,因此您应该有一个 TableView<Invoice>
。由于 tableAccount
列显示类型为 Invoice
的对象的类型为 Account
的属性,它应该是 TableColumn<Invoice, Account>
,等等 tableDate
,我假设 (因为 date
是 String
) 显示 Invoice
类型 String
的属性,所以它应该是 TableColumn<Invoice, String>
。等等,。然后您将能够设置单元格值工厂,使用您显示的 PropertyValueFactory
(具有匹配类型),或者(可能更好)仅使用 lambda (即 tableAccount.setCellValueFactory(cellData -> new SimpleObjectProperty<>(cellData.getValue().getId()));
)。
其次,不要创建新的table! (您已经被告知 。)您的 table 是在 FXML 文件中定义的,并且在那里定义的 table 显示在 UI 中。在您的 setTableView
方法中,您创建一个新的 table,并对其进行配置。但是由于 table 从未显示在 UI 中,您永远不会看到配置的结果。不要创建新的 table,只需配置已有的即可。
最后,您如何尝试填充 table 并不是很清楚。你说 table 中的每一行都是一张发票:所以这意味着 table.setItems(...)
将期望 ObservableList<Invoice>
。你正试图给它一个 ObservableList<Account>
。您需要在此处生成适当的发票列表(您尚未指定应该是什么)而不是 Account
s.
的列表
这里可能还有其他错误,但那些是最明显的(对我来说),应该会让你走上正轨。
我已经设法解决了这个问题,在花了很长时间试图解决它之后。
这似乎是微不足道的,在 GUI.fxml 中,我没有为 tableView 分配 ID,因此它从未在控制器中初始化,并且在设置它时收到 NullPointerException
TableView fx:id="tableView"
我很生气自己浪费了这么多时间,但这是我第一次使用 fxml 和 javafx,所以学到了很多东西。
我正在尝试将我的程序绑定到在 SceneBuilder 中设计的 GUI。 我已经设法让我的 'Accounts.class' ID 显示在最左边的列表中。
现在我需要让 TableView 正常工作,但我没有运气让它填充数据。
它应该包含来自 'Invoice.class' 字段的数据, 在每个帐户对象中都有一个集合 - 这个集合将显示在右侧 TableView 的不同行上。
非常感谢任何帮助!
p.s。原谅我,我知道之前已经被问过很多次了,但是所有其他解决方案似乎都不适合我我试过在参数中添加类型,比如;
tableAccount.setCellValueFactory(new PropertyValueFactory<Invoice, Account>("id"));
运气不好,这让我非常沮丧。从昨晚开始我就一直在胡闹,一点改进都没有,所以在这里发帖是我最后的选择。
Controller.class
public class Controller implements Initializable{
final ObservableList<Account> tableContent = FXCollections.observableArrayList(new Account("A", "B"));
@FXML
private TableView<?> tableView;
@FXML
private TableColumn<?, ?> tableAccount;
@FXML
private TableColumn<?, ?> tableDate;
@FXML
private TableColumn<?, ?> tableTime;
@FXML
private TableColumn<?, ?> tableTotal;
@FXML
private TableColumn<?, ?> tableNotes;
@FXML
private ListView<String> list;
@FXML
private TextArea invoiceView;
@FXML
private TextField amountField;
@FXML
private Button addAmount;
@FXML
private Button newInvoice;
@FXML
private Button saveInvoice;
@FXML
private Button deleteInvoice;
@FXML
private Label messageBar;
@Override
public void initialize(URL location, ResourceBundle resources) {
//list.setPlaceholder(new Label("No Content In List"));
setAccountsList();
//tableView = new TableView<>(names);
Account ac1 = new Account("A-02", "Tina", "96 Grove Vale", "London", "N1 8PT");
Invoice inv = ac1.newInvoice();
InvoiceCalculator calc = new InvoiceCalculator();
inv.add(4.50);
inv.add(4.50);
inv.add(3.00);
inv.add(15.00);
calc.calculateInvoice(inv);
setTableView(ac1);
}
private void setTableView(Account a) {
tableView = new TableView<>();
tableAccount.setCellValueFactory(new PropertyValueFactory<>("id"));
tableDate.setCellValueFactory(new PropertyValueFactory<>("date"));
tableTime.setCellValueFactory(new PropertyValueFactory<>("time"));
tableTotal.setCellValueFactory(new PropertyValueFactory<>("total"));
tableNotes.setCellValueFactory(new PropertyValueFactory<>("notes"));
//tableView.setItems(setTableAccounts());
}
@FXML
public void listViewSelected() {
list.getSelectionModel().getSelectedItem();
// newInvoice.setText(list.getSelectionModel().getSelectedItem());
}
@FXML
public void newInvoiceFired() {
System.out.println("new invoice button has been clicked");
}
@FXML
public void deleteInvoiceFired() {
System.out.println("delete invoice button has been clicked");
}
@FXML
public void saveInvoiceFired() {
System.out.println("save invoice button has been clicked");
}
public void setAccountsList(){
ObservableList<String> names = FXCollections.observableArrayList();
names.addAll(Main.getAllAccounts().stream().map(Account::getId).collect(Collectors.toList()));
list.setItems(names);
names.add("T-112");
}
public ObservableList<Account> setTableAccounts(){
ObservableList<Account> names = FXCollections.observableArrayList();
names.addAll(Main.getAllAccounts());
return names;
}
}
Account.class
public class Account {
private String id;
private String name;
private String address1;
private String address2;
private String postCode;
private Set<Invoice> invoiceArchive = new HashSet<>();
public Account(String id, String name, String address1, String address2, String postCode) {
this.id = id;
this.name = name;
this.address1 = address1;
this.address2 = address2;
this.postCode = postCode;
Main.addAccount(this);
}
public Account(String id, String name, String address1, String postCode) {
this.id = id;
this.name = name;
this.address1 = address1;
this.postCode = postCode;
}
public Account(String name, String id) {
this.name = name;
this.id = id;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress1() {
return address1;
}
public void setAddress1(String address1) {
this.address1 = address1;
}
public String getAddress2() {
return address2;
}
public void setAddress2(String address2) {
this.address2 = address2;
}
public String getPostCode() {
return postCode;
}
public void setPostCode(String postCode) {
this.postCode = postCode;
}
public Set<Invoice> getInvoiceArchive() {
return invoiceArchive;
}
public Invoice newInvoice(){
Invoice i = new Invoice(this);
invoiceArchive.add(i);
return i;
}
@Override
public String toString(){
return this.getId();
}
}
Invoice.class
public class Invoice {
private Account id;
private ArrayList<Double> invoiceAmounts;
private double invoiceTotal;
private String date;
private String time;
private String notes;
private String modified;
DecimalFormat df = new DecimalFormat("#.00");
public Invoice(Account id) {
this.id = id;
this.invoiceAmounts = new ArrayList<>();
this.date = new SimpleDateFormat("dd/MM/yyyy HH:mm").format(Calendar.getInstance().getTime());
}
public String getDate() {
return date;
}
public void setModified(String date) {
this.modified = date;
}
public Account getId() {
return id;
}
public void setId(Account id) {
this.id = id;
}
public ArrayList<Double> getInvoiceAmounts() {
return invoiceAmounts;
}
public void setInvoiceAmounts(ArrayList<Double> invoiceAmounts) {
this.invoiceAmounts = invoiceAmounts;
}
public double getInvoiceTotal() {
return invoiceTotal;
}
public void setInvoiceTotal(double invoiceTotal) {
this.invoiceTotal = invoiceTotal;
}
public void add(Double d){
invoiceAmounts.add(d);
}
private String returnInvoiceAmounts(){
String result="";
for (Double d:invoiceAmounts){
result += "£"+df.format(d)+"\n";
}
return result;
}
@Override
public String toString(){
return "Account: "+id.getId()+
"\nCreated: "+getDate()+"\n"+returnInvoiceAmounts()
+"--------"+"\nTotal\n£"+df.format(invoiceTotal);
}
}
GUI.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.ListView?>
<?import javafx.scene.control.SplitPane?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.image.Image?>
<?import javafx.scene.image.ImageView?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.HBox?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="477.0" prefWidth="641.0" xmlns="http://javafx.com/javafx/8.0.65" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Controller">
<children>
<SplitPane dividerPositions="0.24249999999999972" layoutY="50.0" prefHeight="427.0" prefWidth="641.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="50.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<ListView fx:id="list" layoutX="-24.0" layoutY="62.0" onKeyPressed="#listViewSelected" onKeyReleased="#listViewSelected" onMouseClicked="#listViewSelected" prefHeight="425.0" prefWidth="151.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="445.0" prefWidth="411.0">
<children>
<SplitPane dividerPositions="0.30023640661938533" layoutX="143.0" layoutY="123.0" orientation="VERTICAL" prefHeight="445.0" prefWidth="480.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="100.0" prefWidth="160.0">
<children>
<TableView layoutX="128.0" layoutY="45.0" prefHeight="208.0" prefWidth="478.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<columns>
<TableColumn fx:id="tableAccount" prefWidth="75.0" text="Account" />
<TableColumn fx:id="tableDate" prefWidth="75.0" text="Date" />
<TableColumn fx:id="tableTime" prefWidth="75.0" text="Time" />
<TableColumn fx:id="tableTotal" prefWidth="75.0" text="Amount" />
<TableColumn fx:id="tableNotes" prefWidth="75.0" text="Notes" />
</columns>
</TableView>
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="286.0" prefWidth="478.0">
<children>
<SplitPane dividerPositions="0.4474789915966387" layoutX="168.0" layoutY="48.0" prefHeight="292.0" prefWidth="478.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TextArea fx:id="invoiceView" layoutX="5.0" layoutY="14.0" prefHeight="290.0" prefWidth="209.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" />
</children>
</AnchorPane>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="160.0" prefWidth="100.0">
<children>
<TextField fx:id="amountField" layoutX="82.0" layoutY="86.0" prefHeight="27.0" prefWidth="104.0" promptText="0.00" />
<Button fx:id="addAmount" layoutX="195.0" layoutY="86.0" mnemonicParsing="false" text="Add" />
<Label layoutX="14.0" layoutY="91.0" text="Amount: : " />
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
</children>
</AnchorPane>
</items>
</SplitPane>
<ImageView fitHeight="150.0" fitWidth="200.0" layoutX="14.0" layoutY="11.0" pickOnBounds="true" preserveRatio="true">
<image>
<Image url="@Icon/Logo.png" />
</image>
</ImageView>
<HBox alignment="CENTER_RIGHT" layoutX="462.0" layoutY="14.0" spacing="15.0" AnchorPane.rightAnchor="14.0" AnchorPane.topAnchor="14.0">
<children>
<Button fx:id="newInvoice" mnemonicParsing="false" onAction="#newInvoiceFired" text="New" />
<Button fx:id="saveInvoice" mnemonicParsing="false" onAction="#deleteInvoiceFired" text="Save" />
<Button fx:id="deleteInvoice" mnemonicParsing="false" onAction="#deleteInvoiceFired" text="Delete" />
</children>
</HBox>
</children>
</AnchorPane>
首先,为您的字段使用正确的类型。由于 table 中的每一行都是 Invoice
,因此您应该有一个 TableView<Invoice>
。由于 tableAccount
列显示类型为 Invoice
的对象的类型为 Account
的属性,它应该是 TableColumn<Invoice, Account>
,等等 tableDate
,我假设 (因为 date
是 String
) 显示 Invoice
类型 String
的属性,所以它应该是 TableColumn<Invoice, String>
。等等,。然后您将能够设置单元格值工厂,使用您显示的 PropertyValueFactory
(具有匹配类型),或者(可能更好)仅使用 lambda (即 tableAccount.setCellValueFactory(cellData -> new SimpleObjectProperty<>(cellData.getValue().getId()));
)。
其次,不要创建新的table! (您已经被告知 setTableView
方法中,您创建一个新的 table,并对其进行配置。但是由于 table 从未显示在 UI 中,您永远不会看到配置的结果。不要创建新的 table,只需配置已有的即可。
最后,您如何尝试填充 table 并不是很清楚。你说 table 中的每一行都是一张发票:所以这意味着 table.setItems(...)
将期望 ObservableList<Invoice>
。你正试图给它一个 ObservableList<Account>
。您需要在此处生成适当的发票列表(您尚未指定应该是什么)而不是 Account
s.
这里可能还有其他错误,但那些是最明显的(对我来说),应该会让你走上正轨。
我已经设法解决了这个问题,在花了很长时间试图解决它之后。
这似乎是微不足道的,在 GUI.fxml 中,我没有为 tableView 分配 ID,因此它从未在控制器中初始化,并且在设置它时收到 NullPointerException
TableView fx:id="tableView"
我很生气自己浪费了这么多时间,但这是我第一次使用 fxml 和 javafx,所以学到了很多东西。