我想使用兩個ChoiceBoxes提供相同的選擇項目,但另一個選擇項目除外。但是,在幾次選擇選項之後,整個java進程變得沒有響應。ChoiceBox:從另一個選擇框中刪除選定項目時凍結
更新:如果我使用ComboBox而不是ChoiceBox,則不會發生該問題。然而,爲什麼會發生這樣的解釋會很有趣。
我有兩個ChoiceBoxes
@FXML private ChoiceBox<String> firstCB;
@FXML private ChoiceBox<String> secondCB;
最初具有相同的選擇選項
firstCB.getItems().addAll(Charset.availableCharsets().keySet());
secondCB.getItems().addAll(Charset.availableCharsets().keySet());
和事件監聽器再次刪除從其他ChoiceBox的選擇新的選擇並提供舊選項
firstCB.getSelectionModel().selectedItemProperty()
.addListener((observable, oldVal, newVal) -> {
secondCB.getItems().remove(newVal);
secondCB.getItems().add(oldVal);
});
與JComboBoxe等效的Swing代碼S和下面的事件處理工作
firstCB.addItemListener(itemEvent -> {
if (itemEvent.getStateChange() == ItemEvent.DESELECTED) {
secondCB.addItem((String) itemEvent.getItem());
} else if (itemEvent.getStateChange() == ItemEvent.SELECTED) {
secondCB.removeItem(itemEvent.getItem());
}
});
全碼:
類test.Main
public class Main extends Application {
private Parent rootPane;
@Override
public void start(Stage arg0) throws Exception {
Scene scene = new Scene(rootPane);
arg0.setScene(scene);
arg0.show();
}
@Override
public void init() throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/main.fxml"));
rootPane = loader.load();
loader.<View>getController().init();
}
public static void main(String[] args) {
launch(args);
}
}
類test.View
public class View {
@FXML
private ChoiceBox<String> firstCB;
@FXML
private ChoiceBox<String> secondCB;
public void init() {
firstCB.getItems().addAll(Charset.availableCharsets().keySet());
secondCB.getItems().addAll(Charset.availableCharsets().keySet());
firstCB.getSelectionModel().selectedItemProperty()
.addListener((observable, oldVal, newVal) -> {
System.out.printf("[%s]firstCB selection changed%n", Thread.currentThread().getName());
secondCB.getItems().remove(newVal);
secondCB.getItems().add(oldVal);
});
// removing one of the event listeners doesn't help
secondCB.getSelectionModel().selectedItemProperty()
.addListener((observable, oldVal, newVal) -> {
System.out.printf("[%s]secondCB selection changed%n", Thread.currentThread().getName());
firstCB.getItems().remove(newVal);
firstCB.getItems().add(oldVal);
});
}
}
main.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<Pane fx:id="rootPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="90.0" prefWidth="180.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="test.View">
<children>
<ChoiceBox fx:id="firstCB" layoutX="14.0" layoutY="14.0" prefWidth="150.0" />
<ChoiceBox fx:id="secondCB" layoutX="14.0" layoutY="52.0" prefWidth="150.0" />
</children>
</Pane>
看起來像一個用法錯誤,給我等不是最好的解決辦法:從choicebox API文檔「ChoiceBox使用用於向用戶呈現**相對較小的一組 預定義的選項「 - 它不針對處理較大的項目計數而優化(如同ComboBox,fi通過虛擬化節點) – kleopatra 2014-08-31 09:06:56