Works well for very modularized applications - 在我的情况下,我的大多数应用程序都有3到5个大"modules",它们实际上彼此无关 . 例如,一个模块可能是销售仪表板,一个可能是会计仪表板 . 他们不会互相交谈或任何事情 . 然而,执行官可能想要打开它们,并且它们在任务栏上是独立的框架,这使他的生活更轻松 .
Makes it easy for end-users to reference outside material - 有一次,我有这种情况:我的应用程序有一个"data viewer,",您可以从中单击"Add New",它将打开一个数据输入屏幕 . 最初,两者都是 JFrame . 但是,我希望数据输入屏幕是 JDialog ,其父级是数据查看器 . 我做了改变,并立刻接到了最终用户的电话,他最终依赖于这样一个事实:他可以最小化或关闭 viewer 并保持 editor 打开,同时他引用了程序的另一部分(或者一个网站,我不喜欢't remember). He' s not 在一个多显示器上,所以他需要输入对话框是第一个,而其他东西是第二个,数据查看器完全隐藏 . 这是不可能的 JDialog 当然也不可能 JInternalFrame 也是如此为了他的理智,我不情愿地把它改回了单独的地方,但它教会了我一个重要的教训 .
9 回答
多重
JFrame
方法是我更了解的方法 . However ,随着我作为开发人员的经验和知识的成熟,以及开始阅读和吸收更多经验丰富的Java开发者在线的意见,我尝试了 shift away 来自多个JFrame
方法(在当前项目和未来的项目中) )只有...才能得到......来自我的客户的抵抗!当我开始实现模态对话框来控制"child"窗口和JInternalFrame
s用于单独的组件时,我感到非常惊讶,因为我正在做我认为最好的练习!但是,正如他们所说,"A happy wife is a happy life."同样适合您的客户 . 当然,我是承包商,所以我的最终用户可以直接访问我,开发人员,这显然不是常见的情况 .所以,我将解释多重
JFrame
方法的好处,以及其他人提出的一些缺点 .Ultimate flexibility in layout - 通过允许单独的
JFrame
,您可以让最终用户展开并控制他/她屏幕上的内容 . 这个概念感觉"open"并且不受限制 . 当你走向一个大的JFrame
和一堆JInternalFrame
时,你会失去这个 .Works well for very modularized applications - 在我的情况下,我的大多数应用程序都有3到5个大"modules",它们实际上彼此无关 . 例如,一个模块可能是销售仪表板,一个可能是会计仪表板 . 他们不会互相交谈或任何事情 . 然而,执行官可能想要打开它们,并且它们在任务栏上是独立的框架,这使他的生活更轻松 .
Makes it easy for end-users to reference outside material - 有一次,我有这种情况:我的应用程序有一个"data viewer,",您可以从中单击"Add New",它将打开一个数据输入屏幕 . 最初,两者都是
JFrame
. 但是,我希望数据输入屏幕是JDialog
,其父级是数据查看器 . 我做了改变,并立刻接到了最终用户的电话,他最终依赖于这样一个事实:他可以最小化或关闭 viewer 并保持 editor 打开,同时他引用了程序的另一部分(或者一个网站,我不喜欢't remember). He' s not 在一个多显示器上,所以他需要输入对话框是第一个,而其他东西是第二个,数据查看器完全隐藏 . 这是不可能的JDialog
当然也不可能JInternalFrame
也是如此为了他的理智,我不情愿地把它改回了单独的地方,但它教会了我一个重要的教训 .Myth: Hard to code - 根据我的经验,这不是真的 . 我不明白为什么创建一个
JInternalFrame
比一个JFrame
更容易 . 事实上,根据我的经验,JInternalFrames
提供的灵活性要低得多 . 我已经开发出一种系统的方法来处理我的应用程序中JFrame
的打开和关闭真的很好 . 我几乎完全从框架的代码本身控制框架;创建新框架,SwingWorker
s控制后台线程上的数据检索和EDT上的GUI代码,如果用户试图打开它,则恢复/带到框架前面等等 . 所有你需要打开我的JFrame
s调用一个公共静态方法open()
和open方法,结合一个windowClosing()
事件来处理剩下的(框架是否已打开?是不是打开,但是加载?等等)我把这个方法作为模板所以不难做到为每个框架实施 .Myth/Unproven: Resource Heavy - 我想看看这个推测性陈述背后的一些事实 . 虽然,也许你可以说
JFrame
需要比JInternalFrame
更多的空间,即使你打开100JFrame
,你真的会消耗多少资源?如果由于资源问题导致内存泄漏:调用dispose()
释放框架用于垃圾收集的所有资源(并且,我再说一次,JInternalFrame
应该调用完全相同的问题) .我写了很多,我觉得我可以写得更多 . 无论如何,我希望我不会因为这是一个不受欢迎的观点而被投票 . 这个问题显然是一个有 Value 的问题,我希望我提供了一个有 Value 的答案,即使这不是普遍意见 .
每帧多帧/单个文档(SDI)与单帧/每帧多个文档(MDI)的一个很好的例子是Microsoft Excel . MDI的一些好处:
可以有一些非矩形形状的窗口 - 因此它们不会将桌面或其他窗口隐藏在其他进程中(例如Web浏览器)
可以在第二个Excel窗口中写入时通过一个Excel窗口从另一个进程打开一个窗口 - 使用MDI,尝试在其中一个内部窗口中写入将聚焦到整个Excel窗口,从而隐藏另一个进程的窗口
可以在不同的屏幕上显示不同的文档,这在屏幕不具有相同分辨率时尤其有用
SDI(单文档界面,即每个窗口只能有一个文档):
MDI(多文档界面,即每个窗口可以有多个文档):
糟糕(坏,坏)的做法 .
用户不友好:当期望只看到一个时,用户在任务栏中看到多个图标 . 加上编码问题的副作用..
编码和维护的噩梦:
A modal dialog提供了将注意力集中在该对话框内容上的简单机会 - 选择/修复/取消此项, then 继续 . 多个框架没有 .
当单击父对象时,带有父对象的对话框(或浮动工具栏)将显示在前面 - 如果这是所需的行为,则必须在框架中实现该对话框 .
在一个GUI中有许多显示多个元素的方法,例如:
CardLayout(短demo.) . 适合:
显示类似对话框的向导 .
显示具有关联组件的项目的列表,树等选择 .
在没有组件和可见组件之间翻转 .
JInternalFrame/JDesktopPane通常用于MDI .
JTabbedPane用于组件组 .
JSplitPane显示两个组件的方法,其中一个或另一个(大小)之间的重要性根据用户的行为而变化 .
JLayeredPane很多很好的..层次组件 .
JToolBar通常包含一组操作或控件 . 可以在GUI周围拖动,也可以根据用户需要完全关闭 . 如上所述,将根据父母这样做最小化/恢复 .
作为JList中的项目(下面的简单示例) .
作为JTree中的节点 .
Nested layouts .
但是,如果这些策略不适用于特定用例,请尝试以下操作 . Build 单个主
JFrame
,然后为其余的自由浮动元素显示JDialog或JOptionPane实例,使用框架作为对话框的父级 .很多图片
在多个元素是图像的情况下,最好使用以下任一项:
JLabel
(以滚动窗格为中心)显示用户当时感兴趣的任何图像 . 如ImageViewer所示 .JList
. 如this answer所示 . 'single row'部分仅在它们具有相同尺寸时才有效 . 或者,如果您准备在运行中缩放图像,它们都具有相同的宽高比(例如4:3或16:9) .这不是一个好习惯,但即使你想使用它,你也可以使用单身模式作为它的优点 . 我在项目的大部分时间里都使用了单例模式 .
将jInternalFrame设置为主框架并使其不可见 . 然后你可以用它来进行更多的活动 .
如果帧的大小相同,为什么不创建帧并传递帧然后作为对它的引用 .
通过框架后,您可以决定如何填充框架 . 这就像有一种计算一组数字平均值的方法 . 你会一遍又一遍地创建这个方法吗?
绝对不好的做法 . 一个原因是每个
JFrame
显示一个新的任务栏图标这一事实并非如此 . 控制多个JFrame
将让你脱掉你的头发 .就个人而言,我会使用ONE
JFrame
作为您的应用程序 . 显示多个事物的方法取决于你,有很多 .Canvas
es,JInternalFrame
,CardLayout
,甚至JPanel
可能 .多个JFrame对象=疼痛,麻烦和问题 .
自从我最后一次接触挥杆以来已经有一段时间,但总的来说这是一个不好的做法 . 想到的一些主要缺点:
It's more expensive: 您将不得不分配更多资源来绘制JFrame其他类型的窗口容器,例如Dialog或JInternalFrame .
Not user friendly: 导航到一堆粘在一起的JFrame并不容易,看起来你的应用程序是一组不一致且设计不佳的应用程序 .
It's easy to use JInternalFrame 这是一种修辞,现在它更容易和其他人更聪明(或更多的业余时间)比我们已经通过桌面和JInternalFrame模式思考,所以我建议使用它 .
我想用我刚刚参与的一个例子来反驳“非用户友好”的论点 .
在我们的应用程序中,我们有一个主窗口,用户将各种“程序”作为单独的选项卡运行 . 我们尽可能地尝试将应用程序保留在这个单一窗口中 .
他们运行的一个“程序”呈现系统生成的报告列表,用户可以单击每行上的图标弹出打开报告查看器对话框 . 此查看器显示相当于报告的纵向/横向A4页面,因此像这个窗口的用户非常大,几乎填满了他们的屏幕 .
几个月前,我们开始收到客户的请求,使这些报表查看器窗口无模式,这样他们就可以同时打开多个报表 .
有一段时间我拒绝了这个请求,因为我认为这不是一个好的解决方案 . 然而,当我发现用户如何解决我们系统的“缺陷”时,我的想法发生了变化 .
他们打开一个查看器,使用“另存为”工具将报告作为PDF保存到特定目录,使用Acrobat Reader打开PDF文件,然后他们将对下一个报告执行相同操作 . 他们将使用他们想要查看的各种报告输出运行多个Acrobat Readers .
所以我心软了,让 Spectator 无模式 . 这意味着每个查看者都有一个任务栏图标 .
当上周向他们发布最新版本时,他们的热烈反应是他们喜欢它 . 这是我们最近最受欢迎的系统增强之一 .
因此,您继续告诉您的用户他们想要的是坏的,但最终它不会对您有所帮助 .
一些注意事项:
对于这些无模式窗口,使用JDialog似乎是最佳实践
使用使用新
ModalityType
而不是布尔modal
参数的构造函数 . 这就是为这些对话框提供任务栏图标的原因 .对于无模式对话框,将null父项传递给构造函数,但相对于它们的'parent'窗口找到它们 .
Windows上的Java版本6有一个bug,这意味着你的主窗口可以变成'always on top'而不用你告诉它 . 升级到版本7以解决此问题
我认为使用多个
Jframe
并不是一个好主意 .相反,我们可以在同一个
JFrame
中使用JPanel
多于一个或多个JPanel
.我们也可以在这个
JPanel
之间切换 . 所以它让我们可以自由地展示JFrame
中的东西 .对于每个
JPanel
,我们可以设计不同的东西,所有这些JPanel
可以一次显示在单个JFrame
上 .要在
JPanel
之间切换,请为每个JPanel
或'JButtonfor each
JPanel使用
JMenuBar和
JMenuItems` .不止一个
JFrame
不是一个好习惯,但如果我们想要多个JFrame
则没有错 .但最好根据我们的不同需求改变一个
JFrame
而不是多个JFrame
.