使用多个 JFrames:好还是坏?[关闭]

The Use of Multiple JFrames: Good or Bad Practice? [closed]

提问人:Peddler 提问时间:3/4/2012 最后编辑:Peddler 更新时间:2/8/2018 访问量:147016

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章用事实和引文来回答。

8年前关闭。

社群在 1 年前审查了是否重新打开这个问题,并将其关闭:

原始关闭原因未解决

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

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

Java Swing 用户界面 JFramer

评论

12赞 DNA 9/23/2012
仅当您的目标是多显示器设置时!
18赞 wchargin 6/10/2013
我还认为这与语言无关,并且与用户界面有关,而不是 Java 具体。
7赞 Peddler 6/10/2013
我同意这一点@WChargin这个问题变得比我想象的更有价值!
2赞 jantristanmilan 11/20/2013
我注意到初学者(比如我自己)通常会使用多个 JFrames。可能是因为从主 JFrame 内部调用它比使用 CardLayout 更容易。尽管在某些情况下不建议使用它。
1赞 Andy McRae 2/27/2021
虽然这篇文章被标记为“基于意见”,但我发现它非常有用,因为两部分:反对者和赞成者。根据他们的经历提出他们的意见和例子。这是其他人习惯的。我正在寻找开发一个具有多个 Jframe 的 java 应用程序。我想知道这是否是不好的做法..或。。但事实上,我看到人们这样做,而其他人则没有。所以我很好

答:

468赞 13 revsAndrew Thompson #1

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

糟糕的(坏的,坏的)做法。

  • 用户不友好:用户在任务栏中看到多个图标,而期望只看到一个图标。加上编码问题的副作用。
  • 编码和维护的噩梦:
    • 模式对话框提供了将注意力集中在该对话框内容上的简单机会 - 选择/修复/取消此对话框,然后继续。多帧则不然。
    • 当点击父项时,带有父项的对话框(或浮动工具栏)将出现在前面 - 如果这是所需的行为,则必须在框架中实现它。

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

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

但是,如果这些策略不适用于特定用例,请尝试以下操作。建立一个 main ,然后让 JDialogJOptionPane 实例出现在其余的自由浮动元素中,使用框架作为对话框的父元素。JFrame

许多图片

在这种情况下,如果多个元素都是图像,则最好改用以下任一方法:

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

评论

6赞 Andrew Thompson 4/17/2013
@user417896 “视情况而定。”不,它没有。我用过Gimp。这太可怕了,应该是 MDI。
5赞 Andrew Thompson 8/1/2013
@ryvantage “(Excel) 应该是 MDI 吗?问得好。我觉得它应该以两种方式提供给用户(当然不仅仅是以 MDI 形式)。例如:1)我目前使用TextPad,并且根据我的选择进行配置,它会打开单独的实例,每个实例都提供列表中显示的多个文档。2)虽然我通常会在选项卡式模式下使用FF,但偶尔我会将选项卡拖到新窗口中。-- 示例中的共同因素是用户选择。交付应用。 “随心所欲”。
16赞 DuncanKinnear 8/16/2013
@AndrewThompson 你刚刚用你最后的评论反驳了你自己的论点。在您的主要回答中,您说这是不好的做法,永远不应该这样做,但在上面的评论中,您说您有时喜欢 SDI,我们应该为我们的用户提供选择。当然,这正是 user417896 上面所说的。这要视情况而定。这是我最讨厌的开发人员之一。事实上,他们中的许多人对所谓的“最佳实践”变得虔诚狂热。如果我们都坚持“最佳实践”并且不跳出方框思考,我们就不会有今天的创新 UI。
7赞 Dawood ibn Kareem 12/26/2013
巨大的概括!让用户单独控制他们的窗口,并从任务栏单独访问它们并不总是坏事。好的做法是了解所有选项,并明智地选择一个。当然,在某些情况下,多个 JFrames 很有意义。
4赞 Dawood ibn Kareem 12/29/2013
此处另一个答案中的 Excel 示例清楚地显示了这一点。有趣的是,在我工作的桌面上,我更喜欢在三个单独的窗口中打开 Eclipse。我觉得这样更方便。YMMV。
20赞 Virendra Singh Rathore 10/17/2012 #2

将 jInternalFrame 放入主框架并使其不可见。然后,您可以将其用于其他事件。

jInternalFrame.setSize(300,150);
jInternalFrame.setVisible(true);
9赞 Matt Dawsey 1/10/2013 #3

