В моем редактируемом ComboBox, который фильтрует мои предложения из-за ввода, я могу запустить Button
событий. Проблема в том, что если я набираю одно из имен моих элементов (например, action3
) в редактируемом поле и нажимаю на первое предложение (которое также будет action3
), которое является подходящим элементом, оно всегда запускает ButtonEvent с первым индексом action1
, потому что он имеет первый индекс, но первый индекс - action1
.Link filter Combobox Элемент для ввода
List<EventHandler<ActionEvent>> handlers = Arrays.asList(
this::action1,
this::action2,
this::action3
);
Как я могу связать как действие1 с моим предложением правильное предложение?
public void onEnter(ActionEvent event){
int index = editableComboBox.getSelectionModel().getSelectedIndex();
if (index >= 0) {
handlers.get(index).handle(event);
}
}
EDIT 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
), или что я верю больше, я не могу объединить пользовательский класс с моим настраиваемым ComboBox
.
Я создал собственный ComboBox в новом классе 'AutoCompleteBox <> (autoBox);' который уже доступен для редактирования, я могу добавить ваш нижний код в мои инициализации Controller() '' '' и просто вызвать 'new AutoCompleteBox <> (autoBox); 'потом? Я получаю пустой раскрывающийся список. – Flippy
@Flippy удаляет создание combobox из моего нижнего кода, добавляет его в метод 'initialize()' контроллера и использует 'comboBox.getItems(). SetAll (...)' вместо указания списка элементов в ' ComboBox'. (IDK, если вам нужно изменить свой код с помощью своего типа 'ComboBox' ...) И, конечно же, замените' comboBox' на имя поля 'ComboBox', которое вы используете. – fabian
Я редактирую код в своем вопросе выше, прямо сейчас я получаю элементы (action1 ..), но я не могу использовать действия. – Flippy