JavaFX continuous form dynamically add new row with content in gridpane

匆匆过客 提交于 2019-12-04 20:07:27

I suggest to use ListView with custom ListCell instead of GridPane because your cars list may contain for example 1k values. In that case you will create 3k nodes in GridPane and it will reduce performance. ListView will create only visible cells and reuse them when needed.

Try this code:

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

@Override
public void start(Stage primaryStage) {
    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);

    StackPane root = new StackPane();
    root.getChildren().add(carsListView);

    Scene scene = new Scene(root, 300, 250);

    primaryStage.setTitle("Cars list view");
    primaryStage.setScene(scene);
    primaryStage.show();
}

private class CarListCell extends ListCell<Car> {

    private HBox content = new HBox();
    private ChoiceBox<CAR_TYPE> cb = new ChoiceBox<>();
    private Button add = new Button("+");
    private Button sub = new Button("-");

    public CarListCell() {
        cb.setItems(FXCollections.observableArrayList(CAR_TYPE.values()));
        cb.setMaxWidth(Double.MAX_VALUE);
        HBox.setHgrow(cb, Priority.ALWAYS);
        content.getChildren().addAll(cb, add, sub);
        content.setSpacing(10);
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
        setGraphic(content);
    }

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

}

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;
    }
}

i have added a second dropdown, a save button and changed the start with an empty initial list. this works fine, but how do i get all selected Cars with their color to an ArrayList when i click on the save button?

And if i select the first car with its color without clicking the "+" button the ObservableList is empty.

import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;

public class Main extends Application {
    public static void main(String[] args) {
        Application.launch(args);
    }

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

    @Override
    public void start(Stage primaryStage) {

        Car initialCar = new Car(null,null);

        cars.add(initialCar);

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

        StackPane root = new StackPane();
        root.getChildren().addAll(carsListView, new Button("Save"));

        Scene scene = new Scene(root, 300, 250);

        primaryStage.setTitle("Cars list view");
        primaryStage.setScene(scene);
        primaryStage.show();
    }

    private class CarListCell extends ListCell<Car> {

        private HBox content = new HBox();
        private ChoiceBox<CAR_TYPE> cb_car = new ChoiceBox<>();
        private ChoiceBox<CAR_COLOR> cb_color = new ChoiceBox<>();
        private Button add = new Button("+");
        private Button sub = new Button("-");

        public CarListCell() {

            cb_car.setItems(FXCollections.observableArrayList(CAR_TYPE.values()));
            cb_color.setItems(FXCollections.observableArrayList(CAR_COLOR.values()));

            HBox.setHgrow(cb_car, Priority.ALWAYS);
            HBox.setHgrow(cb_color, Priority.ALWAYS);

            content.getChildren().addAll(cb_car, cb_color, add, sub);
            content.setSpacing(10);
            setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
            setGraphic(content);
        }

        @Override
        protected void updateItem(Car item, boolean empty) {
            super.updateItem(item, empty);
            if (item == null || empty) {
                setText(null);
                setGraphic(null);
            } else {
                setGraphic(content);
                cb_car.setValue(item.getType());
                cb_color.setValue(item.getColor());
                add.setOnAction(e -> {
                    Car newCar = new Car(cb_car.getValue(), cb_color.getValue());
                    cars.add(newCar);
                });
                sub.setOnAction(e -> {
                    cars.remove(item);
                });
            }
        }

    }

    private enum CAR_TYPE {
        CAR1, CAR2, CAR3;
    }

    private enum CAR_COLOR {
        BLUE, RED, GREEN;
    }

    private class Car {

        private CAR_TYPE type;
        private CAR_COLOR color;

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

        public CAR_TYPE getType() {
            return type;
        }

        public void setType(CAR_TYPE type) {
            this.type = type;
        }

        public CAR_COLOR getColor() {
            return color;
        }

        public void setColor(CAR_COLOR color) {
            this.color = color;
        }
    }
}
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!