2017-01-02 27 views
0

我需要一些幫助創建一個類似於ms訪問的格子窗口的連續窗體。最初的格子板有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

如何從列表中刪除行和choicebox的值? 如果更改選擇框,我該如何更新我的列表?

+0

當在第三行單擊刪除按鈕時會發生什麼?是否應刪除當前包含「Car 1」的所有行? –

+0

如果點擊第3行的刪除按鈕,則只應刪除第3行。此外,物體汽車1應該在我的列表中刪除(第1行和第3行中的汽車1具有不同的ID)。 – tonyh

回答

1

我建議使用ListView自定義ListCell而不是GridPane,因爲您的汽車列表可能包含例如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; 
    } 
} 
+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