Как я могу заполнить комбинированный список выделением из другого комбинированного списка?JavaFX - PullRequest
1 голос
/ 05 июня 2019

Я начал создавать графический интерфейс для генератора March Madness , отображая все 64 команды для раунда 1 как Labels, и теперь я пытаюсь создать раскрывающееся меню ComboBox для каждого матча.

Я создал ComboBox для 2 матчей, и теперь я хочу создать новый ComboBox, который извлекает свои опции из двух других ComboBox перед ним.Таким образом, в приведенном ниже примере диаграммы новый ComboBox должен иметь опции Duke и VCU, чтобы пользователь мог выбирать из них.

           (2 combo boxes)        (new combo box)

Duke------
               Duke ---   
ND St. ---

                                        X

VCU -----
               VCU ---
UCF -----  

Как я могу это сделать?

public class ControlPanel extends Application
{

    @Override
    public void start(Stage primaryStage) {

        primaryStage.setTitle("March Madness 2019 Generator");

        BorderPane componentLayout = new BorderPane();
        componentLayout.setPadding(new Insets(20,0,20,20));

        final FlowPane choicePane = new FlowPane();
        choicePane.setHgap(100);
        Label choiceLbl = new Label("Match1");

        ArrayList<Team> round1 = new ArrayList<Team>();

        round1.add(new Team("Duke", 0.670, 1));                    //0
        round1.add(new Team("North Dakota St", 0.495, 16));
        round1.add(new Team("VCU", 0.609, 8));
        round1.add(new Team("UCF", 0.606, 9));


        //The choicebox is populated from an observableArrayList
        ChoiceBox r2Match1 = new ChoiceBox(FXCollections.observableArrayList(  match(round1, 0, 1)   ));

        //Add the label and choicebox to the flowpane
        choicePane.getChildren().add(choiceLbl);
        choicePane.getChildren().add(r2Match1);

        //put the flowpane in the top area of the BorderPane
        componentLayout.setTop(choicePane);

        //Add the BorderPane to the Scene
        Scene appScene = new Scene(componentLayout,500,500);
        //Add the Scene to the Stage
        primaryStage.setScene(appScene);
        primaryStage.show();
    }

    private ArrayList<Team> match(ArrayList<Team> roundPullFrom, int team1, int team2) {
        ArrayList<Team> temp = new ArrayList<Team>();
        temp.add(roundPullFrom.get(team1));
        temp.add(roundPullFrom.get(team2));
        return temp;
    }

}

Ответы [ 2 ]

0 голосов
/ 05 июня 2019

Объедините ComboBox пар, используя подход, опубликованный в моем предыдущем ответе , пока не останется один ComboBox.

Следующий код размещает узлы в чем-то, что тоже напоминает древовидную структуру, но вы можете легко отделить расположение, сохраняя каждый раунд в структуре данных вместо перезаписи значений одного массива. (Так как вы захотите получить доступ к данным, вам все равно следует хранить комбинации в правильной структуре данных.)

private static ComboBox<String> createCombo(double x, double y, double width) {
    ComboBox<String> comboBox = new ComboBox<>();
    comboBox.setLayoutX(x);
    comboBox.setLayoutY(y);
    comboBox.setMaxWidth(Region.USE_PREF_SIZE);
    comboBox.setMinWidth(Region.USE_PREF_SIZE);
    comboBox.setPrefWidth(width);

    return comboBox;
}

private static Label createLabel(String text, double maxWidth) {
    Label label = new Label(text);
    label.setMaxWidth(maxWidth);
    return label;
}

@Override
public void start(Stage primaryStage) {
    String[] teams = new String[64];
    for (int i = 0; i < teams.length; i++) {
        teams[i] = Integer.toString(i);
    }
    final double offsetY = 30;
    final double offsetX = 100;
    final double width = 90;

    Pane root = new Pane();

    // array storing the comboboxes
    // combos for previous round are at the lowest indices
    ComboBox<String>[] combos = new ComboBox[teams.length / 2];

    // create initial team labels & comboboxes
    for (int i = 0, offsetTeams = 0; i < combos.length; i++, offsetTeams += 2) {
        Label label = createLabel(teams[offsetTeams], width);
        double y = offsetTeams * offsetY;
        label.setLayoutY(y);
        root.getChildren().add(label);

        label = createLabel(teams[offsetTeams+1], width);
        label.setLayoutY(y+offsetY);

        ComboBox<String> comboBox = createCombo(offsetX, y + offsetY / 2, width);
        comboBox.getItems().addAll(teams[offsetTeams], teams[offsetTeams+1]);
        combos[i] = comboBox;

        root.getChildren().addAll(label, comboBox);
    }

    double x = 2 * offsetX;
    int count = combos.length / 2; // combos still left for the next round

    for (; count > 0; count /= 2, x += offsetX) { // for each round
        // create comboboxes combining the combos from previous round pairwise
        for (int i = 0, ci = 0; i < count; i++, ci+=2) {
            // get combos pairwise
            ComboBox<String> c1 = combos[ci];
            ComboBox<String> c2 = combos[ci+1];

            ComboBox<String> combo = createCombo(x, (c1.getLayoutY() + c2.getLayoutY()) / 2, width) ;

            // combine data from previous round
            ChangeListener<String> listener = (o, oldValue, newValue) -> {
                final List<String> items = combo.getItems();
                int index = items.indexOf(oldValue);
                if (index >= 0) {
                    if (newValue == null) {
                        items.remove(index);
                    } else {
                        items.set(index, newValue);
                    }
                } else if (newValue != null) {
                    items.add(newValue);
                }
            };
            c1.valueProperty().addListener(listener);
            c2.valueProperty().addListener(listener);

            root.getChildren().add(combo);
            combos[i] = combo;
        }
    }

    primaryStage.setScene(new Scene(new ScrollPane(root), 600, 400));
    primaryStage.show(); 
}
0 голосов
/ 05 июня 2019

Структура вашей проблемы - дерево. Поэтому вы можете захотеть, чтобы ваше решение поддерживало эту структуру. Либо вы используете структуру данных Binary Tree для напоминания турнира, либо вы создаете такую ​​структуру, например, например. имея такие классы, как:

class Team {
   String name;
}

class Match {
   Team teamA;
   Team teamB;
   String where;
   Date when;

   public Team selectWinner() { 
     ...
   }
}

class Tournament {
   List<Team> teams;
   List<Match> getMatches(int round,List<Team> teams) {
     List<Match> matches=new ArrayList<Match>)();
     if (round==1) {
       for (teamIndex=1;teamIndex<=teams.size();teamIndex+=2) {
         Match match=new Match(teams[teamIndex-1],teams(teamIndex)];
         matches.add(match);
       }
     } else { 
       List<Team> winners=new ArrayList<Team>();
       for (Match match:getMatches(round-1)) {
         winners.add(match.selectWinner());
       }
       return getMatches(1,winners);
     }
   }
}

Из этой структуры вы можете затем извлечь необходимые компоненты графического интерфейса, чтобы сделать выбор динамическим, и позволить компонентам графического интерфейса принимать свои значения из классов Tournament, Match и Team.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...