JavaFX可搜索组合框(如js select2)
我正在寻找一个类似JavaFX的组件 一个JavaFX可搜索组合框(如js select2),javafx,Javafx,我正在寻找一个类似JavaFX的组件 一个组合框,当弹出窗口出现并在下面过滤列表视图时,它将有一个可搜索的文本字段 有什么想法或已经做过的事情吗?几个月前我自己就实现了。基本上,您可以将组合框下拉列表包装在FilteredList中,然后将侦听器添加到组合框#textProperty(),以更改FilteredList的谓词 我的类包含很多额外的功能,例如将小写输入转换为大写输入的选项,以及限制输入的长度。如果你不需要这些部件,你可以把它们取下来 import javafx.applicatio
组合框
,当弹出窗口出现并在下面过滤列表视图时,它将有一个可搜索的文本字段
有什么想法或已经做过的事情吗?几个月前我自己就实现了。基本上,您可以将组合框
下拉列表包装在FilteredList
中,然后将侦听器添加到组合框#textProperty()
,以更改FilteredList
的谓词
我的类包含很多额外的功能,例如将小写输入转换为大写输入的选项,以及限制输入的长度。如果你不需要这些部件,你可以把它们取下来
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.collections.transformation.FilteredList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class MCVE extends Application {
@Override
public void start(Stage stage) {
ComboBox<String> box = new ComboBox<String>();
box.setEditable(true);
// For the combo box filter to work properly we need to create the item
// list and wrap it in a FilteredList.
ObservableList<String> items = FXCollections.observableArrayList("One", "Two", "Three", "OneTwo", "ThreeTwo",
"OneTwoThree");
FilteredList<String> filteredItems = new FilteredList<String>(items);
// Then you need to provide the InputFilter with the FilteredList in the
// constructor call.
box.getEditor().textProperty().addListener(new InputFilter(box, filteredItems, false));
box.setItems(filteredItems);
BorderPane view = new BorderPane();
view.setCenter(box);
stage.setScene(new Scene(view));
stage.show();
}
public static void main(String[] args) {
launch();
}
/**
*
* @author Jonatan Stenbacka
*
*/
class InputFilter implements ChangeListener<String> {
private ComboBox<String> box;
private FilteredList<String> items;
private boolean upperCase;
private int maxLength;
private String restriction;
/**
* @param box
* The combo box to whose textProperty this listener is
* added.
* @param items
* The {@link FilteredList} containing the items in the list.
*/
public InputFilter(ComboBox<String> box, FilteredList<String> items, boolean upperCase, int maxLength,
String restriction) {
this.box = box;
this.items = items;
this.upperCase = upperCase;
this.maxLength = maxLength;
this.restriction = restriction;
}
public InputFilter(ComboBox<String> box, FilteredList<String> items, boolean upperCase, int maxLength) {
this(box, items, upperCase, maxLength, null);
}
public InputFilter(ComboBox<String> box, FilteredList<String> items, boolean upperCase) {
this(box, items, upperCase, -1, null);
}
public InputFilter(ComboBox<String> box, FilteredList<String> items) {
this(box, items, false);
}
@Override
public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) {
StringProperty value = new SimpleStringProperty(newValue);
// If any item is selected we save that reference.
String selected = box.getSelectionModel().getSelectedItem() != null
? box.getSelectionModel().getSelectedItem() : null;
String selectedString = null;
// We save the String of the selected item.
if (selected != null) {
selectedString = (String) selected;
}
if (upperCase) {
value.set(value.get().toUpperCase());
}
if (maxLength >= 0 && value.get().length() > maxLength) {
value.set(oldValue);
}
if (restriction != null) {
if (!value.get().matches(restriction + "*")) {
value.set(oldValue);
}
}
// If an item is selected and the value in the editor is the same
// as the selected item we don't filter the list.
if (selected != null && value.get().equals(selectedString)) {
// This will place the caret at the end of the string when
// something is selected.
Platform.runLater(() -> box.getEditor().end());
} else {
items.setPredicate(item -> {
String itemString = item;
if (itemString.toUpperCase().contains(value.get().toUpperCase())) {
return true;
} else {
return false;
}
});
}
// If the popup isn't already showing we show it.
if (!box.isShowing()) {
// If the new value is empty we don't want to show the popup,
// since
// this will happen when the combo box gets manually reset.
if (!newValue.isEmpty() && box.isFocused()) {
box.show();
}
}
// If it is showing and there's only one item in the popup, which is
// an
// exact match to the text, we hide the dropdown.
else {
if (items.size() == 1) {
// We need to get the String differently depending on the
// nature
// of the object.
String item = items.get(0);
// To get the value we want to compare with the written
// value, we need to crop the value according to the current
// selectionCrop.
String comparableItem = item;
if (value.get().equals(comparableItem)) {
Platform.runLater(() -> box.hide());
}
}
}
box.getEditor().setText(value.get());
}
}
}
导入javafx.application.application;
导入javafx.application.Platform;
导入javafx.beans.property.SimpleStringProperty;
导入javafx.beans.property.StringProperty;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.collections.FXCollections;
导入javafx.collections.ObservableList;
导入javafx.collections.transformation.FilteredList;
导入javafx.scene.scene;
导入javafx.scene.control.ComboBox;
导入javafx.scene.layout.BorderPane;
导入javafx.stage.stage;
公共类MCVE扩展应用程序{
@凌驾
公众假期开始(阶段){
ComboBox=新的ComboBox();
box.setEditable(true);
//为了使组合框过滤器正常工作,我们需要创建该项
//列出并将其包装在FilteredList中。
ObservableList items=FXCollections.observableArrayList(“一”、“二”、“三”、“一二”、“三二”,
“一对三”);
FilteredList filteredItems=新的FilteredList(项目);
//然后,您需要在中为InputFilter提供FilteredList
//构造函数调用。
box.getEditor().textProperty().addListener(新的InputFilter(box,filteredItems,false));
框。设置项(过滤项);
BorderPane视图=新建BorderPane();
视图。设置中心(框);
舞台场景(新场景(视图));
stage.show();
}
公共静态void main(字符串[]args){
发射();
}
/**
*
*@作者Jonatan Stenbacka
*
*/
类InputFilter实现ChangeListener{
私人组合框;
私人筛选列表项目;
私有布尔大写;
私有整数最大长度;
私有字符串限制;
/**
*@param-box
*此侦听器指向其textProperty的组合框
*补充说。
*@param项目
*包含列表中项目的{@link FilteredList}。
*/
公共InputFilter(组合框、FilteredList项、布尔大写、int maxLength、,
字符串限制){
this.box=box;
这个项目=项目;
this.upperCase=大写;
this.maxLength=maxLength;
这个限制=限制;
}
公共InputFilter(组合框,FilteredList项,布尔大写,int maxLength){
这(框、项、大写、maxLength、null);
}
公共InputFilter(组合框,FilteredList项,布尔大写){
这(框,项,大写,-1,空);
}
公共输入筛选器(组合框、筛选器列表项){
此(框、项、假);
}
@凌驾
公共无效已更改(可观察值)