【问题标题】:JavaFX: TableView not showing up in GUIJavaFX:TableView 未显示在 GUI 中
【发布时间】:2016-08-16 08:23:55
【问题描述】:

我正在尝试将我的程序绑定到在 SceneBuilder 中设计的 GUI。 我已经设法让我的“Accounts.class”ID 在最左侧的列表中按需要显示。

现在我需要让 TableView 工作,但我没有运气让它填充数据。

它应该包含来自“Invoice.class”字段的数据, 每个 Account 对象内部都有一个 Set - 这个集合将显示在右侧 TableView 的不同行中。

非常感谢任何帮助!

附言原谅我,我知道它已经被问过很多次,但所有其他解决方案似乎都对我不起作用我尝试在参数中添加类型;

  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>

** GUI Display **

【问题讨论】:

    标签: java user-interface javafx tableview fxml


    【解决方案1】:

    首先,为您的字段使用正确的类型。由于表中的每一行都是Invoice,因此您应该有一个TableView&lt;Invoice&gt;。由于tableAccount 列显示来自Invoice 类型对象的Account 类型的属性,它应该是TableColumn&lt;Invoice, Account&gt;tableDate,我假设(因为dateString)显示来自InvoiceString 类型的属性,因此它应该是TableColumn&lt;Invoice, String&gt;。等等,。然后,您将能够设置单元格值工厂,使用您显示的 PropertyValueFactory(具有匹配类型),或者(可能更好)仅使用 lambda(即 tableAccount.setCellValueFactory(cellData -&gt; new SimpleObjectProperty&lt;&gt;(cellData.getValue().getId()));)。

    第二,不要新建表! (您已经被告知here。)您的表是在 FXML 文件中定义的,并且在那里定义的表会显示在 UI 中。在您的 setTableView 方法中,您创建一个新表并对其进行配置。但由于该表从未显示在 UI 中,因此您将永远看不到配置的结果。不要创建新表,只需配置您已有的表即可。

    最后,还不清楚您是如何尝试填充表格的。您说表格中的每一行都是一张发票:这意味着table.setItems(...) 将期待ObservableList&lt;Invoice&gt;。您正试图给它一个ObservableList&lt;Account&gt;。您需要在此处生成相应的发票列表(您尚未指定应该是什么),而不是 Accounts 的列表。

    这里可能还有其他错误,但这些是最明显的(对我而言),应该能让你走上正轨。

    【讨论】:

    • 您好,感谢您的详细回复。我现在已经意识到这一点,我想也许这只是向我展示它们是通用的。我已按照建议进行了更改,并将检查矮个子。生病整理 ObservableList 以及很快就会报告:)
    • 我已经调整了setTableView(Account)方法以包含所有的lambda并调用setItems(Account)方法,现在如下ObservableList&lt;Invoice&gt; invoices = FXCollections.observableArrayList(); a.getInvoiceArchive().forEach(c -&gt; invoices.add(c));。它现在为以下at Controller.setTableView at Controller.initialize 抛出 NullPointerException。我已经通过帐户从initialize(a)setTableView(a) 再到setTableAccounts(a) 不知道为什么以及它的 setTableAccounts 是否返回 null - 我已经为该帐户初始化了 1 张发票。
    • 什么是 null?
    • 我运行了一个println(invoices),它按预期打印数据,所以我不确定我为什么会得到这个。肯定是 setTableAccounts() 方法导致了这个异常 - 可能是 tableView.setItems(setTableAccounts(a)) 不是正确的语法吗?
    • 该行是否抛出异常?如果是这样,那么tableView 显然是空的。为什么你会认为它与setTableAccounts 有任何关系?
    【解决方案2】:

    在花了很长时间试图解决它之后,我设法解决了这个问题。

    这似乎是微不足道的,在 GUI.fxml 中我没有为 tableView 分配 ID,因此它从未在控制器中初始化,并且在设置它时收到 NullPointerException

    TableView fx:id="tableView" 
    

    我很生气自己浪费了这么多时间,但这是我第一次使用 fxml 和 javafx,所以学到了很多。

    【讨论】:

    • @James_D 感谢您的指导,我只需要更深入地了解空指针的开始位置。
    猜你喜欢
    • 1970-01-01
    • 2014-04-15
    • 2016-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多