1

I want to dynamically add new rows based on the input number from text field. I have prepared this row (textField and comboBox) in fxml (scene builder) outside of visible scope.

So I have reference to these objects which I want to add:

@FXML
private ComboBox fieldType;

@FXML
private TextField fieldName;

And based on number from other textField I am adding rows to gridPane:

for (int i = 0; i < newRows; i++) {
    grid.addRow(grid.impl_getRowCount(), fieldName, fieldType);
}

I get this exception:

Exception in thread "JavaFX Application Thread" java.lang.IllegalArgumentException: Children: duplicate children added: parent = Grid hgap=0.0, vgap=5.0, alignment=TOP_LEFT

I thought that I will clone these objects like this:

public class CloningMachine implements Cloneable {

        private Node node;

        public CloningMachine() {
        }

        public CloningMachine setNode(Node node) {
            this.node = node;
            return this;
        }

        public Node getNode() {
            return node;
        }

        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }

for (int i = 0; i < newRows; i++) {
    grid.addRow(grid.impl_getRowCount(), ((CloningMachine)new CloningMachine().setNode(fieldName).clone()).getNode(), ((CloningMachine)new CloningMachine().setNode(fieldType).clone()).getNode());
}

However I get the same exception.

Is it possible to do it somehow? Thanks

Wlad
  • 410
  • 1
  • 9
  • 27
  • You cannot add a node twice to the scene graph. You need to create new instances of ComboBox and TextField and add it to the new row. You can copy the values from the already existing nodes, if required. – ItachiUchiha Feb 02 '16 at 15:43
  • In the end I have created new instances like you said. – Wlad Feb 03 '16 at 09:39

1 Answers1

1

Your CloningMachine does not work as intended.

Object.clone returns a copy of the object where all data, including any references, contain the same data. That means

((CloningMachine)new CloningMachine().setNode(n).clone()).getNode()

is just a complex way of obtaining n, i.e.

((CloningMachine)new CloningMachine().setNode(n).clone()).getNode() == n

always yields true.

The javadoc of Object.clone contains the following sentence about implementing clone.

Typically, this means copying any mutable objects that comprise the internal "deep structure" of the object being cloned and replacing the references to these objects with references to the copies.

Therefore to implement the cloning correctly, you need to copy the Nodes "manually" (i.e. create a new one using the constructor and assigning all the relevant properties). There is no easy way around this.

fabian
  • 80,457
  • 12
  • 86
  • 114