Dois-je éviter l’utilisation des méthodes de taille set (Preferred | Maximum | Minimum) dans Java Swing?

Plusieurs fois, j’ai été critiqué pour avoir suggéré l’utilisation des méthodes suivantes:

  1. setPreferredSize
  2. setMinimumSize
  3. setMaximumSize

sur les composants Swing . 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 dispositions, 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 parsing complète du sujet. J’ai donc les questions suivantes:

  1. Dois-je éviter complètement l’utilisation de ces méthodes?
  2. Les méthodes ont été définies pour une raison. Alors, quand devrais-je les utiliser? Dans quel contexte? A quelles fins?
  3. Quelles sont les conséquences négatives de l’utilisation de ces méthodes? (Je ne peux que penser à append la portabilité entre les systèmes avec une résolution d’écran différente).
  4. Je ne pense pas que 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?
  5. Si la réponse à 4 est “oui”, cela ne conduira-t-il pas à une prolifération de classes LayoutManager qui deviendront difficiles à maintenir?
  6. Dans une situation où j’ai besoin de définir des proportions entre les enfants d’un composant (par exemple, child1 doit utiliser 10% d’espace, child2 40%, child3 50%), est-il possible d’y parvenir sans implémenter un LayoutManager personnalisé?

J’espère avoir été clair.

  1. Dois-je éviter complètement l’utilisation de ces méthodes?

    Oui pour le code de l’application.

  2. Les méthodes ont été définies pour une raison. Alors, quand devrais-je les utiliser? Dans quel contexte? A quelles fins?

    Je ne sais pas, personnellement je le considère comme un accident de conception API. Légèrement forcé par des composants composés ayant des idées spéciales sur la taille des enfants. “Légèrement”, car ils auraient dû implémenter leurs besoins avec un LayoutManager personnalisé.

  3. Quelles sont les conséquences négatives de l’utilisation de ces méthodes? (Je ne peux que penser à append la portabilité entre les systèmes avec une résolution d’écran différente.)

    Certaines raisons (incomplètes, et malheureusement les liens sont rompus suite à la migration de SwingLabs vers java.net) sont mentionnées dans les Règles (hehe) ou dans le lien trouvé dans le commentaire de @bendicott. Sur le plan social, poser des tonnes de travail à votre malheureux compagnon qui doit maintenir le code et doit retrouver une mise en page brisée.

  4. Je ne pense pas que 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?

    Oui, il existe des LayoutManagers suffisamment puissants pour satisfaire à une très bonne approximation de “tous les besoins de mise en page”. Les trois grands sont JGoodies FormLayout, MigLayout, DesignGridLayout. Donc, non, en pratique, vous écrivez rarement LayoutManagers, sauf dans des environnements simples et hautement spécialisés.

  5. Si la réponse à 4 est “oui”, cela ne conduira-t-il pas à une prolifération de classes LayoutManager qui deviendront difficiles à maintenir?

    (La réponse à 4 est “non”.)

  6. Dans une situation où j’ai besoin de définir des proportions entre les enfants d’un composant (par exemple, l’enfant 1 doit utiliser 10% de l’espace, l’enfant 2 40%, l’enfant 3 50%), est-il possible de réaliser un LayoutManager personnalisé?

    N’importe lequel des Big-Three peut, même pas GridBag (ne jamais se soucier de vraiment maîsortingser, trop de problèmes pour trop peu de puissance).

Quelques heuristiques:

  • N’utilisez pas set[Preferred|Maximum|Minimum]Size() lorsque vous voulez vraiment remplacer get[Preferred|Maximum|Minimum]Size() , comme vous le feriez pour créer votre propre composant, illustré ici .

  • N’utilisez pas set[Preferred|Maximum|Minimum]Size() lorsque vous pouvez vous fier à la getPreferred|Maximum|Minimum]Size un composant, comme indiqué ci -dessous.

  • Utilisez set[Preferred|Maximum|Minimum]Size() pour obtenir la géomésortinge post- validate() , comme indiqué 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 mises en page alternatives ou personnalisées lorsque vous constatez que vous devez parcourir plusieurs composants pour obtenir des tailles dérivées, comme indiqué dans ces commentaires .

