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

AWT/Swing Java Discussion :

JTable : positionnement sur une ligne


Sujet :

AWT/Swing Java

  1. #1
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    Par défaut JTable : positionnement sur une ligne
    Bonjour,
    j'ai lu diverses discussions et articles sur l'utilisation d'une JTable nécessitant un JScrollPane et j'en utilise sans problème depuis des années. Récemment je suis confronté à un problème que je ne m'explique pas.
    J'ai une JTable dans une JInternalFrame. Je remplis ma JTable avec mes données et la vue du JScrollPane se positionne pour montrer la dernière ligne du tableau. Je voudrai que la position soit sur la première ligne. J'ai essayé plusieurs solutions mais je n'y arrive pas. Mon scrollbar vertical ne décolle pas du bas du tableau.
    D'après ce que j'avais vu, l'appel à la méthode
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    table.scrollRectToVisible(new Rectangle(0, 0, maTable.getWidth(), maTable.getRowHeight()));
    devrait afficher la première ligne mais en fait cette procédure ne fait pas le job contrairement à ce qu'affirme un message sur le sujet;
    Un tour sur cette méthode montre qu'il s'agit d'une méthode de JComponent et qu'il est préférable d'utiliser celle correspondant au JViewport.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    viewport = (JViewport)maTable.getParent()
    ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    viewport = monJScrollPane.getViewport()
    (le deux méthodes renvoient exactement le même viewport)
    Mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    viewport.scrollRectToVisible(new Rectangle(0, 0, maTable.getWidth(), maTable.getRowHeight()));
    ne fait pas le job non plus. Il semble que cela provienne du fait que le viewport n'est pas valide au moment de l'appel de procédure. Un appel à validate() ne résout pas le problème.
    Une idée ?

  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 : 55
    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
    Billets dans le blog
    2
    Par défaut
    Salut,

    Tu peux te positionner en agissant sur la barre par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monJScrollPane.getVerticalScrollBar().setValue(0);
    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
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    Par défaut
    Citation Envoyé par joel.drigo Voir le message
    Salut,

    Tu peux te positionner en agissant sur la barre par :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    monJScrollPane.getVerticalScrollBar().setValue(0);
    J'ai essayé cela aussi et ça n'a pas marché.
    Je vais faire des tests pour voir pourquoi ça ne marche pas.
    J'ai vraiment l'impression que c'est parce qu'au moment où je lance cette méthode le viewport n'est pas valide.

    Merci de ta réponse.
    Je reviens un peu plus tard avec mes tests.

  4. #4
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    Par défaut
    C'est nécessairement dans mes composants particuliers que cela se joue car le code suivant fonctionne comme je le voudrai sans rien rajouter car par défaut c'est la première ligne du tableau qui est affiché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
     
    import java.awt.Dimension;
     
    import javax.swing.JFrame;
    import javax.swing.JInternalFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
     
    public class Main 
    {
     
    	public static void main(String[] args) 
    	{
    		JFrame f = new JFrame("TEST");
            f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
            JInternalFrame intf = new JInternalFrame("le tableau");
            intf.setPreferredSize(new Dimension(200,350));
            intf.setVisible(true);
            f.add(intf);
            f.pack();
            String contenu = "Le but de ce programme est d'intégrer dans la base de données de HistoireMondiale un territoire ou un fleuve qui "
            		+ "n'y figure pas encore. On appelle aperçu la carte d'origine mise à l'échelle de l'écran. On dispose d'une carte sous "
            		+ "forme d'un fichier image ainsi qu'un fichier texte contenant les limites spatio-temporelles de cette carte. On veut à "
            		+ "terme créer le territoire ou le fleuve correspondant dans la base histoire mondiale.";
            String[] mots = contenu.split(" ");
            String[] entetes = {"MOTS"};
            String[][] donnees = new String[mots.length][1] ;
            for(int i = 0; i < mots.length; i++) donnees[i][0] = mots[i];
            JTable table = new JTable(donnees, entetes);
            JScrollPane scrollPane = new JScrollPane(table);
            table.setFillsViewportHeight(true);
            intf.add(scrollPane);
            f.setVisible(true);
    	}
    }
    Je continue mes investigations.

  5. #5
    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 : 55
    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
    Billets dans le blog
    2
    Par défaut
    Il faudrait qu'on ait plus de code pour te dire. Normalement tu dois appeler ce code après que le modèle est été peuplé, ou après que le modèle ait été changé. Tu peux éventuellement réagir à ça en utilisant l’événement approprié.

    Pour que la réaction se fasse lorsque les données changent :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    table.getModel().addTableModelListener(me-> monJScrollPane.getVerticalScrollBar().setValue(0));
    Si tu changes le modèle (par un JTable.setModel()) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    table.addPropertyChangeListener("model", te-> {
    			((TableModel)te.getNewValue()).addTableModelListener(me-> monJScrollPane.getVerticalScrollBar().setValue(0));
    });
    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.

  6. #6
    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 : 55
    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
    Billets dans le blog
    2
    Par défaut
    Ah oui tu crées la JTable à chaque fois. Donc ce que je viens de dire ne sert à rien.
    Normalement, effectivement, c'est la première ligne qui devrait s'afficher sans avoir rien à faire.

    Normalement, ça ne devrait pas, mais il est possible que le table.setFillsViewportHeight(true); provoque un replacement du scrollpane. Je regarderai ça plus tard. Essaye juste de mettre le "monJScrollPane.getVerticalScrollBar().setValue(0)" après le "intf.add(scrollPane)";

    [EDIT]Oups, je n'avais pas attention que c'était un essai qui fonctionnait. Sans le vrai code qui ne fonctionne pas, je ne peux que me perdre en conjectures.
    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.

  7. #7
    Membre éclairé

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

    Informations forums :
    Inscription : Janvier 2004
    Messages : 469
    Par défaut
    Bon j'ai trouvé. Et en plus je crois qu'à un moment j'ai eu besoin que mes tableaux se positionnent à la fin et non au début. Je crois même que c'est toi qui m'avait donné la solution.
    Dans mes documents contenant des tableaux génériques j'ai ce morceau de code
    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
     
    		//le JScrollPane qui contient le tableau
    		JScrollPane jsp = new JScrollPane(tableau);
    		//si le tableau est vide, c'est le JScrollPane qui reçoit les évènements souris
    		//le document devra en tenir compte.
    		//pour que le JScrollPane se positionne à la fin du tableau lors de
    		//l'ajout d'une ligne
    		jsp.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() 
    		{  
    			private int lastmax=-1;
     
    			@Override
    			public void adjustmentValueChanged(AdjustmentEvent e) 
    			{  
    			    if ( !e.getValueIsAdjusting() ) 
    			    {
    			    	int max=e.getAdjustable().getMaximum();
    			    	int pos=e.getAdjustable().getValue();
    			    	if ( lastmax==-1 || lastmax==pos+e.getAdjustable().getVisibleAmount()) 
    			    	{
    			    		e.getAdjustable().setValue(max);  
    			    	}
    			    	lastmax=max;
    				}
    			}
    		});
    Il me suffit donc de retirer ce listener pour que ça marche
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    	/**
             * si on veut retrouver le comportement par défaut : le tableau affiche sa première ligne
             * et non la dernière
             */
    	public void affichePremièreLigne()
    	{
      	  JScrollPane jsp = (JScrollPane) getContentPane().getComponents()[0];
      	  JScrollBar bar = jsp.getVerticalScrollBar();
      	  bar.removeAdjustmentListener(bar.getAdjustmentListeners()[0]);
    	}

    Merci de t'être penché sur le problème.

Discussions similaires

  1. [JTable] Listener sur une ligne
    Par HunTR dans le forum Composants
    Réponses: 4
    Dernier message: 24/03/2010, 14h57
  2. Réponses: 3
    Dernier message: 23/07/2009, 13h11
  3. Positionner sur une ligne d'un formulaire
    Par devdev dans le forum VBA Access
    Réponses: 1
    Dernier message: 30/03/2009, 18h28
  4. Positionnement sur une ligne d un DataGridVoew
    Par Cedric33 dans le forum C#
    Réponses: 2
    Dernier message: 24/10/2008, 14h44
  5. comment se positionner sur une ligne de table mysql ?
    Par pas30 dans le forum Requêtes
    Réponses: 3
    Dernier message: 13/01/2007, 13h43

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