title: Autocomplete ComboBox With ID and Value Pair Using Javafx
body: <p>I have tried the below code to create an autocomplete combobox with ID and Value. It's working fine when i select any value using mouse event. But with Key Event it is showing error </p>
  
  <pre><code>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) 
  </code></pre>
  
  <p>Code: AutoCompleteComboBoxListener.java</p>
  
  <pre><code>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&lt;T&gt; implements EventHandler&lt;KeyEvent&gt; {
  
      private ComboBox comboBox;
      private StringBuilder sb;
      private ObservableList&lt;T&gt; 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&lt;KeyEvent&gt;() {
  
              @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&lt;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;
      }
  
  }
  </code></pre>
  
  <p>Code: Demo.java</p>
  
  <pre><code>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&lt;Employee&gt; 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&lt;Employee&gt; combobox = new ComboBox&lt;&gt;(data);
          new AutoCompleteComboBoxListener&lt;&gt;(combobox);
          combobox.getSelectionModel().selectedItemProperty().addListener(new ChangeListener&lt;Employee&gt;() {
  
              @Override
              public void changed(ObservableValue&lt;? extends Employee&gt; 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);
      }
  }
  </code></pre>