【问题标题】:JavaFX TableView row added but not visible [duplicate]JavaFX TableView 行已添加但不可见 [重复]
【发布时间】:2020-02-07 08:38:16
【问题描述】:

我有一个 TableView,我想用一些 TextFields 中的数据填充它,为此,我从我的应用程序中的另一个 TableView 复制了代码,因为它正在工作。但是在这第二个 TableView 中,数据并未显示为表中的行。我知道数据已添加,因为我可以使用键盘上的箭头键在行之间切换,并且在调试器模式下,每次添加行时都会更新 items 属性。在另一个 TableView 中,代码工作正常,但第二个没有,关于如何解决这个问题的任何想法?我阅读了其他关于 PropertyValueFactory 的问题,但问题是,第一个示例有效,而第二个示例无效。我尝试更改变量的名称,但仍然没有看。

存储数据的类:

public class Produto {
    private String nome, codigo;
    private double preco, precoCompra;
    private int quantidade;

    public String getNome(){return nome;}
    public String getCodigo(){return codigo;}
    public double getPreco(){return preco;}
    public int getQuantidade(){return quantidade;}
    public double getPrecoCompra(){return precoCompra;}

    public Produto (int quantidade, String nome) {
        this.quantidade = quantidade;
        this.nome = nome;
    }
    public Produto(String nome, String codigo, double preco, double precoCompra) {
        this.nome = nome;
        this.codigo = codigo;
        this.preco = preco;
        this.precoCompra = precoCompra;
    }
    public Produto(String nome, String codigo, double preco, double precoCompra, int quantidade) {
        this.nome = nome;
        this.codigo = codigo;
        this.preco = preco;
        this.precoCompra = precoCompra;
        this.quantidade = quantidade;
    }

    public Produto(String nome, int quantidade){
        this.nome = nome;
        this.quantidade = quantidade;
    }
}

TableView 1 中的工作代码:

控制器:

public class VerEstoque {
    @FXML
    BorderPane root;
    @FXML
    StackPane rootVE;

    @FXML
    private TableView tabela = new TableView();
    private TableColumn<Produto, String> codigo = new TableColumn<>("CODIGO");
    private TableColumn<Produto, String> nome = new TableColumn<>("NOME");
    private TableColumn<Produto, Double> preco = new TableColumn<>("PREÇO DE VENDA");
    private TableColumn<Produto, Double> precoCompra = new TableColumn<>("PREÇO DE COMPRA");
    private TableColumn<Produto, Integer> quantidade = new TableColumn<>("QUANTIDADE");

    private static ArrayList<Produto> produtos = new ArrayList<>();
    private static ObservableList<Produto> listaProdutos = FXCollections.observableArrayList();

    @FXML
    private void initialize() {
        Main.roots.add(rootVE);
        tabela.getColumns().addAll(codigo, nome, preco, precoCompra,  quantidade);
        codigo.setCellValueFactory(new PropertyValueFactory<>("codigo"));
        nome.setCellValueFactory(new PropertyValueFactory<>("nome"));
        preco.setCellValueFactory(new PropertyValueFactory<>("preco"));
        precoCompra.setCellValueFactory(new PropertyValueFactory<>("precoCompra"));
        quantidade.setCellValueFactory(new PropertyValueFactory<>("quantidade"));
        tabela.setItems(listaProdutos);
        tabela.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
        buscarEstoque();
    }

    static void buscarEstoque() {
        //In this case the data is being pulled from a database and added to an arraylist
        BancoDeDados bd = BancoDeDados.getInstance();
        try {
            ResultSet rs = bd.select("SELECT * FROM Estoque");
            while (rs.next()) {
                produtos.add(new Produto(rs.getString("Nome"), rs.getString("Codigo"), rs.getDouble("PrecoVenda"), rs.getDouble("PrecoCompra") , rs.getInt("Quantidade")));
            }
            rs.close();
            listaProdutos.clear();
            listaProdutos.addAll(produtos);
            produtos.clear();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

FXML 文件:

<StackPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" fx:id="rootVE"
       prefHeight="400.0" prefWidth="600.0" fx:controller="mercado.controllers.VerEstoque">
<BorderPane prefHeight="400.0" prefWidth="600.0" fx:id="root">
    <top>
        <HBox alignment="CENTER">
            <children>
                <Label text="ESTOQUE" fx:id="titulo"/>
            </children>
        </HBox>
    </top>
    <center>
        <TableView fx:id="tabela"/>
    </center>
</BorderPane>

上面的代码按预期工作,但我在下面的代码中有错误:

控制器:

public class DefinirProdutos {

    @FXML private StackPane rootDP;
    @FXML private VBox base;
    @FXML private TextField campoQtd, campoNome;
    @FXML private TableView tabela;
    private TableColumn<Produto, Integer> qtd = new TableColumn<>("Qtd");
    private TableColumn<Produto, String> nome = new TableColumn<>("Produto");
    private  ArrayList<Produto> arrayProdutos = new ArrayList<>();
    private  ObservableList<Produto> listaProdutos = FXCollections.observableArrayList();

    @FXML
    private void initialize() {
        tabela.getColumns().addAll(qtd, nome);
        tabela.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
        campoNome.setPromptText("Produto");
        campoQtd.setPromptText("Qtd");
        nome.setCellValueFactory(new PropertyValueFactory<>("produto"));
        qtd.setCellValueFactory(new PropertyValueFactory<>("qtd"));
        tabela.setItems(listaProdutos);
     }

    @FXML
    private void adicionarProduto() {
        int valorQtd = campoQtd.getText().length();
        int valorNome = campoNome.getText().length();
        if(valorQtd == 0 && valorNome == 0){
            //warn that the textfields are empty, irrelevant
        }else if(valorQtd == 0){
            //warn that the textfield is empty
        }else if(valorNome == 0){
            //warn that the textfield is empty
        }else{
            //Codigo pra caso nao estiver adicionado na array
            arrayProdutos.add(new Produto(Integer.parseInt(campoQtd.getText()), campoNome.getText()));
            listaProdutos.clear();
            listaProdutos.addAll(arrayProdutos);
            tabela.refresh();
        }
    }
}

不显示的tableview的FXML:

<StackPane xmlns="http://javafx.com/javafx" xmlns:fx="http://javafx.com/fxml" prefHeight="600.0" 
maxWidth="800.0" fx:id="rootDP"
fx:controller="mercado.controllers.DefinirProdutos">
    <VBox fx:id="base" spacing="30">
        <children>
            <HBox alignment="CENTER">
                <children>
                    <Label text="DEFINIR PRODUTOS" fx:id="titulo"/>
                </children>
            </HBox>
            <HBox alignment="CENTER" spacing="10">
                <children>
                    <TextField fx:id="campoQtd" alignment="CENTER"/>
                    <TextField alignment="CENTER" fx:id="campoNome"/>
                    <Button text="Adicionar" prefWidth="140" prefHeight="40" fx:id="btnAdd" 
onAction="#adicionarProduto"/>
                </children>
            </HBox>
            <TableView fx:id="tabela"/>
            <HBox alignment="CENTER" fx:id="confirmar">
                <children>
                    <Button text="Feito" prefWidth="200" prefHeight="40" fx:id="btnFeito"/>
                </children>
            </HBox>
        </children>
     </VBox>
 </StackPane>

【问题讨论】:

  • 如果您使用与指定相同的数据对象(Producto),我认为 nome.setCellValueFactory(new PropertyValueFactory("produto")); qtd.setCellValueFactory(new PropertyValueFactory("qtd"));不管用。因为“produto”和“qtd”不是 Producto 中的属性。
  • 天哪,感谢您指出这一点,现在它可以工作了哈哈。 “produto”和“qtd”是我完全忘记重命名的属性,来自我之前进行的一些测试。非常感谢:)

标签: java javafx tableview


【解决方案1】:

反思通常是完成任务的最糟糕的方式,这也是原因之一。

当您使用反射时,编译器无法检查您是否为类、方法、字段或 bean 属性使用了不正确或拼写错误的名称。在这种情况下,编译器无法检查您传递给PropertyValueFactory 构造函数的参数是否有效。

更好的方法是完全避免使用 PropertyValueFactory,而是为每个 TableColumn 编写自己的单元格值工厂:

codigo.setCellValueFactory(
    f -> new SimpleStringProperty(f.getValue().getCodigo()));
nome.setCellValueFactory(
    f -> new SimpleStringProperty(f.getValue().getNome()));
preco.setCellValueFactory(
    f -> new SimpleDoubleProperty(f.getValue().getPreco()));
precoCompra.setCellValueFactory(
    f -> new SimpleDoubleProperty(f.getValue().getPrecoCompra()));
quantidade.setCellValueFactory(
    f -> new SimpleIntegerProperty(f.getValue().getQuantidade()));

如果我们对 DefinirProdutos 类中的 TableColumns 进行类似的更改:

nome.setCellValueFactory(
    f -> new SimpleStringProperty(f.getValue().getProduto()));
qtd.setCellValueFactory(
    f -> new SimpleIntegerProperty(f.getValue().getQtd()));

编译器会通知您这些方法不存在。

【讨论】:

    【解决方案2】:

    正如 Sai Dandem 所指出的,我在 setCellValueFactory(new PropertyValueFactory&lt;&gt;() 中的列的属性名称是错误的。通过将它们重命名为数据对象中的属性解决了该问题

    【讨论】:

      猜你喜欢
      • 2012-04-15
      • 2012-12-25
      • 1970-01-01
      • 2017-12-25
      • 2015-10-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-20
      • 2016-05-12
      相关资源
      最近更新 更多