2017-01-02 1 views
0

Мне нужна помощь в создании непрерывной формы с сеткой, например, в режиме ms. Первоначально gridpane имеет 1 ряд и 3 столбцаНепрерывная форма JavaFX динамически добавляет новую строку с содержимым в gridpane

| Choicebox | Кнопка «Удалить» | Кнопка добавления |

>> screenshot initial gridpane

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

Результат должен выглядеть следующим образом:

result gridpane.

Как удалить строку и значение поля выбора из моего списка? И как мне обновить свой список, если изменяется выборка?

+0

Что произойдет, если кнопка удаления нажата в третьей строке? Должны ли быть удалены все строки, содержащие в настоящее время «Автомобиль 1»? –

+0

Если нажать кнопку удаления в строке 3, следует удалить только строку 3. кроме того, предметный автомобиль 1 должен быть удален в моем списке (автомобиль 1 в строках 1 и 3 имеет разные идентификаторы). – tonyh

ответ

1

Я предлагаю использовать ListView с пользовательским ListCell вместо GridPane, потому что ваш список автомобилей может содержать, например, значения 1k. В этом случае вы создадите 3k-узлы в GridPane, и это снизит производительность. 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; 
    } 
} 
+0

спасибо, это здорово и как это выглядит, если есть второй выпадающий список в той же строке, что и цвет автомобиля? – tonyh

0

я добавил второй выпадающий список, кнопка сохранения и изменил старт с пустым первоначальным списком. это прекрасно работает, но как я могу получить все выбранные автомобили с их цветом в 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; 
     } 
    } 
} 
+0

Что значит «получить все выбранные автомобили»? Вы хотите, чтобы в вашем ListView был выбран несколько вариантов или получить все автомобили? Все автомобили находятся в «ObservableList cars'. – MBec

+0

отлично, спасибо – tonyh

Смежные вопросы