entrer la description de l'image ici

 import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.GridLayout; import java.awt.KeyboardFocusManager; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.ArrayList; import java.util.List; import javax.swing.JComponent; import javax.swing.JDesktopPane; import javax.swing.JFrame; import javax.swing.JInternalFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextField; import javax.swing.SwingUtilities; /** * @see https://stackoverflow.com/questions/7229226 * @see https://stackoverflow.com/questions/7228843 */ public class DesignTest { private List list = new ArrayList(); private JPanel panel = new JPanel(); private JScrollPane sp = new JScrollPane(panel); public static void main(Ssortingng args[]) { EventQueue.invokeLater(new Runnable() { @Override public void run() { DesignTest id = new DesignTest(); id.create("My Project"); } }); } private void addField(Ssortingng name) { JTextField jtf = new JTextField(16); panel.add(new JLabel(name, JLabel.LEFT)); panel.add(jtf); list.add(jtf); } private void create(Ssortingng strProjectName) { panel.setLayout(new GridLayout(0, 1)); addField("First Name:"); addField("Last Name:"); addField("Address:"); addField("City:"); addField("Zip Code:"); addField("Phone:"); addField("Email Id:"); KeyboardFocusManager.getCurrentKeyboardFocusManager() .addPropertyChangeListener("permanentFocusOwner", new FocusDrivenScroller(panel)); // Show half the fields sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); sp.validate(); Dimension d = sp.getPreferredSize(); d.setSize(d.width, d.height / 2); sp.setPreferredSize(d); JInternalFrame internaFrame = new JInternalFrame(); internaFrame.add(sp); internaFrame.pack(); internaFrame.setVisible(true); JDesktopPane desktopPane = new JDesktopPane(); desktopPane.add(internaFrame); JFrame frmtest = new JFrame(); frmtest.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frmtest.add(desktopPane); frmtest.pack(); // User's preference should be read from java.util.prefs.Preferences frmtest.setSize(400, 300); frmtest.setLocationRelativeTo(null); frmtest.setVisible(true); list.get(0).requestFocusInWindow(); } private static class FocusDrivenScroller implements PropertyChangeListener { private JComponent parent; public FocusDrivenScroller(JComponent parent) { this.parent = parent; } @Override public void propertyChange(PropertyChangeEvent evt) { Component focused = (Component) evt.getNewValue(); if (focused != null && SwingUtilities.isDescendingFrom(focused, parent)) { parent.scrollRectToVisible(focused.getBounds()); } } } } 

Dois-je éviter complètement l’utilisation de ces méthodes?

Non, il n’y a pas de preuve formelle suggérant d’appeler ou de remplacer ces méthodes n’est pas autorisée. En fait, Oracle indique 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ée).

Plus important encore, peu importe la manière 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 requirejse du composant.

Les méthodes ont été définies pour une raison. Alors, quand devrais-je les utiliser? Dans quel contexte? A quelles fins?

Lorsque vous devez fournir des indications de taille personnalisées au gestionnaire de mise en page des conteneurs afin que le composant soit bien structuré

Quelles sont les conséquences négatives de l’utilisation de ces méthodes? (Je ne peux que penser à append la portabilité entre les systèmes avec une résolution d’écran différente).

  • De nombreux gestionnaires de disposition ne font pas attention à la taille maximale requirejse d’un composant. Cependant, BoxLayout et SpringLayout font. De plus, GroupLayout permet de définir explicitement la taille minimale, préférée ou maximale sans toucher au composant.

  • Assurez-vous que vous avez vraiment besoin de définir la taille exacte du composant. Chaque composant Swing a une taille préférée différente, en fonction de la police utilisée et de l’apparence. Par conséquent, une taille définie peut produire différents aspects de l’interface utilisateur sur différents systèmes.

  • des problèmes peuvent parfois être rencontrés avec GridBagLayout et les champs de texte, dans lesquels 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 substantielle des champs de texte.

  • JFrame n’applique pas le remplacement getMinimumSize() appelant uniquement setMinimumSize(..) sur ses travaux

Je ne pense pas que 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?

Si en mettant en œuvre vous voulez dire utiliser alors oui. Pas un seul LayoutManger ne peut tout gérer, chaque LayoutManager a ses avantages et ses inconvénients et chacun peut être utilisé ensemble pour produire la mise en page finale.

Référence:

Il y a beaucoup de bonnes réponses ici, mais je veux append un peu plus aux raisons pour lesquelles vous devriez normalement les éviter (la question est simplement revenue en double):

À quelques exceptions près, si vous utilisez ces méthodes, vous pourrez probablement adapter votre interface graphique à une apparence spécifique (et à vos parameters 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 insortingnsèquement mauvaises, mais les raisons typiques de leur utilisation sont . Dès que vous commencez à ajuster les positions et les tailles des pixels dans une mise en page, vous risquez de voir votre interface graphique se briser (ou au minimum avoir l’air mal) sur d’autres plates-formes.

À titre d’exemple, essayez de modifier l’apparence par défaut de votre application. Même avec les options disponibles sur votre plate-forme, vous pouvez être surpris de voir à quel point les résultats peuvent être médiocres.

Donc, au nom de garder votre interface graphique fonctionnelle et agréable sur toutes les plates-formes (rappelez-vous que l’un des principaux avantages de Java est son inter-plateforme), vous devez vous fier aux gestionnaires de disposition pour ajuster automatiquement la taille de vos composants afin qu’ils soient rendus 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 insortingnsèquement mauvais, mais leur utilisation est normalement un grand drapeau rouge indiquant des problèmes potentiels d’interface graphique. Assurez-vous que vous êtes conscient du potentiel élevé de complications si / quand vous les utilisez, et essayez toujours de penser, s’il existe une autre solution indépendante à votre problème, le plus souvent, vous constaterez que les méthodes ne sont pas nécessaires.

En passant, si vous êtes frustré par les gestionnaires de disposition standard, il existe de nombreux logiciels tiers gratuits et gratuits, par exemple FormLayout de FormLayout ou MigLayout . Certains générateurs d’interface graphique prennent même en charge les gestionnaires de disposition tiers: l’éditeur graphique de WindowBuilder d’Eclipse, par exemple, prend en charge FormLayout et MigLayout .

Si vous rencontrez des problèmes avec les mises en page dans Java Swing, alors je peux recommander fortement le JGoodies FormLayout fourni gratuitement dans la bibliothèque gratuite de Forms par Karsten Lentzsch ici .

Ce gestionnaire de disposition très populaire est extrêmement flexible, ce qui permet de développer des interfaces utilisateur Java très perfectionnées.

Vous trouverez ici la documentation de Karsten, ainsi que de la documentation plutôt bonne de l’éclipse ici .

Ces méthodes sont mal comsockets par la plupart des gens. Vous ne devez absolument pas ignorer ces méthodes. Il appartient au gestionnaire de mise en page s’ils respectent ces méthodes. Cette page contient un tableau qui indique quels gestionnaires de mise en page respectent laquelle de ces méthodes:

http://thebadprogrammer.com/swing-layout-manager-sizing/

J’écris du code Swing depuis plus de 8 ans et les responsables de la mise en page inclus dans le JDK ont toujours répondu à mes besoins. Je n’ai jamais eu besoin d’un gestionnaire de disposition tiers pour réaliser mes mises en page.

Je dirai que vous ne devriez pas essayer de donner ces astuces au gestionnaire de mise en page tant que vous n’en avez pas besoin. Faites votre mise en page sans donner de conseils de dimensionnement (c.-à-d. Laissez le gestionnaire de disposition faire son travail) et apportez des corrections mineures si nécessaire.

Dans une situation où je dois définir des proportions entre les enfants d’un composant (l’enfant 1 doit utiliser 10% de l’espace, child2 40%, child3 50%), est-il possible d’y parvenir sans implémenter un gestionnaire de disposition personnalisé?

Peut-être que GridBagLayout satisferait vos besoins. En plus de cela, il y a une tonne de gestionnaires de disposition sur le web, et je parie qu’il y en a un qui répond à vos besoins.

Je le vois différemment de la réponse acceptée.

1) Dois-je éviter complètement l’utilisation de ces méthodes?

Ne jamais éviter! 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 disposition et essayez de gérer vous-même la disposition visuelle.

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 de définir OOP pour que votre propre composant soit doté de 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 devrais-je les utiliser? Dans quel contexte? A quelles fins?

Toujours. Lorsque vous créez un composant, définissez sa taille minimale / maximale / réaliste 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 que deux caractères (avec la police actuelle, etc.), mais cela n’a probablement pas de sens. Après tout, les symboles de pays sont deux caractères. Comme ci-contre, si vous avez un JTextField pour saisir, par exemple, un nom de client, sa taille peut être identique à celle de 20 caractères, mais sa taille peut être agrandie. Dans le même temps, avoir un JTextField de largeur 0px est inutile, donc définissez une taille minimale réaliste (je dirais la taille de pixel de 2 caractères).

3) Quelles sont les conséquences négatives de l’utilisation de ces méthodes?

