簡體   English   中英

JavaFX。 動態手風琴

[英]JavaFX. Dynamic Accordion

我有 JavaFX 項目,其中 fxml 和代碼用於制作 GUI。

有一個圖形用戶界面: 在此處輸入圖片說明 在此處輸入圖片說明

如您所見,有 2 個JavaFX.TitledPane 它們是在 fxml 中創建的。 在他們之后,我有一個JavaFX.Accordion 我從JavaFX.TextField獲取管道JavaFX.TextField並生成它們。 有一些不同類型的JavaFX.TitledPane被放入 Accordion。 您可以在屏幕截圖上看到不同的類型。

我有一個問題:手風琴中的每個 TitledPane 都有第一個 ChoiceBox。 這個 ChoiceBox 定義了 TitledPane 的類型。 所以我們在 #1 屏幕截圖上有默認的 TitledPane。 當用戶從 ComboBox 中選擇另一個項目時,我們需要重新創建 TitledPane。 此外,我們需要將數據保存在 TitledPane 的文本框中,並將其恢復到新的 TitledPane 中。 請給我建議或部分代碼,它可以以正確的方式解決這個問題。

我有這樣的控制器類:

public class Controller {

@FXML
TextField textFieldNonConservatismCoef;
@FXML
TextField textFieldDiffusionCoef;
@FXML
TextField textFieldFlowSpeed;
@FXML
TextField textFieldRiverDepth;
@FXML
TextField textFieldRiverWidth;
@FXML
TextField textFieldSubstance;
@FXML
TextField textFieldProportion;
@FXML
TextField textFieldLAC;
@FXML
TextField textFieldConcentration;
@FXML
TextField textFieldNumberOfPipes;
@FXML
Accordion accordionPlant;





public void fillAccordion(int numberOfPipes){

    accordionPlant.getPanes().add(createTitledPaneCoastalConcentratedPipe(0));
    accordionPlant.getPanes().add(createTitledPaneCoastalSpreadPipe(1));

}

//Create the first type of a TitledPane
protected TitledPane createTitledPaneCoastalConcentratedPipe(int index){

    TilePane tile = new TilePane(Orientation.HORIZONTAL, 5, 5);
    Label typeLabel = new Label("Тип выпуска");
    ChoiceBox<String> choiceBoxTypeOfPipe = createChoiceBoxTypeOfPipes();
    choiceBoxTypeOfPipe.getSelectionModel().select(0);
    choiceBoxTypeOfPipe.setPrefWidth(choiceBoxTypeOfPipe.USE_COMPUTED_SIZE);
    choiceBoxTypeOfPipe.setPrefHeight(choiceBoxTypeOfPipe.USE_COMPUTED_SIZE);
    VBox typeContainer = new VBox(typeLabel,choiceBoxTypeOfPipe);

    Label bankLabel = new Label("Берег");
    bankLabel.setId("textWithTooltip");
    Tooltip.install(bankLabel, new Tooltip("Берег, с которого производится выпуск"));
    ChoiceBox<String> choiceBoxCoast = createChoiceBoxCoast();
    choiceBoxCoast.getSelectionModel().select(0);
    VBox bankContainer = new VBox(bankLabel, choiceBoxCoast);

    Label labelCoordinateX = new Label("Точка выпуска (км)");
    Tooltip.install(labelCoordinateX, new Tooltip("Координата x точки выпуска относительно положения контрольного створа"));
    labelCoordinateX.setId("textWithTooltip");

    TextField textFieldCoordinate = new TextField();

    VBox coordinateContainer = new VBox(labelCoordinateX, textFieldCoordinate);

    tile.getChildren().addAll(typeContainer, bankContainer, coordinateContainer);

    TitledPane titledPane = new TitledPane("Параметры выпуска " + (index+1), tile);

    return titledPane;
}

//Create the second type of a TitledPane
protected TitledPane createTitledPaneCoastalSpreadPipe(int index){

    TilePane tile = new TilePane(Orientation.HORIZONTAL, 5, 5);
    Label typeLabel = new Label("Тип выпуска");
    ChoiceBox<String> choiceBoxTypeOfPipe = createChoiceBoxTypeOfPipes();
    choiceBoxTypeOfPipe.getSelectionModel().select(1);
    VBox typeContainer = new VBox(typeLabel,choiceBoxTypeOfPipe);

    Label bankLabel = new Label("Берег");
    bankLabel.setId("textWithTooltip");
    Tooltip.install(bankLabel, new Tooltip("Берег, с которого производится выпуск"));
    ChoiceBox<String> choiceBoxCoast = createChoiceBoxCoast();
    choiceBoxCoast.getSelectionModel().select(0);
    VBox bankContainer = new VBox(bankLabel, choiceBoxCoast);

    Label labelCoordinateX = new Label("Точка выпуска (км)");
    labelCoordinateX.setId("textWithTooltip");
    Tooltip.install(labelCoordinateX, new Tooltip("Координата x точки выпуска относительно положения контрольного створа"));

    TextField textFieldCoordinate = new TextField();
    VBox coordinateContainer = new VBox(labelCoordinateX, textFieldCoordinate);

    Label labelLength = new Label("Распределенная часть (м)");
    labelLength.setId("textWithTooltip");
    Tooltip.install(labelLength, new Tooltip("Длина распределенной части выпуска (м)"));
    TextField textFieldLength = new TextField();
    VBox lengthContainer = new VBox(labelLength, textFieldLength);

    tile.getChildren().addAll(typeContainer, bankContainer, coordinateContainer, lengthContainer);

    TitledPane titledPane = new TitledPane("Параметры выпуска " + (index+1), tile);


    return titledPane;
}

//creates choiceBox of pipes
protected ChoiceBox<String> createChoiceBoxTypeOfPipes(){
    return new ChoiceBox(FXCollections.observableArrayList("Береговой сосредоточенный",
            "Береговой распределенный", "Русловой сосредоточенный", "Русловой рассеивающий",
            "Русловой рассеивающий с двумя ветками выпуска"));

}

}

