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

Composants Java Discussion :

JcomboBox éditable dans une JTable


Sujet :

Composants Java

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut JcomboBox éditable dans une JTable
    Bonjour,

    J'ai besoin d'aide sur un problème swing...
    Je souhaite mettre un comboBox 'autocomplétable' dans une JTable.
    J'ai récupéré le code d'une JComboBox autocomplétable mais je n'arrive pas à l'intégrer à ma JTable.


    Ci dessous le code :

    La classe principale (déclaration de la table) et la ComboBox :
    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
     
    import javax.swing.DefaultCellEditor;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.TableColumn;
     
    public class myJCB extends JComboBox{
     
        public myJCB(Object[] pTabObj) {
            super(pTabObj);
            this.setEditor(new myAutoCompleteEditor(this, true));
        }
     
    	public static void main(String[] args)
    	{
    		JFrame f = new JFrame("Table Combo");
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		String[] choix = {"ab", "abc", "ac", "aca", "acb", "ace", "acf", "acft", "acfty", "acfs", "ar", "are", "arez", "b", "bb"};
    		JTable myTable1 = new JTable(2, 2);
     
    		myJCB box1 = new myJCB(choix);
    		box1.setEditable(true);
    		TableColumn maColonne1 = myTable1.getColumnModel().getColumn(0);
    		maColonne1.setCellEditor(new DefaultCellEditor(box1));
    		maColonne1.setHeaderValue("AutoComp");
     
    		JScrollPane myScrollPane = new JScrollPane(myTable1);
    		f.getContentPane().add(myScrollPane);
     
    		f.pack();
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);
    	}
    }
    L'éditeur de la combo :

    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
     
    import java.awt.Component;
    import javax.swing.JComboBox;
    import javax.swing.JTextField;
    import javax.swing.plaf.basic.BasicComboBoxEditor;
     
    /*	 * AutoCompleteEditor.java	 */
    public class myAutoCompleteEditor extends BasicComboBoxEditor
    {
    	private JTextField editor = null;
    	public myAutoCompleteEditor(JComboBox combo, boolean caseSensitive){
    		super();
    		editor = new myAutoCompleteEditorComponent(combo, caseSensitive);
    	}
    	public Component getEditorComponent(){
    		return editor;
    	}
    }
    Et finalement le code que j'ai récupéré pour l'autocomplétion :

    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
     
    import javax.swing.JComboBox;
    import javax.swing.JTextField;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.Document;
    import javax.swing.text.PlainDocument;
     
    /*	 * AutoCompleteEditorComponent.java	 */
    public class myAutoCompleteEditorComponent extends JTextField {
    	JComboBox combo = null;
    	boolean caseSensitive = false;
    	public myAutoCompleteEditorComponent(JComboBox combo, boolean caseSensitive){
    		super();
    		this.combo = combo;
    		this.caseSensitive = caseSensitive;
    	}
    	protected Document createDefaultModel(){
    		return new PlainDocument()
    		{
    			public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
    				if (str == null || str.length() == 0)
    					return;
    				int size = combo.getItemCount();
    				String text = getText(0, getLength());
    				for (int i = 0; i < size; i++) {
    					String item = combo.getItemAt(i).toString();
    					if (getLength() + str.length() > item.length())
    						continue;
    					if (!caseSensitive){
    						if ((text + str).equalsIgnoreCase(item)){
    							combo.setSelectedIndex(i);
    							if (!combo.isPopupVisible())
    								combo.setPopupVisible(true);
    							super.remove(0, getLength());
    							super.insertString(0, item, a);
    							return;
    						}else if (item.substring(0, getLength() + str.length()).equalsIgnoreCase(text + str)){
    							combo.setSelectedIndex(i);
    							if (!combo.isPopupVisible())
    								combo.setPopupVisible(true);
    							super.remove(0, getLength());
    							super.insertString(0, item, a);
    							return;
    						}
    					}else if (caseSensitive){
    						if ((text + str).equals(item)){
    							combo.setSelectedIndex(i);						
    							if (!combo.isPopupVisible()) combo.setPopupVisible(true);
    							super.remove(0, getLength());
    							super.insertString(0, item, a);
    							return;
    						}else if (item.substring(0, getLength() + str.length()).equals(text + str)){
    							combo.setSelectedIndex(i);
    							if (!combo.isPopupVisible()) combo.setPopupVisible(true);
    							super.remove(0, getLength());
    							super.insertString(0, item, a);
    							return;
    						}
    					}
    				}
    			}
    		};
    	}
    }
    Ce code fonctionne bien lorsque le combo n'est pas dans une table mais lorsqu'il est dans la table j'ai une erreur sur l'instruction
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    combo.setPopupVisible(true);
    qui me renvoie l'erreur suivante lorsque je tape une touche :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Exception in thread "AWT-EventQueue-0" java.awt.IllegalComponentStateException: component must be showing on the screen to determine its location
    	at java.awt.Component.getLocationOnScreen_NoTreeLock(Component.java:1680)
    	at java.awt.Component.getLocationOnScreen(Component.java:1654)
    	at javax.swing.JPopupMenu.show(JPopupMenu.java:945)
    	at javax.swing.plaf.basic.BasicComboPopup.show(BasicComboPopup.java:191)
    	at javax.swing.plaf.basic.BasicComboBoxUI.setPopupVisible(BasicComboBoxUI.java:823)
    	at javax.swing.JComboBox.setPopupVisible(JComboBox.java:790)
    	at myAutoCompleteEditorComponent$1.insertString(myAutoCompleteEditorComponent.java:54)
    Lorsque je supprime la ligne qui pose problème je n'ai plus d'erreur mais je ne peux taper qu'un seul caractère à la fois dans le champ. (Il faut que je reclique sur la zone pour pouvoir en saisir un autre...) Lorsque je supprime la ligne combo.setSelectedIndex(i) je peux taper plusieurs caractères (mais la liste ne se positionne pas => normal). J'imagine que l'instruction setSelectedIndex doit rendre le focus à la table.

    Apparemment c'est un problème de focus, j'ai fait plusieurs tests mais je ne maîtrise pas suffisamment Swing ...

    Quelqu'un aurait-il une solution à me proposer ou une piste que je pourrai explorer ?

    RQ : J'ai cru comprendre qu'il existe un composant swingx qui fait ce travail mais je ne souhaite pas ajouter des bibliothèques supplémentaires.

  2. #2
    Membre averti
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2006
    Messages : 11
    Par défaut
    Bonjour,

    Bon je vois que je n'ai pas un franc succès avec mon post ...

    J'ai réussi à "bricoler" quelquechose, je vous mets la solution que j'ai trouvée si ca peut aider certains ou si quelqu'un peut critiquer/donner son avis sur ce que j'ai fait. (ce serait sympa)

    En fait j'ai essayé de bloquer l'appel à fireActionEvent dans la méthode setSelectedItem de la classe JComboBox pour ne pas que la table reprenne le focus.

    1-
    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
     
    import javax.swing.DefaultCellEditor;
    import javax.swing.JComboBox;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.table.TableColumn;
     
    public class myJCB extends JComboBox{
     
    	private boolean tstFAE; //+
     
        public myJCB(Object[] pTabObj) {
            super(pTabObj);
            this.setEditor(new myAutoCompleteEditor(this));//+ 
            tstFAE=true;//+
        }
     
        public void change_tstFAE(boolean pbool){//+
        	this.tstFAE=pbool;//+
        }//+
        protected void fireActionEvent() {//+
        	if(tstFAE) super.fireActionEvent();	//+
        } //+
     
    	public static void main(String[] args)
    	{
    		JFrame f = new JFrame("Table Combo");
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		String[] choix = {"ab", "abc", "ac", "aca", "acb", "ace", "acf", "acft", "acfty", "acfs", "ar", "are", "arez", "b", "bb"};
    		JTable myTable1 = new JTable(2, 2);
     
    		myJCB box1 = new myJCB(choix);
    		box1.setEditable(true);
    		TableColumn maColonne1 = myTable1.getColumnModel().getColumn(0);
    		maColonne1.setCellEditor(new DefaultCellEditor(box1));
    		maColonne1.setHeaderValue("AutoComp");
     
    		JScrollPane myScrollPane = new JScrollPane(myTable1);
    		f.getContentPane().add(myScrollPane);
     
    		f.pack();
    		f.setLocationRelativeTo(null);
    		f.setVisible(true);
    	}
    }
    2-
    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
     
    import java.awt.Component;
    import javax.swing.JComboBox;
    import javax.swing.JTextField;
    import javax.swing.plaf.basic.BasicComboBoxEditor;
     
    /*	 * AutoCompleteEditor.java	 */
    public class myAutoCompleteEditor extends BasicComboBoxEditor
    {
    	private JTextField editor = null;
    	public myAutoCompleteEditor(myJCB combo){
    		super();
    		editor = new myAutoCompleteEditorComponent(combo);
    	}
    	public Component getEditorComponent(){
    		return editor;
    	}
    }
    3-
    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
     
    import javax.swing.JTextField;
    import javax.swing.text.AttributeSet;
    import javax.swing.text.BadLocationException;
    import javax.swing.text.Document;
    import javax.swing.text.PlainDocument;
     
    public class myAutoCompleteEditorComponent extends JTextField
    {
    	myJCB combo = null;
    	boolean caseSensitive = false;
     
    	public myAutoCompleteEditorComponent(myJCB combo)
    	{
    		super();
    		this.combo = combo;
    	}
     
        public void requestFocus() {
            super.requestFocus();
            this.setText("");
        }
     
    	protected Document createDefaultModel()
    	{
    		return new PlainDocument()
    		{
    			public void insertString(int offs, String str, AttributeSet a) throws BadLocationException
    			{
     
    				if (str == null || str.length() == 0)
    					return;
    				int size = combo.getItemCount();
    				String text = getText(0, getLength());
    				for (int i = 0; i < size; i++)
    				{
    					String item = combo.getItemAt(i).toString();
    					if (getLength() + str.length() > item.length())
    						continue;
     
    					if ((text + str).equalsIgnoreCase(item))
    					{
    						combo.change_tstFAE(false);
    						combo.setSelectedIndex(i);
    						combo.change_tstFAE(true);
    						if (!combo.isPopupVisible()) combo.setPopupVisible(true);
    						super.remove(0, getLength());
    						super.insertString(0, item, a);
    						return;
    					}
    					else if (item.substring(0, getLength() + str.length()).equalsIgnoreCase(text + str))
    					{
    						combo.change_tstFAE(false);
    						combo.setSelectedIndex(i);
    						combo.change_tstFAE(true);
    						if (!combo.isPopupVisible()) combo.setPopupVisible(true);
    						super.remove(0, getLength());
    						super.insertString(0, item, a);
    						return;
    					}
    				}
    			}
    		};
    	}
     
     
    }

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

Discussions similaires

  1. Mise à jour JCombobox dans une JTable
    Par badich dans le forum Composants
    Réponses: 3
    Dernier message: 12/06/2013, 11h25
  2. Insérer une JComboBox dans une JTable sous NetBeans ?
    Par khadi8 dans le forum Composants
    Réponses: 1
    Dernier message: 29/04/2012, 17h49
  3. Réponses: 11
    Dernier message: 07/09/2007, 15h11
  4. JComboBox en couleur dans une JTable
    Par ythim dans le forum Composants
    Réponses: 8
    Dernier message: 04/09/2006, 13h23
  5. supprimer un item d'un jcombobox dans une jtable
    Par bellout dans le forum Composants
    Réponses: 6
    Dernier message: 22/06/2006, 16h06

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