547 votes

L'utilisation de plusieurs JFrames : Bonne ou mauvaise pratique ?

Je suis en train de développer une application qui affiche des images et joue des sons à partir d'une base de données. J'essaie de décider si je dois ou non utiliser un JFrame séparé pour ajouter des images à la base de données depuis l'interface graphique.

Je me demande simplement si c'est une bonne pratique d'utiliser plusieurs fenêtres JFrame ?

12 votes

Seulement si vous visez une installation multi-moniteurs !

18 votes

Je dirais aussi que c'est agnostique de la langue et a trait à la interface utilisateur plus que Java spécifiquement.

7 votes

Je suis d'accord avec cela @WChargin Cette question a pris plus de valeur que je ne l'aurais jamais imaginé !

466voto

Andrew Thompson Points 108505

Je me demande simplement si c'est une bonne pratique d'utiliser plusieurs JFrames ?

Mauvaise (mauvaise, mauvaise) pratique.

  • Inconvénient pour l'utilisateur : l'utilisateur voit plusieurs icônes dans sa barre de tâches alors qu'il s'attendait à n'en voir qu'une seule. Plus les effets secondaires des problèmes de codage
  • Un cauchemar à coder et à maintenir :
    • A dialogue modal offre la possibilité de concentrer son attention sur le contenu de cette boîte de dialogue - choisir/réparer/annuler ceci, puis procéder. Les trames multiples ne le font pas.
    • Une boîte de dialogue (ou une barre d'outils flottante) avec un parent s'affiche lorsque l'on clique sur le parent - il faudrait implémenter cela dans les cadres si c'était le comportement souhaité.

Il existe un grand nombre de façons d'afficher de nombreux éléments dans une interface graphique, par exemple :

  • CardLayout (courte démo. ). C'est bon pour :
    1. Afficher des dialogues de type "assistant".
    2. Affichage des sélections de listes, d'arbres, etc. pour les éléments qui ont un composant associé.
    3. Basculement entre l'absence de composant et le composant visible.
  • JInternalFrame / JDesktopPane généralement utilisé pour un MDI .
  • JTabbedPane pour les groupes de composants.
  • JSplitPane Une façon d'afficher deux composants dont l'importance entre l'un ou l'autre (la taille) varie en fonction de ce que fait l'utilisateur.
  • JLayeredPane beaucoup de composants bien superposés.
  • JToolBar contient généralement des groupes d'actions ou de contrôles. Ils peuvent être déplacés dans l'interface graphique ou en être retirés selon les besoins de l'utilisateur. Comme mentionné ci-dessus, il sera minimisé/rétabli en fonction du parent qui le fait.
  • Comme les éléments d'une JList (exemple simple ci-dessous).
  • Comme les nœuds d'une JTree .
  • Mises en page imbriquées .

Mais si ces stratégies ne fonctionnent pas pour un cas d'utilisation particulier, essayez ce qui suit. Créez un seul site principal JFrame alors on a JDialog o JOptionPane apparaissent pour le reste des éléments flottants, en utilisant le cadre comme parent pour les boîtes de dialogue.

Plusieurs images

Dans ce cas où les éléments multiples sont des images, il serait préférable d'utiliser l'un des éléments suivants à la place :

  1. Un seul JLabel (centré dans un volet de défilement) pour afficher l'image qui intéresse l'utilisateur à ce moment-là. Comme on le voit dans ImageViewer .
  2. Une seule rangée JList . Comme on le voit dans cette réponse . La partie "ligne unique" ne fonctionne que si les images ont toutes les mêmes dimensions. Sinon, si vous êtes prêt à mettre les images à l'échelle à la volée et si elles ont toutes le même rapport d'aspect (par exemple 4:3 ou 16:9).

0 votes

@AndrewThompson C'est étrange, j'utilise un CardLayout, sur le deuxième panneau il y a un autre CardLayout différent utilisé (Aucune image n'est affichée ici) Si je saute entre les panneaux, ils commencent à s'imbriquer l'un dans l'autre. Je suppose donc que je me demande si c'est une mauvaise pratique d'avoir une CL à l'intérieur d'une autre CL...

0 votes

@AndrewThompson Pourquoi l'utilisation de multiples JFrame s bad practice ? Qu'est-ce qui en fait une pratique peu conviviale et un cauchemar de codage ?

5 votes

@AndrewThompson Je n'avais jamais rencontré une situation où j'avais besoin de plusieurs JFrame et je n'avais jamais considéré ces questions, merci de l'expliquer !

209voto

ryvantage Points 2307

Les multiples JFrame est une approche que j'ai mise en œuvre depuis que j'ai commencé à programmer des applications Swing. Pour la plupart, je l'ai fait au début parce que je ne connaissais pas mieux. Cependant Au fur et à mesure que j'ai acquis de l'expérience et des connaissances en tant que développeur et que j'ai commencé à lire et à absorber les opinions de nombreux développeurs Java plus expérimentés en ligne, j'ai tenté de se détourner des multiples JFrame (tant dans les projets actuels que dans les projets futurs) pour se heurter à... écoutez ça... résistance de mes clients ! Lorsque j'ai commencé à mettre en place des boîtes de dialogue modales pour contrôler les fenêtres "enfants" et les JInternalFrame pour les composants séparés, mes clients ont commencé à se plaindre ! J'ai été assez surprise, car je faisais ce que je pensais être la meilleure pratique ! Mais, comme on dit, "Une femme heureuse est une vie heureuse". Il en va de même pour vos clients. Bien sûr, je suis un entrepreneur et mes utilisateurs finaux ont donc un accès direct à moi, le développeur, ce qui n'est évidemment pas un scénario courant.

Donc, je vais vous expliquer les avantages des multiples JFrame ainsi que de démolir certains des arguments négatifs présentés par d'autres.

  1. Flexibilité ultime en matière d'aménagement - En autorisant des JFrame vous donnez à votre utilisateur final la possibilité de s'étendre et de contrôler ce qui s'affiche sur son écran. Le concept est "ouvert" et non contraignant. Vous perdez cela lorsque vous vous orientez vers un grand JFrame et un groupe de JInternalFrame s.
  2. Fonctionne bien pour les applications très modulaires - Dans mon cas, la plupart de mes applications comportent 3 à 5 grands "modules" qui n'ont vraiment rien à voir les uns avec les autres. Par exemple, un module peut être un tableau de bord des ventes et un autre un tableau de bord de la comptabilité. Ils ne communiquent pas entre eux. Cependant, le cadre peut vouloir ouvrir les deux et le fait qu'ils soient séparés dans la barre des tâches lui facilite la vie.
  3. Permet aux utilisateurs finaux de se référer facilement à des documents externes. - Une fois, j'ai eu cette situation : Mon application disposait d'un "visualiseur de données", à partir duquel vous pouviez cliquer sur "Ajouter nouveau", ce qui ouvrait un écran de saisie de données. Au départ, les deux étaient JFrame s. Cependant, je souhaitais que l'écran de saisie des données soit une JDialog dont le parent était le visualisateur de données. J'ai effectué la modification et j'ai immédiatement reçu un appel d'un utilisateur final qui comptait beaucoup sur le fait qu'il pouvait minimiser ou fermer la fenêtre d'affichage des données. téléspectateur et garder le éditeur ouvert pendant qu'il faisait référence à une autre partie du programme (ou à un site web, je ne me souviens plus). Il no sur un multi-moniteur, il avait donc besoin que le dialogue d'entrée soit en premier et autre chose pour être le second, avec le visualisateur de données complètement caché. Cela était impossible avec une JDialog et aurait certainement été impossible avec un JInternalFrame également. A contrecoeur, je l'ai changé pour qu'il soit à nouveau séparé. JFrames pour sa santé mentale, mais ça m'a appris une leçon importante.
  4. Mythe : difficile à coder - Ce n'est pas vrai dans mon expérience. Je ne vois pas pourquoi il serait plus facile de créer un fichier JInternalFrame qu'un JFrame . En fait, d'après mon expérience, JInternalFrames offrent beaucoup moins de flexibilité. J'ai mis au point une méthode systématique pour gérer l'ouverture et la fermeture des fenêtres. JFrame dans mes applications qui fonctionnent vraiment bien. Je contrôle le cadre presque entièrement à partir du code du cadre lui-même ; la création du nouveau cadre, SwingWorker s qui contrôlent la récupération des données sur les threads d'arrière-plan et le code de l'interface graphique sur EDT, qui restaurent/amènent le cadre si l'utilisateur essaie de l'ouvrir deux fois, etc. Tout ce dont vous avez besoin pour ouvrir mon JFrame est d'appeler une méthode statique publique open() et la méthode ouverte, combinée à une windowClosing() gère le reste (le cadre est-il déjà ouvert ? n'est-il pas ouvert, mais en cours de chargement ? etc.) J'ai fait de cette approche un modèle pour qu'il ne soit pas difficile de l'implémenter pour chaque cadre.
  5. Mythe/non prouvé : Lourdeur des ressources - J'aimerais voir des faits derrière cette déclaration spéculative. Bien que, peut-être, vous pourriez dire JFrame a besoin de plus d'espace qu'un JInternalFrame même si vous ouvrez 100 JFrame combien de ressources supplémentaires consommeriez-vous réellement ? Si votre préoccupation est les fuites de mémoire à cause des ressources : appeler dispose() libère toutes les ressources utilisées par le cadre pour la collecte des déchets (et, je le répète, une JInternalFrame devrait susciter exactement la même préoccupation).

J'ai beaucoup écrit et j'ai l'impression que je pourrais écrire encore plus. Quoi qu'il en soit, j'espère que je ne serai pas descendu simplement parce que c'est une opinion impopulaire. La question est clairement intéressante et j'espère avoir fourni une réponse intéressante, même si ce n'est pas l'opinion générale.

Un excellent exemple de cadres multiples/un seul document par cadre ( SDI ) par rapport à une image unique/plusieurs documents par image ( MDI ) est Microsoft Excel. Certains des avantages de MDI :

  • il est possible d'avoir quelques fenêtres de forme non rectangulaire - afin qu'elles ne cachent pas le bureau ou une autre fenêtre d'un autre processus (par exemple un navigateur web)
  • il est possible d'ouvrir une fenêtre d'un autre processus sur une fenêtre Excel tout en écrivant dans une deuxième fenêtre Excel - avec MDI, essayer d'écrire dans une des fenêtres internes donnera le focus à toute la fenêtre Excel, cachant ainsi la fenêtre d'un autre processus
  • il est possible d'avoir des documents différents sur des écrans différents, ce qui est particulièrement utile lorsque les écrans n'ont pas la même résolution

SDI (Single-Document Interface, c'est-à-dire que chaque fenêtre ne peut avoir qu'un seul document) :

enter image description here

MDI (Multiple-Document Interface, c'est-à-dire que chaque fenêtre peut contenir plusieurs documents) :

enter image description here

17 votes

Bien pensé. Si vous avez plusieurs modules qui n'ont rien à voir les uns avec les autres, pourquoi ne pas créer des applications distinctes ? En outre, il n'y a aucune restriction disant que vous devez utiliser modal vous pouvez utiliser des boîtes de dialogue sans modèle pour servir de deuxième "cadre".

1 votes

Très bonne réponse et réponse détaillée bien que je doive être d'accord avec @kleopatra sur ce point J'ai eu une fois une application avec plus de cent écrans où les utilisateurs voulaient comparer les données de sortie de plusieurs écrans/du même écran avec différentes entrées. Nous avons construit un système de fenêtrage personnalisé pour nous permettre de le faire. Les utilisateurs étaient simplement plus à l'aise avec 2 JFrames à garder l'un à côté de l'autre ;)

1 votes

Bien que je comprenne votre argument, je préférerais toujours avoir tout en un seul. JFrame et un grand parent JTabbedPane mais avec la possibilité d'ouvrir une deuxième fenêtre (ou même plus) où la disposition peut être différente, offrant ainsi un comportement hybride où les amateurs de SDI sont heureux et ceux de MDI aussi. Dans tous les cas, j'ai toujours considéré JInternalFrame comme un modèle horrible qui vous donne tous les inconvénients des deux mondes. La flexibilité qu'ils offrent est tout simplement nulle et ils grignotent beaucoup d'espace précieux à l'écran sans aucun but réel.

54voto

DuncanKinnear Points 1062

J'aimerais contrer l'argument du "manque de convivialité" avec un exemple auquel je viens d'être confronté.

Dans notre application, nous avons une fenêtre principale dans laquelle les utilisateurs exécutent divers "programmes" dans des onglets séparés. Dans la mesure du possible, nous avons essayé de limiter notre application à cette seule fenêtre.

L'un des "programmes" qu'ils exécutent présente une liste de rapports qui ont été générés par le système, et l'utilisateur peut cliquer sur une icône sur chaque ligne pour ouvrir une fenêtre de visualisation du rapport. Cette visionneuse affiche l'équivalent de la ou des pages A4 du rapport en format portrait ou paysage, et les utilisateurs aiment que cette fenêtre soit assez grande, remplissant presque leur écran.

Il y a quelques mois, nous avons commencé à recevoir des demandes de nos clients pour que ces fenêtres de visualisation de rapports soient sans modèle, afin qu'ils puissent avoir plusieurs rapports ouverts en même temps.

Pendant un certain temps, j'ai résisté à cette demande car je ne pensais pas que c'était une bonne solution. Cependant, j'ai changé d'avis lorsque j'ai découvert comment les utilisateurs contournaient cette "déficience" de notre système.

Ils ouvraient une visionneuse, utilisaient la fonction "Enregistrer sous" pour enregistrer le rapport au format PDF dans un répertoire spécifique, utilisaient Acrobat Reader pour ouvrir le fichier PDF, puis faisaient de même avec le rapport suivant. Ils utilisaient plusieurs Acrobat Reader avec les différents rapports qu'ils souhaitaient consulter.

J'ai donc cédé et fait en sorte que le visualiseur ne soit pas un modèle. Cela signifie que chaque visionneuse a une icône dans la barre des tâches.

Lorsque la dernière version leur a été présentée la semaine dernière, ils ont été nombreux à dire qu'ils l'ADORENT. C'est l'une des améliorations récentes les plus populaires du système.

Vous allez donc dire à vos utilisateurs que ce qu'ils veulent est mauvais, mais que cela ne vous rendra pas service.

QUELQUES NOTES :

  • Il semble que la meilleure pratique consiste à utiliser des JDialog pour ces fenêtres sans modèle.
  • Utilisez les constructeurs qui utilisent le nouveau ModalityType plutôt que le booléen modal argument. C'est ce qui donne à ces boîtes de dialogue l'icône de la barre des tâches.
  • Pour les boîtes de dialogue sans modèle, passez un parent nul au constructeur, mais localisez-les par rapport à leur fenêtre "parent".
  • La version 6 de Java sur Windows a un bogue ce qui signifie que votre fenêtre principale peut devenir "toujours en haut" sans que vous le lui disiez. Passez à la version 7 pour corriger ce problème

7 votes

C'est exactement mon expérience aussi. S'il y a une chose dont je suis certain, c'est que vous faites quelque chose de mal lorsque les gens essaient de contourner votre convivialité pour faire ce qu'ils veulent vraiment faire. La fonctionnalité est reine.

0 votes

Une façon de contourner ce problème est de permettre l'ouverture de plusieurs JFrame, offrant toutes les mêmes fonctionnalités, mais par défaut, tout se fait dans une seule fenêtre. Cela permet en fait à l'utilisateur de choisir entre SDI et MDI.

0 votes

Pardon ? Pouvez-vous expliquer votre solution un peu mieux, s'il vous plaît ? Comment peut-il s'agir d'une fenêtre unique ET de plusieurs fenêtres ? Nous avons une fenêtre principale où l'application principale s'exécute, mais parfois nous avons besoin d'ouvrir des boîtes de dialogue, et parfois ces boîtes de dialogue (basées sur les besoins de l'utilisateur) doivent être sans modèle. En établissant des règles selon lesquelles l'interface doit être telle ou telle chose, vous ne ferez que creuser un grand trou.

20voto

Faire un jInternalFrame dans le cadre principal et le rendre invisible. Vous pouvez ensuite l'utiliser pour d'autres événements.

jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);

19voto

Necronet Points 3212

Cela fait un moment que je n'ai pas touché au swing mais en général, c'est une mauvaise pratique de faire cela. Quelques-uns des principaux inconvénients qui me viennent à l'esprit :

  • C'est plus cher : vous devrez allouer beaucoup plus de ressources pour dessiner un JFrame qu'un autre type de conteneur de fenêtre, tel que Dialog ou JInternalFrame.

  • Pas facile à utiliser : Il n'est pas facile de naviguer dans un tas de JFrame collés les uns aux autres, on aura l'impression que votre application est un ensemble d'applications incohérentes et mal conçues.

  • Il est facile d'utiliser JInternalFrame C'est un peu rétorqué, maintenant c'est beaucoup plus facile et d'autres personnes plus intelligentes (ou avec plus de temps libre) que nous ont déjà réfléchi au motif Desktop et JInternalFrame, donc je recommande de l'utiliser.

8 votes

N'avez-vous pas le même effet pour l'utilisateur lorsque vous utilisez de multiples JInternalFrame s aussi ? Personnellement, je ne suis pas d'accord avec l'utilisation de JInternalFrame 's ! CardLayout est une vraie bénédiction !

6 votes

Je suis d'accord avec @brano88. JInternalFrame n'offre aucun avantage dans aucun des trois cas que vous avez mentionnés (1. où est la preuve que JInternalFrame est plus léger que JFrame ? 2. Votre site JInternalFrame peuvent être tout aussi encombrés, désordonnés ou collés les uns aux autres qu'un groupe de JFrame s. 3. Comment JInternalFrame plus facile ? C'est exactement le même code, sauf que l'un est contenu dans un JDesktopPane et un autre est contenu dans la zone d'écran naturel. Ils me semblent tout aussi complexes l'un que l'autre).

1 votes

1. JFrame est un composant lourd comparé à JInternalFrame qui est un composant léger. 2. Avez-vous déjà vu une application qui contient des tonnes de Windows en même temps pour être fonctionnelle ? IDE, navigateurs, même dans une application financière, c'est un objectif de les garder dans la même portée. 3. J'ai trouvé JIF très facile à utiliser dans le passé et je n'ai pas à me plaindre. Bien sûr, il faut choisir le composant qui convient le mieux à un scénario.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X