绝对是坏的做法。一个原因是它不是很“用户友好”,因为每个图标都显示一个新的任务栏图标。控制多个 s 会让你扯掉你的头发。JFrameJFrame

就个人而言,我会将 ONE 用于您的应用程序。显示多个事物的方法取决于你,有很多。es、、、甚至 s 可能。JFrameCanvasJInternalFrameCardLayoutJPanel

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

评论

11赞 kleopatra 1/10/2013
嗯。。。与公认的答案相比,没什么新鲜的,afaics?
6赞 Rolf 5/27/2014
“每个 JFrame 都显示一个新的任务栏图标” - 这仅适用于 Windows!在 Mac OS X 上,每个应用程序都只有一个停靠图标,无论它打开了多少个窗口,并且应用程序通常具有多个顶级窗口。
19赞 Necronet 3/5/2013 #4

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

  • 它的成本更高:您必须分配更多的资源来绘制 JFrame 而不是其他类型的窗口容器,例如 Dialog 或 JInternalFrame。

  • 对用户不友好:导航到一堆粘在一起的 JFrame 并不容易,看起来您的应用程序是一组不一致且设计不佳的应用程序。

  • JInternalFrame 易于使用这有点反转,现在它更容易了,其他人比我们更聪明(或有更多的空闲时间)已经考虑过桌面和 JInternalFrame 模式,所以我建议使用它。

评论

