具有自定义对象的可编辑组合框重写下拉列表中的项目
Editable ComboBox with custom objects rewrites items on dropdown list
我有一个可过滤的 ComboBox
填充自定义 Subjekt
对象。
使用 SubjektDAO.searchSubjectsByName()
方法从数据库填充过滤列表。
向 ComboBox
的编辑器添加了监听器,并使用 cbNazivKupca.show()
方法在我开始输入时自动打开下拉列表(填充并显示)。
过滤工作正常(当我输入列表时被过滤),但是当我 select 列表中的项目(比方说 "abraham")时,更改其在 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()出现在下拉列表中。
已编辑:我也遇到了类似的解决方案,但让我感到困惑的是:
当我单击下拉按钮并列出项目时,如果我单击列表中的第一个,它会被复制到可编辑部分,但如果我单击任何其他按钮,编辑器将获得光标并且为空,如果我再次单击它,一切都很好,这只会发生一次。
您的转换器的 fromString
方法无效。 this method的目的是return一个对象,其类型为StringConverter
的泛型参数类型,没有别的:
Converts the string provided into an object defined by the specific
converter. Format of the string and type of the resulting object is
defined by the specific converter.
所以在这个方法中你不应该得到选择的项目,更糟糕的是你不应该修改选择的项目,实际上这就是修改下拉列表中的项目的原因。
当您在 ComboBox
的编辑器中输入时使用 fromString
方法,然后按回车键找出应选择的项目(该项目是方法 returns ) 基于您在编辑器中输入的字符串(方法的输入参数)。
你应该做的是从 ComboBox
的项目中获取对应的 Subject
实例,例如:
@Override
public Subjekt fromString(String productString) {
return cbNazivKupca.getItems().stream().filter(item -> productString.equals(item.getSubjekt_naziv())).findFirst().orElse(null);
}
这将 return ComboBox
中项目的第一个元素,其中 subjekt_naziv
成员与指定的 String
相同,如果无法匹配则为 null .
我有一个可过滤的 ComboBox
填充自定义 Subjekt
对象。
使用 SubjektDAO.searchSubjectsByName()
方法从数据库填充过滤列表。
向 ComboBox
的编辑器添加了监听器,并使用 cbNazivKupca.show()
方法在我开始输入时自动打开下拉列表(填充并显示)。
过滤工作正常(当我输入列表时被过滤),但是当我 select 列表中的项目(比方说 "abraham")时,更改其在 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()出现在下拉列表中。
已编辑:我也遇到了类似的解决方案,但让我感到困惑的是: 当我单击下拉按钮并列出项目时,如果我单击列表中的第一个,它会被复制到可编辑部分,但如果我单击任何其他按钮,编辑器将获得光标并且为空,如果我再次单击它,一切都很好,这只会发生一次。
您的转换器的 fromString
方法无效。 this method的目的是return一个对象,其类型为StringConverter
的泛型参数类型,没有别的:
Converts the string provided into an object defined by the specific converter. Format of the string and type of the resulting object is defined by the specific converter.
所以在这个方法中你不应该得到选择的项目,更糟糕的是你不应该修改选择的项目,实际上这就是修改下拉列表中的项目的原因。
当您在 ComboBox
的编辑器中输入时使用 fromString
方法,然后按回车键找出应选择的项目(该项目是方法 returns ) 基于您在编辑器中输入的字符串(方法的输入参数)。
你应该做的是从 ComboBox
的项目中获取对应的 Subject
实例,例如:
@Override
public Subjekt fromString(String productString) {
return cbNazivKupca.getItems().stream().filter(item -> productString.equals(item.getSubjekt_naziv())).findFirst().orElse(null);
}
这将 return ComboBox
中项目的第一个元素,其中 subjekt_naziv
成员与指定的 String
相同,如果无法匹配则为 null .