Plusieurs fois, on m'a reproché d'avoir suggéré l'utilisation des méthodes suivantes:
- setPreferredSize
- setMinimumSize
- setMaximumSize
sur les Swing
composants. Je ne vois aucune alternative à leur utilisation lorsque je veux définir des proportions entre les composants affichés. On m'a dit ceci:
Avec les mises en page, la réponse est toujours la même: utilisez un LayoutManager approprié
J'ai cherché un peu sur le Web, mais je n'ai trouvé aucune analyse complète du sujet. J'ai donc les questions suivantes:
- Dois-je éviter complètement l'utilisation de ces méthodes?
- Les méthodes ont été définies pour une raison. Alors, quand dois-je les utiliser? Dans quel contexte? À quelles fins?
- Quelles sont exactement les conséquences négatives de l'utilisation de ces méthodes? (Je ne peux que penser à ajouter de la portabilité entre des systèmes avec une résolution d'écran différente).
- Je ne pense pas qu'un LayoutManager puisse satisfaire exactement tous les besoins de mise en page souhaités. Dois-je vraiment implémenter un nouveau LayoutManager pour chaque petite variation de ma mise en page?
- Si la réponse à 4 est "oui", cela ne conduira-t-il pas à une prolifération de classes LayoutManager qui deviendra difficile à maintenir?
- Dans une situation où je dois définir des proportions entre les enfants d'un composant (par exemple, enfant1 doit utiliser 10% de l'espace, enfant2 40%, enfant3 50%), est-il possible d'y parvenir sans implémenter un LayoutManager personnalisé?
la source
JEditorPane
avec HTML qui ne suggère pas lui-même une largeur. OTOH Je ne sais pas si j'ai raté quelque chose. J'examinerai attentivement les réponses sur le fil, mais je serais intéressé si vous aviez des commentaires, en particulier sur ce dernier cas.Quelques heuristiques:
Ne l'utilisez pas
set[Preferred|Maximum|Minimum]Size()
lorsque vous avez vraiment l' intention de remplacerget[Preferred|Maximum|Minimum]Size()
, comme cela pourrait être fait lors de la création de votre propre composant, illustré ici .Ne l'utilisez pas
set[Preferred|Maximum|Minimum]Size()
lorsque vous pouvez compter sur un composant soigneusement remplacégetPreferred|Maximum|Minimum]Size
, comme illustré ici et ci-dessous.Utilisez-le
set[Preferred|Maximum|Minimum]Size()
pour dériver la post-validate()
géométrie, comme illustré ci-dessous et ici .Si un composant n'a pas de taille préférée, par exemple
JDesktopPane
, vous devrez peut-être dimensionner le conteneur, mais un tel choix est arbitraire. Un commentaire peut aider à clarifier l'intention.Envisagez des dispositions alternatives ou personnalisées lorsque vous constatez que vous devrez parcourir plusieurs composants pour obtenir des tailles dérivées, comme mentionné dans ces commentaires .
la source
setPreferredSize()
remplace toujours le calcul du composant par un choix arbitraire.Non, il n'y a aucune preuve formelle suggérant que l'appel ou la substitution de ces méthodes n'est pas autorisé. En fait, Oracle dit que ces méthodes sont utilisées pour donner des indications de taille: http://docs.oracle.com/javase/tutorial/uiswing/layout/using.html#sizealignment .
Ils peuvent également être remplacés (ce qui est la meilleure pratique pour Swing) lors de l' extension d' un composant Swing (plutôt que d'appeler la méthode sur l'instance de composant personnalisé)
Plus important encore, quelle que soit la façon dont vous spécifiez la taille de votre composant, assurez-vous que le conteneur de votre composant utilise un gestionnaire de disposition qui respecte la taille demandée du composant.
Lorsque vous devez fournir des indications de taille personnalisées au gestionnaire de disposition des conteneurs afin que le composant soit bien disposé
De nombreux gestionnaires de mise en page ne prêtent pas attention à la taille maximale demandée d'un composant. Cependant,
BoxLayout
etSpringLayout
faites. En outre,GroupLayout
offre la possibilité de définir explicitement la taille minimale, préférée ou maximale, sans toucher au composant.Assurez-vous que vous devez vraiment définir la taille exacte du composant. Chaque composant Swing a une taille préférée différente, en fonction de la police qu'il utilise et de l'apparence. Ainsi, avoir une taille définie peut produire des looks variés de l'interface utilisateur sur différents systèmes
parfois, des problèmes peuvent être rencontrés avec les
GridBagLayout
champs de texte, où si la taille du conteneur est inférieure à la taille préférée, la taille minimale est utilisée, ce qui peut entraîner une réduction assez importante des champs de texte.JFrame
n'applique pas outrepasségetMinimumSize()
uniquement en faisant appelsetMinimumSize(..)
à ses œuvresSi en implémentant vous entendez utiliser alors oui. Personne ne
LayoutManger
peut tout gérer, chacunLayoutManager
a ses avantages et ses inconvénients, chacun peut donc être utilisé ensemble pour produire la mise en page finale.Référence:
la source
setXxxSize
méthodes comme un drapeau rouge que je pourrais finir ici , même lorsque les documents le suggèrent. J'aurais presque toujours dû passer outregetXxxSize
, où l'on a accès à la géométrie requise; et même de courts exemples sont recyclés plus que je ne le pense. +1 pour mentionner les variations entre les gestionnaires de mise en page et citer le didacticiel.Il y a beaucoup de bonnes réponses ici, mais je veux ajouter un peu plus sur les raisons pour lesquelles vous devriez normalement les éviter (la question vient de se poser à nouveau dans un sujet en double):
À quelques exceptions près, si vous utilisez ces méthodes, vous ajustez probablement votre interface graphique pour bien paraître sur un aspect spécifique (et avec vos paramètres spécifiques au système, par exemple votre police de bureau préférée, etc.). Les méthodes elles-mêmes ne sont pas intrinsèquement mauvaises, mais les raisons typiques de leur utilisation le sont . Dès que vous commencez à régler la position et la taille des pixels dans une mise en page, vous risquez de casser votre interface graphique (ou, au minimum, de ne pas bien paraître) sur d'autres plates-formes.
Par exemple, essayez de changer l'apparence par défaut de votre application. Même avec les options disponibles sur votre plate-forme, vous serez peut-être surpris de la mauvaise qualité des résultats.
Donc, au nom de garder votre interface graphique fonctionnelle et agréable sur toutes les plates-formes (rappelez-vous, l'un des principaux avantages de Java est sa multiplicité), vous devez vous fier aux gestionnaires de mise en page, etc., pour ajuster automatiquement les tailles de vos composants afin qu'il s'affiche correctement en dehors de votre environnement de développement spécifique.
Cela dit, vous pouvez certainement concevoir des situations où ces méthodes sont justifiées. Encore une fois, ils ne sont pas intrinsèquement mauvais, mais leur utilisation est normalement un gros drapeau rouge indiquant des problèmes potentiels d'interface graphique. Assurez-vous simplement que vous êtes conscient du risque élevé de complications si / quand vous les utilisez, et essayez toujours de penser s'il existe une autre solution indépendante de l'apparence à vos problèmes - le plus souvent, vous constaterez que ces les méthodes ne sont pas nécessaires.
Soit dit en passant, si vous vous sentez frustré par les gestionnaires de mise en page standard, il y en a beaucoup de bons tiers gratuits et open source, par exemple JGoodies
FormLayout
, ouMigLayout
. Certains constructeurs d'interface graphique ont même une prise en charge intégrée des gestionnaires de disposition tiers - l'éditeur d'interface graphique WindowBuilder d'Eclipse, par exemple, est livré avec la prise en charge deFormLayout
etMigLayout
.la source
JTextField.setColumns
pour définir le nombre de colonnes, qui ajuste la taille préférée en conséquence. Si vous le faites,setPreferredSize
vous codez en dur une taille, ce qui cassera vos dispositions en fonction de la taille de la police de la plate-forme. Voici quelques champs de texte dans une disposition de sac de grille avecsetColumns
appelé de manière appropriée . Pour vos boutons, utilisez les dispositions / poids de grille appropriés pour contrôler les tailles.Si vous rencontrez des problèmes avec les mises en page dans Java Swing, je peux fortement recommander les JGoodies
FormLayout
fournis gratuitement dans le cadre de la bibliothèque de logiciels gratuits Forms par Karsten Lentzsch ici .Ce gestionnaire de mise en page très populaire est extrêmement flexible, ce qui permet de développer des interfaces utilisateur Java très raffinées.
Vous trouverez la documentation de Karsten ici , et une assez bonne documentation d'Eclipse ici .
la source
Ces méthodes sont mal comprises par la plupart des gens. Vous ne devez absolument pas ignorer ces méthodes. Il appartient au gestionnaire de mise en page s'il respecte ces méthodes. Cette page contient un tableau qui indique quels gestionnaires de mise en page honorent laquelle de ces méthodes:
http://thebadprogrammer.com/swing-layout-manager-sizing/
J'écris du code Swing depuis plus de 8 ans et les gestionnaires de mise en page inclus dans le JDK ont toujours répondu à mes besoins. Je n'ai jamais eu besoin d'un gestionnaire de mise en page tiers pour réaliser mes mises en page.
Je dirai que vous ne devriez pas essayer de donner des conseils au gestionnaire de disposition avec ces méthodes tant que vous n'êtes pas sûr d'en avoir besoin. Faites votre mise en page sans donner de conseils de dimensionnement (c.-à-d. Laissez le gestionnaire de mise en page faire son travail) et vous pourrez ensuite apporter des corrections mineures si vous en avez besoin.
la source
Peut
GridBagLayout
- être satisferait vos besoins. En plus de cela, il y a une tonne de gestionnaires de mise en page sur le Web, et je parie qu'il y en a un qui correspond à vos besoins.la source
Je vois cela différemment de la réponse acceptée.
1) Dois-je éviter complètement l'utilisation de ces méthodes?
N'évitez jamais! Ils sont là pour exprimer les contraintes de taille de vos composants au gestionnaire de disposition. Vous pouvez éviter de les utiliser si vous n'utilisez aucun gestionnaire de mise en page et essayez de gérer la mise en page visuelle par vous-même.
Malheureusement, Swing ne vient pas avec des dimensions par défaut raisonnables. Cependant, au lieu de définir les dimensions d'un composant, il est préférable d'utiliser la POO pour descendre votre propre composant avec des valeurs par défaut raisonnables. (Dans ce cas, vous appelez setXXX dans votre classe descendante.) Vous pouvez également remplacer les méthodes getXXX pour le même effet.
2) Les méthodes ont été définies pour une raison. Alors, quand dois-je les utiliser? Dans quel contexte? À quelles fins?
Toujours. Lorsque vous créez un composant, définissez sa taille réaliste min / préférée / max en fonction de l'utilisation de ce composant. Par exemple, si vous avez un JTextField pour saisir des symboles de pays tels que le Royaume-Uni, sa taille préférée doit être aussi large pour contenir deux caractères (avec la police actuelle, etc.), mais il est probablement inutile de le laisser grossir. Après tout, les symboles de pays sont deux caractères. Comme ci-contre, si vous avez un JTextField pour entrer par exemple un nom de client, il peut avoir une taille préférée comme la taille de pixel pour 20 caractères, mais peut devenir plus grand si la mise en page est redimensionnée, alors définissez la taille maximale sur plus. Dans le même temps, avoir un JTextField large de 0px est inutile, alors définissez une taille minimale réaliste (je dirais la taille de pixel de 2 caractères).
3) Quelles sont exactement les conséquences négatives de l'utilisation de ces méthodes?
(Je ne peux que penser à ajouter de la portabilité entre des systèmes avec une résolution d'écran différente).
Pas de conséquences négatives. Ce sont des conseils pour le gestionnaire de mise en page.
4) Je ne pense pas qu'un LayoutManager puisse répondre exactement à tous les besoins de mise en page souhaités.
Dois-je vraiment implémenter un nouveau LayoutManager pour chaque petite variation de ma mise en page?
Non, absolument pas. L'approche habituelle consiste à mettre en cascade différents gestionnaires de mise en page de base tels que la mise en page horizontale et verticale.
Par exemple, la disposition ci-dessous:
est d'avoir deux parties. Les parties gauche et droite sont une disposition horizontale. La partie droite est un JPanel ajouté à la disposition horizontale, et ce JPanel a une disposition verticale qui dispose les boutons verticalement.
Bien sûr, cela peut devenir délicat avec une mise en page réelle. Par conséquent, les gestionnaires de disposition basés sur une grille tels que MigLayout sont bien meilleurs si vous êtes sur le point de développer quelque chose de sérieux.
5) Si la réponse à 4 est "oui", cela ne conduira-t-il pas à une prolifération de classes LayoutManager qui deviendra difficile à maintenir?
Non, vous ne développerez certainement pas de gestionnaires de mise en page, sauf si vous avez besoin de quelque chose de très spécial.
6) Dans une situation où je dois définir des proportions ...
entre les enfants d'un composant (par exemple, enfant1 doit utiliser 10% de l'espace, enfant2 40%, enfant3 50%), est-il possible d'y parvenir sans implémenter un LayoutManager personnalisé?
Fondamentalement, une fois que les tailles préférées sont définies correctement, vous ne voudrez peut-être rien faire en pourcentage. Tout simplement, parce que les pourcentages sont inutiles (par exemple, il est inutile d'avoir un JTextField 10% de la taille de la fenêtre - car on peut réduire la fenêtre pour que JTextField ait une largeur de 0px, ou peut agrandir la fenêtre pour que le JTextField soit sur deux affichages sur un écran). configuration multi-affichage).
Mais, parfois, vous pouvez utiliser les pourcentages pour contrôler la taille des blocs de construction plus gros de votre interface graphique (panneaux, par exemple).
Vous pouvez utiliser JSplitPane où vous pouvez prédéfinir le rapport des deux côtés. Ou, vous pouvez utiliser MigLayout qui vous permet de définir ces contraintes en pourcentage, pixels et autres unités.
la source
btnBar.setPreferredSize( dimTouchBtn );
est la meilleure façon de le faire. Simple, pas besoin de gestionnaire de mise en page personnalisé. J'utilise principalementGridBagLayout
avec certainsBorderLayout
etBoxLayout
, emboîtant quand c'est pratique. Il s'agit d'une combinaison solide et facile à utiliser.Dois-je éviter complètement l'utilisation de ces méthodes? Je ne dirais pas "les éviter". Je dirais que si vous pensez en avoir besoin, vous faites probablement quelque chose de mal. Les tailles des composants sont déterminées en fonction du contexte. Par exemple, la taille des composants de texte est déterminée par le nombre de lignes et de colonnes que vous spécifiez, combiné à la police que vous avez choisie. La taille de votre bouton et de votre étiquette sera la taille du graphique, si vous en avez défini un, ou l'espace nécessaire pour afficher le texte que vous avez défini. Chaque composant a une taille naturelle et les gestionnaires de disposition les utiliseront pour tout disposer sans que vous ayez à spécifier de tailles. La principale exception est le JScrollPane, qui a une taille indépendante de ce qu'il contient. Pour ceux-là, je vais parfois appeler
setSize()
, et laisser cette taille déterminer la taille initiale de la fenêtre, en appelantJFrame.pack()
. Habituellement, je laisse la taille de la fenêtre déterminer la taille de JScrollPane. L'utilisateur déterminera la taille de la fenêtre. De nombreux gestionnaires de mise en page ignorent de toute façon les tailles que vous définissez, donc ils ne font souvent pas grand-chose.Les méthodes ont été définies pour une raison. Alors, quand dois-je les utiliser? Dans quel contexte? À quelles fins? Je pense qu'ils ont été ajoutés pour fournir des conseils aux gestionnaires de mise en page. Ils peuvent avoir été écrits pour des raisons historiques, car les gestionnaires de mise en page étaient nouveaux et les gens ne leur faisaient pas entièrement confiance. Je connais quelques développeurs qui ont évité les gestionnaires de mise en page et ont tout placé manuellement, simplement parce qu'ils ne voulaient pas se soucier d'apprendre un nouveau paradigme. C'est une terrible idée.
Quelles sont exactement les conséquences négatives de l'utilisation de ces méthodes? (Je ne peux que penser à ajouter la portabilité entre des systèmes avec une résolution d'écran différente). Ils sont inefficaces et produisent de mauvaises dispositions, les objets étant serrés ou étirés à des tailles non naturelles. Et les dispositions seront fragiles. Les modifications de la taille de la fenêtre cassent parfois la disposition et mettent les choses aux mauvais endroits.
Je ne pense pas qu'un LayoutManager puisse satisfaire exactement tous les besoins de mise en page souhaités. Dois-je vraiment implémenter un nouveau LayoutManager pour chaque petite variation de ma mise en page? Vous ne devez pas "implémenter" un nouveau LayoutManager. Vous devez instancier ceux qui existent déjà. J'utilise souvent plusieurs gestionnaires de mise en page dans une seule fenêtre. Chaque JPanel aura son propre gestionnaire de mise en page. Certaines personnes rechignent aux dispositions imbriquées, car elles sont difficiles à maintenir. Lorsque je les utilise, je donne à chacun sa propre méthode de création pour qu'il soit plus facile de voir ce que chacun fait. Mais je n'implémente jamais un gestionnaire de mise en page. Je les instancie juste.
Si la réponse à 4 est "oui", cela ne conduira-t-il pas à une prolifération de classes LayoutManager qui deviendra difficile à maintenir? Si vous implémentez de nouvelles classes de gestionnaire de disposition pour de légères variations de disposition, vous les utilisez mal. Si vous implémentez simplement de nouveaux gestionnaires de disposition, vous faites probablement quelque chose de mal. La seule fois où j'ai étendu une classe LayoutManager, c'était pour ajouter un curseur de zoom à un JScrollPane.
Dans une situation où je dois définir des proportions entre les enfants d'un composant (par exemple, enfant1 doit utiliser 10% de l'espace, enfant2 40%, enfant3 50%), est-il possible d'y parvenir sans implémenter un LayoutManager personnalisé? Le JSplitPane a un moyen de spécifier le pourcentage que chaque composant doit obtenir. Le séparateur est mobile par défaut, mais vous pouvez le désactiver si vous le souhaitez. Je n'utilise pas beaucoup cette fonctionnalité. J'ai généralement certains composants qui prennent une taille définie, et le reste de l'espace est occupé par un volet de défilement. La taille du volet de défilement s'ajustera à la taille de la fenêtre. Si vous avez deux volets de défilement côte à côte, vous pouvez les placer dans un JSplitPane et spécifier le pourcentage de nouvel espace donné à chacun à mesure que l'utilisateur agrandit et contracte les fenêtres.
la source