我必须根据用户输入创建一个自动填充ComboBox.
我的代码是这样的:
public class JavaFXApplication1 extends Application {
@Override
public void start(Stage primaryStage) {
ComboBox<String> combo = new ComboBox<>();
ObservableList<String> list = FXCollections.observableArrayList();
list.add("A");
list.add("AND");
list.add("ANDR");
list.add("ANDRE");
list.add("B");
list.add("BP");
list.add("BPO");
combo.setItems(list);
new AutoCompleteComboBoxListener(combo);
StackPane root = new StackPane();
root.getChildren().add(combo);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
AutoCompleteComboBoxListener取自此answer.
使用此自动完成工作正常.我在列表大小方面遇到了问题,
运行该应用程序并单击ComboBox下拉列表以查看弹出窗口大小.
>在组合框中键入ANDRE(将在弹出窗口中显示ANDRE选项).现在删除所有字符.(按退格键)
>现在,已填充的列表使用滚动条缩小为一个条目大小.
>再次单击组合框下拉列表以获取完整大小列表.
如何根据内容制作列表大小?
解决方法:
这是因为comboBox.hide();方法未被调用(下拉列表在show上自动更新).
您可以将侦听器改进为:
public class AutoCompleteComboBoxListener<T> implements EventHandler<KeyEvent> {
private ComboBox<T> comboBox;
private ObservableList<T> data;
private boolean moveCaretToPos = false;
private int caretPos;
public AutoCompleteComboBoxListener(final ComboBox<T> comboBox) {
this.comboBox = comboBox;
data = comboBox.getItems();
this.comboBox.setEditable(true);
this.comboBox.setOnKeyReleased(AutoCompleteComboBoxListener.this);
}
@Override
public void handle(KeyEvent event) {
if(event.getCode() == KeyCode.UP) {
caretPos = -1;
moveCaret(comboBox.getEditor().getText().length());
return;
} else if(event.getCode() == KeyCode.DOWN) {
if(!comboBox.isShowing())
comboBox.show();
caretPos = -1;
moveCaret(comboBox.getEditor().getText().length());
return;
}
if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
|| event.isControlDown() || event.getCode() == KeyCode.HOME
|| event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
return;
}
comboBox.hide();
if(event.getCode() == KeyCode.BACK_SPACE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
} else if(event.getCode() == KeyCode.DELETE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
}
ObservableList<T> list = FXCollections.observableArrayList();
for (int i=0; i<data.size(); i++) {
if(data.get(i).toString().toLowerCase().startsWith(
AutoCompleteComboBoxListener.this.comboBox
.getEditor().getText().toLowerCase())) {
list.add(data.get(i));
}
}
String t = comboBox.getEditor().getText();
comboBox.setItems(list);
comboBox.getEditor().setText(t);
if(!moveCaretToPos) {
caretPos = -1;
}
moveCaret(t.length());
if(!list.isEmpty()) {
comboBox.show();
}
}
private void moveCaret(int textLength) {
if(caretPos == -1)
comboBox.getEditor().positionCaret(textLength);
else
comboBox.getEditor().positionCaret(caretPos);
moveCaretToPos = false;
}
}
此更新将确保每次更改搜索字符串时都会隐藏并重新显示下拉列表.