8赞 Branislav Lazic 6/15/2013
使用多个时,你对用户没有同样的效果吗?就个人而言,我不同意使用 's! 真是有福气!JInternalFrameJInternalFrameCardLayout
6赞 ryvantage 7/31/2013
我同意@brano88。 在你提到的三种情况下,任何一种都没有优势(1.比?2. 你的 s 可能像一堆 s 一样杂乱/凌乱/粘在一起。如何更容易?这是完全相同的代码,只是一个包含在 a 中,一个包含在自然屏幕区域内。对我来说,它们听起来同样复杂。JInternalFrameJInternalFrameJFrameJInternalFrameJFrameJInternalFrameJDesktopPane
1赞 Necronet 7/31/2013
1. JFrame 是一个轻量级的组件,而 JInternalFrame 是一个轻量级的组件。2.您是否见过同时包含大量窗口的应用程序可以正常运行?IDE,浏览器,即使在金融应用程序中,也要将其保持在相同的范围内。3. 我过去发现 JIF 非常易于使用,并且没有任何抱怨,当然选择最适合场景的组件
5赞 ryvantage 7/31/2013
1. 我想看看这方面的证据。两者都是对象,都是 s,两者都具有几乎相同的结构,除了一个在 a 上渲染,一个不是。再次对不起,但我相信您是在猜测 .2. 我的应用程序使用SDI,我的客户非常满意。但是,你说“一大堆窗户”,这当然会很糟糕。但是,我的观点是:“一吨”JInternalFrame会很糟糕!如果你说 JIF 允许你成为一个草率的 UI 设计师,那就太糟糕了。杂乱无章就是杂乱无章的乱七八糟,无论是 JF 还是 JIF。JComponentJDesktopJFrame
2赞 Necronet 8/1/2013
“当然,选择最适合场景的组件”
216赞 ryvantage 7/31/2013 #5

自从我开始编写 Swing 应用程序以来,我就已经实现了多种方法。在大多数情况下,我一开始就这样做了,因为我不知道更好。然而,随着我作为开发人员的经验和知识的成熟,以及我开始在线阅读和吸收许多更有经验的 Java 开发人员的意见,我试图摆脱多种方法(无论是在当前项目还是未来的项目中),结果却遇到了......得到这个...来自客户的抵制!当我开始实现模态对话框来控制单独组件的“子”窗口和 s 时,我的客户开始抱怨!我很惊讶,因为我正在做我认为是最佳实践的事情!但是,正如他们所说,“幸福的妻子是幸福的生活。您的客户也是如此。当然,我是承包商,所以我的最终用户可以直接访问我,开发人员,这显然不是一个常见的情况。JFrameJFrameJInternalFrame

因此,我将解释多种方法的好处,并打破其他人提出的一些缺点。JFrame

  1. 布局的极致灵活性 - 通过允许单独的布局,您可以让最终用户能够展开并控制他/她的屏幕上的内容。这个概念给人的感觉是“开放”和无限制的。当你走向一个大而一堆时,你就会失去这个。JFrameJFrameJInternalFrame
  2. 适用于非常模块化的应用程序 - 就我而言,我的大多数应用程序都有 3 - 5 个大“模块”,它们实际上彼此没有任何关系。例如,一个模块可能是销售仪表板,另一个模块可能是会计仪表板。他们不互相交谈或做任何事情。但是,高管可能希望同时打开这两个框架,并且它们在任务栏上是单独的框架,这使他的生活更轻松。
  3. 使最终用户能够轻松引用外部材料 - 有一次,我遇到过这种情况:我的应用程序有一个“数据查看器”,您可以从中单击“添加新”,它将打开一个数据输入屏幕。最初,两者都是s。但是,我希望数据输入屏幕的父级是数据查看器。我做了这个改变,我立即接到了一个最终用户的电话,他在很大程度上依赖于这样一个事实,即他可以最小化或关闭查看器,并在他引用程序的另一部分(或网站,我不记得了)时保持编辑器打开。他不在多显示器上,所以他需要输入对话框放在第一位,其他内容放在第二位,数据查看器完全隐藏。这在 a 上是不可能的,当然在 a 上也是不可能的。我不情愿地把它改回了分开,因为他的理智,但它给了我一个重要的教训。JFrameJDialogJDialogJInternalFrameJFrames
  4. 误区:难以编码 - 根据我的经验,这不是真的。我不明白为什么创建一个会比创建一个更容易。事实上,根据我的经验,提供的灵活性要小得多。我已经开发了一种系统的方法,可以在我的应用程序中处理 s 的打开和关闭,这真的很有效。我几乎完全从框架的代码本身控制框架;创建新帧,控制后台线程上的数据检索和 EDT 上的 GUI 代码,如果用户尝试打开两次帧,则恢复/将其置于帧前面等。打开我的 s 所需要做的就是调用一个公共静态方法,open 方法与事件相结合处理其余部分(框架是否已经打开?它不是打开的,而是正在加载的?等等)我把这种方法作为一个模板,这样每一帧都不难实现。JInternalFrameJFrameJInternalFramesJFrameSwingWorkerJFrameopen()windowClosing()
  5. 谣言/未经证实:资源繁重 - 我想看看这个推测性陈述背后的一些事实。虽然,也许,你可以说 a 比 a 需要更多的空间,即使你打开 100 秒,你真正会消耗多少资源?如果您担心的是由于资源导致的内存泄漏:调用会释放帧用于垃圾回收的所有资源(我再说一遍,应该调用完全相同的问题)。JFrameJInternalFrameJFramedispose()JInternalFrame

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

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

  • 可以有一些非矩形的窗口 - 这样它们就不会从另一个进程(例如Web浏览器)中隐藏桌面或其他窗口
  • 在第二个 Excel 窗口中写入时,可以在一个 Excel 窗口上打开另一个进程的窗口 - 使用 MDI,尝试在其中一个内部窗口中写入将使焦点聚焦于整个 Excel 窗口,从而隐藏另一个进程的窗口
  • 可以在不同的屏幕上显示不同的文档,这在屏幕分辨率不同时特别有用

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

enter image description here

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

enter image description here

评论

17赞 Jeffrey 7/31/2013
深思熟虑。如果您有多个彼此无关的模块,为什么不创建单独的应用程序呢?此外,没有限制说您必须使用模态对话框,您可以使用无模式对话框作为第二个“框架”。
1赞 javatarz 10/9/2013
非常好的答案和详细的答案,尽管我必须同意@kleopatra这一点。我曾经有一个拥有一百多个屏幕的应用程序,用户希望比较多个屏幕/同一屏幕与不同输入的输出数据。我们构建了一个自定义窗口系统来做到这一点。用户只是更愿意让 2 个 JFrames 彼此相邻;)
1赞 Guillaume Polet 10/1/2014
虽然我理解你的论点,但我仍然更愿意把所有东西都放在一个大父母身上;但有可能打开第二个窗口(甚至更多),其中布局可以不同,因此提供了一种混合行为,SDI 爱好者和 MDI 爱好者也很高兴。在所有情况下,我一直认为这是一种可怕的模式,它给你带来了两个世界的所有不便。它们提供的灵活性非常糟糕,它们会无缘无故地消耗大量宝贵的屏幕空间。JFrameJTabbedPaneJInternalFrame
0赞 Suma 3/27/2018
我同意SDI有时是合适的(用户通常更喜欢它)。还有一个缺点,不幸的是,到目前为止,我没有找到任何解决方法:每个都有自己的任务栏图标。有时这正是您想要的,但有时并非如此。在 WinAPI 中,这很容易配置,但在 Swing 中似乎无法完成。JFrame
1赞 pbierre 9/28/2020
我的应用程序是一个 Dataflow Geometry 编程应用程序,有 2 个 JFrame 窗口:一个编程 GUI(模块拖动单击编辑器,您可以在其中设计程序) 一个 2D 计算机图形(您可以在其中看到程序运行) 它在 MacOS 上运行非常流畅。我唯一需要帮助的是,当您单击任一应用程序窗口(给它 z == 0 排名)时,您如何使兄弟姐妹窗口向前出现(到 z== 1 排名)?我的尝试都导致了无限递归。
55赞 DuncanKinnear 8/30/2013 #6

