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 :

Evenements sur une cellule de JTable


Sujet :

Composants Java

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Développeur Java disponible
    Inscrit en
    Janvier 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Java disponible
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2018
    Messages : 12
    Points : 7
    Points
    7
    Par défaut Evenements sur une cellule de JTable
    Bonjour à tous,

    Je me permets d'apporter ma pierre à l'édifice de ce forum en vous faisant part de mon blocage actuel.

    Je vous explique le contexte rapidement :
    Je développe sans but professionnel une petite application de gestion de mot de passe et je fais face à un blocage total lorsque je souhaite qu'un label, présent dans une cellule, réagisse à certains événements.

    Je dispose donc d'une JTable qui se remplit correctement aucun souci là dessus, mon problème se situe sur la gestion de l’événement me permettant de gérer le survol et le clic sur une cellule contenant une URL, elle même contenue dans un JLabel.

    Pourriez-vous m'aiguiller sur un principe permettant de mettre le focus d'un événement sur le contenu d'une cellule et non pas sur la JTable.

    J'ai vu des choses sur le principe de la "plaque de verre" mais comment le contourner ?

    Merci à ceux qui m'aideront.

    A bientôt.

  2. #2
    Modérateur
    Avatar de joel.drigo
    Homme Profil pro
    Ingénieur R&D - Développeur Java
    Inscrit en
    Septembre 2009
    Messages
    12 430
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 54
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieur R&D - Développeur Java
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2009
    Messages : 12 430
    Points : 29 131
    Points
    29 131
    Billets dans le blog
    2
    Par défaut
    Salut,

    Pour les cellules d'une JTable, il y a deux concepts :
    1. un pour l'affichage, ou rendu : javax.swing.table.TableCellRenderer
    2. un pour l'édition : javax.swing.table.TableCellEditor


    Même si pour une raison de simplicité on constitue le rendu avec des composants Swing, il ne s'agit pas comme dans le cas de composants mis dans un JPanel, de composants interactifs. A chaque fois qu'une cellule doit être affichée, on fait appelle au TableCellRenderer pour faire le dessin, on le copie tel quel graphiquement, et on recommence pour la cellule suivante. Le rendu de cellule n'est donc pas interactif.

    Pour l'éditeur, c'est différent : on a, normalement, qu'une seule cellule en édition à la fois, donc la JTable "déplace" le composant créé par le TableCellEditor au bon endroit. Du coup, on peut gérer différents type de composants interactifs dans les cellules, à partir d'un seul composant (ou de plusieurs éventuellement, si on veut des composants différents suivant le type des données, ou les valeurs par exemple).

    En revanche, si la JTable gère bien une notion de focus sur la cellule (qu'on peut exploiter dans le TableCellRenderer comme TableCellEditor), ce sera plus compliqué pour le survol par exemple sans interférence avec l'édition, parce qu'il faudra éventuellement utiliser un autre état (sélection, focus) pour simuler un highlight (en gérant ça sur le mousemove, et le mouseexit), et que ces deux états sont utilisés par l'édition (puisqu'il faut (la plupart du temps) cliquer dans une cellule qu'on veut éditer). S'il n'y a pas de possibilité d'édition, ce sera plus simple donc, parce qu'on n'a pas à gérer cette interférence. On peut aussi au lieu d'utiliser le focus ou la sélection gérer son propre état en forçant un refresh du renderer au besoin.

    Attention, les exemples avec tooltip peuvent tromper : on peut mettre un tooltip sur le composant de rendu parce que la méthode getTooltipText() va chercher le tooltip du composant affiché (en en faisant le rendu à la demande).

    Voici une démo de principe pour le survol (hover) , par état spécifique (gérer juste par un couple ligne/colonne). Je ne gère que le survol, mais si tu veux gérer un état "déjà cliqué" par exemple, c'est en gros le même principe de couple à stocker, mais à gérer sur l'événement clicked...

    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
    public class JTableLink {
     
     
    	public static void main(String[] args) throws MalformedURLException {
     
    		String[] col = {"URL"};
     
    		Object[][] data = {
    				{ new URL("https://www.developpez.net/")},
    				{new URL("https://www.developpez.net/forums/f6/java/")},
    				{new URL("https://java.developpez.com/faq/")}	
    		};
     
    		TableModel model = new DefaultTableModel(data, col) {
    			public boolean isCellEditable(int row, int column) {return false;}
    			@Override
    			public Class<?> getColumnClass(int columnIndex) {
    				return URL.class;
    			}
    		};
     
    		JTable table = new JTable(model);
    		table.setRowHeight(24);
    		table.setCellSelectionEnabled(false);
    		new LinkCellRenderer(table);
     
    		JFrame frame = new JFrame();
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
     
    		JPanel panel = new JPanel(new BorderLayout());
    		panel.add(table.getTableHeader(),BorderLayout.NORTH);
    		panel.add(new JScrollPane(table));
     
     
     
    		frame.add(panel);
     
    		frame.setSize(300, 300);
    		frame.setLocationRelativeTo(null);
    		frame.setVisible(true);
     
    	}
     
    	public static class LinkCellRenderer extends DefaultTableCellRenderer implements MouseMotionListener, MouseListener {
     
    		private JTable table;
    		private Point hoverCell;
    		private Color defaultForeground;
     
    		public LinkCellRenderer(JTable table) {			
    			this.table=table;
    			this.table.addMouseListener(this);
    			this.table.addMouseMotionListener(this);
    			table.setDefaultRenderer(URL.class, this);
    		}
     
    		@Override
    		public void setForeground(Color c) {
    			defaultForeground=c;
    			super.setForeground(c);
    		}
     
    		@Override
    		public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
    				int row, int column) {
    			if ( isHover(row,column) ) {
    				super.setForeground(Color.BLUE);
    			}
    			else if ( hasFocus ) { // par exemple, pour simuler que le focus highlight aussi le lien
    				super.setForeground(Color.BLUE);
    			}
    			else {
    				super.setForeground(defaultForeground);
    			}
    			return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
    		}
     
    		private boolean isHover(int row, int column) {
    			return hoverCell!=null && hoverCell.x==row && hoverCell.y==column;
    		}
     
    		@Override
    		public void mouseDragged(MouseEvent e) {
     
    		}
     
    		@Override
    		public void mouseMoved(MouseEvent e) {
    		      Point p = e.getPoint();
     
    	        int hitColumnIndex = table.columnAtPoint(p);
    	        int hitRowIndex = table.rowAtPoint(p);
     
    	        if ( hoverCell==null || hoverCell.x!=hitRowIndex || hoverCell.y!=hitColumnIndex ) {
    	        	Point old = hoverCell;
    	        	hoverCell = new Point(hitRowIndex,hitColumnIndex);
    	        	if (old!=null && old.x!=-1 && old.y!=-1 ) {
    		        	table.tableChanged(new TableModelEvent(table.getModel(), old.x, old.x, old.y));
    	        	}
    	        	table.tableChanged(new TableModelEvent(table.getModel(), hitRowIndex, hitRowIndex, hitColumnIndex));
    	        }
     
    		}
     
    		@Override
    		public void mouseClicked(MouseEvent e) {
    			// TODO Auto-generated method stub
     
    		}
     
    		@Override
    		public void mousePressed(MouseEvent e) {
    			// TODO Auto-generated method stub
     
    		}
     
    		@Override
    		public void mouseReleased(MouseEvent e) {
    			// TODO Auto-generated method stub
     
    		}
     
    		@Override
    		public void mouseEntered(MouseEvent e) {
    			// TODO Auto-generated method stub
     
    		}
     
    		@Override
    		public void mouseExited(MouseEvent e) {
            	Point old = hoverCell;
    	        hoverCell = new Point(-1,-1);
            	if (old!=null && old.x!=-1 && old.y!=-1 ) {
    	        	table.tableChanged(new TableModelEvent(table.getModel(), old.x, old.x, old.y));
            	}
    		}
     
     
     
    	}
     
     
     
    }
    L'expression "ça marche pas" ne veut rien dire. Indiquez l'erreur, et/ou les comportements attendus et obtenus, et donnez un Exemple Complet Minimal qui permet de reproduire le problème.
    La plupart des réponses à vos questions sont déjà dans les FAQs ou les Tutoriels, ou peut-être dans une autre discussion : utilisez la recherche interne.
    Des questions sur Java : consultez le Forum Java. Des questions sur l'EDI Eclipse ou la plateforme Eclipse RCP : consultez le Forum Eclipse.
    Une question correctement posée et rédigée et vous aurez plus de chances de réponses adaptées et rapides.
    N'oubliez pas de mettre vos extraits de code entre balises CODE (Voir Mode d'emploi de l'éditeur de messages).
    Nouveau sur le forum ? Consultez Les Règles du Club.

  3. #3
    Futur Membre du Club
    Homme Profil pro
    Développeur Java disponible
    Inscrit en
    Janvier 2018
    Messages
    12
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur Java disponible
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2018
    Messages : 12
    Points : 7
    Points
    7
    Par défaut
    Wouah !

    Merci de ta réponse que je pense avoir compris dans le principe et qu'il me faut maintenant digérer pour l'adapter à ma situation.
    (profil junior <--)

    Encore merci.

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

Discussions similaires

  1. Enlever la selection ou focus sur une cellule dans jTable
    Par saidou007 dans le forum Langage
    Réponses: 2
    Dernier message: 26/12/2012, 22h56
  2. mettre un evenement sur une cellule
    Par huître dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 06/04/2012, 18h19
  3. [XL-2002] Ecouter un evenement sur une cellule et le reproduire sur une autre cellule
    Par kulnae dans le forum Macros et VBA Excel
    Réponses: 28
    Dernier message: 17/08/2009, 21h21
  4. Evenement de click sur une cellule de JTable
    Par mitnick2006 dans le forum Composants
    Réponses: 3
    Dernier message: 10/08/2008, 17h34
  5. Réponses: 3
    Dernier message: 19/05/2006, 16h30

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