英文:
Layout Manger to Freely place your objects
问题
我是一个自学的Java开发者,我使用IntelliJ IDEA进行Java开发。最近我在YouTube上看到一个视频,里面的人正在使用NetBeans,在他的JFrame窗体中,他能够自由地放置诸如JButton、JTextField、JLabel等对象。我无法弄清楚如何做到这一点。在IntelliJ IDEA中,我找到了几个布局管理器,如Border、Card、Grid、Bag等,但没有一个能达到预期的效果。请问有人可以告诉我如何获得一个布局管理器,在其中可以自由地放置所有的对象,并可以自由调整它们的大小,没有任何限制?非常感谢您提前的任何帮助。
英文:
I am a self-taught java developer and I use IntelliJ IDEA for Java. Recently I saw a video on youtube in which the guy was using NetBeans and in his JFrame form, he was able to freely place his objects like JButton, JTextFeild, JLabel, etc. I am not able to figure out how to do that. In IntelliJ IDEA I found several layout managers such as Border, Card, Grid, Bag, etc. but none of them gave the desired result. can somebody please tell me how can I get a layout manager in which I can freely place all my objects and also freely resize them without any restrictions? Thank you in advance for any help.
答案1
得分: 1
在Swing中,每个组件都extends Container
。这意味着每个组件都可以有嵌套组件(它们都有add(Component)
方法)。然而,并非所有组件都支持嵌套组件的布局。
我想表达的是,你可以将一个组件添加到JButton
,但是JButton
不能显示其嵌套组件。
因此,为了实现嵌套,我们使用支持其嵌套组件布局方向的组件 - 容器。
这些组件都是窗口(JFrame
,JDialog
等等...)和JPanel
。还有一些其他支持布局特定类型嵌套组件的组件。例如,JMenu
能够正确地显示JMenuItem
。
现在,这些“顶级”/空容器通过使用布局管理器来对齐和显示其嵌套组件。基于容器的布局管理器,组件会被显示出来。
这就是为什么你不能“随意”地将组件放入JFrame
中的原因。因为它的布局管理器负责放置组件。所以,你要寻找的是改变它的布局管理器(使用setLayout
方法)为一个允许你随意放置组件的布局管理器。
猜猜看?并没有这样的布局管理器。简单地说,因为它将无事可做/计算,因为你已经在处理组件的布局。因此,为了实现“自由”组件布局,你必须使用jframe.setLayout(null);
。为了在其后布局组件,你将不得不使用componentInsideJFrame.setBounds(...)
并给它常量坐标/尺寸。
这是一个糟糕的实践。在界面设计方面非常糟糕。给一个组件静态坐标和尺寸是不好的。你必须问自己一些问题。
如果用户调整窗口大小怎么办?如果窗口是301x301
,那么它的中心在(150,150)
。所以你把一个组件放在(150,150)
。好,它起作用了。现在用户调整窗口大小,使其变为501x501
。中心现在位于(250,250)
。但是组件仍然停留在(150,150)
。当然有setResizable(false)
的解决方案,但你有多少次使用过“无法调整大小”的应用程序?如果用户想要调整大小怎么办?
我希望你能理解我在尝试表达什么。
通过使用布局管理器,你可以轻松解决这类问题,因为布局管理器会处理调整大小并计算新的中心。
是的。我知道这感觉很奇怪,但所有这些YouTube教程并没有教你制作Swing GUI的正确方法。(这可能是另一个时间的对话)
我真诚建议你阅读Swing文档的教程,以便了解布局管理器的工作原理。你将会从中受益匪浅。
最后,我建议你暂时不要使用“GUI构建工具”。它们似乎有助于构建GUI,但它们会添加很多额外/无用的代码,而且大多数时候它们容易导致“糟糕的UI创建”。尽量自己编写GUI代码。
起初,这可能听起来有点苛刻,但你始终可以运行你的应用程序并查看GUI的结果。经过一些错误,最终你将能够仅通过查看container.setLayout(..)
和container.add(...)
这些代码行来想象GUI的结果。
英文:
In swing every component extends Container
. That means that every component can have nested components (they all have add(Component)
method). However, not all of them support the layout-ing of nested components.
What I want to say is, that you can add a component to a JButton
, but a JButton
is not capable of showing its nested components.
So, in order to have nesting, we use the components - containers that support the orientation of their nested components.
These components are all windows (JFrame
, JDialog
, etc...) and JPanel
s. There some others that support layout-ing a specific type of nested components. For example a JMenu
is capable of showing JMenuItem
s properly.
Now, these "top-level"/empty containers are using Layout Managers in order to align-show their nested components. Based on the container's layout manager, the components are shown.
This is why you can't "freely" place the components into a JFrame
. Because its Layout Manager is taking care of the components will be placed. So, what you are looking for, is to change its LayoutManager (use setLayout
method) to one that allows you to freely place the components.
Guess what? There is no such layout manager. Simply because, it would have nothing to do/calculate since you are taking care the layout of the components. So, in order to achieve the "free" component layout, you must use jframe.setLayout(null);
. In order to layout the components after it, you will have to use componentInsideJFrame.setBounds(...)
and give it constant coordinates /dimension.
This is bad practice. A very bad one when it comes to UI. Giving a component static coordinates and dimension is bad. There are some questions you have to ask yourself.
What if user resizes the window? If the window is 301x301
, the center of it, is at (150,150)
. So you place a component at (150,150)
. Ok it works. Now user resizes the window and makes it 501x501
. The center is now standing at (250,250)
. But the component is staying at (150,150)
. There is the solution of setResizable(false)
, to this kind of problems, but how often have you used "uncapable of resizing" applications? What if user wants to resize it?
I hope you get it and understood what I am trying to say.
By using layout managers, you are solving this kind of problems easily, since the layout manager will take care of the resize and calculate the new center.
Yes. I know it feels weird, but all these youtube tutorials are not teaching you the correct way to make Swing GUIs. (This is a conversation for another day, I guess)
I truly suggest you read the tutorials of Swing documentation in order to get some ideas of how layout managers work. You will really benefit from those.
Finally, I suggest you to leave outside the whole "gui-builder-tool" thing. They seem to help you building your GUI, but they are adding so much additional/useless code and most of the times they are "bad UI creation" prone. Try to code the GUI by yourself.
At first, this sounds a bit harsh, but you can always run your application and see the result of the GUI. After some mistakes, you will finally be able to imagine the GUI result by only seeing the container.setLayout(..)
and container.add(...)
lines.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论