JavaFX 自动完成组合框下拉大小
Posted
技术标签:
【中文标题】JavaFX 自动完成组合框下拉大小【英文标题】:JavaFX autocomplete ComboBox drop-down size 【发布时间】:2016-12-16 17:31:06 【问题描述】:我必须根据用户输入创建一个自动填充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
下拉菜单以查看弹出窗口大小。
如何根据内容制作列表大小?
【问题讨论】:
@Reimeus 如何在这种情况下使用 sizeToScene() 方法。 【参考方案1】:这是因为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
时下拉列表将被隐藏并重新显示。
【讨论】:
这可能会产生奇怪的视觉效果,如果弹出窗口只是消失一瞬间...... 是的,我知道。我猜原来的那个已经打算使用这种隐藏显示机制:comboBox.hide()
on keyPress
。我将搜索如何将下拉列表调整为内容而不会出现这种“闪烁”。【参考方案2】:
不完全是 “根据内容的列表大小”(如果项目数量太大而无法在屏幕上显示,这会很糟糕,顺便说一句),但您可以指定使用 CSS 弹出的ListView
。
这可确保弹出窗口大小永远不会变得太小。即使物品数量很少,这也会在ListView
的底部留下一些“空白”:
.combo-box .combo-box-popup > .list-view
-fx-min-height: 200;
【讨论】:
这是一个没有我想象的那么糟糕的解决方案。谢谢,@f***。【参考方案3】:我建议尝试使用小型实用程序库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();
【讨论】:
以上是关于JavaFX 自动完成组合框下拉大小的主要内容,如果未能解决你的问题,请参考以下文章