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 :

Q: JTable - prepareRenderer - colorier lignes au-dessus d'une ligne sélectionnée


Sujet :

Composants Java

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Points : 121
    Points
    121
    Par défaut Q: JTable - prepareRenderer - colorier lignes au-dessus d'une ligne sélectionnée
    Bonjour à vous, esprits salvateurs.

    J'ai une IHM dotée d'une JTable, elle-même dotée d'un modèle de table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    public class MonModèleDeTablePrinc extends AbstractTableModel
    Au démarrage, cette table ne montre que quelques lignes bidon, à titre d'exemple (constructeur de
    MonModèleDeTablePrinc(String[] titresColonnes)
    ), mais son contenu peut varier à loisir en fonction du choix d'un fichier .csv adéquat
    public void populateTable(File pathNomFichierCsvDEntrée)
    De plus, cette table est équipée d'une colonne de tête de lignes contenant leur numérotation, ainsi que d'une table inférieure affichant divers résultats de calculs (totaux, ...).
    Je cherche à pouvoir doter d'une couleur de background particulière (LIGHT_GRAY) les rangées situées au-dessus d'une première ligne et en-dessous d'une deuxième ligne, déterminées en les cliquant.
    Cette fonctionnalité pourrait intéresser nombre de programmeurs de HMI-Swing, n'est-ce-pas ?
    Mon problème : parvenir à rendre 'renderer' atteignable dans toute la classe
    public class FichierDonnéesDEntrée extends JScrollPane implements ActionListener
    , et particulièrement dans sa volumineuse méthode
    public void actionPerformed(ActionEvent e)
    contenant la structure de traitement des nombreux boutons et radio-boutons.

    Voici les lignes de code de mes deux fichiers concernés :
    - FichierDonnéesDEntré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
    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
    public class FichierDonnéesDEntrée extends JScrollPane implements ActionListener
    {   
        // Déclaration des variables
        ...
        private JTable tablePrinc, tableInfér;
        private int[] sélectionLignes;
        private TableCellRenderer renderer1;
        ...
        private void initGuiComponents(String pathNomFichier)
        {
            // Instanciation des variables
        ...
            monModèleDeTablePrinc = new MonModèleDeTablePrinc(titresCol_TablePrinc);
            sélectionLignes = new int[2];      // Sélection par groupe de lignes
            tablePrinc = new JTable(monModèleDeTablePrinc)
            {   @Override public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
                {   renderer1 = renderer;
    //? renderer1 n'est qu'une référence recevant copie de la référence d'un renderer instancié au niveau de 'new JTable() , OK ?
                    Component c = super.prepareRenderer(renderer, row, column);
                    if (!isRowSelected(row))
                    {
                        c.setBackground(getBackground());
                        if (row < monModèleDeTablePrinc.lignesàEliminer[0] ||
                            row > monModèleDeTablePrinc.lignesàEliminer[1])
                            c.setBackground(Color.LIGHT_GRAY);
                    }
                    return c;
                }
            };
        ...
            tablePrinc.getSelectionModel().addListSelectionListener(new ListSelectionListener()
                {   @Override public void valueChanged(ListSelectionEvent event)
                    {   
                        sélectionLignes = tablePrinc.getSelectedRows();
                    }
                }                                                  );
        ...
        // GroupLayout
        // Fin de 'initGuiComponents()'
        ...
        @Override public void actionPerformed(ActionEvent e)
        {   int[] parRéf = new int[1];
            int enChampDeTexte;
     
            if (e.getSource() == radioBouton1)
            {
            ...
                    if( (tablePrinc.getSelectedRow() == -1) ||
                         sélectionLignes[0]<0 ||
                         sélectionLignes[0]> monModèleDeTablePrinc.nbreLignesTotal
                      )
                ...
                    {   // Une rangée valide du tableau a été préalablement sélectionnée.
                ...
                        } else
                        {   /* Le numéro de ligne (première colonne de la rangée) est identique
                             * à celle du champs de texte à côté du radio-bouton --> 
                             * Lancer la commande : Coloration des lignes supérieures  */
                            monModèleDeTablePrinc.lignesàEliminer[0] = sélectionLignes[0];
                            tablePrinc.prepareRenderer(renderer, sélectionLignes[0], 0);    // AUCUN EFFET.
                        }
            ...
    - Classe MonModèleDeTablePrinc :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
        public int[] lignesàEliminer = new int[2];
        ...
            lignesàEliminer[0] = 2;         // Lignes au-dessus de
            lignesàEliminer[1] = nbreLignesTotal-1;         // Lignes en-dessous de
     
            fireTableDataChanged();
    , ce qui suffit à faire fonctionner la méthode 'prepareRenderer(...' . Les 'lignesàEliminer[n]' figurent tant dans le constructeur que dans la fonction 'populateTable(File pathNomFichierCsvDEntrée)'. Elles se mettent bien en gris lors de l'appel du constructeur et de 'populateTable()' mais ne se laissent pas modifier ensuite, soit à partir de la méthode 'actionPerformed()'.
    Comment faire pour qu'on puisse relancer le 'renderer' afin qu'il mette en gris les lignes qui précédent la ligne sélectionnée ?

    Merci bcp d'avance.
    "Ah oui ! Juste encore cette toute dernière petite question ..." (Columbo - Peter Falk)

  2. #2
    Membre habitué
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Août 2005
    Messages
    86
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : Finance

    Informations forums :
    Inscription : Août 2005
    Messages : 86
    Points : 174
    Points
    174
    Par défaut
    Bonjour Chavadam,

    Si je résume ton problème, tu souhaites que toutes les lignes au dessus de ta ligne sélectionnée se colories automatiquement par exemple en gris et les lignes en dessous de ta ligne sélectionnée se colories automatiquement en bleu....

    Si j'ai bien compris, tu n'as vraiment pas besoin que le renderer soit accessible par toute ta classe. Un renderer est sollicité après chaque repaint d'une vue contenant une JTable séléctionnable. Du coup tu peux conditionner le coloriage de tes lignes dans la méthode getTableCellRendererComponent.

    Voici un exemple de code permettant de sélectionner une ligne de JTable via une action bouton :

    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
     
     
    public class TableRenderer {
     
    	public static void main(String[] argv) {
     
    		Object rowData[][] = { 
    				{ "blabla", "blablablabla"},
    				{ "blablabla", "bla"} ,
    				{ "blabla", "blablablabla"},
    				{ "blabla", "blablablabla"},
    				{ "blablabla", "bla"} ,
    				{ "blablabla", "bla"} ,
    		};
    		Object columnNames[] = { "Colonne 1", "Colonne 2"};
    		final JTable table = new JTable(rowData, columnNames);
     
    		table.getColumnModel().getColumn(0).setCellRenderer(new MonRenderer());
    		table.getColumnModel().getColumn(1).setCellRenderer(new MonRenderer());
    		table.getSelectionModel().setSelectionInterval(0, 0);
     
    		final JTextField numLigne = new JTextField(6);
    		JButton btnOK = new JButton("Séléctionner");
    		btnOK.addActionListener(new ActionListener() {
    			@Override
    			public void actionPerformed(ActionEvent e) {
    				Integer num = Integer.valueOf(numLigne.getText());
    				if (num<0 || num> table.getRowCount()-1) {
    					return;
    				}
    				table.getSelectionModel().setSelectionInterval(num, num);
    			}
    		});
     
    		Box box = Box.createHorizontalBox();
    		box.add(new JLabel("Numéro de ligne"));
    		box.add(numLigne);
    		box.add(btnOK);
     
    		JFrame f = new JFrame();
    		f.setSize(300,300);
    		f.add(box , BorderLayout.NORTH);
    		f.add(new JScrollPane(table), BorderLayout.CENTER);
    		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		f.setVisible(true);
    	}
     
    }
     
     
    class MonRenderer extends DefaultTableCellRenderer {
     
    	private static final long serialVersionUID = 1L;
     
    	private int selectedRow;
     
    	@Override
    	public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
    			boolean hasFocus, int rowIndex, int vColIndex) {
     
    		selectedRow = table.getSelectedRow();
     
    		if (selectedRow > rowIndex) {
    			setBackground(Color.LIGHT_GRAY);
    		} else if (selectedRow == rowIndex) {
    			setBackground(Color.red);
    		} else if (selectedRow < rowIndex) {
    			setBackground(Color.BLUE);
    		}
     
    		setText((String) value);
    		return this;
    	}
    }
    J'espère que ça répond à ton besoin.

    Awane
    Si mon message t'a aidé, un petit ne fera pas de mal
    Pensez aussi à

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Points : 121
    Points
    121
    Par défaut
    Bonsoir à tous.
    J'apprécie bcp ta proposition de solution, Awane : la méthode getTableCellRendererComponent au lieu de
    Component c = super.prepareRenderer(renderer, row, column);
    Je suis désolé de ne te répondre que si tard; et encore, c'est pour dire que je pense que je vais pouvoir l'essayer que dans une semaine ou deux. Je suis un peu freiné par de la programmation d'un autre aspect pour la même application, et un peu par des tas de choses qui ne sont demandées qu'aux 'papy's.
    Je te promets une réponse à ce sujet. A bientôt et grand merci.
    "Ah oui ! Juste encore cette toute dernière petite question ..." (Columbo - Peter Falk)

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    263
    Détails du profil
    Informations personnelles :
    Âge : 73
    Localisation : Belgique

    Informations forums :
    Inscription : Décembre 2008
    Messages : 263
    Points : 121
    Points
    121
    Par défaut Coloriage de l'arrière-plan de plusieurs groupes séparés de lignes d'une JTable
    Bonjour à tous, et en particulier à Awane.

    Voici que j'ai un peu de temps à présent pour revenir à mon problème de coloriage de l'arrière-plan de plusieurs groupes séparés de lignes d'une JTable, de couleur différente suivant son appartenance à l'un des groupes de lignes que l'utilisateur ou le programme a sélectionné :
    (Il s'agit d'une table de toutes les heures de tous les jours d'une année : 24 x 365 = 8.760 lignes)
    - Les lignes précédant la ligne de début de période à considérer et suivant la ligne de fin de période : en gris, p.ex.
    - Les lignes correspondant aux jours de weekend et de fête (listées dans une Array) : en cyan.
    - Les lignes des heures de nuit (non listées dans une Array mais dont la 4e colonne contient une valeur ) : en jaune
    (Fonctionnalité de large intérêt, il me semble)

    Question supplémentaire au passage, svp : un Repaint() est systématiquement commandé à la fin du traitement
    - soit de la fonction cachée de Java qui appelle '@Override public void actionPerformed(ActionEvent e)'
    - soit d'un 'monModèleDeTablePrinc.fireTableDataChanged();' ?

    J'observe que j'ai besoin que le renderer soit accessible, si pas par toute ma classe, du moins dans plusieurs options de ma fonction '@Override public void actionPerformed(ActionEvent e)'. C'est pourquoi je m'attendais à ce que 'super.prepareRenderer(renderer, row, column);' suffise (placée dans ma fonction 'initGuiComponents()'); c à d que je n'aie pas besoin d'utiliser plutôt 'getTableCellRendererComponent()' '. Or ta réponse annonce le contraire. Peux-tu éclaircir quand l'une méthode et quand l'autre ?

    3e et dernière question : Je suis surpris par { ... } dans l'expression
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
            tablePrinc = new JTable(monModèleDeTablePrinc)
            {   @Override public Component prepareRenderer(TableCellRenderer renderer, int row, int column)
                {   FichierDonnéesDEntrée.this.renderer = renderer;
                    composantTablePrinc = super.prepareRenderer(renderer, row, column);
     
                    if (!isRowSelected(row))
                    {
                        composantTablePrinc.setBackground(getBackground());
                 ...
            };
    Où ou quand cette construction d'instanciation plutôt rare est-elle encore pratiquée ?

    Grand merci d'avance.
    "Ah oui ! Juste encore cette toute dernière petite question ..." (Columbo - Peter Falk)

Discussions similaires

  1. Réponses: 3
    Dernier message: 08/04/2009, 11h53
  2. Réponses: 0
    Dernier message: 17/02/2009, 16h13
  3. Afficher une ligne par dessus d'autres éléments ?
    Par Yogy dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 10/09/2008, 11h41
  4. [Jtable]comment permettre le non selection d'une ligne ?
    Par Invité dans le forum Composants
    Réponses: 1
    Dernier message: 30/11/2005, 11h36
  5. [JTable] Modifier la couleur de fond d'une ligne
    Par joes_bushi dans le forum Composants
    Réponses: 2
    Dernier message: 20/09/2005, 12h13

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