2010-09-11 13 views
17

J'essaie d'obtenir la mise en page d'un JDialog à mon goût pour un look particulier qu'un programme dans lequel je porte sur Java, j'ai déjà utilisé plusieurs LayoutManagers avec beaucoup de succès mais pour une raison que je ne peux pas sembler pour que cela fonctionne du tout. Mon objectif est d'avoir le côté droit (Est) de la JDialog contenir un bouton "Trouver Suivant" et "Annuler" dans un ordre descendant, puis tout espace supplémentaire ci-dessous de sorte que les deux boutons sont toujours en haut de la JDialog , mais pour une raison quelconque BoxLayout ignore continuellement toutes les tentatives de changer (c'est où je suis perdu) la largeur d'un JButton. Le code suit.Pourquoi BoxLayout ne me permet-il pas de changer la largeur d'un JButton mais permettez-moi de changer la hauteur?

JButton findNext = new JButton("Find Next"); 
JButton cancel = new JButton("Cancel"); 
cancel.setPreferredSize(new Dimension((int)findNext.getPreferredSize().getWidth(), 
    (int)cancel.getPreferredSize().getHeight())); 

JPanel example = new JPanel(); 
example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS)); 
example.add(findNext); 
example.add(cancel); 
example.add(Box.createGlue()); 

Peu importe ce que j'essaie, cancel demeure toujours intact sa taille normale. J'ai essayé setMinimumSize() et setMaximumSize() avec les mêmes paramètres que setPreferredSize sans chance. J'ai même essayé cancel.setPreferredSize(new Dimension(500, 500)); et la hauteur des boutons était la seule chose ajustée, il a TOUJOURS conservé la largeur par défaut qui lui a été donnée. Pour éclaircir les questions, voici à quoi il ressemble (maintenant que je l'ai terminé) et vous verrez que les boutons "Rechercher Suivant" et "Annuler" n'ont pas la même taille.

example image

+0

J'ai ajouté un lien vers la question principale du JDialog terminé afin que vous puissiez mieux comprendre mon problème. –

+0

@Tim Merci, je révisais le code pour mettre la partie pertinente ici, désolé j'ai manqué la parenthèse. –

+0

@izuriel - Pas de problème, je l'ai juste copié sur Eclipse pour le jouer un peu et j'ai remarqué qu'il manquait, donc je voulais le réparer pour les autres. :) –

Répondre

40

Je sais que c'est une vieille question mais je ne vois pas vraiment une bonne explication. Donc, pour les chercheurs qui tombent sur cela, je vais ajouter mes deux cents.

Il existe trois méthodes associées au dimensionnement des composants dans Swing: setPreferredSize(), setMinimumSize() et setMaximumSize(). Cependant, le point important est qu'il appartient au gestionnaire de disposition particulier utilisé de savoir s'il honore ou non l'une de ces méthodes.

