我已尝试使用以下代码创建具有ID和值的自动完成组合框。当我使用鼠标事件选择任何值时,它工作正常。但是使用Key Event它会显示错误
Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: java.lang.String cannot be cast to demo.Demo$Employee
at demo.Demo$1.changed(Demo.java:34)
代码:AutoCompleteComboBoxListener.java
package demo;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.control.ComboBox;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
public class AutoCompleteComboBoxListener<T> implements EventHandler<KeyEvent> {
private ComboBox comboBox;
private StringBuilder sb;
private ObservableList<T> data;
private boolean moveCaretToPos = false;
private int caretPos;
public AutoCompleteComboBoxListener(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(AutoCompleteComboBoxListener.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(
AutoCompleteComboBoxListener.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;
}
}
代码:Demo.java
package demo;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
/**
*
* @author vikassingh
*/
public class Demo extends Application {
private final ObservableList<Employee> data
= FXCollections.observableArrayList(
new Employee("Azamat", 2200.15),
new Employee("Veli", 1400.0),
new Employee("Nurbek", 900.5));
@Override
public void start(Stage primaryStage) {
ComboBox<Employee> combobox = new ComboBox<>(data);
new AutoCompleteComboBoxListener<>(combobox);
combobox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Employee>() {
@Override
public void changed(ObservableValue<? extends Employee> arg0, Employee arg1, Employee arg2) {
if (arg2 != null) {
System.out.println("Selected employee: " + arg2.getName());
System.out.println("Salary: " + arg2.getSalary());
}
}
});
StackPane root = new StackPane();
root.getChildren().add(combobox);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
public static class Employee {
private String name;
private Double salary;
@Override
public String toString() {
return name;
}
public Employee(String name, Double salary) {
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:0)
使用以下start()方法替换start()方法并理解代码。
public void start(Stage primaryStage) {
ComboBox<Employee> combobox = new ComboBox<>(data);
new AutoCompleteComboBoxListener<>(combobox);
combobox.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Selected employee: " + combobox.getSelectionModel().getSelectedItem());
System.out.println("Salary: " + combobox.getSelectionModel().getSelectedItem().getSalary());
}
});
combobox.setConverter(new StringConverter<Employee>() {
@Override
public String toString(Employee object) {
if (object == null) return null;
return object.toString();
}
@Override
public Employee fromString(String string) {
Employee employee = new Employee();
for(Employee emp : combobox.getItems()){
if(emp.getName().equals(string)){
employee = emp;
break;
}
}
return employee;
}
});
StackPane root = new StackPane();
root.getChildren().add(combobox);
primaryStage.setScene(new Scene(root, 300, 250));
primaryStage.show();
}
由于您在comboBox中使用了editable true,因此您需要调用上面代码中给出的combobox.setconverter()函数。 我希望它会对你有所帮助。