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 :

Bug affichage Jpanel (contenant JButton) dans une JTable


Sujet :

Composants Java

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 56
    Points : 59
    Points
    59
    Par défaut Bug affichage Jpanel (contenant JButton) dans une JTable
    Amis du soir bonsoir,
    j'ai une JTable alimentée par une base de données. Chaque ligne est dotée en fin de ligne des boutons "Valider", "Annuler" et "Supprimer".



    Le bouton "Annuler" doit s'allumer quand on modifie une des cellules de la ligne correspondante, si on clique c'est la ligne d'origine qui revient.
    EN code, il récupère l'identifiant de la ligne modifiée, supprime cette ligne, recherche dans les résultats (ResultSet) de la requête d'origine la ligne correspondant à l'identifiant récupéré, et réinsère cette ligne au même endroit dans la JTable.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    private void Annuler (java.awt.event.ActionEvent ae) {
    		int numLigne = Ppal.TableR.getSelectedRow();
    		long idPiece = (long)Ppal.TableR.getValueAt (Ppal.TableR.getSelectedRow(), 0);
    		Piece pieceOriginale = Ppal.getPieceRequete (idPiece);
    		Ppal.philaTM.Supprimer (numLigne);
    		Ppal.philaTM.Inserer (numLigne, pieceOriginale);
    }
    Déjà je me demande si c'est un bon procédé, je ne sais pas s'il y a d'autres techniques.
    En tout cas ça marche pour les 5-6 premiers clics, puis après ça commence à faire le bug du JPanel, qui contient le bouton "Annuler", qui disparait.
    De même quand je clique sur le bouton "Chercher" au centre, il y a le gros carré bleu en haut à gauche qui apparait, ou plutôt devrais je dire une partie de l'image de fond qui disparait. J'ai essayé tous les repaint() de tous les éléments possibles et de partout mais rien n'y fait

    Est ce une erreur dans mon code ou bien c'est l'affichage Java qui est comme ça et je ne peux rien y faire? Y a-t-il un moyen de forcer une sorte de rafraichissement? Toucher à l'Editor AnnulerBtnCellEditor de la colonne "Annuler" ? Ou rajouter manuellement à chaque fois l'objet (AnnulerBtnCell) dans la table afin qu'il se réactualise tout seul?
    Bref j'ai testé diverses solutions mais rien n'y fait, si vous avez le début d'une idée merci de m'en faire part

    Voila le code correspondant si quelqu'un veut vraiment se plonger dedans :

    L'objet que l'on passera à la JTable, un JPanel contenant le bouton "Annuler" :
    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 AnnulerBtnCell extends JPanel {
    	private JButton annulerBtn;
     
    	public AnnulerBtnCell () {
    		annulerBtn = new JButton ("Annuler");
    		//annulerBtn.setEnabled (false);
    		this.setLayout(new GridBagLayout ());
     
    		annulerBtn.addActionListener (
    				new java.awt.event.ActionListener () {
    					public void actionPerformed (java.awt.event.ActionEvent evt){
    						Annuler (evt);
    					}
    				}
    		);
     
    		add(annulerBtn, new GridBagConstraints (0, 0, 1, 1, 0, 0,
                    GridBagConstraints.CENTER,
                    GridBagConstraints.CENTER,
                    new Insets (0,0,0,0), 0, 0));
    	}
     
    	private void Annuler (java.awt.event.ActionEvent ae) {
    		int numLigne = Ppal.TableR.getSelectedRow();
    		long idPiece = (long)Ppal.TableR.getValueAt (Ppal.TableR.getSelectedRow(), 0);
    		Piece pieceOriginale = Ppal.getPieceRequete (idPiece);
    		Ppal.philaTM.Supprimer (numLigne);
    		Ppal.philaTM.Inserer (numLigne, pieceOriginale);
    	}
    }
    Son renderer :
    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
     
    public class AnnulerBtnCellRenderer implements TableCellRenderer {
     
    	public AnnulerBtnCellRenderer () {
    	}
     
    	public Component getTableCellRendererComponent(	JTable table,
    													Object value,
    													boolean isSelected,
    													boolean hasFocus,
    													int row,
    													int column) {
    		return (AnnulerBtnCell)value;
    	}
    }

    Son Editor :
    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
     
    public class AnnulerBtnCellEditor extends AbstractCellEditor implements TableCellEditor{
    	AnnulerBtnCell annulerBtn;
     
    	public AnnulerBtnCellEditor() {
    		super();
    		annulerBtn = new AnnulerBtnCell();
    	}
     
    	@Override
        public Object getCellEditorValue() {
            return annulerBtn;
        }
     
    	public Component getTableCellEditorComponent (	JTable table,
    													Object value,
    													boolean isSelected,
    													int row,
    													int column){
    		return (AnnulerBtnCell) value;
    	}
    }

    Le Modèle de la JTable :
    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
     
    public class PhilaTableModel extends AbstractTableModel implements TableModel{
    	private String [] titresColonnes;
    	private List<Piece> lignes = new ArrayList<Piece>();
     
     
    	public PhilaTableModel(String [] titresColonnes){
    		this.titresColonnes = titresColonnes;
    	}
     
    	public void Ajouter (Piece ligne){
    		lignes.add(ligne);
            fireTableRowsInserted(lignes.size()-1, lignes.size() -1);
    	}
     
    	public void Inserer (int rowIndex, Piece ligne) {
    		lignes.add(rowIndex, ligne);
            fireTableRowsInserted(rowIndex, rowIndex);
    	}
     
    	public void Supprimer (int rowIndex){
    		lignes.remove (rowIndex);
    		fireTableRowsDeleted(rowIndex, rowIndex);
    	}
     
    	public void ViderTable () {
    		int Nblignes = lignes.size();
    		lignes.clear();
    		fireTableRowsDeleted(0, Nblignes);
    	}
     
    	public Class<?> getColumnClass(int columnIndex) {
    		return getValueAt(0, columnIndex).getClass();
    	}
     
    	public int getColumnCount() { return titresColonnes.length; }
    	public String getColumnName(int columnIndex) { return titresColonnes[columnIndex]; }
    	public int getRowCount() { return lignes.size(); }
    	public Object getValueAt (int rowIndex, int columnIndex) {
    		//System.out.println ("row : "+ rowIndex + " - col : " + columnIndex + " - sizeLignes : " + lignes.size());
    		switch (columnIndex){
    		case 0 :
    			return lignes.get(rowIndex).getIdPiece();
    		case 1 :
    			return lignes.get(rowIndex).getPhoto();
    		case 2 :.....
    		default :
    			return 0;
    		}
    	}
     
    	public void setValueAt (Object aValue, int rowIndex, int columnIndex) {
    		if (aValue != null) {
    			Piece piece = lignes.get (rowIndex);
    			switch (columnIndex){
    			case 2 :
    				piece.setSujet((String) aValue);
    				break;
    			case 3 :.....
    			}
    			fireTableCellUpdated (rowIndex, columnIndex);
    		}
    	}
     
    	public boolean isCellEditable(int row, int col) { return col<=2 ? false : true;
    	}
    }

    Et la JFrame principale qui contient tous les composants :
    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
     
    public class Ppal extends JFrame {
    	public Ppal() {
     
                    philaTM = new PhilaTableModel (Entetes);
    		//System.out.println (philaTM.getTableModelListeners ());
    		TableR = new JTable (philaTM);
    		TableR.getColumnModel().getColumn(1).setCellRenderer (new PhotoCellRenderer());
     
    		TableR.getColumnModel().getColumn(8).setCellRenderer (new ValiderBtnCellRenderer());
    		TableR.getColumnModel().getColumn(9).setCellRenderer (new AnnulerBtnCellRenderer());
    		TableR.getColumnModel().getColumn(10).setCellRenderer (new SupprimerBtnCellRenderer());
     
    		TableR.getColumnModel().getColumn(8).setCellEditor (new ValiderBtnCellEditor());
    		TableR.getColumnModel().getColumn(9).setCellEditor (new AnnulerBtnCellEditor());
    		TableR.getColumnModel().getColumn(10).setCellEditor (new SupprimerBtnCellEditor());
     
    		TableR.getModel().addTableModelListener(new PhilaTableModelListener());
    		TableR.setRowHeight(100);
     
     
     
    	protected static Piece getPieceRequete (long idP) {
    		try {
    			//L'objet ResultSet contient le résultat de la requête SQL
    			rsltSet = stmt.executeQuery(Requete);
     
    			while(rsltSet.next()){
    				long idPiece = (long) rsltSet.getObject(1);
     
    				if (idPiece == idP) { 
    					String photo = (String) rsltSet.getObject(2);
    					String sujet = (String) rsltSet.getObject(3);
    					String type = (String) rsltSet.getObject(4);
    					String race = (String) rsltSet.getObject(5);
    					String pays = (String) rsltSet.getObject(6);
    					String numero = (String) rsltSet.getObject(7);
    					String desc = (String) rsltSet.getObject(8);
    					String annee = (String) rsltSet.getObject(9);
    					String tome = (String) rsltSet.getObject(10);
    					String etat = (String) rsltSet.getObject(11);
    					String typeDoc = (String) rsltSet.getObject(12);
    					String anneeAchat = (String) rsltSet.getObject(13);
    					String prix = (String) rsltSet.getObject(14);
    					String anneeCote = (String) rsltSet.getObject(15);
    					String coteNeuf = (String) rsltSet.getObject(16);
    					String coteBon = (String) rsltSet.getObject(17);
    					String coteZero = (String) rsltSet.getObject(18);
    					String vendeur = (String) rsltSet.getObject(19);
    					boolean manco = (boolean) rsltSet.getObject(20);
    					String valeur = (String) rsltSet.getObject(21);
     
    					piece = new Piece (idPiece, photo, sujet, type, race, pays, numero, desc, annee, tome, etat, typeDoc, anneeAchat, prix, anneeCote, coteNeuf, coteBon, coteZero, vendeur, manco, valeur, new ValiderBtnCell(), new AnnulerBtnCell(), new SupprimerBtnCell());
     
    					return piece;
    				}
    			}
    		} catch (SQLException sqle) {
    			JOptionPane.showMessageDialog(null, "La requête suivante a provoqué une erreur :\n" + Requete, "Erreur base de données", JOptionPane.ERROR_MESSAGE);
    		}
     
    		return null;
    	}

  2. #2
    Membre actif Avatar de uhrand
    Profil pro
    Développeur informatique
    Inscrit en
    Octobre 2009
    Messages
    203
    Détails du profil
    Informations personnelles :
    Localisation : Luxembourg

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Octobre 2009
    Messages : 203
    Points : 275
    Points
    275
    Par défaut Table Button Column
    Citation Envoyé par Ayok13 Voir le message
    j'ai une JTable ... Chaque ligne est dotée en fin de ligne des boutons "Valider", "Annuler" et "Supprimer". ... ça marche pour les 5-6 premiers clics, puis après ça commence à faire le bug du JPanel, qui contient le bouton "Annuler", qui disparait.
    Cette page pourrait aider: Table Button Column

    Cordialement,
    André

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 56
    Points : 59
    Points
    59
    Par défaut
    Merci d'avoir répondu.
    En fait j'avais essayer cette solution à la base car je ne savais pas si la table pouvait rendre un bouton correctement de façon "native", mais ce n'est pas trop le cas dans le sens où le bouton prend toutes la place de la cellule :



    C'est pour ça que je m'étais orienté plutôt vers l'affichage d'un JPanel qui contient mon bouton, au moins je peux jouer comme je veux avec le layout. Mais apparemment avec un objet trop compliqué comme ça il gère moyen. Mais à bien y réfléchir je crois que je préfère encore un gros bouton qui tient plutôt qu'un joli bouton qui bug lol

    Mais je me suis rendu compte d'un bug algorithimique, et probablement que le bug d'affichage en découle. Malheureusement je ne peux pas y faire grand chose.
    En fait dans la méthode getValueAt() du TableModel un moment il me donne un "rowIndex" de -1, forcément je suis alors OutOfBoundException..... les méthodes fonctionnent, le bouton marche encore, ça ne bloque pas le programme mais c'est tout de même très étrange.
    Le problème c'est qu'on ne contrôle pas les appels de getValueAt() du coup je suis bloqué. Je m'en suis rendu compte avec un "mouchard" :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public Object getValueAt (int rowIndex, int columnIndex) {
    		System.out.println ("Model row : " + rowIndex + " - col : " + columnIndex);
    		switch (columnIndex){
    		case 0 :
    			return lignes.get(rowIndex).getIdPiece();
    		case 1 :
    			return lignes.get(rowIndex).getDetailsBtnCell();
    		case 2 :
    			return lignes.get(rowIndex).getPhoto();
    ...................
    Affichage :
    .......
    Model row : 1 - col : 10
    Model row : 1 - col : 11
    Model row : -1 - col : 0
    Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: -1


    Bref je laisse encore le sujet ouvert si quelqu'un a une idée sur la question ou si c'est déjà arrivé. Sinon je marquerai "résolu" plus tard en utilisant les boutons moches ^^

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Novembre 2011
    Messages
    56
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2011
    Messages : 56
    Points : 59
    Points
    59
    Par défaut
    VICTOIRE !!!
    Enfin demi-victoire!
    Le bug d'affichage venait bien du bug d'algorithme. En fait c'est la fonction getSelectedRow() de la table qui couille et qui retourne de temps en temps -1, et quand j'y faisais appel pour un getValueAt() forcément ça marche pas. La solution est de faire en sorte de ne pas faire le traitement lorsqu'on tombe sur un -1.
    Donc c'est + du bidouillage qu'une réelle solution, mais au moins je peux garder mes JPanel qui ne disparaissent plus des cellules

    Exemple toujours avec mon bouton "Annuler"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    private void Annuler (java.awt.event.ActionEvent ae) {
    		int numLigne = Ppal.TableR.getSelectedRow();
    		if (numLigne != -1){
    			long idPiece = (long)Ppal.TableR.getValueAt (numLigne, 0);
    			System.out.println("idPiece Annuler : " + idPiece);
    			Piece pieceOriginale = Ppal.getPieceRequete (idPiece);
    			Ppal.philaTM.Supprimer (numLigne);
    			Ppal.philaTM.Inserer (numLigne, pieceOriginale);
    		}
    	}
    Forcément s'il faut détecter les bugs des fonctions Java on n'est pas sorti de l'auberge pour programmer correctement

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

Discussions similaires

  1. Affichage d'un Double dans une JTable
    Par Brice22 dans le forum Composants
    Réponses: 1
    Dernier message: 16/03/2009, 16h38
  2. Listen un JButton dans une JTable
    Par Goupo dans le forum Composants
    Réponses: 1
    Dernier message: 14/03/2008, 03h21
  3. Utilsation des JButton dans une Jtable
    Par henpower dans le forum Composants
    Réponses: 4
    Dernier message: 18/09/2007, 16h58
  4. Comment mettre un JButton dans une JTable
    Par vinceLeBarbare dans le forum Composants
    Réponses: 6
    Dernier message: 05/06/2006, 11h43
  5. Icon pour pour JButton dans une Jtable + pb colonnes
    Par dim_italia dans le forum Composants
    Réponses: 3
    Dernier message: 22/02/2006, 18h05

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