JavaFX continuous form dynamically add new row with content in gridpane

天大地大妈咪最大 提交于 2019-12-21 06:27:23

问题


I need some help creating a continuous form with a gridpane like in ms access. Initially the gridpane has 1 row and 3 columns

| Choicebox | Delete Button | Add Button |

public class myGridpane {

    @FXML
    private GridPane gp_form;
    private List<Car> myCars = new ArrayList();

    public void initialize() {
        myCars = loadCars();
        initGridpane(myCars);
    }

    private initGridpane(List<Car> myCars) {

        int rowIndex = 0;

        for (Car myCar : myCars) {

          Button b_newCar = new Button("+");
          Button b_deleteCar = new Button("-");

          ChoiceBox<Car> cb_car = new ChoiceBox<>();
          cb_car.setItems(Car.getAllCarKeys());
          cb_car.setValue(myCar.getModel());


          b_deleteCar.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent e) {
              // remove row
              // remove car from List myCars
            }
          });

          b_newCar.setOnAction(new EventHandler<ActionEvent>() {
            @Override public void handle(ActionEvent e) {
              // add new row
            }
          });

          cb_car.getSelectionModel().selectedIndexProperty().addListener(new ChangeListener<Number>() {

                @Override
                public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
                    // update myList
                }
            });

          gp_form.add(cb_car, 0, rowIndex);
          gp_form.add(b_deleteCar, 1, rowIndex);
          gp_form.add(b_newCar, 2, rowIndex);

          rowIndex++;
        }
    }
}

The result should look like this:

.

How do I remove the row and the value of the choicebox from my list? And how do I update my list if a choicebox is changed?


回答1:


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



回答2:


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


来源:https://stackoverflow.com/questions/41429711/javafx-continuous-form-dynamically-add-new-row-with-content-in-gridpane

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