我正在学习JavaFX中的ComboBox,并试图构建一个UI,以使用户可以选择选择模式(单或多)并选择模型中列出的国家/地区。我能够为模型添加变更侦听器,并且在“多重选择”模式下按住Ctrl +选择国家/地区时,它也可以工作,并且还可以选择数据。但是,当我取消选择较早选择的国家/地区时,它不会触发更改,也不会从UI底部显示的字符串-“所选项目为”中删除。我试图了解如何触发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()方法用于获取选定数量的项目,这些项目显示在创建的GUI的页脚处。甚至可以使用ComboBox来实现此功能,还是应该使用任何其他组件?请帮忙!
答案 0 :(得分:1)
您可以一次绑定完成所有操作。
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));
答案 1 :(得分:0)
问题在于您正在听的内容。如果您处于MultiSelection模式,则可以收听getSelectedItems()。当然,这也将与“单选”一起使用..因此,将您的侦听器实现更改为
listCountries.getSelectionModel().getSelectedItems().addListener((ListChangeListener)observable -> {
lblSelectedItem.setText(getItems());
primaryStage.sizeToScene();
});
答案 2 :(得分:0)
我尝试了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();
}
});