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

Agents de placement/Fenêtres Java Discussion :

[JDialog]comment effectuer un setsize (ou pack) sans repaint


Sujet :

Agents de placement/Fenêtres Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut [JDialog]comment effectuer un setsize (ou pack) sans repaint
    J'ai fait une palette d'outils à partir d'un jdialog composé d'un JPanel boxlayout vertical. Ce JPanel contient des zones de palettes (class PaletteZone extends JPanel) repliables et dépliables.

    Voilà mon petit soucis :
    La méthode de la class PaletteZone utilisée pour replier (à partir d'un MouseClick event) est :

    public void collapse(){
    ContentVisible=false;
    ZoneTitle.title.setIcon(rightTriangle);
    // le component 0 est la barre de titre, le component 1 est l'ensemble d'icones :
    this.remove(1);
    JP.validate();
    }

    **** 1 ) en utilisant JP.validate(), je n'ai aucun scintillement (flickering) sur ma palette et le look est très fluide... MAIS malheureusement le JDialog n'est pas remis à la bonne taille. On obtient ceci en cliquant sur "construction" :

    AVANT :


    APRES :


    **** 2 ) en utilisant JP.pack(), bien sûr le dialogue est correctement retaillé et redessiné, mais cela cause un scintillement qui m'exaspère fortement (tous les composants sont redessinés)

    **** 3 ) en utilisant JP.setSize(), cela a le même effet qu'un pack...

    Comment puis-je me sortir d'après vous de ce dilemne ???
    [/img]

  2. #2
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Comment ca un scintillement ? Tu animes la transition ou pas ?

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    Non, non, pas de transition : la zone de palette se replie brutalement après le remove et le validate

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    En fait dans mon netbeans en mode debbug, j'ai remarqué que lorsque je faisais un pack(), tout le contenu de la palette était effacé puis redessiné ensuite. Cette effacement redessinage est probablement ce qui produit le scintillement...

  5. #5
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Tu utilises quel JDK ?

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    JDK 1.4

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    Plus précisément :
    java version "1.4.2_09"

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    Je viens de faire de multiples essais simples avec JFrames et JDialog contenant des JButtons. A chaque appel de "pack()" ou de "setsize()", le contenu de la fenêtre est d'abord effacé (immédiatement) et ensuite passé aux paint methods...

    Je suis tout nouveau en java : il y a moins d'un mois que je m'y suis mis... Et je ne sais pas du tout comment me sortir de ce mauvais pas... Il y a t il quelqueclose à gratter du côté du doublebuffering ou je ne sais quoi encore, pour limiter les effets de ce pack ou de ce setsize qui me semblent de plus en plus lourdingues ?

  9. #9
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Cela me parait tres etrange. Avant de t'embourber dans un double buffering inutile, essaye avec le JDK 1.5. Deja tu auras de bien meilleures performances dans tes applis Swing sans rien faire. Tu n'es pas OBLIGE de developper avec les nouvelles fonctionnalites de Java 1.5 pour en profiter. Il te suffit de compiler avec -source 1.4 -target 1.4. Bref essaye ca en vaut la peine.

  10. #10
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    Je viens de faire l'essai en mettant la 1.5.0_05-48 comme default java platform dans netbeans. En compilant 1.5, le problème reste exactement le même...

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut Pour être beaucoup plus clair !
    Je viens de faire un essai en refaisant un autre projet "essaiflicker". Pour me rassurer, j'ai tout fait dans le GUIbuilder de netbeans : tout le code est craché automatiquement, sauf les bricoles setsizes... Je me dis que le pb ne vient donc pas de ma façon de programmer.

    Voilà le truc :
    ***** 1) Tout d'abord un lien de téléchargement du dossier contenant essaiflicker.jar :
    http://db-maths.nuxit.net/essaiflicker.zip

    ***** 2) En cliquant sur "Flicker !" on voit le scintillement (je suis sur mac, mais je viens de faire l'essai sur un PC : pareil)

    ***** 3) En cliquant sur "Flicker au ralenti !" on se dirige sur une methode ou je ne fais que rajouter une pause d'une seconde juste après le setSize... Pendant 1 seconde, on voit bien que le background est effacé

    ***** 4) Pour être encore plus clair, voici le code de ma jdialog :


    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
    package essaiflicker;
     
    public class JDialog extends javax.swing.JDialog {
     
        public JDialog(java.awt.Frame parent, boolean modal) {
            super(parent, modal);
            initComponents();
            this.setSize(300,300);
        }
     
        private void initComponents() {
            jButton1 = new javax.swing.JButton();
            jButton2 = new javax.swing.JButton();
            jButton3 = new javax.swing.JButton();
            jButton4 = new javax.swing.JButton();
            jButton5 = new javax.swing.JButton();
     
            getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.Y_AXIS));
     
            setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
            jButton1.setText("Flicker !");
            jButton1.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    jButton1MouseClicked(evt);
                }
            });
     
            getContentPane().add(jButton1);
     
            jButton2.setText("Flicker au ralenti (1s) !");
            jButton2.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    jButton2MouseClicked(evt);
                }
            });
     
            getContentPane().add(jButton2);
     
            jButton3.setText("jButton3");
            getContentPane().add(jButton3);
     
            jButton4.setText("jButton4");
            getContentPane().add(jButton4);
     
            jButton5.setText("jButton5");
            getContentPane().add(jButton5);
     
            pack();
        }
     
        private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {
            if (this.getSize().height==300){
                this.setSize(500,500);
            }else{
                this.setSize(300,300);
            }
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
            }
        }
     
        private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
            if (this.getSize().height==300){
                this.setSize(500,500);
            }else{
                this.setSize(300,300);
            }
     
        }
     
        public static void main(String args[]) {
            java.awt.EventQueue.invokeLater(new Runnable() {
                public void run() {
                    new JDialog(new javax.swing.JFrame(), true).setVisible(true);
                }
            });
        }
     
        private javax.swing.JButton jButton1;
        private javax.swing.JButton jButton2;
        private javax.swing.JButton jButton3;
        private javax.swing.JButton jButton4;
        private javax.swing.JButton jButton5;
    }

    ***** 5) Plus clairement ma question donc : il y a t-il un moyen d'éviter cet effacement du background qui provoque le scintillement à chaque setsize...

  12. #12
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Avec le bouton Flicker je n'ai *aucun* scintillement avec Java SE 6 et en effet un tres leger scintillement avec Java 1.5. Je ne sais pas trop comment tu pourrais corriger ca sans Java 1.6 Le cas de ton Flicker ralenti est beaucoup plus simple en revanche : tu bloques le thread qui est charge de redessiner l'interface graphique. Il est donc normal que rien ne soit redessine. Bref, le cas de Flicker c'est pas ta faute, Flicker au ralenti, c'est ta faute Je demanderai demain aux autres gars de l'equipe Swing s'ils connaissent une technique efficace avec Java 1.4 et 1.5 pour eviter ce scintillement sur un pack() de la fentetre.

    Un truc tout bete mais pourrais-tu essaye avec Toolkit.getDefaultToolkit().setDynamicLayout(true) dans ton main, avant de creer la fenetre. Je ne garantis rien mais ca pourra peut-etre aider.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    avec Toolkit.getDefaultToolkit().setDynamicLayout(true); dans le Main, c'est pareil...
    Par contre je ne comprends pas ce que tu dis sur le thread : bien sûr je bloque pendant la pause, mais cela signifie bien tout de même qu'en sortant du setSize le background a été effacé non ? que de façon "lowlevel" cette instruction provoque un clear ?
    En fait on obtient exactement la même chose en mode debug en mettant un marqueur d'arrêt juste après l'instruction.
    C'est là ma question : ce clear de bas niveau effectué par setSize (ou pack), comment l'éviter ?

  14. #14
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Il faut Java 1.6.

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    Question : quand tu as fais l'essai avec java 1.6, est-ce-que "flicker au ralenti" montrait un background effacé ?
    Si c'est le cas, j'ai des doutes que 1.6 résolve mon problème :

    dans "essaiflicker" j'ai mis que 5 petits boutons standard, et c'est donc dans le genre léger... Je ne doute pas qu'avec un peu plus de rapidité de la VM, on ne voit plus le scintillement.

    Par contre, dans mon appli, il y a beaucoup plus de choses à redessiner (la palette est plein de barres, d'icônes et de sliders : voir plus haut)... Et là je me dis que la 1.6 aussi pourrait très bien montrer le scintillement...

    Le vrai problème c'est cet effacement du background provoqué par setsize ou pack. Ce qui est très étonant, c'est que java sait pourtant faire autrement : un validate(), que que soit la VM, ne provoque absolument aucun scintillement lors de la rétractation des zones de palette, car justement il ne fait pas de clear background...

  16. #16
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Ce n'est pas une question de vitesse. Java 1.6 ne montre aucun scintillement car le double buffering a ete change. Par exemple dans n'importe quelle application Swing 1.4 ou 1.5 si tu promenes tres rapidement une fenetre par dessus tu verras un rectangle gris apparaitre parfois. Dans 1.6 c'est impossible.

    Question : quand tu as fais l'essai avec java 1.6, est-ce-que "flicker au ralenti" montrait un background effacé ?
    Si c'est le cas, j'ai des doutes que 1.6 résolve mon problème :
    Ton test ne prouve rien du tout. En pratique, a moins de faire des choses absurdes comme cela, le probleme n'arrivera pas avec Java 1.6.

    Bref, avec 1.6, l'arriere-plan n'est pas efface mais pas encore dessine, ce qui est tres different. En executant tes tests, la partie correspondant a la petite fenetre est encore affichee correctement alors que la zone supplementaire, apparue suite a l'agrandissement de la fenetre, est "transparente" car Java n'a pas encore dessine dedans.

    Quoi qu'il en soit j'ai modifie ton code et ca va deja beaucoup mieux dans Java 1.5 :

    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
     
        private void jButton2MouseClicked(java.awt.event.MouseEvent evt) {
            if (this.getSize().height==300){
                 java.awt.EventQueue.invokeLater(new Runnable() {
                  public void run() { setSize(500,500); }
                });
            }else{
                 java.awt.EventQueue.invokeLater(new Runnable() {
                  public void run() { setSize(300,300); }
                });
            }
            try {
                Thread.currentThread().sleep(1000);
            } catch (InterruptedException e) {
            }
        }
     
        private void jButton1MouseClicked(java.awt.event.MouseEvent evt) {
            if (this.getSize().height==300){
                java.awt.EventQueue.invokeLater(new Runnable() {
                  public void run() { setSize(500,500); }
                });
            }else{
                java.awt.EventQueue.invokeLater(new Runnable() {
                  public void run() { setSize(300,300); }
                });
            }
     
        }

  17. #17
    Membre régulier
    Profil pro
    Inscrit en
    Mars 2006
    Messages
    11
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2006
    Messages : 11
    Par défaut
    En executant tes tests, la partie correspondant a la petite fenetre est encore affichee correctement alors que la zone supplementaire, apparue suite a l'agrandissement de la fenetre, est "transparente" car Java n'a pas encore dessine dedans.
    Alors là d'accord (c'est d'ailleurs comme cela que j'imagine un refresh) ! Dommage toutefois qu'il me faille attendre 1.6 (pas encore là sur os x ...) .

    Une question de débutant total que je suis : lorsque je compilerai en JDK 6, est-ce ça marchera aussi en choisissant de le faire avec l'option -source 1.4 -target 1.4 ?

    Et pour terminer : merci d'avoir remanié mon code ! je ne connaissais pas cet invokeLater qui fait effectivement un peu mieux sur ma palette.

    Désolé de toutes ces questions en cascade , et merci encore !

  18. #18
    Gfx
    Gfx est déconnecté
    Expert confirmé
    Avatar de Gfx
    Inscrit en
    Mai 2005
    Messages
    1 770
    Détails du profil
    Informations personnelles :
    Âge : 43

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 770
    Par défaut
    Oui ca marchera encore avec -source et -target. Ces options concernent le bytecode genere et les mots-cle autorise dans le code source mais ne changent rien a l'API. Tu conservera donc les avantages de Java SE 6 tout en restant compatible avec les anciennes versions.


    Pour l'invokeLater je te conseille de te renseigner (cf la FAQ notamment) sur la gestion de l'EDT, ou Event Dispatch Thread. C'est LE point cle pour programmer efficacement avec Swing.

Discussions similaires

  1. Comment récupérer le nom du fichier sans l'extension ?
    Par altahir007 dans le forum Langage
    Réponses: 16
    Dernier message: 13/11/2009, 14h20
  2. Réponses: 6
    Dernier message: 24/03/2005, 15h29
  3. Comment effectuer un retour chariot dans 1 JTextarea
    Par elitost dans le forum Composants
    Réponses: 2
    Dernier message: 21/06/2004, 18h18
  4. Réponses: 6
    Dernier message: 27/05/2004, 11h41

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