IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaFX Discussion :

ComboBox : Récupérer l'objet correspondant à la sélection.


Sujet :

JavaFX

  1. #1
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2011
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2011
    Messages : 67
    Points : 87
    Points
    87
    Par défaut ComboBox : Récupérer l'objet correspondant à la sélection.
    Bonjour,

    J'utilise une ComboBox pour pouvoir sélectionner un objet en DB. Je passe donc par un objet "ComboBoxChoice" qui encapsule simplement l'ID de l'objet ainsi qu'un CODE lisible qui permet à l'utilisateur de l'identifier.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    @FXML
    private ComboBox<ComboBoxChoice> colDomain;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    public class ComboBoxChoice {	
    	private Integer id; 
    	private String displayString;
     
    	public ComboBoxChoice(Integer id, String displayString){
    	this.id = id;
    	this.displayString = displayString;
    	}
     
    	public Integer getId() {
    		return id;
    	}
     
    	public void setId(Integer id) {
    		this.id = id;
    	}
     
    	public String getDisplayString() {
    		return displayString;
    	}
     
    	public void setDisplayString(String displayString) {
    		this.displayString = displayString;
    	}
     
    	@Override
    	public String toString(){
    		return "AAA" +displayString;
    	}
    }
    Je peuple donc mon ComboBox.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    List<ComboBoxChoice> choices = defDomainDAO.getAllComboBoxChoices();
    colDomain.setItems(FXCollections.observableArrayList(choices));

    Pourtant lorsque j'appelle cette méthode, alors que mon IDE me dit bien que getSelectedItem() doit me renvoyer un objet de type ComboBoxChoice, en déguggant, je me rends compte que je reçoit un objet de type String et cela provoque une erreur au Runtime.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ComboBoxChoice c = colDomain.getSelectionModel().getSelectedItem();
    Et si j'essaye de récupérer la valeur dans un String, c'est évidemment mon compilateur qui râle ...

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    String s = colDomain.getSelectionModel().getSelectedItem();
    Est-ce que quelqu'un a une idée d'où vient le problème ?

    Bien à vous.

    Lionel

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 867
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 867
    Points : 22 924
    Points
    22 924
    Billets dans le blog
    52
    Par défaut
    Si tu recois un objet String, c'est qu'à priori ta combo en contient. Tu devrais donc vérifier les valeurs retournées par ces appels, nottament ce que retourne réellement la première ligne :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    List<ComboBoxChoice> choices = defDomainDAO.getAllComboBoxChoices();
    colDomain.setItems(FXCollections.observableArrayList(choices));
    Comme les generics Java ne force le type qu'avant la compilation et pas du tout à l'éxécution, il est quand même possible que ta couche qui accède à la BD te produise une List<String> même si ce n'est pas sensé être le cas.

  3. #3
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2011
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2011
    Messages : 67
    Points : 87
    Points
    87
    Par défaut
    Merci pour cette info sur les generics, je ne connaissais pas cette subtilité.

    Malheureusement le souci ne vient pas de là

    Puisque ma liste choices contient bien les bons objets



    Et ensuite le liste observable contenue par la ComboBox contient aussi les bons objets




    Ca reste donc un mystère.

  4. #4
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 867
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 867
    Points : 22 924
    Points
    22 924
    Billets dans le blog
    52
    Par défaut
    Hum, dans ce cas je ne vois pas trop. Ce cas de figure ne devrait pas se produire.

    Je ne suis pas habitue au débogueur d'Eclipse, essaie quand même de voir plus en avant dans la ComboBox ce que contient effectivement la liste interne (2nd écran) puisque ici on ne voit que des valeurs textuelles.

    La ligne ou tu retires l'objet sélectionné est placée immédiatement après le remplissage de la combo ou ailleurs dans un listener ?
    Vérifie également, au cas ou, si tu n'aurais pas une seconde combo nommée a l'identique déclarée en variable locale (ou au contraire en variable globale) et sur laquelle tu attacherais ton ChangeListener.

  5. #5
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2011
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2011
    Messages : 67
    Points : 87
    Points
    87
    Par défaut
    En fait je n'utilise pas de Listener.

    Ma ComboxBox est peuplée à l'ouverture d'un panel, et j'essaye simplement de récupérer sa valeur lorsque j'appuie sur un bouton "Save".


    J'ai bien vérifié qu'il n'y a pas d’ambiguïté avec le nom d'une autre variable. Les lignes de codes que j'ai données sont les seules à interagir avec ce ComboBox dans tout mon controlleur.

    Je vais approfondir l'inspection avec le débogueur car en effet, ce que tu me suggères semble être la seule explication valable.

    J'ai pensé un moment que ça pouvait venir de mon FXML, car par défaut le SceneBuilder place toujours dans un ComboBox quelques valeurs statiques (Item 1, 2, 3), ce qui aurait pu "forcer" le type générique du ComboBox en ComboBox<String> en lieu et place d'un ComboBox<ComboBoxChoice> comme défini dans mon controlleur.

    Mais ce n'est visiblement pas le cas puisque j'ai toujours le problème en ayant remplacé dans mon FXML


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    <ComboBox fx:id="colDomain" editable="true" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">              
       <items>
                    <FXCollections fx:factory="observableArrayList">
                      <String fx:value="Item 1" />
                      <String fx:value="Item 2" />
                      <String fx:value="Item 3" />
                    </FXCollections>
        </items>
    </ComboBox>
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <ComboBox fx:id="colDomain" editable="true" prefWidth="200.0" GridPane.columnIndex="1" GridPane.rowIndex="1">
     
    </ComboBox>

  6. #6
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2011
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2011
    Messages : 67
    Points : 87
    Points
    87
    Par défaut
    Je viens de trouver la solution.

    Au lieu de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ComboBoxChoice c = colDomain.getSelectionModel().getSelectedItem();
    il suffit de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ComboBoxChoice c = colDomain.getValue();
    Comme toujours dans ce genre de cas, je me sens idiot.

    Enfin, il reste quand même un mystère, c'est pourquoi pour la première méthode, le typage au Buildtime n'est pas le même que celui au Runtime ... Si quelqu'un trouve, ça reste intéressant ! C'est pour celà que je ne met pas le sujet en "résolu"

    Lionel

  7. #7
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 867
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 867
    Points : 22 924
    Points
    22 924
    Billets dans le blog
    52
    Par défaut
    Effectivement, j'avais oublié les valeurs par défaut rajoutées par SceneBuilder qui sont des chaines (je les enlève toujours manuellement du FXML) même si ça ne joue pas ici.

    Hum... mouai bizarre... je n'ai jamais rencontré ce problème et cette difference de comportement. Ceci dit il y a pas mal de requêtes concernant ComboBox sur le Jira et pourtant je n'ai jamais rencontre la quasi-totalité des bugs listés.

  8. #8
    Membre régulier
    Homme Profil pro
    Développeur Java
    Inscrit en
    Novembre 2011
    Messages
    67
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Finance

    Informations forums :
    Inscription : Novembre 2011
    Messages : 67
    Points : 87
    Points
    87
    Par défaut
    Je viens d'affiner ma compréhension du problème.

    En fait c'est un "hasard" si la ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ComboBoxChoice c = colDomain.getValue();
    M'a bien renvoyé l'objet attendu.

    En réalité, je recevais une String parce que ma ComboBox était en mode editable=true

    Dans ce cas, l'utilisateur est donc suceptible de taper n'importe quoi dans la ComboBox et donc la valeur retournée est bel et bien un String. En réalité le typage <T> ne permet (dans ce cas) que de typer les objets qui vont venir dynamiquement peupler la ComboBox.

    Si je la met en editable=false, le seul moyen de peupler la ComboBox étant de le faire via le code, et bien on est sûr qu'elle ne contient que des objets de type <T>.

    Voilà, c'est l'explication la plus "fine" que j'ai à ce sujet.

    Lionel

  9. #9
    Membre régulier
    Femme Profil pro
    Développeur Java
    Inscrit en
    Août 2013
    Messages
    61
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Août 2013
    Messages : 61
    Points : 105
    Points
    105
    Par défaut
    Ah et ça expliquerait bien les "ralâges" décalés entre le String c et le ComboBoxChoice c .. dans un cas il râle effectivement car il sait qu'il doit te renvoyer une ComboBoxChoice, dans l'autre il râle car en pratique il te renvoyait une String...

    En tout cas merci, c'est ce genre de tirbouchonnage de cerveau qui font que j'aime programmer

  10. #10
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 867
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 48
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 867
    Points : 22 924
    Points
    22 924
    Billets dans le blog
    52
    Par défaut
    Ah oui effectivement. Je n'avais pas envisage ce cas de figure car je n'ai pas de combo éditables et je ne me suis jamais penche sur le cas de cellules editor.

    Mais le fond du problème est le même : les generics n'imposent pas le type lors de l’exécution, uniquement a la compilation.

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Développeur Java
    Inscrit en
    Décembre 2013
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java
    Secteur : Associations - ONG

    Informations forums :
    Inscription : Décembre 2013
    Messages : 49
    Points : 39
    Points
    39
    Par défaut
    Bonjour, je fais quelque chose comme ça pour avoir un ID numérique:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
     
    //Remplir la combo
    public void crearComboInteger(final String comboTabla, String strPosicion, final String strColumna, final String strId, String strConsulta){
    		String sSQL="SELECT "+strId+", "+strColumna+" FROM "+ strConsulta +" ORDER BY "+strColumna;	
    		final JComboBox combo = new JComboBox ();	
    		ComboLlenar comboInteger = new ComboLlenar();
    		comboInteger.llenarInteger(combo, strId, strColumna, strId, sSQL);
    		combo.setToolTipText("Seleccione un valor en la lista o escriba uno nuevo...");
    		combo.setName(strTabla);
    		combo.setActionCommand(strSQL);
    		combo.setEditable(true);
    		final ComboAutoNoEstricto comboAuto  = new ComboAutoNoEstricto(combo);
    		combo.getEditor().getEditorComponent().addFocusListener(new FocusListener(){
    			private String strMsgContenido ="";
    			private String strMsgTitulo="Aviso de nuevos datos";
    			private String strNuevo="";
    			public void focusGained(FocusEvent e) {			}
    			public void focusLost(FocusEvent e) {
    //***MUY IMPORTANTE
    			if ((comboAuto.getEstatus() == false) && (combo.getSelectedItem()!= null)) {
    				strNuevo= combo.getSelectedItem().toString();
    				strMsgContenido = "<html>El dato: <font color=red><b><u>" + strNuevo + "</u></b></font> no existe. "+
    							 		"¿Quiere agregarlo? <br><br>Verifique que está escrito correctamente antes de agregarlo.</html>" ;
    				strTabla=combo.getName();
    				if (Mensajes.verSiNo(strMsgContenido, strMsgTitulo) == JOptionPane.YES_OPTION){
    //Ouvre una deuxi�me f�netre pour ajouter les donn�es. 
    					new frmAgregarDosCampos(strNuevo, strTabla).setVisible(true);
     
    /*Ici je voudrais retourner a ma f�netre originale, actualiser la combobox et recuperer son Id avec:
    					intMapa.put(strTabla,agregar.getIdEntero()); */
    					//					AgregarSimple agregar = new AgregarSimple(combo.getName(), strColumna, combo.getSelectedItem().toString());
    //					intMapa.put(strTabla,agregar.getIdEntero());
    					}
    				}
    				if ((comboAuto.getEstatus() == true) && (combo.getSelectedItem()!= null) ) {
    				Couple intId = (Couple)combo.getSelectedItem();	
    						intMapa.put(strTabla,(Integer) intId.getPremier());
    					}
    				else{
    					System.out.println("Insertar el valor : "+ combo.getSelectedItem() + " en columna :" + strTabla);		
    				}
    			}
    La classe qui remplit ma combo a cette méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    		public void llenarInteger(JComboBox combo, String campoID, String campoDato,  String strToolTip, String strSQL) {
     
    		AdminBD db =  new AdminBD();
            ResultSet rst = db.getRst(strSQL);
            db.cerrarConexion();
            System.out.println("****"+strSQL);
        	try {
                while (rst.next()) {
                	combo.addItem (new Couple <Integer, String, String>(rst.getInt(campoID), rst.getString(campoDato),strToolTip+rst.getString(campoDato))); 
    //            	combo.addItem (new IdMasNombre <Integer, String>(rst.getInt(campoID), rst.getString(campoDato))); 
    //            	combo.addItem (new Couple <Integer, String, String>(rst.getLong(campoID), rst.getString(campoDato),strToolTip)); 
     
                	System.out.println("****"+rst.getInt(campoID)+ rst.getString(campoDato)+strToolTip);
    //            	combo.addItem (new DatoIDint (rst.getInt(campoID), rst.getString(campoDato), strToolTip+rst.getString(campoDescr))); 
    //System.out.println(rst.getString(strDato)+rst.getInt(strID));
                }
                rst.close();
                combo.setRenderer(new ComboIntegerRenderer());
                combo.setSelectedIndex(-1);
        	} catch (Exception ex) {
     //           System.out.println(ex.getMessage());
        		}
        	db.cerrarConexion();
     
    	}
    Et ma classe Couple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
     
    public class Couple<T, U, V> {
    private T x;
    private U y;
    private V z;
     
    public Couple (T premier, U second, V descr){
    	x = premier; y=second;z=descr;
    }
    public T getPremier(){
    	return x;
    }
     
    public U getSecond(){
    	return y;
    }
    public V getDescr(){
    	return z;
    }
    public void affiche(){
    	System.out.println("1er: "+ x + " * 2me: "+ y);
    }
    public String toString()
    {
    	return (String) y; //"NomId [nom=" + nom + ", id=" + id + "]";
    } 
     
    }
    //long lngId, String strDato, String strDescr
    C'est du Swing, mais je pense que ça pourrais servir pour du JavaFX?

    Je ne sais pas si cela pourrais aider

Discussions similaires

  1. Réponses: 2
    Dernier message: 24/11/2008, 10h53
  2. [JComboBox] Récupérer l'objet sélectionné
    Par Terminator dans le forum Composants
    Réponses: 3
    Dernier message: 14/09/2005, 12h29
  3. Récupérer un objet d'une liste déroulante
    Par Hell dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/01/2005, 14h59
  4. [servlet][bean]comment récupérer l'objet request
    Par otminou dans le forum Servlets/JSP
    Réponses: 3
    Dernier message: 27/09/2004, 14h40
  5. Réponses: 4
    Dernier message: 15/09/2004, 16h52

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo