使用多个JFrame:好的还是不好的做法?[关闭]


530

我正在开发一个显示图像并播放数据库声音的应用程序。我正在尝试确定是否使用单独的JFrame从GUI向数据库添加图像。

我只是想知道使用多个JFrame窗口是否是一种好习惯?


11
仅当您针对多显示器设置时!
DNA

17
我还要指出,这与语言无关,并且与用户界面的关系比Java特别多。
wchargin 2013年

6
我同意@WChargin这个问题比我以前想象的要有价值!
小贩

1
我注意到,初学者(例如我自己)通常会使用多个JFrame。可能是因为从主JFrame内调用它比使用CardLayout容易。尽管在某些情况下不建议使用它。
Hoodlum

调试就像吃仙人掌一样。这是不可取的。
塔斯林·奥塞尼

Answers:


447

我只是想知道使用多个JFrame是否是一种好习惯?

坏习惯(坏习惯)。

  • 用户不友好:用户只希望看到一个图标时,会在任务栏中看到多个图标。加上编码问题的副作用。
  • 编写和维护代码的噩梦:
    • 一个模态对话框提供对对话内容的轻松机会,重点关注-选择/修复/取消,然后继续。多个帧则没有。
    • 单击父级时,带有父级的对话框(或浮动工具栏)将位于最前面-如果这是所需的行为,则必须在框架中实现。

有多种方法可以在一个GUI中显示许多元素,例如:

  • CardLayout(简短演示。)。适用于:
    1. 显示向导之类的对话框。
    2. 显示具有关联组件的项目的列表,树等选择。
    3. 在无组件和可见组件之间翻转。
  • JInternalFrame/JDesktopPane通常用于MDI
  • JTabbedPane 用于组件组。
  • JSplitPane 一种显示两个组件的方法,其中两个组件之间的重要性(大小)根据用户的操作而变化。
  • JLayeredPane 许多很好的..layered组件。
  • JToolBar通常包含一组动作或控件。可以在GUI上拖动,或完全根据用户需要将其关闭。如上所述,将根据父级的操作将其最小化/还原。
  • 作为一个项目JList(下面是一个简单的示例)。
  • 作为中的节点JTree
  • 嵌套的布局

但是,如果这些策略不适用于特定用例,请尝试以下方法。建立单个main JFrame,然后使用其余框作为对话框的父级,为其余的自由浮动元素显示JDialogJOptionPane实例。

许多图像

在多个元素是图像的情况下,最好使用以下任一方法:

  1. 单个JLabel(居中于滚动窗格中)显示当时用户感兴趣的任何图像。如图所示ImageViewer
  2. 单行JList。从这个答案中可以看出。仅当它们的尺寸相同时,“单行”部分才有效。或者,如果您准备即时缩放图像,并且它们的纵横比都相同(例如4:3或16:9)。


4
@AndrewThompson我以前从未遇到过需要多个JFrames且从未考虑过这些问题的情况,感谢您的解释!
杰弗里

4
@ user417896 “仅取决于。” 不,不是。我用过金普。这太可怕了,应该是MDI。
Andrew Thompson

4
@ryvantage “(Excel)应该是MDI吗?” 好问题。我觉得应该以两种方式(一定不仅以MDI形式)提供给用户。例如:1)我目前使用TextPad,通过选择配置,它可以打开单独的实例,每个实例都提供列表中显示的多个文档。2)尽管我通常会在选项卡模式下使用FF,但偶尔我会将选项卡拖到新窗口中。-示例中的共同因素是用户选择。交付应用程序。“无论用户想要什么”。
Andrew Thompson

12
@AndrewThompson您刚刚用上一条评论反驳了自己的论点。在您的主要答复中,您说这是一种不好的做法,绝不应该这样做,但在上面的评论中,您说有时您喜欢SDI,我们应该为用户提供选择。当然,这正是user417896在上面所说的。这取决于。这是我对同伴开发人员最大的不满之一。他们中的许多人对所谓的“最佳实践”产生了宗教狂热。如果我们都坚持“最佳实践”并且不去思考问题,那么我们将没有今天拥有的创新UI。
DuncanKinn13年

4
巨大的概括!让用户单独控制自己的窗口并从任务栏中单独访问它们总是很不错的。好的做法是要了解所有选项,并明智地选择一个。当然,在某些情况下,多个JFrame有意义。
达伍德·伊本·卡里姆

203

JFrame自从我开始对Swing应用程序进行编程以来,我已经实现了多种方法。在大多数情况下,我在一开始就这样做了,因为我没有更好的了解。但是,随着我作为开发人员的经验和知识日渐成熟,并开始在线阅读和吸收许多经验丰富的Java开发人员的意见,我尝试摆脱多种JFrame方法(在当前项目和将来的项目中) )只会遇到...得到我的客户的抵制!当我开始实现模式对话框以控制JInternalFrame单独组件的“子”窗口和s时,我的客户开始抱怨!我很惊讶,因为我正在做我认为是最佳实践的事情!但是,正如他们所说,“幸福的妻子就是幸福的生活”。您的客户也一样。当然,我是承包商,因此我的最终用户可以直接与我(开发人员)联系,这显然不常见。

因此,我将解释多重JFrame方法的好处,以及消除其他方法所带来的一些弊端。

  1. 布局的最大灵活性 -通过允许使用JFrames,您可以使最终用户能够分散并控制其屏幕上的内容。该概念感到“开放”且不受限制。当您趋向于一个大JFrame的一堆JInternalFrames 时,您将失去这一点。
  2. 对于非常模块化的应用程序,它可以很好地工作 -就我而言,我的大多数应用程序都具有3-5个大的“模块”,它们实际上彼此之间没有任何关系。例如,一个模块可能是销售仪表板,而一个模块可能是会计仪表板。他们不互相交谈或任何东西。但是,主管可能希望同时打开它们,并且它们在任务栏上是单独的框架,这使他的生活更加轻松。
  3. 使最终用户可以轻松地参考外部材料 -遇到这种情况:我的应用程序有一个“数据查看器”,您可以从中单击“添加新内容”,这将打开一个数据输入屏幕。最初,两者均为JFrames。但是,我希望数据输入屏幕是JDialog其父屏幕是数据查看器。我进行了更改,然后立即收到来自最终用户的电话,该用户在很大程度上依赖于这样的事实,即当他引用程序的另一部分时,他可以最小化或关闭查看器并使编辑保持打开状态(或网站,不记得了)。他不在多显示器上,因此他需要首先输入对话框,然后再进行其他操作其次,数据查看器完全隐藏。使用a是不可能的JDialog,当然使用a JInternalFrame也不可能。我勉强将其改回JFrames为他的理智而分开,但这给了我一个重要的教训。
  4. 误区三:难以编写代码 -根据我的经验,事实并非如此。我不明白为什么创建一个JInternalFrame比创建一个容易JFrame。实际上,以我的经验,JInternalFrames灵活性要差得多。我开发了一种系统的方法来处理JFrame我的应用程序中s 的打开和关闭,这确实很好。我几乎完全从框架代码本身内控制框架。新框架的建立,SwingWorkers表示控制在后台线程和EDT GUI代码数据的检索,恢复/大家带来前方的框架,如果用户试图两次打开它,等你只需要打开我的JFrames的调用公共静态方法open()和open方法,并结合windowClosing() 事件处理其余部分(框架是否已打开?是否未打开,但正在加载?等),所以我将此方法用作模板,因此对于每个框架都很难实现。
  5. 神话/未经证实:资源繁重 -我想看看这个投机性言论背后的一些事实。尽管也许可以说a JFrame比a 需要更多的空间JInternalFrame,但是即使您打开100 JFrames,您实际上会消耗多少资源?如果您担心的是由于资源导致的内存泄漏:调用dispose()将释放该帧用于垃圾回收的所有资源(而且,我再说一遍,a JInternalFrame应该调用完全相同的问题)。

我写了很多书,我觉得我可以写更多。无论如何,我希望我不要因为它是一种不受欢迎的观点而被否决。这个问题显然是一个有价值的问题,我希望我已经提供了一个有价值的答案,即使这不是普遍的看法。

Microsoft Excel是一个很好的例子,每帧多帧/单文档(SDI)与每帧单帧/多文档(MDI)。MDI的一些好处:

  • 可能有一些非矩形的窗口-因此它们不会在其他进程(例如Web浏览器)中隐藏桌面或其他窗口
  • 在第二个Excel窗口中编写时,可以在一个Excel窗口中从另一个进程打开一个窗口-使用MDI,尝试在其中一个内部窗口中编写将使整个Excel窗口都具有焦点,因此可以从另一个进程中隐藏窗口
  • 可能在不同的屏幕上有不同的文档,这在屏幕分辨率不同的情况下尤其有用

SDI(单文档界面,即每个窗口只能有一个文档):

在此处输入图片说明

MDI(多文档界面,即每个窗口可以有多个文档):

在此处输入图片说明


16
深思熟虑。如果您有多个彼此无关的模块,为什么不创建单独的应用程序呢?另外,没有限制说您必须使用模式对话框,可以使用无模式对话框作为第二个“框架”。
杰弗里

很好的答案和详细的答案,尽管我必须在这一点上与@kleopatra保持一致。.我曾经有一个具有一百多个屏幕的应用程序,用户想要比较来自多个屏幕/具有相同输入的同一屏幕的输出数据。我们构建了一个自定义窗口系统,以使我们能够做到这一点。用户对拥有2个JFrame彼此相邻感到更舒服;)
javatarz

虽然我理解你的说法,我还是宁愿在一个一切都JFrame和一个大的父母JTabbedPane; 但是可以打开第二个窗口(或什至更多个窗口),在这里可以更改布局,从而提供SDI爱好者和MDI爱好者满意的混合行为。在所有情况下,我始终认为这JInternalFrame是一种可怕的模式,它给您带来了两个世界的所有不便之处。他们提供的灵活性太糟糕了,他们没有真正目的就吞噬了许多宝贵的屏幕空间。
Guillaume Polet

我同意SDI有时是适当的(用户通常更喜欢)。还有一个缺点,不幸的是,到目前为止,我还没有找到任何解决方法:每个工具JFrame都有自己的任务栏图标。有时这正是您想要的,但有时不是。在WinAPI中,这很容易配置,但是在Swing中,似乎无法完成。
Suma,

@suma在这种情况下,我想我会选择一个JDialog比一个JFrame
ryvantage

51

我想用一个我刚刚涉及的例子来反驳“非用户友好”的论点。

在我们的应用程序中,我们有一个主窗口,用户可以在其中运行各种“程序”作为单独的选项卡。我们已尽可能尝试将我们的应用程序保留在单个窗口中。

他们运行的“程序”之一显示了系统已生成的报告列表,用户可以单击每行上的图标以弹出打开报告查看器对话框。该查看器正在显示与报告的纵向A4页面相同的图像,因此用户喜欢此窗口很大,几乎充满了他们的屏幕。

几个月前,我们开始收到客户的要求,使这些报表查看器窗口变为无模式,以便他们可以同时打开多个报表。

一段时间以来,我拒绝了此请求,因为我认为这不是一个好的解决方案。但是,当我发现用户如何解决我们系统的“缺陷”时,我的想法改变了。

他们正在打开查看器,使用“另存为”功能将报告另存为PDF到特定目录,使用Acrobat Reader打开PDF文件,然后对下一个报告执行相同的操作。他们将有多个Acrobat Reader运行,并带有他们想要查看的各种报告输出。

因此,我放松了一下,使观众变得毫无模样。这意味着每个查看器都有一个任务栏图标。

当上周向他们发布最新版本时,他们的压倒性反应是他们喜欢它。这是我们最近最流行的系统增强功能之一。

因此,您继续告诉用户他们想要的东西是不好的,但最终它不会给您带来任何好处。

一些注意事项:

  • 在这些无模式窗口中使用JDialog似乎是最佳实践
  • 使用使用new ModalityType而不是boolean modal参数的构造函数。这就是为这些对话框提供任务栏图标的原因。
  • 对于无模式对话框,请将空父级传递给构造函数,但要相对于其“父级”窗口定位它们。
  • Windows上的Java版本6有一个错误,这意味着您的主窗口可以在不通知您的情况下始终位于“顶部”。升级到版本7以解决此问题

6
这也是我的经验。如果我能确定一件事,那就是当人们尝试绕过您的用户友好性来做他们真正想做的事情时,您做错了。功能为王。
ryvantage

解决此问题的一种方法是允许打开多个JFrame,所有JFrame提供相同的功能,但是默认情况下,所有操作都在单个窗口中完成。实际上,这允许用户在SDI或MDI之间进行选择。
Guillaume Polet,2014年

抱歉?您能否更好地解释您的解决方案?怎么可能是一个窗口和多个窗口?我们有一个运行主应用程序的主窗口,但是有时我们需要打开对话框,并且有时这些对话框(基于用户要求)必须是无模式的。制定规则以使接口采用这种方式,否则将为您自己挖一个大漏洞。
DuncanKinn'14年

1
@GuillaumePolet我同意邓肯的看法,您能解释一下您的意思吗?我同意他的困惑
Ungeheuer

我认为他的意思是用户可以启动应用程序的多个副本(“ JFrame”),但在每个副本中都包含SDI。但是,我们的客户端应用程序是非常胖的客户端,因此这将是一种资源匮乏的方法。
DuncanKinnear 2015年


