我有一个可过滤的ComboBox
填充了自定义Subjekt
个对象。
使用SubjektDAO.searchSubjectsByName()
方法从数据库填充过滤列表。
在ComboBox
的编辑器中添加了监听器,并使用cbNazivKupca.show()
方法在我开始输入时自动打开下拉列表(已填充并显示)。
过滤工作正常(因为我输入列表被过滤),但是当我从列表中选择项目时(比如说“亚伯拉罕”),在ComboBox
文本字段中改变它的值(比如说“abrah”)和点击其他地方(所以ComboBox
失去焦点)“abrah”值出现在下拉列表中,我松开了原始值。
我需要禁用在列表中输入新值(我可以通过设置组合框不可编辑来完成此操作),但我有大量滚动浏览。
此外,如果我点击按钮显示列表中的项目并单击第一行,它将填充在文本框中,但如果我点击第二个或下一个我需要点击他两次(这只发生一次)。
我不知道如何解决这个问题,我是JavaFX和学习的新手。
请帮忙。
try {
final FilteredList<Subjekt> filteredItems = new FilteredList<>(SubjektDAO.searchSubjectsByName(), p -> true);
cbNazivKupca.getEditor().textProperty().addListener((obs, oldValue, newValue) -> {
cbNazivKupca.show();
final TextField editor = cbNazivKupca.getEditor();
final Subjekt selected = cbNazivKupca.getSelectionModel().getSelectedItem();
/*
This needs run on the GUI thread to avoid the error described
here: https://bugs.openjdk.java.net/browse/JDK-8081700.
*/
Platform.runLater(() -> {
/*
If the no item in the list is selected or the selected item
isn't equal to the current input, we refilter the list.
*/
if (selected == null || !selected.toString().equals(editor.getText())) {
filteredItems.setPredicate(item -> {
cbNazivKupca.setVisibleRowCount(10);
// We return true for any items that contains the
// same letters as the input. We use toUpperCase to
// avoid case sensitivity.
if (item.getSubjekt_naziv().toUpperCase().contains(newValue.toUpperCase())) {
return true;
} else {
return false;
}
});
}
});
});
cbNazivKupca.setItems(filteredItems);
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}
// rendering of the list of values in ComboBox drop down.
cbNazivKupca.setCellFactory((comboBox) -> {
return new ListCell<Subjekt>() {
@Override
protected void updateItem(Subjekt subjekt, boolean empty) {
super.updateItem(subjekt, empty);
if (subjekt == null || empty) {
setText(null);
} else {
setText(subjekt.getSubjekt_naziv());
}
}
};
});
cbNazivKupca.setConverter(new StringConverter<Subjekt>() {
@Override
public String toString(Subjekt subjekt) {
if (subjekt == null) {
return null;
} else {
return subjekt.getSubjekt_naziv();
}
}
@Override
public Subjekt fromString(String productString)
{
if(cbNazivKupca.getValue() != null)
{
((Subjekt)cbNazivKupca.getValue()).setSubjekt_naziv(productString);
return (Subjekt)cbNazivKupca.getValue();
}
return null;
}
});
已编辑:我已将问题的来源缩小为cbNazivKupca.setConverter fromString方法,但我卡住了,我需要检查下拉列表中是否存在cbNazivKupca.getValue()。
已编辑:我也遇到了类似的解决方案,但令我困惑的是: 当我点击下拉按钮并列出项目如果我点击第一个列表它会被复制到可编辑的部分,但如果我点击任何其他编辑器获取光标并且是空的,如果我再次点击它一切都很好,这只会发生一旦。
答案 0 :(得分:0)
转换器的fromString
方法无效。 this method的目的是返回一个对象,其类型为StringConverter
的泛型参数类型,没有别的:
将提供的字符串转换为特定的对象 转换器。字符串的格式和结果对象的类型是 由特定的转换器定义。
因此,在此方法中,您不应该获取所选项目,更糟糕的是,您不应该修改所选项目,实际上这是修改下拉列表中项目的原因。
当您在fromString
的编辑器中键入时,使用ComboBox
方法然后按Enter键以根据您拥有的字符串找出应该选择的项目(方法返回的项目)键入编辑器(方法的输入参数)。
您应该做的是从Subject
的项目中获取相应的ComboBox
实例,例如:
@Override
public Subjekt fromString(String productString) {
return cbNazivKupca.getItems().stream().filter(item -> productString.equals(item.getSubjekt_naziv())).findFirst().orElse(null);
}
这将返回ComboBox
中subjekt_naziv
成员与指定String
相同的项目中的第一个元素,如果无法匹配,则返回null。