Pour BoxLayout (la mise en page de l'affiche originale utilise):

  • setMinimumSize() - BoxLayout honneurs cette
  • setMaximumSize() - BoxLayout honneurs cette
  • setPreferredSize() - si X_AXIS est utilisé largeur est respectée, si Y_AXIS est utilisé hauteur est honorée

L'OP utilise un Y_AXIS BoxLayout qui est la raison pour laquelle seule sa hauteur était ch anged.

Mise à jour: J'ai mis en place une page avec cette même information pour tous les gestionnaires de disposition. Espérons que cela peut aider certains chercheurs sur: http://thebadprogrammer.com/swing-layout-manager-sizing/

+1

Oui c'est une vieille question, et oui mon problème a été résolu avec les réponses précédentes données mais je dois vous remercier beaucoup pour expliquer ce qui a causé exactement ce problème. Je ne connais pas autant le fonctionnement interne de Java que je le souhaiterais et j'apprends plutôt lentement alors j'apprécie vraiment cette réponse! Je vous remercie! –

+0

+1 pour le bon résumé. Nitpicking: ce n'est pas le _setXX_ en ce que le LayoutManager honore (ou pas), c'est le _property_ XX: les composants devraient implémenter quelque chose de raisonnable, en particulier pour maximumSize. Certains composants de base ne le font pas (comme les fi l-one comme textField, comboBox ... doivent atteindre leur hauteur) – kleopatra

6

Vous ne voulez pas Box.createGlue(), qui « grows as necessary pour absorber un espace supplémentaire dans son contenant. » Au lieu de cela, utilisez Box.createVerticalStrut()entre les boutons, comme indiqué ci-dessous et dans le ControlPanel de ce simulation.

example.setLayout(new BoxLayout(example, BoxLayout.Y_AXIS)); 
example.add(findNext); 
Box.createVerticalStrut(10); 
example.add(cancel); 

Addendum:

ajouter à setMaximumSize() fait fonctionner.

Ceci est le comportement attendu pour les composants ayant des largeurs maximales identiques dans un BoxLayout vertical, tel que décrit dans Box Layout Features. La largeur préférée du conteneur devient celle des enfants (également grands) et l'alignement X devient inutile.

example.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
JButton findNext = new JButton("Find Next"); 
JButton cancel = new JButton("Cancel"); 
Dimension d = findNext.getMaximumSize(); 
cancel.setMaximumSize(new Dimension(d)); 
example.add(findNext); 
example.add(cancel); 
+0

J'apprécie la réponse trashgod mais je pense que vous avez peut-être mal compris la question. Le seul problème que j'ai est que BoxLayout (au moins je suppose que c'est ce qui le fait) ne permet pas ou affiche des changements à la largeur de la JButton annuler que je voudrais faire la même taille que le JButton findNext . La boîte.createGlue(); est là pour le but pour lequel il était destiné, pour prendre tout l'espace au-dessous des deux boutons qui garderaient les boutons en haut du JDialog. –

+0

@izuriel: Tout à fait raison, j'ai mal lu; Pardon. J'ai ajouté ma compréhension de la raison pour laquelle 'setMaximumSize()' fonctionne. – trashgod

+0

Encore une fois, merci pour la réponse, votre description avec Tim m'a aidé à comprendre le problème que j'avais et j'apprécie tout. –

3

Comme mentionné dans les commentaires sur la question, vous étiez en mesure de le réparer en passant à setMaximumSize(). Cependant, comme vous l'avez noté, setPreferredSize() ne fonctionne pas. Alors, qu'est-ce qui se passe avec ça?

Avec beaucoup de choses Swing, les propriétés utilisées pour déterminer la taille réelle des composants lors de l'utilisation du BoxLayout sont quelque peu aléatoires (à mon avis). Lors de la détermination du rendu des composants, Swing appelle le layoutComponent() sur le gestionnaire de disposition, qui indique où positionner tout.

la mise en œuvre de » BoxLayout de layoutComponent() implique un appel à une méthode qui crée SizeRequirements objets pour la largeur et la hauteur de chacun des composants que vous ajoutez à la JPanel, en fonction de leurs méthodes getMinimum/Preferred/MaximumSize(). Plus tard, il appelle SizeRequirements.calculateAlignedPositions() pour déterminer les valeurs de largeur correctes pour chaque composant, car votre orientation est BoxLayout.Y_AXIS (Les hauteurs sont calculées en utilisant une méthode différente).En prenant des extraits de la source, la mise en œuvre pertinente de cette méthode est la suivante:

for (int i = 0; i < children.length; i++) { 
    SizeRequirements req = children[i]; 
    //... 
    int maxAscent = (int)(req.maximum * alignment); 
    int maxDescent = req.maximum - maxAscent; 
    //... 
    int descent = Math.min(totalDescent, maxDescent); 
    //... 
    spans[i] = (int)Math.min((long) ascent + (long)descent, Integer.MAX_VALUE); 
} 

Notez que totalDescent est la largeur disponible, donc descent est toujours à maxDescent, qui est basé sur SizeRequirements.maximum, qui a été prise de JButton.getMaximumSize() . La valeur de spans[i] est ensuite utilisée plus tard dans un appel à JButton.setBounds() en tant que largeur. Comme vous le remarquerez, getPreferredSize() n'a jamais été impliqué ici, ce qui explique pourquoi le réglage n'a aucun impact dans ce cas.

+0

Merci beaucoup pour l'aide et l'explication, j'admettrai que c'est un peu au-dessus de moi pour comprendre complètement maintenant mais je comprends le concept de base de pourquoi ça fonctionne de cette façon et j'apprécie l'aide supplémentaire. –

0

Habituellement, si vous voulez assurer une taille du composant dans Swing, vous devez appeler setMinimumSize(), setMaximumSize(), et SetPrefferedSize() avec la même valeur.

+0

Oui, normalement je le fais mais il semble que j'ai fait l'erreur (au moins dans mon cas) de copier-coller en copiant le setPreferredSize(), je l'ai collé deux fois, un setMinimumSize et j'ai quitté l'autre accidentellement, pensant que je l'avais changé. Une erreur simple que j'ai oubliée. Merci pour l'aide. –

+0

non, vous ne voulez pas [interférer avec les conseils de dimensionnement fournis par les composants] (http://stackoverflow.com/a/7229519/203657), jamais ;-) – kleopatra

+0

@kleopatra: Je sais que vous ne devriez pas jouer avec ces mais assez souvent on arrive à cette méthode en désespoir de cause pour essayer de faire fonctionner la mise en page damnée. –

-1
button.setMaximumSize(getMaximumSize()); 
0

Si vous mettez vos boutons dans un panneau GridLayout ils seront la même largeur.

+0

En plus de remplir tout l'espace autour d'eux, ils peuvent, comme tout le côté est du panneau - ce qui en fait un solution non idéale malheureusement. Bien que GridLayout ait un but, je ne pense pas que ce soit applicable à la résolution de ce problème, et comme cela a été décrit de manière informative dans la réponse acceptée, la solution était assez simple. –