Java 扩展 JFrame 与在程序中创建它
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22003802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Extends JFrame vs. creating it inside the program
提问by satnam
When making an application using Swing, I've seen people do one of the two things to create a JFrame. Which is a better approach and why?
在使用 Swing 制作应用程序时,我看到人们通过两件事之一来创建 JFrame。哪个是更好的方法,为什么?
I'm a beginner at Java and programming. My only source of learning is books, YouTube and Stack Overflow.
我是 Java 和编程的初学者。我唯一的学习来源是书籍、YouTube 和 Stack Overflow。
import {imports};
public class GuiApp1 {
public static void main(String[] args) {
new GuiApp1();
}
public GuiApp1() {
JFrame guiFrame = new JFrame();
guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
guiFrame.setTitle("Example GUI");
guiFrame.setSize(300,250);
................
}
AND
和
import {imports};
public class GuiApp1 extends JFrame {
public Execute() {
getContentPane().setBackground(Color.WHITE);
getContentPane().setLayout(null);
setSize(800, 600);
.............
}
public static void main(String[] args) {
Execute frame1 = new Execute();
frame1.setVisible(true);
}
}
采纳答案by Hovercraft Full Of Eels
Thoughts:
想法:
- Avoid extending JFrame as it ties your GUI to being, well a JFrame. If instead you concentrate on creating JPanels instead, then you have the freedom to use these JPanels anywhere needed -- in a JFrame, or JDialog, or JApplet, or inside of another JPanel, or swapped with other JPanels via a CardLayout.
- Avoid inheritance in general, especially of complex classes. This will prevent pernicious errors, such as inadvertent method overrides (try creating a JFrame or JPanel that has a
getX()
andgetY()
method to see what I mean!). - Avoid inheritance of complex classes if you are using an IDE: If you override a complex class, when you call methods on objects of these classes, you will have many, too many, choices of methods offered to you.
- Encapsulation is good, is and allows for creation of safer code. Expose only that which needs to be exposed, and control that exposure as much as possible.
- 避免扩展 JFrame,因为它会将您的 GUI 与 JFrame 联系起来。相反,如果您专注于创建 JPanel,那么您可以在任何需要的地方自由使用这些 JPanel——在 JFrame、JDialog、JApplet 或另一个 JPanel 内部,或通过 CardLayout 与其他 JPanel 交换。
- 一般避免继承,尤其是复杂的类。这将防止有害错误,例如无意的方法覆盖(尝试创建具有
getX()
andgetY()
方法的 JFrame 或 JPanel以了解我的意思!)。 - 如果您使用 IDE,请避免继承复杂类:如果您覆盖一个复杂类,当您对这些类的对象调用方法时,您将有很多方法可供选择。
- 封装是好的,并且允许创建更安全的代码。只曝光需要曝光的部分,并尽可能控制曝光。
回答by arcy
It does not matter.
没关系。
There are reasons why you might do one or the other, but absent any of those reasons it makes no difference whatsoever.
你可能会做其中一个是有原因的,但如果没有这些原因中的任何一个,它都没有任何区别。
Now, if you were writing something that might operate from the command line or might be a GUI program, obviously you could want a 'main' class that was not a GUI class.
现在,如果您正在编写一些可能从命令行操作或可能是 GUI 程序的东西,显然您可能需要一个不是 GUI 类的“主”类。
If you worked in a programming shop where one or the other was the standard, by all means follow the standard. There is no right answer to this one, and in fact very little to choose between them.
如果您在一个或另一个是标准的编程商店工作,请务必遵循标准。这个没有正确的答案,实际上在它们之间选择很少。
回答by Reimeus
The first approach is better.
第一种方法更好。
Typically you are not adding any new functionality to the frame so creating a direct instance of the class makes sense.
通常,您不会向框架添加任何新功能,因此创建类的直接实例是有意义的。
回答by Andrew Thompson
Prefer composition over inheritance.
更喜欢组合而不是继承。
The 2nd example uses inheritance, but for no good reason, since it does not change the functionality of JFrame
.
第二个示例使用继承,但没有充分的理由,因为它不会改变JFrame
.
As an aside, if those are examples of code you are seeing, find a new source1 supplementary. Even in the few code lines shown, each does highly questionable things. E.G.
顺便说一句,如果这些是您看到的代码示例,请查找新的源1 补充。即使在显示的几行代码中,每行都做了非常有问题的事情。例如
- Neither GUI is created on the Event Dispatch Thread.
getContentPane().setBackground(Color.WHITE); getContentPane().setLayout(null); setSize(800, 600);
- The first part of the 1st line (
getContentPane()
) has not been necessary since Java 1.5 - The second line uses a
null
layout, which will break in more ways I can count or describe. - The third line should best be replaced with
pack();
- The first part of the 1st line (
JFrame guiFrame = new JFrame(); guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); guiFrame.setTitle("Example GUI"); guiFrame.setSize(300,250);
- The first and 3rd lines could be contracted to:
JFrame guiFrame = new JFrame("Example GUI");
- The 2nd line is better set to
guiFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- The 3rd line again sets a size to the frame.
- The first and 3rd lines could be contracted to:
- 两个 GUI 都不是在事件调度线程上创建的。
getContentPane().setBackground(Color.WHITE); getContentPane().setLayout(null); setSize(800, 600);
getContentPane()
自 Java 1.5 以来,第一行的第一部分 ( ) 不再需要- 第二行使用了一个
null
布局,它将以我可以计算或描述的更多方式中断。 - 第三行最好替换为
pack();
JFrame guiFrame = new JFrame(); guiFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); guiFrame.setTitle("Example GUI"); guiFrame.setSize(300,250);
- 第一条和第三条线路可以承包给:
JFrame guiFrame = new JFrame("Example GUI");
- 第二行最好设置为
guiFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
- 第三行再次为框架设置大小。
- 第一条和第三条线路可以承包给:
Supplement
补充
- Having mentioned you do search SO, here is a tip. Check out the posts of the top 15 providers of answers in the Swing top users. Whatever advice/code you glean from these people, would commit few if any of the mistakes in those code samples.
Some don't often (or ever) provide self contained examples like a few of us commonly do (and don't look to thoseexamples necessarily for OO design as opposed to just technique), but whatever code they provide, or advice they give, should be highly considered.
- 提到您确实进行了搜索,这里是一个提示。查看Swing 顶级用户中排名前 15 位的答案提供者的帖子。无论您从这些人那里收集到什么建议/代码,在这些代码示例中几乎不会犯任何错误。
有些人不经常(或从来没有)像我们中的一些人通常那样提供自包含的示例(并且不要为了 OO 设计而必须查看这些示例,而不仅仅是技术),但是无论他们提供什么代码,或者他们给出的建议,应高度重视。
回答by MadProgrammer
Personally, the first approach (creating an instance of JFrame
) is preferred, I prefer this because...
就个人而言,JFrame
首选第一种方法(创建 的实例),我更喜欢这种方法,因为...
It doesn't lock your application into a dedicated container...you see a lot of people wanting to add applets to frames and frames to applets, if they had simple put the majority of there GUI in a JPanel
to start with, they wouldn't have these issues.
它不会将您的应用程序锁定到专用容器中……您会看到很多人想要将小程序添加到框架中,并将框架添加到小程序中,如果他们简单地将大部分 GUI 放在一个JPanel
开始,他们就不会没有这些问题。
It also means that the UI you create is much more flexible. For example, you can re-use it, either in the current application or future applications, you don't lock yourself in.
这也意味着您创建的 UI 更加灵活。例如,您可以重复使用它,无论是在当前应用程序中还是在未来应用程序中,您都不会将自己锁定。
The main gripe I have with extending JFrame
is, you're not actually adding any new features or functionality to it, which could be effectively re-used beyond using setVisible
我对扩展的主要抱怨JFrame
是,你实际上并没有向它添加任何新特性或功能,这些特性或功能可以在使用之外有效地重用setVisible
The other issue I have with extending JFrame
is people then promptly override paint
, which is really, really bad. There are so many issues with doing this it's simply painful to have to repeatedly list them...
我在扩展方面遇到的另一个问题JFrame
是人们会立即覆盖paint
,这真的非常糟糕。这样做有很多问题,不得不反复列出它们真是太痛苦了......
So...for more 2 cents worth. Create an instance of JFrame
and add your content to it. If required, create a static
method call showMyAwesomeGUI
which does it for you...
所以...多值 2 美分。创建一个实例JFrame
并将您的内容添加到其中。如果需要,请创建一个为您执行此操作的static
方法调用showMyAwesomeGUI
...
回答by ravi.patel
Go for the first approach.
选择第一种方法。
Because with that you can have more frames to be created. Because the application can have more than one window. As in the second case you can't create more frames.
因为这样你可以创建更多的框架。因为应用程序可以有多个窗口。与第二种情况一样,您无法创建更多帧。