JavaFX连续表单在gridpane中动态添加包含内容的新行

JavaFX连续表单在gridpane中动态添加包含内容的新行,javafx,gridpane,Javafx,Gridpane,我需要一些帮助来创建一个带有网格窗格(如ms access中的网格窗格)的连续表单。最初,gridpane有1行和3列 |选择框|删除按钮|添加按钮| >屏幕截图初始网格窗格“> 公共类myGridpane{ @FXML 私人网格窗格gp_表; private List myCars=new ArrayList(); 公共无效初始化(){ myCars=载重汽车(); initGridpane(myCars); } private initGridpane(列出我的汽车){ int rowInd

我需要一些帮助来创建一个带有网格窗格(如ms access中的网格窗格)的连续表单。最初,gridpane有1行和3列

|选择框|删除按钮|添加按钮|

>屏幕截图初始网格窗格“>

公共类myGridpane{
@FXML
私人网格窗格gp_表;
private List myCars=new ArrayList();
公共无效初始化(){
myCars=载重汽车();
initGridpane(myCars);
}
private initGridpane(列出我的汽车){
int rowIndex=0;
用于(我的车:我的车){
按钮b_newCar=新按钮(“+”);
按钮b_deleteCar=新按钮(“-”);
ChoiceBox cb_car=新的ChoiceBox();
cb_car.setItems(car.getAllCarKeys());
cb_car.setValue(myCar.getModel());
b_deleteCar.setOnAction(新的EventHandler(){
@重写公共无效句柄(ActionEvent e){
//删除行
//从我的汽车列表中删除汽车
}
});
b_newCar.setOnAction(neweventhandler()){
@重写公共无效句柄(ActionEvent e){
//添加新行
}
});
cb_car.getSelectionModel().selectedIndexProperty().addListener(新的ChangeListener()){
@凌驾

public void changed(observevalue我建议将ListView与自定义ListCell一起使用,而不是GridPane,因为您的cars列表可能包含例如1k值。在这种情况下,您将在GridPane中创建3k节点,这将降低性能。ListView将仅创建可见单元格,并在需要时重用它们

请尝试以下代码:

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;
    }
}
private observeList cars=FXCollections.observearraylist();
@凌驾
公共无效开始(阶段primaryStage){
添加所有(新车(Car_TYPE.CAR1)、新车(Car_TYPE.CAR2)、新车(Car_TYPE.CAR3));
ListView carsListView=新建ListView();
setCellFactory(c->new CarListCell());
carsListView.setItems(汽车);
StackPane root=新的StackPane();
root.getChildren().add(carsListView);
场景=新场景(根,300,250);
setTitle(“汽车列表视图”);
初级阶段。场景(场景);
primaryStage.show();
}
私有类CarListCell扩展了ListCell{
私有HBox内容=新HBox();
私有ChoiceBox cb=新的ChoiceBox();
私有按钮添加=新按钮(“+”);
私有按钮子节点=新按钮(“-”);
公共电话{
cb.setItems(FXCollections.observableArrayList(CAR_TYPE.values());
cb.setMaxWidth(双倍最大值);
HBox.setHgrow(cb,优先级总是);
content.getChildren().addAll(cb,add,sub);
内容。设置间隔(10);
setContentDisplay(仅限ContentDisplay.GRAPHIC_);
设置图形(内容);
}
@凌驾
受保护的void updateItem(汽车项目,布尔值为空){
super.updateItem(项,空);
如果(项==null | |空){
setText(空);
设置图形(空);
}否则{
设置图形(内容);
cb.setValue(item.getType());
添加.设置操作(e->{
Car newCar=新车(cb.getValue());
汽车。添加(新车);
});
sub.setOnAction(e->{
车辆。移除(项目);
});
}
}
}
私家车{
CAR1,CAR2,CAR3;
}
私家车{
私家车类型;
公共汽车(汽车型){
this.type=type;
}
公共汽车类型getType(){
返回类型;
}
公共无效设置类型(车辆类型){
this.type=type;
}
}

我添加了第二个下拉菜单,一个保存按钮,并用一个空的初始列表更改了开始。这很好,但是当我单击保存按钮时,如何将所有选定的汽车及其颜色添加到ArrayList中

如果我没有点击“+”按钮选择第一辆车的颜色,ObservableList是空的

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;
        }
    }
}
导入javafx.application.application;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.control.ChoiceBox;
导入javafx.scene.control.ContentDisplay;
导入javafx.scene.control.ListCell;
导入javafx.scene.control.ListView;
导入javafx.scene.layout.HBox;
导入javafx.scene.layout.Priority;
导入javafx.scene.layout.StackPane;
导入javafx.stage.stage;
公共类主扩展应用程序{
公共静态void main(字符串[]args){
应用程序启动(args);
}
private ObservableList cars=FXCollections.observableArrayList();
@凌驾
公共无效开始(阶段primaryStage){
车辆初始值Car=新车(空,空);
cars.add(初始化car);
ListView carsListView=新建ListView();
setCellFactory(c->new CarListCell());
carsListView.setItems(汽车);
StackPane root=新的StackPane();
root.getChildren().addAll(carsListView,新按钮(“保存”);
场景=新场景(根,300,250);
setTitle(“汽车列表视图”);
初级阶段。场景(场景);
primaryStage.show();
}
私有类CarListCell扩展了ListCell{
私有HBox内容=新HBox();
私人选择框cb_car=新选择框();
私有ChoiceBox cb_color=新的ChoiceBox();
私有按钮添加=新按钮(“+”);
私有按钮子节点=新按钮(“-”);
公共电话{
cb_car.setItems(FXCollections.observableArrayList(car_TYPE.values());
cb_color.setItems(FXCollections.observableArrayList(CAR_color.values());
HBox.setHgrow(cb_车,优先权,始终);
HBox.setHgrow(cb_颜色,优先级,始终);
content.getChildren().addAll(cb_car,cb_color,add,sub);
内容。设置间隔(10);
设置内容显示(续
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;
        }
    }
}