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 :

[Ubuntu] Affichage corrompu d'un JTable contenu dans un JScrollPane


Sujet :

Composants Java

  1. #1
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut [Ubuntu] Affichage corrompu d'un JTable contenu dans un JScrollPane
    Bonjour,

    j'ai développé une application qui utilise un JTable inséré dans un JScrollPane. Sous Windows, l'affichage ne pose aucun souci. Par contre sous Ubuntu lorsque je déplace l'ascenseur horizontal, le dessin des colonnes et de leur titre est corrompu (voir pièce jointe).
    D'où vient le problème ?

    Voici ce que me donne la commande java -version :
    java version "1.7.0_55"
    OpenJDK Runtime Environment (IcedTea 2.4.7) (7u55-2.4.7-1ubuntu1)
    OpenJDK 64-Bit Server VM (build 24.51-b03, mixed mode)
    Merci.
    Images attachées Images attachées  

  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,

    As-tu affecté le tableHeader au rowHeaderView du JScrollPane (scrollpane.setRowHeaderView(jtable.getJTableHeader()). C'est quelque chose qui est couramment omis parce que sous Windows on ne voit pas l'effet que ça a la plupart du temps. Mais il est possible que l'implémentation soit plus sensible à cette omission sous Ubuntu.
    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
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Salut,

    Merci pour ta réponse. Non, effectivement, je n'ai pas fait cette opération.

    Petite correction dans mon message précédent : le problème survient lors du déplacement de l'ascenseur horizontal et non vertical comme je l'avais écrit


    Dans le constructeur de ma classe dérivée d'un JScollPane j'ai fait comme ceci :
    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
           JViewport view = new JViewport();
     
            // Ajout de la table "table" au JScrollPane
            this.setViewportView(table);
     
            // Ajout de la table "tableFix" au RowHeader pour avoir une colonne fixe
            view.setView (tableFix);
            dimFixCol.width = 80 * Constants.N_COL_FIX;
            dimFixCol.height = Constants.ROW_HEIGHT * Constants.N_ROW;
            tableFix.setPreferredSize(dimFixCol);
            view.setPreferredSize(dimFixCol);
            this.setRowHeader(view);

    Je pensais que ce code suffirait (je me suis servi d'un code posté dans les tutos java). Le JViewPort est là pour avoir fixer une colonne fixe à gauche lors du déplacement de la barre horizontale.

    Je testerai ta solution dans le courant de la semaine prochaine.

  4. #4
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,


    @joel.drigo : le TableHeader s'affecte au setColumnHeaderView() et non pas au setRowHeaderView().
    Le setColumnHeaderView() est automatique si on place directement la JTable dans un JScrollPane.


    @Auteur : tu veux faire un entête pour les lignes ? Dans ce cas justement il faut utiliser setRowHeaderView() justement.
    Je ne sais pas ce que tu as fait dans ta redéfinition de JScrollPane, mais le problème doit venir de là (en plus d'être inutile).


    Exemple basique :
    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
    	public static void main(String[] args) {
     
    		final int ROWS = 50;
    		final int COLS = 20;
     
    		String[] colNames = new String[COLS];
    		String[] rowNames = new String[ROWS];
     
    		Object[][] rowData = new Object[ROWS][COLS];
     
     
    		for (int col = 0; col < COLS; col++) {
    			colNames[col] = "Col " + col;
    		}
    		for (int row = 0; row < ROWS; row++) {
    			rowNames[row] = "Row " + row;
    			for (int col = 0; col < COLS; col++) {
    				rowData[row][col] = row + "-" + col;
    			}
    		}
     
    		JTable table = new JTable(rowData, colNames);
     
    		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    		JScrollPane scroll = new JScrollPane(table);
    		scroll.setPreferredSize(new Dimension(600, 400));
     
    		scroll.setRowHeaderView(createRowHeader(table, rowNames, 60));
     
    		JOptionPane.showMessageDialog(null, scroll);
    	}
     
    	public static JComponent createRowHeader(JTable table, String[] rowNames, int width) {
    		JList<String> rowHeader = new JList<String>(rowNames);
    		rowHeader.setFixedCellWidth(width);
    		rowHeader.setFixedCellHeight(table.getRowHeight());
    		rowHeader.setCellRenderer(new RowHeaderRenderer());
    		return rowHeader;
    	}

    Avec le RowHeaderRenderer défini comme ceci (pour reprendre le style de l'entête des colonnes) :
    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 RowHeaderRenderer extends JLabel implements ListCellRenderer<String> {
     
    	RowHeaderRenderer() {
    		setOpaque(true);
    		setBorder(UIManager.getBorder("TableHeader.cellBorder"));
    		setHorizontalAlignment(CENTER);
    		setForeground(UIManager.getColor("TableHeader.foreground"));
    		setBackground(UIManager.getColor("TableHeader.background"));
    		setFont(UIManager.getFont("TableHeader.font"));
    	}
     
    	public Component getListCellRendererComponent(JList<? extends String> list,
    			String value, int index, boolean isSelected, boolean cellHasFocus) {
    		setText((value == null) ? "" : value.toString());
    		return this;
    	}
    }


    Si ton TableModel est fixe cela peut amplement faire l'affaire.
    Maintenant s'il peut être modifié ou trié, cela risque d'être un peu plus complexe car il faudrait mettre à jour les infos en simultanée...


    a++

  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 : 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
    Citation Envoyé par adiGuba Voir le message
    Salut,


    @joel.drigo : le TableHeader s'affecte au setColumnHeaderView() et non pas au setRowHeaderView().
    Le setColumnHeaderView() est automatique si on place directement la JTable dans un JScrollPane.
    Oui au temps pour moi, lapsus. En revanche, tu es sûr que c'est automatique ? Parce que j'ai déjà vu des cas où il avait fallu le faire explicitement (cf http://www.developpez.net/forums/d15...ode-scrollbar/)
    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
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Parce qu'il ne met pas la JTable directement dans le JScrollPane : il y a un JPanel intermédiaire pour modifier le comportement du resize-auto.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    	JPanel innerPanel = new JPanel(new BorderLayout()); // ou new GridLayout(0, 1)
    	innerPanel.add(table);
    	JScrollPane scrollpane = new JScrollPane(innerPanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);

    Or la JTable configure le JScrollPane, mais uniquement lorsque c'est un parent directe.
    De plus ce n'est pas tip-top car JTable implémente l'interface Scrollable qui permet d'optimiser le scroll.
    Or ceci ne peut être pris en compte que si l'on rajoute la JTable directement dans le JScrollPane.

    On peut voir cela sur la différence lorsqu'on scrolle vers le bas en appuyant sur la flèche du JScrollBar :
    • Si le JTable est directement dans le JScrollPane, on a un scroll qui se fait ligne par ligne.
    • Sinon on a un scroll pixel par pixel bien moins efficace.



    Au passage cette interface Scrollable permet de résoudre plus proprement le problème en question... (je détaille dans l'autre post)


    a++

  7. #7
    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
    Citation Envoyé par adiGuba Voir le message
    Parce qu'il ne met pas la JTable directement dans le JScrollPane : il y a un JPanel intermédiaire pour modifier le comportement du resize-auto.
    Ah, bah, oui, forcément.

    Citation Envoyé par adiGuba Voir le message
    Au passage cette interface Scrollable permet de résoudre plus proprement le problème en question... (je détaille dans l'autre post)
    C'est un peu dommage que ça ne le fasse pas nativement et qu'il faille adapter. Du coup, ça me semblait plus simple et rapide d'intercaler un JPanel, mais je n'avais pas penser à l'impact sur le scrolling par ligne. J'attends de voir te solution via Scrollable.
    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.

  8. #8
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Oui effectivement, il y a une ligne et une colonne fixe pour mes entêtes. Pour le code je me suis inspiré de cette source :
    http://java.developpez.com/telecharg...colonnes-fixes

    adiGuba, je vais essayer ta solution.

    Je me demandais aussi si un repaint() ou (re)validate() pouvait résoudre le problème car si je redimensionne la fenêtre (JFrame) tout revient en place.

  9. #9
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut
    Je me suis aperçu que cela ne touchait pas que les JTables mais aussi mes JFileChooser.

    Je crois que je viens de trouver l'origine du problème :
    http://stackoverflow.com/questions/2...ect-in-jdk-1-7
    Je vais donc essayer la solution proposée :
    -Dsun.java2d.d3d=false

  10. #10
    Expert éminent sénior
    Avatar de Auteur
    Profil pro
    Inscrit en
    Avril 2004
    Messages
    7 648
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 7 648
    Points : 11 137
    Points
    11 137
    Par défaut


    Ça ne vient pas du code. Voici donc les paramètres qu'il m'a fallu ajouter pour corriger ce problème (en plus du paramètre -jar).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    java -Dsun.java2d.d3d=false -Dsun.java2d.opengl=true -jar monJar.jar
    A toutes fins utiles, voici la liste des flags : docs.oracle.com/javase/7/docs/technotes/guides/2d/flags.html

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 04/04/2013, 21h06
  2. Réponses: 4
    Dernier message: 14/10/2010, 09h00
  3. Réponses: 4
    Dernier message: 26/08/2009, 05h54
  4. pb repaint sur JPanel contenu dans un JScrollPane
    Par pcouas dans le forum Agents de placement/Fenêtres
    Réponses: 3
    Dernier message: 12/03/2009, 12h27
  5. [DIV] [FireFox] Problème affichage du contenu dans un div
    Par jibouze dans le forum Balisage (X)HTML et validation W3C
    Réponses: 6
    Dernier message: 24/11/2005, 11h06

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