(Je ne peux que penser à append la portabilité entre les systèmes avec une résolution d’écran différente).

Pas de conséquences négatives. Ce sont des conseils pour le gestionnaire de disposition.

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 disposition horizontale et verticale.

Par exemple, la mise en page ci-dessous:

 
 +--------------+--------+ | ###JTABLE### | [Add] | | ...data... |[Remove]| | ...data... | | | ...data... | | +--------------+--------+ 

est en deux parties. Les parties gauche et droite sont horizontales. 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 difficile avec une mise en page réelle. Par conséquent, les gestionnaires de disposition basés sur une grid tels que MigLayout sont bien meilleurs si vous êtes sur le sharepoint développer quelque chose de grave.

5) Si la réponse à 4 est “oui”, cela ne conduira-t-il pas à une prolifération des classes LayoutManager qui deviendront difficiles à maintenir?

Non, vous ne devez absolument pas développer de gestionnaires de mise en page, sauf si vous avez besoin de quelque chose de très spécial.

6) Dans une situation où j’ai besoin de définir des proportions …

entre les enfants d’un composant (par exemple, child1 doit utiliser 10% d’espace, child2 40%, child3 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. Simplement, parce que les pourcentages sont inutiles (par exemple, il est inutile d’avoir un JTextField de 10% de la taille de la fenêtre – puisqu’on peut réduire la fenêtre pour que JTextField ait une largeur de 0px ou pour que la JTextField soit visible configuration multi-affichage).

Mais, parfois, vous pouvez utiliser les pourcentages pour contrôler la taille des plus gros blocs de construction de votre interface graphique (panneaux, par exemple).

Vous pouvez utiliser JSplitPane où vous pouvez prédéfinir le ratio des deux côtés. Ou, vous pouvez utiliser MigLayout qui vous permet de définir de telles contraintes en pourcentage, pixels et autres unités.