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 :

[JSplitPane] Problème avec setDividerLocation


Sujet :

AWT/Swing Java

  1. #1
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut [JSplitPane] Problème avec setDividerLocation
    Bonjour,

    Voila j'ai un problème assez bateau mais pas moyen de le résoudre.

    J'ai trois splitpanes imbriques et a l'appui d'une touche je voudrais remettre le splitter la ou je veux.

    Cela marche pour 2 des trois mais pour le troisieme cela ne marche que si la hauteur du splitpane le contenant n'a pas ete touchee.

    Comme un bout de code vaut mieux qu'un long discour:

    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
     
    import java.awt.BorderLayout;
    import java.awt.Container;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSplitPane;
     
     
    public class TestSplit extends JFrame
    {
     
      public TestSplit()
      {
        super();
     
        addWindowListener(new WindowAdapter()
        {
          public void windowClosing(WindowEvent event)
          {
            System.exit(0);
          }
        });
     
        Container contentPane = getContentPane();
        contentPane.setLayout(new BorderLayout());
     
        final JSplitPane split3 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, new JPanel(), new JPanel());
        final JSplitPane split2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JPanel(), split3);
        final JSplitPane split1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);
     
        JButton but = new JButton("Reset");
        but.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent event)
          {
            split1.setDividerLocation(0.5);
            split2.setDividerLocation(0.7);
            split3.setDividerLocation(0.5);
          }
        });
     
        split1.setTopComponent(but);
        split1.setBottomComponent(split2);
     
        split1.setDividerLocation(0.5);
        split2.setDividerLocation(0.7);
        split3.setDividerLocation(0.5);
     
        contentPane.add(split1, BorderLayout.CENTER);
     
        pack();
        setSize(400, 400);
        show();
      }
     
      public static void main(String[] args)
      {
        try
        {
          new TestSplit();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    }
    Pour les gentlemen ayant pris la peine de tester la classe ci-dessus: lors de l'appui sur le bouton reset les splitpanes devraient etre agences comme suit:

    split1 (Le grand split vertical avec le bouton reset en haut): splitter a 50 %: ca c'est ok

    split2 (Le split horizontal en bas de split1): splitter a 70 % ca c'est ok

    split3 (Le split vertical a droite de split2): splitter a 50 % ca c'est pas bon et il faut recliquer sur reset pour le mettre a la bonne place.

    Pour tester, il suffit de bouger le grand splitter horizontal, puis le petit splitter horizontal pour le mettre par exemple tout en bas, on clique sur reset .. et pas bon.

    J'ai essaye avec des revalidate un peu partout, rien n'a change, j'ai essaye un delai avant de faire le setDividerLocation au cas ou ce serait un probleme de synchro dans l'EDT .. il s'en fout.

    Alors si quelqu'un a une idee je suis preneur.

    Merci d'avance,

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  2. #2
    Membre éclairé
    Avatar de bbclone
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 537
    Points : 704
    Points
    704
    Par défaut
    essaye ca:

    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
    import java.awt.BorderLayout;
    import java.awt.Container;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
     
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JSplitPane;
    import javax.swing.SwingUtilities;
     
     
    public class TestSplit extends JFrame
    {
     
      public TestSplit() {
        setDefaultCloseOperation(EXIT_ON_CLOSE);
     
        Container contentPane = getContentPane();
     
        final JSplitPane split3 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true, new JPanel(), new JPanel());
        final JSplitPane split2 = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, new JPanel(), split3);
        final JSplitPane split1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true);
     
        JButton but = new JButton("Reset");
        but.addActionListener(new ActionListener()
        {
          public void actionPerformed(ActionEvent event) {
            split1.setDividerLocation(0.5);
            split2.setDividerLocation(0.7);
     
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    System.out.println("Divider location before " + split3.getDividerLocation());
                    System.out.println("Size before " + split3.getSize().height);
     
                    split3.setDividerLocation(0.5);
                    System.out.println("Divider location after " + split3.getDividerLocation());
                    System.out.println("Size after " + split3.getSize().height);
                }
     
            });
          }
        });
     
        split1.setTopComponent(but);
        split1.setBottomComponent(split2);
     
     
        split1.setDividerLocation(0.5);
        split2.setDividerLocation(0.7);
        split3.setDividerLocation(0.5);
     
        contentPane.add(split1, BorderLayout.CENTER);
     
        setSize(400, 400);
        setVisible(true);
      }
     
      public static void main(String[] args)
      {
        try
        {
          new TestSplit();
        }
        catch (Exception e)
        {
          e.printStackTrace();
        }
      }
    }
    comme tu l'a dit c'est un problem d'EDT.
    maintenant le code qui est la est pas tres propre non plus.

    show est deprecated!
    faire un pack suivi d'un setSize je vois pas l'interet?
    faire un addWindowListener pour faire un System.exit
    ...

  3. #3
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Deja mon projet est en 1.4 donc show pas deprecated.

    Ensuite je vais pas balancer les sources du boulot sur le net, c'est juste un exemple qui reproduit le bug, d'ou le system.exit et le setSize, tant qu'a faire des commentaires debiles tu aurais pu aussi me demander a quoi sert un bouton reset en plein milieu d'une fenetre avec des splitpane vide un peu partout

    Ensuite pour ta solution sache que la methode actionPerformed est deja executee sur l'EDT donc ton invokeLater est un peu louche et surement pas un fix que je vais implementer dans mon projet, ca tient plus de la bidouille qu'autre chose. A moins bien sur que tu ai une explication plus rationnelle que "bah au moins ca marche comme ca" pour appeller une methode depuis un thread pour executer un code ... sur ce meme thread..
    Le seul effet de bord de ce code c'est de laisser le temps a l'EDT de changer la taille du splitpane contenant celui qui marche pas, ce n'est pas garanti de fonctionner tout le temps et j'aurais esperé qu'un appel explicite a revalidate aurais eu cet effet.

    Bon pour eviter des reponses du meme accabi (je devrais coller ca dans ma signature bon sang) je ne suis pas un lapereau de 6 semaines, j'ai un poil d'experience avec java (genre 10 ans de bons et loyaux codages), alors :

    1 - evitez de me prendre pour un debile
    2 - proposez un truc qui ressemble pas a une bidouille infame
    3 - vous pouvez me prendre de haut mais vous risquez une reponse de ce genre
    4 - oui je sais je me suis levé du pied gauche et je retourne me pieuter de suite

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  4. #4
    Membre éclairé
    Avatar de bbclone
    Profil pro
    Inscrit en
    Mai 2006
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2006
    Messages : 537
    Points : 704
    Points
    704
    Par défaut
    10 ans d'experience en java
    ok j'en ai bcp bcp moins!

    mais j'aime pas qu'on me traite!

    alors vite vite sur tes points!!
    show et setVisible
    http://java.sun.com/j2se/1.3/docs/ap...l#show(boolean)
    ceci est le javadoc 1.3 et show est deja deprecated.

    pack et setSize.
    c'est les deux ensemble qui est bizzare!


    1 - evitez de me prendre pour un debile
    j'ai fais ca moi?

    2 - proposez un truc qui ressemble pas a une bidouille infame
    ton code au depart est pire qu' "une bidouille infame".

    - appel a setDividerLocation avant que la frame ne soit visible
    - pack suivi d'un setSize
    - je vais pas demander pourquoi tu n'a pas mis de EventQueue.invokeLater dans ton main

    le code que tu a mis a l'air d'un code de quelqu'un qui vient de commencer a apprendre java.

    3 - vous pouvez me prendre de haut mais vous risquez une reponse de ce genre
    j'ai fais ca moi?

    4 - oui je sais je me suis levé du pied gauche et je retourne me pieuter de suite
    c'est une raison de me traiter?


    je vais pas t'expliquer pourquoi le code que j'ai mis marchera toujours. comme tu as 10 ans d'experience en java reflechis un peu.
    en plus parfois je prend des raccourcis! je le dis que le code que je poste ici est pas propre. je dis pas qu'il faut copier ca comme ca parce que c'est pas propre, je sais. tu m'aurais gentillement demander une explication, je te l'aurais donner comme je l'ai toujours fais jusque maintenant.
    la tu te crois pour je sais pas qui, je te repond plus.
    après 10 ans d'experience en java commence par apprendre a lire la javadoc.a commencer par JSplitPane#setDividerLocation la classe Thread l'interface Runnable la classe EventQueue.

  5. #5
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Deja le show de la JFrame vient de la classe Window et en 1.3 pas deprecated: http://java.sun.com/j2se/1.3/docs/ap...wt/Window.html

    Le setSize juste apres le pack c'est pour la demo que j'ai poste, histoire de ne pas avoir a redimensionner la fenetre pour mettre en evidence le bug.

    Ensuite je l'ai mal pris car j'ai poste a dessein un code (5min sous eclipse) simple montrant le probleme et toi tu debarques sans comprendre que ce code n'a d'autre interet que de mettre en evidence le probleme du setDividerLocation

    L'appel a setDividerLocation avant que la frame soit visible .. oui bah ça ça fait parti des choses ecrites vite faites dans la demo qui ne sont pas dans l'appli sur laquelle j'ai le probleme.

    - je vais pas demander pourquoi tu n'a pas mis de EventQueue.invokeLater dans ton main
    Pas la peine je le repete c'est une demo ..

    Quand a ce qui est de traiter les gens de quoi que ce soit .. si tu me relis tu ne trouveras aucune insulte mais seulement une reaction a tes critiques faciles alors que tu passes a cote du probleme.

    Tu peux expliquer pourquoi un invokeLater sur ce setDividerLocation alors que juste au dessus les 2 autres fonctionnent sans probleme ? Cela m'etonnerait, je reste persuade qu'il y a une solution propre a ce problème.

    Si tu ne souhaite plus me répondre tant mieux, on a perdu tout les 2 notre temps dans cette discussion stérile, passe la main, tu me rendras service.

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  6. #6
    Rédacteur
    Avatar de bulbo
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Février 2004
    Messages
    1 259
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : Finance

    Informations forums :
    Inscription : Février 2004
    Messages : 1 259
    Points : 1 937
    Points
    1 937
    Par défaut
    Bon je suis tombe sur un bug report chez sun qui ressemble etrangement au mien par contre son status est "closed will not be fixed" .. pas cool ca.

    Bref afin de resoudre ce probleme j'ai du "patcher" le JSplitPane pour refaire un setDividerLocation si besoin est au moment du paint.

    C'est pas forcement le top, mais c'est garanti de toujours fonctionner.

    Desole pour l'acces de mauvaise humeur un peu plus haut, mais je suis sur les dents en ce moment ...

    Bulbo
    [Java] [NetBeans] [CVS]
    La FAQ Java
    Merci de ne pas me poser de questions techniques par MP.

  7. #7
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Août 2010
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 15
    Points : 28
    Points
    28
    Par défaut
    Après avoir galéré aussi pas mal de temps voici une surcharge de JSplitPane qui fonctionne bien pour setDividerLocation.

    http://bugs.sun.com/bugdatabase/view...bug_id=4101306

    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
    	boolean isPainted = false;
    	boolean hasProportionalLocation = false;
    	double proportionalLocation;
    	public void setDividerLocation(double proportionalLocation)
    	{       if (!isPainted)
    	        {       hasProportionalLocation = true;
    	                this.proportionalLocation = proportionalLocation;
    	        }
    	        else
    	                super.setDividerLocation(proportionalLocation);
    	}
    	public void paint(Graphics g)
    	{       if (!isPainted)
    	        {       if (hasProportionalLocation)
    	                        super.setDividerLocation(proportionalLocation);
    	                isPainted = true;
    	        }
    	        super.paint(g);
    	}

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

Discussions similaires

  1. Problème avec JSplitPane
    Par Substitut dans le forum Interfaces Graphiques en Java
    Réponses: 2
    Dernier message: 21/08/2012, 11h48
  2. VC++ Direct3D8, problème avec LPD3DXFONT et LPD3DTEXTURE8
    Par Magus (Dave) dans le forum DirectX
    Réponses: 3
    Dernier message: 03/08/2002, 11h10
  3. Problème avec le type 'Corba::Any_out'
    Par Steven dans le forum CORBA
    Réponses: 2
    Dernier message: 14/07/2002, 18h48
  4. Problème avec la mémoire virtuelle
    Par Anonymous dans le forum CORBA
    Réponses: 13
    Dernier message: 16/04/2002, 16h10

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