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

AWT/Swing Java Discussion :

Comment faire un [CellEditor] personnalisable


Sujet :

AWT/Swing Java

  1. #1
    Membre éclairé Avatar de grabriel
    Inscrit en
    Septembre 2006
    Messages
    946
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 946
    Par défaut Comment faire un [CellEditor] personnalisable
    Bonjour,

    Ca fait un bout de temps que je bloque la dessus, au début je pensais que c'était tout simple mais, plus ca va plus et moins j'y arrive....

    Ca que je voudrais faire c'est un cellEditor personnalisable, les seules exemple que j'ai trouvé c'est des colorchooser. J'ai essayé de décliner le principe mais ca marche po!!!

    Est-ce que quelqu'un à un exemple sous la main, voir la solution .

    Sur le principe c'est la même chose que le colorchooser, suite à une action clique sur la cellule un dialog s'ouvre me proposant la couleur que je veux avec la couleur que j'ai déjà en surbrillance je choisi une autre couleur je valide et mon dialog se ferme et ma cellule est à jour avec la nouvelle couleur. Sauf que moi au lieu des couleurs je veux saisir un texte en appuyant sur entrée une fenêtre s'ouvre et je peux choir d'autres valeurs prochent de ce que j'ai déjà tapé dans la cellule, je valide mon choix le dialog se ferme et mon tableau affiche la valeur.

    Si c'est trop complexe ou si une autre solution existe je suis preneur.

    MERCI

  2. #2
    Membre éclairé Avatar de grabriel
    Inscrit en
    Septembre 2006
    Messages
    946
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 946
    Par défaut
    AAAahhhhhh au secours!!!

    Quelqu'un à une idée, une piste (un lien, même une vague idée), plus de renseignements de ma part??

    A votre bon coeur!!

  3. #3
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Bonjour,

    As-tu été voir du côté de SwingX pour l'autocomplétion ?
    [EDIT] Désolé, je n'y ai pas pensé lors de notre dernière discussion.
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  4. #4
    Membre éclairé Avatar de grabriel
    Inscrit en
    Septembre 2006
    Messages
    946
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 946
    Par défaut
    J'use et j'abuse déjà de swingx mais pour ce que je voudrais faire ca rentre pas dans le moule de l'autocomplit....

    je veux saisir un texte en appuyant sur entrée une fenêtre s'ouvre et je peux choisir d'autres valeurs prochent de ce que j'ai déjà tapé dans la cellule, je valide mon choix le dialog se ferme et mon tableau affiche la valeur.
    C'est pour un programme comptable et si le client saisie un libelle de compte et valide je voudrais dans la fenêtre qui s'ouvre des comptes qui contiennent le mot saisie pas seulement qui commencent par celui-ci... par exemple si le client saisie hon ca peut etre pour rechercher le compte honoraires comme pour retrouver le client Honduras ou Chonponplon. C'est pour ca que le principe du colorchooser me semblait plus approprié.

  5. #5
    Membre Expert
    Homme Profil pro
    Directeur technique
    Inscrit en
    Janvier 2007
    Messages
    1 348
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 49
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Directeur technique

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 348
    Par défaut
    Qu'est-ce qui ne marche pas dans l'adaptation que tu as faite ?

  6. #6
    Membre éclairé Avatar de grabriel
    Inscrit en
    Septembre 2006
    Messages
    946
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 946
    Par défaut
    Qu'est-ce qui ne marche pas dans l'adaptation que tu as faite ?
    Un peu tout, au niveau de la détection de la touche entrée pour choisir le compte, le fait que je ne récupère pas la valeur courante de la cellule puisque le focus est toujours dessus (stopcellediting), j'ai aussi du mal pour récupérer correctement la valeur choisie... j'ai posté pour les deux premiers problèmes, mais ca reste instable et un peu bricolé sur l'ensemble.

    J'ai trouvé un autre tuto qui à l'air plus simple je suis actuellement dessus.
    http://www.iam.ubc.ca/guides/javatut...orchooser.html

    Si vous avez d'autres liens je suis preneur.

    MERCI.

  7. #7
    Membre Expert
    Avatar de xavlours
    Inscrit en
    Février 2004
    Messages
    1 832
    Détails du profil
    Informations forums :
    Inscription : Février 2004
    Messages : 1 832
    Par défaut
    Bon, et en faisant un truc du style :
    - enlever l'entrée de l'inputmap liée à entrée sur la JTable (ce que tu as déjà fait, et fallait y penser)
    - créer une classe héritant de JTextField qui utilise un ActionListener pour afficher un JPopupMenu (lorsqu'on appuie sur entrée), un DocumentListener pour mettre à jour le ListModel de la JList contenue dans le JPopupMenu et un ListSelectionListener sur la JList pour cacher le JPopupMenu et changer le texte du JTextField ?
    - si le traitement de la JList est long, penser à utiliser un Thread ou un SwingWorker et une JProgressBar.

    Ensuite, tu mets ceci en paramètre d'un DefaultCellEditor.
    Ca me donne envie de coder, tout ça.
    "Le bon ni le mauvais ne me feraient de peine si si si je savais que j'en aurais l'étrenne." B.V.
    Non au langage SMS ! Je ne répondrai pas aux questions techniques par MP.
    Eclipse : News, FAQ, Cours, Livres, Blogs.Et moi.

  8. #8
    Membre éclairé Avatar de grabriel
    Inscrit en
    Septembre 2006
    Messages
    946
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 946
    Par défaut
    Merci pour toute l'analyse, je suis toujours pas arrivé au traitement des jlist mais ca va m'éviter de partir sur des trucs bancales et m'arracher les cheveux.

    Ca me donne envie de coder, tout ça.
    J'ai entendu et jaimerai tellement te faire plaisir en te laissant code tout ca!!!!

    Je mettrai mon code final en ligne dès que tout ça sera fini (j'espère bientôt).

  9. #9
    Membre éclairé Avatar de grabriel
    Inscrit en
    Septembre 2006
    Messages
    946
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 946
    Par défaut
    Bon j'ai fini y'a un bout de temps (pas trop long comme meme) mais j'ai pas pris le temps de mettre le code pour ceux et celles que ca pourrai intéresser, je ne sais pas si c'est la meilleur solution mais au moins elle a le mérite de fonctionner.
    On commence par la création de la table avec un model classique :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    final JTable tableSaisie = new JTable(new MonTableModel());
    Suivant qu'on double clique sur la cellule ou qu'on saisisse une fois que le focus est sur la cellule, la touche entrée n'est pas détectée.

    Donc pour le premier cas "double clique pour éditer la cellule puis saisie", je crée un editor à partir d'un JTextField avec un document listener qui lance un popup dès qu'on presse la touche entrée.

    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
    //applique un editor sur la colonne
     
    		final JTextField textfield = new JTextField();
    		textfield.getDocument().addDocumentListener(new DocumentListener() {
     
    			public void changedUpdate(DocumentEvent e) {printText(e);}
    			public void insertUpdate(DocumentEvent e) {printText(e);}
    			public void removeUpdate(DocumentEvent e) {printText(e);}
     
    			private void printText(DocumentEvent e) {
    				//détecte si entrée
    				textfield.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),"check");
    		        textfield.getActionMap().put("check", new AbstractAction() {
    		        	public void actionPerformed(ActionEvent e) {
    		        		fenetrePopUp(panel, textfield, tableSaisie);
    		        	}
    		        });
    			}
    		});
     
    		DefaultCellEditor editor = new DefaultCellEditor(textfield);
    		tableSaisie.getColumnModel().getColumn(MonTableModel.MA_COL).setCellEditor(editor);
    La j'enleve le comportement normal de la touche entrée qui est de passer d'une cellule à l'autre et je lui demande d'afficher le PopUp :

    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
     
    //      Enleve le comportement normal de la touche entrée
            InputMap inputMap = (InputMap)UIManager.get("Table.ancestorInputMap");
            inputMap.remove(KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_ENTER, 0));
     
    final Action rechercheCompte = new AbstractAction() {
    			public void actionPerformed(ActionEvent e) {
    				if (tableSaisie.getEditingColumn() == MonTableModel.MA_COL){
    					fenetrePopUp(panel, textfield, tableSaisie);
    				}
    			}
    		};
     
            tableSaisie.getInputMap().put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0),"ENTREE");
            tableSaisie.getActionMap().put("ENTREE", rechercheCompte);
    La méthode qui lance la fenetrePopUp et qui met à jour la cellule de la table :
    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
    43
    44
    45
    46
    /**
             * Lance le navigateur des comptes et met la cellule de la table à jour
             * @param panel
             * @param textfield
             * @param tableSaisie
             */
    	public static void fenetrePopUp(JPanel panel, JTextField textfield, JTable tableSaisie){
    //		recup la frame
    		JFrame laFrame = ActionUtils.recupFrame(panel);
     
    		//recup la colonne et la ligne editée
    		int row = tableSaisie.getSelectedRow();
    		int col = tableSaisie.getSelectedColumn();
     
    		//Stop l'edition pour pouvoir récupérer le contenu de la cellule
    		tableSaisie.getCellEditor().stopCellEditing();
     
    		String value = "";
     
    		//recup de la valeur saisie
    		if (row != -1 || col != -1){
    			value = tableSaisie.getModel().getValueAt(row, col).toString();
    ActionUtils.echo("recup de la valeur saisie" + value);			
    		}
     
    		//reédite la cellule
    		tableSaisie.editCellAt(row, col);
     
    		//affiche le pop up
    		DialogueNavigueCompte cnd = new DialogueNavigueCompte(laFrame, "Sélectionnez un compte", true, value.toUpperCase());
    		cnd.setVisible(true);
    		cnd.pack();
     
    		String libelle = "";
     
    		Object [] retour = cnd.getDonnees();
     
        	if (retour != null){
        		libelle = retour[0].toString();
     
        		//met à jour la valeur de la cellule
        		textfield.setText(libelle);
        		//edite la colonne suivante
        		tableSaisie.editCellAt(row, col+1);
        	}
    	}
    La ou j'ai pas mal galéré c'était pour comprendre le pourquoi je n'arrivais pas à récupérer la valeur de la cellule saisie et après pourquoi je n'arrivais pas à la mettre à jour.
    La solution est si on récupère la valeur d'une cellule en cours d'édition, on récupère pas la valeur éditée mais son ancienne valeur, il faut arréter l'édition de la cellule pour pouvoir récupérer sa valeur avec stopCellEditing(). Et après avoir récupéré sa valeur, la rééditer pour mettre la valeur sélectionnée dans le pop-up dedans.

    J'espère que ça aidera quelqu'un sinon je me serai fait ch*** à poster ce message pour rien.


    j'ai failli oublier mon dialogue qui liste les valeurs (ici gère des comptes comptable) :

    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
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
     
    public class DialogueNavigueCompte extends JDialog{
    	String libelleCompte = "";
    	DaoCompte daoCompte = new DaoCompte();
    	JList JlistCompte;
    	JFrame fenetre;
     
    	public DialogueNavigueCompte(JFrame f, String titre, boolean modal, String libelleCompte){
    		super(f,titre, modal);
    		Init(libelleCompte);
    		this.fenetre = f;
    	}
     
    	// récupère les données mises à jour par la boîte de dialogue
    	public Object [] getDonnees(){
    		return new Object[]{libelleCompte};
    	}
     
    	/**
             * Action du bouton Annuler
             * @param e
             */
    	void jButtonCANCEL_actionPerformed(ActionEvent e) {
    	     setVisible(false);
    	}
     
    	/**
             * Action du bouton OK
             * @param e
             */
    	void jButtonOK_actionPerformed(ActionEvent e) {
    		if (JlistCompte.getSelectedValue() != null){
    		     libelleCompte = JlistCompte.getSelectedValue().toString();
    		     if (libelleCompte.equals("Créer un nouveau compte")){
    		    	 libelleCompte = "";
    		    	 DialogueCreateCompte dcc = new DialogueCreateCompte(fenetre, "Création de compte", true,"");
    		    	 dcc.pack();
     
    		    	 //créer le compte et renvoie le libelle
    		    	 String libelle = "";
    		    	 String numero = "";
    				 boolean achat = false;
    				 boolean vente = false;
    				 boolean treso = false;
     
    				 dcc.setVisible(true);
     
    				 Object [] retour = dcc.getDonnees();
     
    				if (retour != null){
    					libelle = retour[0].toString();
    					numero = retour[1].toString();
    					achat = (Boolean)retour[2];
    					vente = (Boolean)retour[3];
    					treso = (Boolean)retour[4];
     
    					if (!numero.equals("") && !numero.equals("0")){
    						int result = 1;
    						try {
    							result = Comptes.creeCompte(libelle, numero, achat, vente, treso);
    						} catch (BusinessException be) {
    							Erreurs.Warning(be);
    						}
    						if (result == 0){
    							libelleCompte = libelle;
    						}
    					}
    				}
    		     }
    			 setVisible(false);
    		}
    	}
     
    	/**
             * Gère l'interface pour le choix du compte
             * @param libelleCompte
             */	
    	private void Init(String libelleCpt) {
    		JPanel panelChoix = new JPanel();
    		panelChoix.setLayout(new GridBagLayout());
    		JButton jbtAnnuler = new JButton("Annuler");
    		jbtAnnuler.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent ev) {
    				jButtonCANCEL_actionPerformed(ev);
    			}
    		});
    		JButton jbtOk = new JButton("Sélectionner");
    		jbtOk.addActionListener(new ActionListener(){
    			public void actionPerformed(ActionEvent ev) {
    				jButtonOK_actionPerformed(ev);
    			}
    		});
    		//affiche les comptes qui commencent par libelleCompte
    		List<Compte> listeCompte = new ArrayList<Compte>();
    		//si le libelleCpt est un entier rechercher tous les comptes qui commencent
    		//avec ce numéro
    		try{
    			@SuppressWarnings("unused")
    			int numCpt = Integer.parseInt(libelleCpt);
    			try {
    				listeCompte = daoCompte.getAllComptesByNumero(libelleCpt);
    			} catch (BusinessException be) {
    				Erreurs.Warning(be);
    			}
    		}catch(NumberFormatException ne){
    			try {
    				listeCompte = daoCompte.getAllComptesByLibelle(libelleCpt);
    			} catch (BusinessException be) {
    				Erreurs.Warning(be);
    				be.printStackTrace();
    			}
    		}
     
    		String[] listeLibelleCompte = new String[listeCompte.size()+1];
    		int i = 0;
    		for (Compte unCompte : listeCompte){
    			listeLibelleCompte[i] = unCompte.getLibelle()+" ["+unCompte.getNumero()+"]";
    			i++;
    		}
     
    		//Ajouter le compte créer un compte
    		listeLibelleCompte[i] = "Créer un nouveau compte";
     
    		JlistCompte = new JList(listeLibelleCompte);
    		if (listeLibelleCompte.length>0){
    			JlistCompte.setSelectedIndex(0);
    		}
    		//ajoute un keylistener pour valider la sélection avec entrée 
    		//et fermer la fenetre avec echap 
    		JlistCompte.addKeyListener(new KeyListener(){
    			public void keyPressed(KeyEvent arg0) {}
    			public void keyReleased(KeyEvent arg0) {}
     
    			public void keyTyped(KeyEvent ev) {
    				if (ev.getKeyChar() == KeyEvent.VK_ENTER){
    					jButtonOK_actionPerformed(null);
    				}
     
    				if (ev.getKeyChar() == KeyEvent.VK_ESCAPE){
    					jButtonCANCEL_actionPerformed(null);
    				}
    			}			
    		});
     
    		panelChoix.add(new JScrollPane(JlistCompte), new GBC(0,0,1,2));
     
    		panelChoix.add(jbtOk, new GBC(1,0));
    		panelChoix.add(jbtAnnuler, new GBC(1,1));
     
    		//positionner le jdialog
    	    setLocation(200, 100);
     
    	    this.setPreferredSize(new Dimension(450,200));
    	    this.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    	    this.setResizable(false);
    	    this.pack();
    	    this.add(panelChoix);
    	}
    }
    et le petit disclaimer qui va bien : j'ai modifié le code pour qu'il soit affichable ici j'ai peut etre fait des erreurs en recopiant donc je ne peux pas garantir que le code fonctionne tel quel.

    Et un grand merci à tout ceux qui m'ont aidé.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 3
    Dernier message: 24/08/2011, 14h06
  2. Réponses: 3
    Dernier message: 03/06/2011, 10h44
  3. comment faire une ihm personnalisable
    Par djedjeyop dans le forum Général Python
    Réponses: 7
    Dernier message: 31/01/2010, 19h35
  4. Comment faire pour mettre l'ecran en veille ?
    Par March' dans le forum MFC
    Réponses: 6
    Dernier message: 29/08/2002, 14h25
  5. Comment faire pour créer un bitmap
    Par GliGli dans le forum C++Builder
    Réponses: 2
    Dernier message: 24/04/2002, 15h41

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