1

I have JavaFx TableView and I permit user to enter some data in the table and retrieve what a user entered in the table for this reason I create also ArrayList of TextFields and use the following code but the size of the ArrayList should be 3 in my case but I found the size 7, what's wrong?

Edit the full code here

import java.util.ArrayList;
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;

public class TestTableView extends Application
{

    private final TableView <ProductOpeningBalance> tableProductOpeningBalance = new TableView();
    private final Scene scene = new Scene(tableProductOpeningBalance, 400, 200);
    private final TableColumn productQuantity = new TableColumn("Product Quantity");
    private final ObservableList <ProductOpeningBalance> data = FXCollections.observableArrayList(
                                                                new ProductOpeningBalance("0"),
                                                                new ProductOpeningBalance("0"));
    private final ArrayList <TextField> txtProductQuantity = new ArrayList <> ();

    @Override
    public void start(Stage stage)
    {
        productQuantity.impl_setReorderable(false);
        productQuantity.setEditable(true);
        productQuantity.setCellValueFactory(new PropertyValueFactory("ProductQuantity"));
        productQuantity.setCellFactory(column -> new TableCell()
    {
        @Override
        public void startEdit()
        {
            if(!isEmpty())
            {
                super.startEdit();

                createTextField();

                setText(null);

                setGraphic(txtProductQuantity.get(txtProductQuantity.size() - 1));

                txtProductQuantity.get(txtProductQuantity.size() - 1).selectAll();
            }
        }

        @Override
        public void cancelEdit()
        {
            super.cancelEdit();

            setText((String) getItem());

            setGraphic(null);
        }

        public void updateItem(String item, boolean empty)
        {
            super.updateItem(item, empty);

            if(empty)
            {
                setText(null);

                setGraphic(null);
            }

            else
            {
                if(isEditing())
                {
                    if(txtProductQuantity.get(txtProductQuantity.size() - 1) != null)
                    {
                        txtProductQuantity.get(txtProductQuantity.size() - 1).setText(getString());
                    }

                    setText(null);

                    setGraphic(txtProductQuantity.get(txtProductQuantity.size() - 1));
                }

                else
                {
                    setText(getString());

                    setGraphic(null);
                }
            }
        }

        private void createTextField()
        {
            txtProductQuantity.add(new TextField(getString()));

            txtProductQuantity.get(txtProductQuantity.size() - 1).
                                     setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
            txtProductQuantity.get(txtProductQuantity.size() - 1).setAlignment(Pos.BASELINE_RIGHT);
            txtProductQuantity.get(txtProductQuantity.size() - 1).focusedProperty().
            addListener((ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean arg2) ->
            {
                if(!arg2)
                {
                    commitEdit(txtProductQuantity.get(txtProductQuantity.size() - 1).getText());
                }
            });
        }

        private String getString()
        {
            return getItem() == null ? "" : getItem().toString();
        }
    });

        tableProductOpeningBalance.setEditable(true);
        tableProductOpeningBalance.getColumns().addAll(productQuantity);
        tableProductOpeningBalance.setItems(data);

        stage.setScene(scene);
        stage.show();
    }

    public class ProductOpeningBalance
    {
        private final SimpleStringProperty ProductQuantity;

        public ProductOpeningBalance(String productQuantity)
        {
            this.ProductQuantity = new SimpleStringProperty(productQuantity);
        }

        public void setProductQuantity(String productQuantity)
        {
            ProductQuantity.set(productQuantity);
        }

        public String getProductQuantity()
        {
            return ProductQuantity.get();
        }
    }
}

Solution finally:

this code help me to find what I need after spent a lot of time in searching and trying a lot of methods

    purchaseItemPrice.setCellFactory(column -> new TableCell()
    {
        @Override
        public void startEdit()
        {
            if(!isEmpty())
            {
                if(txtPurchaseItemPrice.size() < data.size() && getGraphic() == null)
                {
                    super.startEdit();

                    txtPurchaseItemPrice.add(new TextField());

                    txtPurchaseItemPrice.get(txtPurchaseItemPrice.size() - 1).setAlignment(Pos.BASELINE_RIGHT);

                    setGraphic(txtPurchaseItemPrice.get(txtPurchaseItemPrice.size() - 1));
                }
            }
        }

        public void updateItem(String item, boolean empty)
        {
            super.updateItem(item, empty);

            if(!empty)
            {
                if(isEditing())
                {
                    setGraphic(txtPurchaseItemPrice.get(txtPurchaseItemPrice.size() - 1));
                }
            }
        }
    });
PeroSof
  • 69
  • 7
  • Sorry I'm new in stack overflow, I'll do in the future, but what the wrong I edit my code and it work as I need the the only problem is the size of the arraylist – PeroSof Mar 03 '20 at 23:28
  • You mean by reproducible to add the whole code to permit edit on it – PeroSof Mar 03 '20 at 23:30
  • @kleopatra I post the full code can you help me find the solution? – PeroSof Mar 03 '20 at 23:53
  • @kleopatra I add the code which contain the problem when press the key btnEdit the size of the arraylist is 7 but I expect only 2 as the table contain only two columns – PeroSof Mar 04 '20 at 00:42
  • this the only problem now but it works as I expect except the size of the array it bigger than what I expect – PeroSof Mar 04 '20 at 00:45
  • @kleopatra any solution for this case? – PeroSof Mar 05 '20 at 00:40
  • strip it down to be a [mcve] (no need for layout/beautifying code, not need for more than 2 columns f.i.), change to using java naming conventions and .. read an arbitrary tutorial on how custom cells should be implemented (bet you don't find any that accesses nodes _external_ to the cell). Actually, I don't understand what you are after that might bring you to such a horrible idea .. make the textField private to the cell and you are done (probably ;) – kleopatra Mar 06 '20 at 11:15
  • @kleopatra now I make the code only fit one table with only one column to exactly what a problem in and I add simple print inside the updateItem() method to illustrate that it is called much times with compare to table rows – PeroSof Mar 06 '20 at 14:15
  • good, will look at it later (at the weekend) - just a note: the cell mechanism is designed such that the cells are re-used as often as possible (vs. created), so updateItem is called a lot, intentionally. That's why we must not do any heavy lifting in that methods, particularly not create nodes! – kleopatra Mar 06 '20 at 16:01
  • I use this mechanism for specific purpose, and I hope it work to call this method as needed (for rows size) – PeroSof Mar 06 '20 at 18:33
  • @kleopatra thanks very much for your interest my problem is solved finally and I edit the post to add the solution, finally thanks very much – PeroSof Mar 07 '20 at 10:01

0 Answers0