19

自上次我接触秋千以来已经有一段时间了,但总的来说,这样做是一种不好的做法。想到的一些主要缺点:

  • 这更昂贵:您将不得不分配更多的资源来绘制JFrame来绘制其他类型的窗口容器,例如Dialog或JInternalFrame。

  • 不友好:导航进入一堆JFrame并不容易,这看起来像您的应用程序是一组不一致的应用程序,并且设计很差。

  • 易于使用JInternalFrame这是一种反驳,现在,它比我们通过Desktop和JInternalFrame模式所想的要容易得多,并且其他人可以更聪明(或有更多的空闲时间),所以我建议使用它。


7
使用多个时,对用户也没有相同的效果JInternalFrame吗?我个人不同意使用JInternalFrameCardLayout是一个真正的祝福!
Branislav Lazic 2013年

4
我同意@ brano88。JInternalFrame在您提到的三种情况中,任何一种都没有任何优势(1.哪一个证据JInternalFrameJFrame?更轻?2.您的JInternalFrames可能像一堆JFrames 一样混乱/混乱/粘在一起。3.多么JInternalFrame容易?完全相同的代码,只不过其中JDesktopPane一个包含在屏幕中,一个包含在自然屏幕区域中。对我来说,它们听起来同样复杂。)
ryvantage 2013年

1
1.与轻量级的JInternalFrame相比,JFrame是一个重量级的组件。2.您是否看过同时包含大量窗口的应用程序正常运行?IDE,浏览器,甚至在财务应用程序中,也要使其保持在同一范围内。3.我发现JIF过去非常易于使用,并且毫无怨言地选择了最适合场景的组件
Necronet,2013年

4
1.我想证明这一点。两者都是对象,都是JComponents,都具有几乎相同的结构,除了一个在a上渲染JDesktop而一个不是。再次抱歉,但是我相信您正在猜测的“重量” JFrame。2.我的应用程序使用SDI,我的客户很高兴。但是,您说的是“大量的窗户”,这当然很糟糕。但是,我的意思是:“一吨” JInternalFrame会糟透了!如果说JIF允许您成为草率的UI设计器,那就太糟糕了。混乱的混乱是混乱的混乱,无论是JF还是JIF。
ryvantage

2
“当然选择最适合方案的组件”
Necronet

10

绝对是错误的做法。原因之一是每个人都JFrame显示一个新的任务栏图标,这并不是很“用户友好” 。控制多个JFrames将使您扯头发。

就我个人而言,我将使用ONE JFrame进行此类应用。显示多种事物的方法取决于您,有很多。CanvasES, ,JInternalFrameCardLayout甚至JPanelŞ可能。

多个JFrame对象=痛苦,麻烦和问题。


9
嗯……与公认的答案相比,没有什么新奇的东西了吗?
kleopatra 2013年

5
“每个JFrame都会显示一个新的任务栏图标”-仅适用于Windows!在Mac OS X上,无论打开了多少窗口,每个应用程序都只有一个停靠图标,并且应用程序通常具有多个顶级窗口。
罗尔夫2014年

8

我认为使用Multiple Jframe并不是一个好主意。

相反,我们可以在同JPanel一个中使用s个以上。JPanelJFrame

我们也可以在JPanels 之间切换。因此,它给了我们自由展示的余地JFrame

对于每种产品,JPanel我们可以设计不同的事物,并且所有这些JPanel可以一次显示在JFrame一个事物上。

本之间进行切换JPanel的使用JMenuBarJMenuItems用于每个JPanel或“的JButton for eachJPanel`。

一个以上的JFrame做法不是一个好习惯,但是,如果我们想要多个,那就没有错JFrame

但是,最好是JFrame根据我们的不同需求更改一个,而不要使用多个JFrames。


5

如果框架要具有相同的尺寸,为什么不创建框架并将其作为参考传递。

通过框架后,您可以决定如何填充框架。就像拥有一种用于计算一组图形平均值的方法一样。您会一遍又一遍地创建该方法吗?


1
基本上,这就是Cardlayout和JTabbedPane可以做到的,但是相反地,这样做却会使您的代码过于复杂,而您却没有干净而简单的解决方案来实现相同的目的。
Guillaume Polet 2014年

4

这不是一个好习惯,但是即使您希望使用它,也可以将单例模式用作它的好方法。在我的大多数项目中,我都使用了单例模式。


3
单例模式是一场噩梦。任何想要扩展的项目都应不惜一切代价避免使用单例模式。
纪尧姆·波莱
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.