作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
在我的可编辑组合框中,根据输入过滤我的建议,我可以触发 Button
事件。问题是,如果我在可编辑字段中输入我的项目名称之一(例如 action3
),然后单击第一个建议(也将是 action3
),是合适的项目,它总是用第一个索引 action1
触发 ButtonEvent,因为它有第一个索引,但第一个索引是 action1
。
List<EventHandler<ActionEvent>> handlers = Arrays.asList(
this::action1,
this::action2,
this::action3
);
那么我如何像action1一样链接到我的建议正确的建议?
public void onEnter(ActionEvent event){
int index = editableComboBox.getSelectionModel().getSelectedIndex();
if (index >= 0) {
handlers.get(index).handle(event);
}
}
编辑1:
我的新的initialize()方法如下所示:
protected void initialize() {
new AutoCompleteBox<>(autoBox);
ObservableList<ActionEventHandler> data = FXCollections.observableArrayList(
new ActionEventHandler("action1", this::action1),
new ActionEventHandler("action2", this::action2,
new ActionEventHandler("action3", this::action3)
);
autoBox.getItems().setAll(data);
FilteredList<ActionEventHandler> filtered = new FilteredList<>(data);
ComboBox<ActionEventHandler> autoBox = new ComboBox<>(filtered);
autoBox.setOnAction(event -> {
ActionEventHandler h = autoBox.getValue();
if (h != null) {
h.handle(event);
}
});
autoBox.setEditable(true);
autoBox.setConverter(new StringConverter<ActionEventHandler>() {
@Override
public String toString(ActionEventHandler object) {
return object == null ? "" : object.toString();
}
@Override
public ActionEventHandler fromString(String string) {
if (string == null) {
return null;
}
for (ActionEventHandler h : data) {
if (string.equals(h.toString())) {
return h;
}
}
return null;
}
});
autoBox.getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
filtered.setPredicate(h -> h.toString().startsWith(newValue));
});
}
以及自定义ComboBox
类:
public class AutoCompleteBox<T> implements EventHandler<KeyEvent> {
private ComboBox comboBox;
private StringBuilder sb;
private ObservableList<T> data;
private boolean moveCaretToPos = false;
private int caretPos;
public AutoCompleteBox(final ComboBox comboBox) {
this.comboBox = comboBox;
sb = new StringBuilder();
data = comboBox.getItems();
this.comboBox.setEditable(true);
this.comboBox.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent t) {
comboBox.hide();
}
});
this.comboBox.setOnKeyReleased(AutoCompleteBox.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;
} else if(event.getCode() == KeyCode.BACK_SPACE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
} else if(event.getCode() == KeyCode.DELETE) {
moveCaretToPos = true;
caretPos = comboBox.getEditor().getCaretPosition();
}
if (event.getCode() == KeyCode.RIGHT || event.getCode() == KeyCode.LEFT
|| event.isControlDown() || event.getCode() == KeyCode.HOME
|| event.getCode() == KeyCode.END || event.getCode() == KeyCode.TAB) {
return;
}
ObservableList list = FXCollections.observableArrayList();
for (int i=0; i<data.size(); i++) {
if(data.get(i).toString().toLowerCase().startsWith(
AutoCompleteBox.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;
}
}
我无法链接函数(例如 action1
到字符串 action1
),或者我更相信的是,我无法将自定义类与我的自定义 组合框
。
最佳答案
在这种情况下,似乎最好使用 EventHandler<ActionEvent>
s 作为返回 toString
字符串的项目。添加converter
将项目转换为非 String
对象。
public class ActionEventHandler implements EventHandler<ActionEvent> {
private final EventHandler<ActionEvent> eventHandler;
private final String name;
public ActionEventHandler(String name, EventHandler<ActionEvent> eventHandler) {
Objects.requireNonNull(name);
Objects.requireNonNull(eventHandler);
this.name = name;
this.eventHandler = eventHandler;
}
@Override
public String toString() {
return name;
}
@Override
public void handle(ActionEvent event) {
eventHandler.handle(event);
}
}
ObservableList<ActionEventHandler> data = FXCollections.observableArrayList(
new ActionEventHandler("action1", this::action1),
new ActionEventHandler("action2", this::action2),
new ActionEventHandler("action3", this::action3)
);
FilteredList<ActionEventHandler> filtered = new FilteredList<>(data);
ComboBox<ActionEventHandler> comboBox = new ComboBox<>(filtered);
comboBox.setOnAction(event -> {
ActionEventHandler h = comboBox.getValue();
if (h != null) {
h.handle(event);
}
});
comboBox.setEditable(true);
comboBox.setConverter(new StringConverter<ActionEventHandler>() {
@Override
public String toString(ActionEventHandler object) {
return object == null ? "" : object.toString();
}
@Override
public ActionEventHandler fromString(String string) {
if (string == null) {
return null;
}
for (ActionEventHandler h : data) {
if (string.equals(h.toString())) {
return h;
}
}
return null;
}
});
comboBox.getEditor().textProperty().addListener((observable, oldValue, newValue) -> {
filtered.setPredicate(h -> h.toString().startsWith(newValue));
});
<小时/>
编辑
以下代码应该与您的 AutoCompleteBox
一起使用类。
@FXML
private ComboBox<ActionEventHandler> autoBox;
@FXML
private void initialize() {
autoBox.getItems().setAll(
new ActionEventHandler("action1", this::action1),
new ActionEventHandler("action2", this::action2),
new ActionEventHandler("action3", this::action3));
autoBox.setOnAction(event -> {
ActionEventHandler h = autoBox.getValue();
if (h != null) {
h.handle(event);
}
});
autoBox.setConverter(new StringConverter<ActionEventHandler>() {
@Override
public String toString(ActionEventHandler object) {
return object == null ? "" : object.toString();
}
@Override
public ActionEventHandler fromString(String string) {
if (string == null) {
return null;
}
for (ActionEventHandler h : autoBox.getItems()) {
if (string.equals(h.toString())) {
return h;
}
}
return null;
}
});
new AutoCompleteBox<>(autoBox);
}
(不过我还没有检查您的 AutoCompleteBox
类(class)的详细信息...)
关于java - 将过滤后的组合框项链接到输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40608292/
我正在开发一个 voip 调用应用程序。我需要做的是在接到来电时将 Activity 带到前台。我在应用程序中使用 Twilio,并在收到推送消息时开始调用。 问题是我试图在接到任何电话时显示 Act
我是一名优秀的程序员,十分优秀!