Многократный выбор и отмена выбора с использованием ComboBox в JavaFX - PullRequest
0 голосов
/ 11 октября 2018

Я изучаю ComboBox на JavaFX и пытаюсь создать пользовательский интерфейс, чтобы пользователь мог выбрать режим выбора, ОДИН или МНОЖЕСТВЕННЫЙ, и выбрать страны, указанные в модели.Мне удалось добавить прослушиватель изменений для модели, и он работает, когда я удерживаю Ctrl + Выбрать страны в режиме множественного выбора, и данные также выбираются.Однако, когда я отменяю выбор ранее выбранной страны, это не вызовет изменения, а также не удалит его из строки, отображаемой в нижней части пользовательского интерфейса - «Выбранные элементы».Я пытаюсь понять, как я могу вызвать прослушиватель изменений ComboBox для удаления выбранного значения.Вот код до сих пор.

import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

public class Exercise_16_16_Copy extends Application {

ListView<String> listCountries = new ListView<String>(); 

public static void main(String[] args) {
    Application.launch(args);
}

@Override
public void start(Stage primaryStage) throws Exception {
    HBox topSection = new HBox();
    topSection.setPadding(new Insets(3));
    topSection.setSpacing(5);
    topSection.setAlignment(Pos.CENTER);

    ComboBox<SelectionMode> comboList = new ComboBox<SelectionMode>();
    comboList.getItems().add(SelectionMode.SINGLE);
    comboList.getItems().add(SelectionMode.MULTIPLE);
    comboList.setValue(comboList.getItems().get(0));
    comboList.setOnAction(e-> listCountries.getSelectionModel().setSelectionMode(comboList.getValue()));

    Label comboBoxLabel = new Label("Selection Mode: ", comboList);

    comboBoxLabel.setContentDisplay(ContentDisplay.RIGHT);

    topSection.getChildren().add(comboBoxLabel);

    HBox bottomSection = new HBox();
    bottomSection.setPadding(new Insets(3));
    bottomSection.setAlignment(Pos.CENTER_LEFT);

    Label lblSelectedItem = new Label("No Selected Items");
    lblSelectedItem.setPadding(new Insets(5));

    bottomSection.getChildren().add(lblSelectedItem);

    Pane centerSection = new Pane();
    listCountries.getItems().addAll("China", "Japan", "Korea", "India", "Malaysia", "Vietnam");
    listCountries.setPrefHeight(listCountries.getItems().size() * 26);
    centerSection.getChildren().add(listCountries);

    listCountries.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
        lblSelectedItem.setText(getItems());
        primaryStage.sizeToScene();
    });

    BorderPane brdrPane = new BorderPane();
    brdrPane.setTop(topSection);
    brdrPane.setCenter(centerSection);
    brdrPane.setBottom(bottomSection);
    Scene scene = new Scene(brdrPane);
    primaryStage.setScene(scene);
    primaryStage.setTitle("ListView");
    primaryStage.show();
}

private String getItems() {
    ObservableList<String> selectedCountries = listCountries.getSelectionModel().getSelectedItems();
    if (selectedCountries.size() == 0) {
        return "No Countries Selected";
    }
    if (selectedCountries.size() == 1) {
        return "Selected Item " + selectedCountries.get(0);
    }
    String displayText = "Selected Items are ";
    for (String country : selectedCountries) {
        displayText += country + " ";
    }
    return displayText;
}
}

Метод getItems () используется для получения выбранного количества элементов, которые отображаются в нижнем колонтитуле созданного графического интерфейса.Можно ли реализовать эту функцию с помощью ComboBox или я должен использовать какой-либо другой компонент?Пожалуйста, помогите!

Ответы [ 3 ]

0 голосов
/ 11 октября 2018

Вы можете сделать все это в одной привязке.

final List<String> selectedCountries = listCountries.getSelectionModel().getSelectedItems();
lblSelectedItem.textProperty().bind(Bindings.createStringBinding(() -> {
    if (selectedCountries.isEmpty()) {
        return "No Countries Selected";
    }
    else if (selectedCountries.size() == 1) {
        return "Selected Item is " + selectedCountries.get(0);
    }
    else {
        return "Selected Items are " + String.join(", ", selectedCountries);
    }
}, selectedCountries));
0 голосов
/ 19 октября 2018

Я попробовал подход, предложенный Jai, и он работает, но с ограничением, что всякий раз, когда вы выбираете несколько элементов в комбинированном окне, он будет печатать элементы, выбранные на ярлыке ниже, и если вы выберете больше элементов, это былопредполагается расширить сцену автоматически, но есть ограничение с изменением размера сцены.Вот код, который я использовал для этого.

final ObservableList<String> selectedCountries = listCountries.getSelectionModel().getSelectedItems(); 

lblSelectedItem.textProperty().bind(Bindings.createStringBinding(() -> getItems(pStage), selectedCountries));

Если кто-нибудь посмотрит, как я решил эту проблему, этот ответ может помочь!Я решил эту проблему, реализовав следующий код:

listCountries.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(final MouseEvent mouseEvent) {
        lblSelectedItem.setText(getItems());
        if(listCountries.getSelectionModel().getSelectedItems().size() > 2)
            listCountries.setPrefWidth(listCountries.getSelectionModel().getSelectedItems().size() * 20);
        pStage.sizeToScene();
    }
});
0 голосов
/ 11 октября 2018

Проблема в том, что вы слушаете.Если вы находитесь в режиме MultiSelection, вы можете прослушать getSelectedItems ().Конечно, это будет работать и с Single selection ... так что измените реализацию слушателя на

listCountries.getSelectionModel().getSelectedItems().addListener((ListChangeListener)observable -> {
        lblSelectedItem.setText(getItems());
        primaryStage.sizeToScene();
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...