我不保存節點的實例,因為我不知道如何在重新創建后更改它們。 我想我們需要了解更改了選擇框的標題窗格,然后重新創建此標題窗格。 但是我們需要恢復以前的數據,我的方法無法恢復它們。 所以,請。

解決方案

感謝 James_D,我找到了解決方案:我只需要ArrayList<Map<String, Node>>每個Map包含TextFieldChoiceBox es。

protected TitledPane createTitledPanePipe(int index){

    Map<String, Node> content = new HashMap<>();

    /* Базовая часть всех труб */
    TilePane tile = new TilePane(Orientation.HORIZONTAL, 5, 5);
    Label typeLabel = new Label("Тип выпуска");
    ChoiceBox<String> choiceBoxTypeOfPipe = createChoiceBoxTypeOfPipes();
    choiceBoxTypeOfPipe.getSelectionModel().select("Береговой сосредоточенный");
    content.put("choiceBoxTypeOfPipe", choiceBoxTypeOfPipe);
    VBox typeContainer = new VBox(typeLabel,choiceBoxTypeOfPipe);



    Label bankLabel = new Label("Берег");
    bankLabel.setId("textWithTooltip");
    Tooltip.install(bankLabel, new Tooltip("Берег, с которого производится выпуск"));
    ChoiceBox<String> choiceBoxCoast = createChoiceBoxCoast();
    content.put("choiceBoxCoast", choiceBoxCoast);
    VBox bankContainer = new VBox(bankLabel, choiceBoxCoast);


    Label labelCoordinateX = new Label("Точка выпуска (км)");
    labelCoordinateX.setId("textWithTooltip");
    Tooltip.install(labelCoordinateX, new Tooltip("Координата x точки выпуска относительно положения контрольного створа"));
    TextField textFieldCoordinate = new TextField();
    content.put("textFieldCoordinate", textFieldCoordinate);
    VBox coordinateContainer = new VBox(labelCoordinateX, textFieldCoordinate);


    tile.getChildren().addAll(typeContainer, bankContainer, coordinateContainer);

    /*_______________________________________________________*/

    /* Береговая распределенная труба */

    Label labelLength = new Label();
    labelLength.setId("textWithTooltip");
    TextField textFieldLength = new TextField();
    VBox lengthContainer = new VBox(labelLength, textFieldLength);

    Label labelMiniPipes = new Label("Патрубки (м)");
    labelMiniPipes.setId("textWithTooltip");
    Tooltip.install(labelMiniPipes, new Tooltip("Расстояние между патрубками (м)"));
    TextField textFieldMiniPipes = new TextField();
    VBox miniPipesContainer = new VBox(labelMiniPipes, textFieldMiniPipes);

    /* ___________________________________________________________ */

choiceBoxTypeOfPipe.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            switch (oldValue) {
                case "Береговой распределенный":
                    content.keySet().remove("textFieldLength");
                    content.keySet().remove("textFieldMiniPipes");
                    tile.getChildren().remove(lengthContainer);
                    tile.getChildren().remove(miniPipesContainer);
                    break;
                case "Русловой сосредоточенный":
                    content.keySet().remove("textFieldLength");
                    tile.getChildren().remove(lengthContainer);
                    break;

            }
            switch (newValue) {
                case "Береговой распределенный":
                    content.put("textFieldLength", textFieldLength);
                    content.put("textFieldMiniPipes", textFieldMiniPipes);
                    labelLength.setText("Распределенная часть (м)");
                    Tooltip.install(labelLength, new Tooltip("Длина распределенной части выпуска (м)"));
                    tile.getChildren().addAll(lengthContainer, miniPipesContainer);
                    break;
                case "Русловой сосредоточенный":
                    labelLength.setText("Протяженность (м)");
                    content.put("textFieldLength", textFieldLength);
                    Tooltip.install(labelLength, new Tooltip("Расстояние от берега до точки выпуска"));
                    tile.getChildren().addAll(lengthContainer);
                    break;
            }
    });


    TitledPane titledPane = new TitledPane("Параметры выпуска " + index, tile);
    this.dynamicComponents.add(content);
    return titledPane;
}

