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 :

JTable apparence graphique d'une ligne sélectionnée


Sujet :

Composants Java

  1. #1
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut JTable apparence graphique d'une ligne sélectionnée
    Bonjour
    Je ne suis pas vraiment un débutant en java mais là j'y perd mon latin.
    Donc j'ai une JTable avec un modèle et un renderer spécifique. Toutes les cellules de ma table sont des String. Les cellules ne sont pas éditables.
    Tout d'abord ce que je veux : lorsque je clique sur une cellule du tableau, toutes la ligne prend une couleur fond qui la distingue des autres lignes.
    Si je ne mets pas la méthode :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	public Class<?> getColumnClass(int col) 
    	{
    		return String.class;
    	}
    Cela fonctionne mais par contre le tableau n'utilise pas mon renderer spécifique.

    Si je mets la méthode ci-dessus, mon renderer fonctionne. Par contre quand je clique sur une cellule, le renderer utilisé pour la cellule cliquée n'est pas mon renderer personnel mais semble-t'il un autre renderer par défaut propre aux JTable.

    Quelqu'un a une idée ?
    Au cas où, bien que je pense que cela n'apporte rien je vous mets mon renderer personnel.
    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
     
    public class RendererActe extends DefaultTableCellRenderer 
    {
    	@Override
        public Component getTableCellRendererComponent(JTable table, Object val, boolean isSelected, boolean hasFocus, int lig, int col)
    	{
    		Component composant = super.getTableCellRendererComponent(table,val,isSelected,hasFocus,lig,col);
    		TableauActes tableau = (TableauActes) table;
    		DonneeActe acte = (DonneeActe) tableau.getDonneeLigne(lig);
    		if (acte.isValide()) composant.setBackground(Color.LIGHT_GRAY);
    		else composant.setBackground(Color.WHITE);
    		if (acte.getSV().isEmpty() || acte.getCote_reduite().isEmpty())  composant.setForeground(Color.BLACK);
    		else composant.setForeground(Color.BLUE);
    		return composant;
    	}	
     
    }
    Bien sûr j'ai appliqué ce renderer à mon tableau
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    	public TableauActes(ModeleActes m) 
    	{
    		super(m);
    		setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    		setDefaultRenderer(String.class,new RendererActe());
    	}
    Je précise en outre que j'ai utilisé
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    		//sélection par ligne seulement
    		tableau.setRowSelectionAllowed(true);
    		tableau.setColumnSelectionAllowed(false);
    C'est en respectant les autres que l'on se fait respecter.

  2. #2
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut Pb résolu
    Je me réponds à moi-même.
    Je ne sais pas s'il y a une solution plus élégante mais j'en ai trouvé une.
    J'utilise un document contenant un tableau qui utilise un modèle construit sur une type de donnée.
    Le tableau bénéficie d'un renderer spécifique.
    Le document est une JInternalFrame qui écoute son tableau (plus exactement la sélection sur un tableau). la partie importante pour mon problème se trouve dans valueChanged

    Le document
    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
     
    public class DocumentActes  extends JInternalFrame implements ListSelectionListener
    {
    	TableauActes tableau;
    	private int ligneSelectionnee = -1;
     
    	public DocumentActes(File fichierDonnees) 
    	{
    		super(fichierDonnees.getName());
    		tableau  = new TableauActes(new ModeleActes(fichierDonnees));
    		//on peut sélectionner une seule ligne à la fois
    		tableau.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
    		//sélection par ligne seulement : je n'ai plus besoin de cela
    		//tableau.setRowSelectionAllowed(true);
    		//tableau.setColumnSelectionAllowed(false);
    		//le JScrollPane qui contient le tableau
    		JScrollPane jsp = new JScrollPane(tableau);
    		ajouteListSelectionListener(this);
    		//ne pas oublier d'ajouter le JScrollPane au document
    		add (jsp);
    		this.setVisible(true);
    	}
    .../...
     
    	public int getLigneSelectionnee() 
    	{
    		return tableau.getLigneSelectionnee();
    	}
     
    	public DonneeActe getDonnee(int lig) 
    	{
    		return (DonneeActe) tableau.getDonneeLigne(lig);
    	}
     
    	@Override
    	public void valueChanged(ListSelectionEvent e) 
    	{
    		if (e.getValueIsAdjusting()) return;
    		DonneeActe acte;
    		int lig = getLigneSelectionnee(); 
    		if (ligneSelectionnee == lig) return;
    		if (lig < 0) return;
    		if (ligneSelectionnee >= 0) 
    		{
    			acte = getDonnee(ligneSelectionnee);
    			acte.setSelected(false);
    		}
    		ligneSelectionnee = lig;
    		acte = getDonnee(ligneSelectionnee);
    		acte.setSelected(true);
     
    		((ModeleActes) tableau.getModel()).fireTableDataChanged();
    	}
     
    	public static void main(String[] args) 
    	{
    		javax.swing.SwingUtilities.invokeLater(new Runnable() 
    		{
    			public void run() 
    			{
    				JFrame fenetre = new JFrame();
     
    				DocumentActes actes = new DocumentActes(new File("E:\\CORAIL_SEXE_PRENOM\\COMMUNES\\22113\\incoherences.txt"));
    				fenetre.add(actes);
    				//extension maximale 
    				fenetre.setExtendedState(JFrame.MAXIMIZED_BOTH);
    				//fermeture du programme
    				fenetre.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    				//dimension en cas de redimensionnement
    				fenetre.setSize(1200, 500);
     
    				fenetre.setVisible(true);
    	    	       }
    		});
    	}
    }
    Le tableau est une classe fille d'une classe personnelle Tableau qui découle de 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
     
    public class TableauActes  extends Tableau
    {
     
    	public TableauActes(ModeleActes m) 
    	{
    		super(m);
    		setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    		setDefaultRenderer(String.class,new RendererActe());
    	}
    	.../...
    	public Class<?> getColumnClass(int col) 
    	{
    		return String.class;
    	}
    }
    Le modèle dérive d'un modèle personnel qui découle lui-même de AbstractTableModel
    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
     
    public class ModeleActes extends ModeleTableau 
    {
    	File fichierDonnees;
     
    	public ModeleActes(File fichier) 
    	{
    		super();
    		entetes = "acte;date_greg;sexe;bebe_nom;bebe_prenom;papa_prenom;maman_nom;maman_prenom;date_repub;ID;SV;cote".split(";");
    		//la largeur des colonnes
    		int[] colonnesN = {1,10,1,15,15,15,15,15,10,9,15,30};
    		largeurs = colonnesN;
    		boolean[] editables = new boolean[entetes.length];
    		for(int i = 0; i < 12; i++) editables[i] = false;
    		this.colonnesEditables = editables;
    		this.fichierDonnees = fichier;
    		chargerDonnees();
    	}
     
    	@Override
    	protected void chargerDonnees() 
    	{
    		try 
    		{
    			String contenu = Fichiers.chargerContenuTexte(fichierDonnees);
    			String[] actes = contenu.split("\n");
    			for(int i = 1; i < actes.length; i++)
    			{
    				donnees.add(new DonneeActe(actes[i]));
    			}
    		} 
    		catch (IOException e) 
    		{
    			e.printStackTrace();
    		}
    	}
     
    	@Override
    	public Object getValueAt(int lig, int col) 
    	{
    		DonneeActe d = (DonneeActe)getDonneesLigne(lig);
            switch(col)
            {
                case 0  : return d.getType();
    			.../...
                default  : throw new IllegalArgumentException("la colonne " + col + " n'existe pas");       
            }
    	}
     
    .../...
    }
    Les données sont stockées dans fichier CSV dont les champs sont séparés par un ';'. J'ai rajouté un booléen "selectionnee" qui est mis à jour via la méthode valueChanged du document.
    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
     
    public class DonneeActe extends DonneeTableau implements Comparable<DonneeActe> 
    {
    ../...
    	private boolean valide = false;
    	private boolean selectionnee;
     
    	public DonneeActe(String acte) 
    	{
    		champs = acte.split(";");
    		.../...
    	}
     
    	public String toCSV() 
    	{
    		return type + ";" + date + ";" + sexe + ";" + nom + ";" + prenom + ";" + prenomPere + ";" + nomMere + ";" 
    				+ prenomMere + ";" + dateRep + ";" + id + ";" + (SV_nom.isEmpty() ? "?" : SV_nom) + ";" + cote_reduite;
    	}
     
    	.../...
    	public boolean isValide() 
    	{
    		return valide ;
    	}
     
    	public void setValide(boolean b) 
    	{
    		valide = b;
    	}
     
    	public boolean isSelected() 
    	{
    		return selectionnee;
    	}
     
    	public void setSelected(boolean b) 
    	{
    		selectionnee = b;
    	}
    }
    et enfin le 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
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
     
    public class RendererActe extends DefaultTableCellRenderer 
    {
    	@Override
        public Component getTableCellRendererComponent(JTable table, Object val, boolean isSelected, boolean hasFocus, int lig, int col)
    	{
    		Component composant = super.getTableCellRendererComponent(table,val,isSelected,hasFocus,lig,col);
    		TableauActes tableau = (TableauActes) table;
    		DonneeActe acte = (DonneeActe) tableau.getDonneeLigne(lig);
     
    		if (acte.isSelected()) 
    		{
    			composant.setBackground(Color.LIGHT_GRAY);
    		}
    		else
    		{
    			if (acte.isValide()) composant.setBackground(Color.YELLOW);
    			else composant.setBackground(Color.WHITE);
    		}
     
    		if (acte.getSV().isEmpty() || acte.getCote_reduite().isEmpty())  composant.setForeground(Color.BLACK);
    		else composant.setForeground(Color.BLUE);
    		return composant;
    	}	
     
    }
    Je ne garantis en rien l'harmonie des couleurs, mais maintenant la ligne sélectionnée est bien d'un couleur spécifique (LIGHT_GRAY) et seulement elle.
    C'est en respectant les autres que l'on se fait respecter.

  3. #3
    Membre averti

    Profil pro
    Inscrit en
    Janvier 2004
    Messages
    464
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2004
    Messages : 464
    Points : 332
    Points
    332
    Par défaut Il y a beaucoup plus simple pour ce problème de ligne sélectionnée
    Je reprends ce problème de janvier ayant été confronté au même problème
    En fait il y a une solution déjà implémentée dans Java : isRowSelected(int lig)
    Donc en réécrivant le renderer on n'a plus besoin d'une variable supplémentaire selectionnee
    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 class RendererActe extends DefaultTableCellRenderer 
    {
        @Override
        public Component getTableCellRendererComponent(JTable table, Object val, boolean isSelected, boolean hasFocus, int lig, int col)
        {
    		Component composant = super.getTableCellRendererComponent(table,val,isSelected,hasFocus,lig,col);
    		TableauActes tableau = (TableauActes) table;
    		DonneeActe acte = (DonneeActe) tableau.getDonneeLigne(lig);
     
    		if (tableau.isRowSelected(lig))
    		{
    			composant.setBackground(Color.LIGHT_GRAY);
    		}
    		else
    		{
    			if (acte.isValide()) composant.setBackground(Color.YELLOW);
    			else composant.setBackground(Color.WHITE);
    		}
     
    		if (acte.getSV().isEmpty() || acte.getCote_reduite().isEmpty())  composant.setForeground(Color.BLACK);
    		else composant.setForeground(Color.BLUE);
    		return composant;
    	}	
    }
    Et voilà.
    C'est en respectant les autres que l'on se fait respecter.

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

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