2013-10-08 20 views
8

Ho un ComboBox<Perosn> di tipo Person, in cui ho aggiunto qualche oggetto di Person classe,JavaFX modificabile ComboBox: Questa è toString sulla selezione della voce

ho usato setCellFactory(Callback) metodo per mostrare nome della persona in ComboBox discesa

combobox.setCellFactory(
    new Callback<ListView<Person >, ListCell<Person >>() { 
     @Override 
     public ListCell<Person > call(ListView<Person > p) { 
      ListCell cell = new ListCell<Person >() { 
       @Override 
       protected void updateItem(Person item, boolean empty) { 
        super.updateItem(item, empty); 
        if (empty) { 
         setText(""); 
        } else { 
         setText(item.getName()); 
        } 
       } 
      }; 
      return cell; 
     } 
    }); 

E, setButtonCell(ListCell) metodo per mostrare il nome in combobox sulla selezione.

combobox.setButtonCell(
    new ListCell<Object>() { 
     @Override 
     protected void updateItem(Person t, boolean bln) { 
      super.updateItem(t, bln); 
      if (bln) { 
       setText(""); 
      } else { 
       setText(t.getName()); 
      } 
     } 
    }); 

Questo funziona perfettamente con il caso normale, ma quando uso combobox modificabile, questo non riesce.

Quando scrivo, combobox.setEditable(true); quindi sulla selezione dell'oggetto il campo di testo (editor) della casella combinata mostra il metodo toString() della classe persona.

Caso normale: Normal Case

Caso modificabile: Editable Case

C'è qualche soluzione per questo ??

ho una classe del modello,

public class Person { 
    String name; 
    int age; 

    public String getName() { 
     return name; 
    } 

    public void setName(String name) { 
     this.name = name; 
    } 

    public int getAge() { 
     return age; 
    } 

    public void setAge(int age) { 
     this.age = age; 
    } 

    @Override 
    public String toString() { 
     return "Person{" + "name=" + name + ", age=" + age + '}'; 
    } 
} 

risposta

11

Ecco una risposta alla mia domanda che ho trovato migliore dopo molti sforzi e correzioni.

mainComboBox.setButtonCell(
    new ListCell<Object>() { 
     @Override 
     protected void updateItem(Object t, boolean bln) { 
      super.updateItem(t, bln); 
      if (bln) { 
       setText(""); 
      } else { 
       setText(getStringField(t)); 
      } 
     } 
    }); 

mainComboBox.setConverter(
    new StringConverter() { 
     private Map<String, Object> map = new HashMap<>(); 

     @Override 
     public String toString(Object t) { 
      if (t != null) { 
       String str = getStringField(t); 
       map.put(str, t); 
       return str; 
      } else { 
       return ""; 
      } 
     } 

     @Override 
     public Object fromString(String string) { 
      if (validate && !map.containsKey(string)) { 
       mainComboBox.setValue(null); 
       mainComboBox.getEditor().clear(); 
       return null; 
      } 
      return map.get(string); 
     } 
    }); 

mainComboBox.setCellFactory(
    new Callback<ListView<Object>, ListCell<Object>>() { 
     @Override 
     public ListCell<Object> call(ListView<Object> p) { 
      ListCell cell = new ListCell<Object>() { 
       @Override 
       protected void updateItem(Object item, boolean empty) { 
        super.updateItem(item, empty); 
        if (empty) { 
         setText(""); 
        } else { 
         setText(getStringField(item)); 
        } 
       } 
      };return cell; 
     } 
    }); 

E con funzione richiesta di getStringField(Object),

public String getStringField(Object o) { 
    return ((Pesron) o).getName(); 
} 
+1

Hai guardato la mia risposta che dà la soluzione giusta ed è stato postato 1 ora dopo la tua domanda è stata presentata? – Sebastian

15

È necessario impostare un StringConverter sulla casella combinata a tale scopo (non c'è altro modo, guardando il codice sorgente del ComboBox)

Ecco un esempio:

import javafx.application.Application; 
import javafx.scene.Group; 
import javafx.scene.Scene; 
import javafx.scene.control.Button; 
import javafx.scene.control.ComboBox; 
import javafx.stage.Stage; 
import javafx.util.StringConverter; 

import java.util.Arrays; 
import java.util.List; 

public class ComboBoxTest extends Application { 
    private ComboBox<Integer> cmb_year = new ComboBox<>(); 

    public static void main(String[] args) { 
     launch(args); 
    } 

    @Override 
    public void start(Stage primaryStage) throws Exception { 
     Group root = new Group(); 
     root.getChildren().add(cmb_year); 
     cmb_year.setPrefWidth(150); 
     Scene scene = new Scene(root, 500, 500); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 

     List<Integer> ints = Arrays.asList(2012, 2013, 2014, 2015); 
     cmb_year.getItems().addAll(ints); 

     cmb_year.setConverter(
      new StringConverter<Integer>() { 
       @Override 
       public String toString(Integer integer) { 
        if (integer == null) { 
         return ""; 
        } else { 
         return "that's a year: " + integer.intValue(); 
        } 
       } 

       @Override 
       public Integer fromString(String s) { 
        try { 
         return Integer.parseInt(s); 
        } catch (NumberFormatException e) { 
         return null; 
        } 
       } 
      }); 

     cmb_year.setPromptText("select year"); 
     cmb_year.setEditable(true); 

     Button distraction = new Button("distraction"); 
     distraction.setLayoutX(100); 
     distraction.setLayoutY(100); 
     root.getChildren().add(distraction); 
    } 
} 

risultato:

enter image description here enter image description here

Problemi correlati