0

I a have tabPane with multiple tabs and inside one of the tabPane i have scrollPane. Inside the scrollPane i have a number of UI controls As shown on this image that i want to be dynamically added when i click a button.

This image here shows the UI setup of what i have. The UI controls are in an Hbox which is inside a Vbox.

When a user clicks the add button i would like to add another row with all the controls as shown in this image.

I have looked at post such as these and still cannt get to achieve the same effect on my code.

  1. JavaFX continuous form dynamically add new row with content in gridpane,
  2. Dynamically add elements to a fixed-size GridPane in JavaFX,
  3. How to maintain GridPane's fixed-size after adding elemnts dynamically

When i followed the approach suggested by another stack-overflow member on the first question cited above, to use a listView the code worked. However his suggestion programmatically codes UI controls and when i try to change and use UI controls i created within scene builder it doesn't work. Also when i put the controls inside a tabPane my code doesn't work. Meaning when i click the add button it doesn't add the UI controls as expected.

My question is how can i dynamically add UI controls within a tab inside a tabPane when a button which is also in that tab is clicked.

Here is my code :

public class DynamicalyAddControlsController {

@FXML
private VBox vbox;

@FXML
private HBox hbox;

@FXML
private StackPane stack1;

@FXML
private Label taskid;

@FXML
private TextField taskname;

@FXML
private ComboBox<String> combobox;

@FXML
private TextArea textarea;

@FXML
private Button save;

private ObservableList<Car> cars = FXCollections.observableArrayList();

public void initialize(URL url, ResourceBundle rb) {
cars.addAll(new Car(CAR_TYPE.CAR1), new Car(CAR_TYPE.CAR2), new Car(CAR_TYPE.CAR3));

ListView<Car> carsListView = new ListView<>();
carsListView.setCellFactory(c -> new CarListCell());
carsListView.setItems(cars);


stack1.getChildren().add(carsListView);

} 

private class CarListCell extends ListCell<Car> {


private ChoiceBox<CAR_TYPE> choiceBox = new ChoiceBox<>();


public CarListCell(){ 

choiceBox.setItems(FXCollections.observableArrayList
(CAR_TYPE.values()));  

    hbox.getChildren().addAll(taskid,taskname,combobox,choiceBox);
    vbox.getChildren().addAll(hbox,textarea);
    setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
    setGraphic(vbox);
}

@Override
protected void updateItem(Car item, boolean empty) {
    super.updateItem(item, empty);
    if (item == null || empty) {
        setText(null);
        setGraphic(null);
    } else {
        setGraphic(vbox);
        choiceBox.setValue(item.getType());
        save.setOnAction(e -> {
            Car newCar = new Car(choiceBox.getValue());
            cars.add(newCar);
        });

    }
}

}

private enum CAR_TYPE {
   CAR1, CAR2, CAR3;
}

private class Car {

private CAR_TYPE type;

public Car(CAR_TYPE type) {
    this.type = type;
}

public CAR_TYPE getType() {
    return type;
}

public void setType(CAR_TYPE type) {
    this.type = type;
}
}
public void initialize(URL url, ResourceBundle rb) {

} 

}

JavaApplication main class

    @Override
public void start(Stage primaryStage) throws Exception{

    Parent viewB = FXMLLoader.load(getClass().getResource("DynamicalyAddControls.fxml"));
    Stage stageB = new Stage();
    stageB.setScene(new Scene(viewB));
    stageB.show();

}


public static void main(String[] args) {
    launch(args);
}
kaddie
  • 233
  • 1
  • 5
  • 27

0 Answers0