目前還不清楚這里的實際問題是什么,或者為什么需要兩種不同的方法。

為什么不這樣做:

protected TitledPane createTitledPaneCoastalPipe(int index, boolean concentrate){

    TilePane tile = new TilePane(Orientation.HORIZONTAL, 5, 5);
    Label typeLabel = new Label("Тип выпуска");
    ChoiceBox<String> choiceBoxTypeOfPipe = createChoiceBoxTypeOfPipes();

    // remove this line:
    // choiceBoxTypeOfPipe.getSelectionModel().select(1);

    VBox typeContainer = new VBox(typeLabel,choiceBoxTypeOfPipe);

    Label bankLabel = new Label("Берег");
    bankLabel.setId("textWithTooltip");
    Tooltip.install(bankLabel, new Tooltip("Берег, с которого производится выпуск"));
    ChoiceBox<String> choiceBoxCoast = createChoiceBoxCoast();
    choiceBoxCoast.getSelectionModel().select(0);
    VBox bankContainer = new VBox(bankLabel, choiceBoxCoast);

    Label labelCoordinateX = new Label("Точка выпуска (км)");
    labelCoordinateX.setId("textWithTooltip");
    Tooltip.install(labelCoordinateX, new Tooltip("Координата x точки выпуска относительно положения контрольного створа"));

    TextField textFieldCoordinate = new TextField();
    VBox coordinateContainer = new VBox(labelCoordinateX, textFieldCoordinate);

    Label labelLength = new Label("Распределенная часть (м)");
    labelLength.setId("textWithTooltip");
    Tooltip.install(labelLength, new Tooltip("Длина распределенной части выпуска (м)"));
    TextField textFieldLength = new TextField();
    VBox lengthContainer = new VBox(labelLength, textFieldLength);

    tile.getChildren().addAll(typeContainer, bankContainer, coordinateContainer);

    choiceBoxTypeOfPipes.getSelectionModel().selectedIndexProperty().addListener(
        (obs, oldIndex, newIndex) -> {
            // may need different logic here: question is unclear
            if (newIndex.intValue()==1) {
                tile.getChildren().add(lengthContainer);
            }
            if (oldIndex.intValue()==1) {
                tile.getChildren().remove(lengthContainer);
            }
        }
    );

    if (concentrate) {
        choiceBoxTypeOfPipes.getSelectionModel().select(0);
    } else {
        choiceBoxTypeOfPipes.getSelectionModel().select(1);
    }

    TitledPane titledPane = new TitledPane("Параметры выпуска " + (index+1), tile);


    return titledPane;
}

然后只是

public void fillAccordion(int numberOfPipes){

    accordionPlant.getPanes().add(createTitledPaneCoastalPipe(0, true));
    accordionPlant.getPanes().add(createTitledPaneCoastalPipe(1, false));

}

沒有所有冗余代碼,這不是您想要的嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM