我必须根据用户输入创建自动填充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
下拉列表以查看弹出窗口大小。
如何根据内容制作列表大小?
答案 0 :(得分:3)
根据内容&#34; 不完全是&#34;列表大小(如果项目数量太大而无法放在屏幕上,这会很糟糕,BTW),但你可以使用CSS指定弹出窗口中显示的ListView
的最小高度。
这可确保弹出窗口大小永远不会变得太小。即使项目数量很少,这也会留下一些空白空间&#34;在ListView
:
.combo-box .combo-box-popup > .list-view {
-fx-min-height: 200;
}
答案 1 :(得分:2)
这是因为未调用comboBox.hide();
方法(下拉列表会在显示时自动更新)。
您可以将听众改进为:
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;
}
}
此更新将确保每次更改搜索String
时都会隐藏并重新显示下拉列表。
答案 2 :(得分:1)
我建议尝试使用小型实用程序库jalvafx
中的解决方案List<String> items = Arrays.asList("Mercury",
"Venus",
"Earth",
"Mars",
"Jupiter",
"Saturn",
"Neptune");
ComboBoxCustomizer.create(comboBox)
.autocompleted(items)
.customize();
默认情况下,双击以清除值。还有一些其他有用的功能。您可以添加额外的列或字形,选择特定项目,将项目默认更改为字符串表示形式...
ComboBoxCustomizer.create(comboBox)
.autocompleted(items)
.overrideToString(o -> "planet: " + o)
.multyColumn(o -> Arrays.asList("column 2", "column 3"))
.emphasized(o -> o.endsWith("s"))
.customize();