我想用我刚刚参与的一个例子来反驳“对用户不友好”的论点。

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

他们运行的一个“程序”显示系统生成的报告列表,用户可以单击每行上的图标以弹出打开报告查看器对话框。此查看器显示的相当于报表的纵向/横向 A4 页面,因此用户希望此窗口非常大,几乎填满了他们的屏幕。

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

有一段时间,我拒绝了这个要求,因为我认为这不是一个好的解决方案。然而,当我发现用户如何绕过我们系统的这个“缺陷”时,我的想法发生了变化。

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

所以我心软了,让观众无模式。这意味着每个查看器都有一个任务栏图标。

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

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

一些注意事项:

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

评论

7赞 ryvantage 9/27/2013
这也正是我的经验。如果有一件事我可以肯定,那就是当人们试图规避你的用户友好性去做他们真正想做的任何事情时,你做错了什么。功能为王。
0赞 Guillaume Polet 10/2/2014
解决这个问题的一种方法是允许打开多个 JFrame,它们都提供相同的功能,但默认情况下,一切都在一个窗口中完成。这实际上允许用户在SDI或MDI之间进行选择。
0赞 DuncanKinnear 10/2/2014
不好意思?你能更好地解释一下你的解决方案吗?它怎么可能是单个窗口和多个窗口?我们有一个运行主应用程序的主窗口,但有时我们需要打开对话框,有时这些对话框(基于用户要求)需要无模式。制定规则,界面应该是这样的,否则只会给自己挖一个大坑。
1赞 Ungeheuer 12/17/2015
@GuillaumePolet我同意邓肯的观点,你能解释一下你的意思吗?我和他一样困惑
0赞 DuncanKinnear 12/17/2015
我认为他的意思是用户可以启动应用程序的多个副本(“JFrame”),但在每个副本中都是 SDI。但是,我们的客户端应用程序是一个非常胖的客户端,因此这将是一种资源匮乏的方法。
5赞 Keith Spriggs 9/4/2013 #7

如果帧的大小相同,为什么不创建帧并将帧作为对它的引用传递。

通过帧后,您可以决定如何填充它。这就像有一种计算一组数字平均值的方法。你会一遍又一遍地创建这个方法吗?

评论

1赞 Guillaume Polet 10/2/2014
这基本上是在做 Cardlayout 和 JTabbedPane 可以做的事情,但反过来做,使你的代码过于复杂,而你有干净和简单的解决方案来实现同样的事情。
5赞 arunjoseph 12/14/2013 #8

这不是一个好的做法,但即使你希望使用它,你也可以使用单例模式作为它的优点。我在大部分项目中都使用了单例模式,这很好。

评论

3赞 Guillaume Polet 10/2/2014
单例模式是一场噩梦。任何想要扩展的项目都应该不惜一切代价避免单例模式。
8赞 Lijo 12/18/2013 #9

我认为使用多个 s 不是一个好主意。Jframe

相反,我们可以在同一 .JPanelJPanelJFrame

我们也可以在这两者之间切换。因此,它让我们可以自由地展示更多的东西。JPanelJFrame

对于每一个,我们可以设计不同的东西,所有这些都可以一次显示在一个上面。JPanelJPanelJFrame

要在此 s 之间切换,请使用 for each 或 'JButtonJPanel'。JPanelJMenuBarJMenuItemsJPanelfor each

不止一个不是一个好的做法,但是如果我们想要不止一个,那就没有错了。JFrameJFrame

但是,最好根据我们的不同需求更改一个,而不是拥有多个。JFrameJFrame