如何在 Swing 中获得组件堆叠在一起的 LinearLayout?
我正在尝试创建一个自定义 JDialog
。我希望将组件以其首选的高度堆叠在彼此的顶部,但宽度应填满容器。类似于 Android 中的 LinearLayout
。我希望在调整窗口大小时组件保持其首选高度。
来自使用布局管理器:
场景:您需要以自然大小在紧凑的行中显示一些组件。
考虑使用 JPanel 对组件进行分组,并使用 JPanel 的默认 FlowLayout 管理器或 BoxLayout 管理器。 SpringLayout 对此也很有用。
例如,我希望在 JTabbedPane
上方有一个 JTextField
。我已尝试使用所有建议的布局管理器 FlowLayout、BoxLayout、SpringLayout,但当 JDialog 窗口增加高度时,它们不会保留组件的自然大小。
Java Swing 中是否有适合我的情况的布局管理器?
这是一个小例子,显示了我的 Swing 布局问题:
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
public class TestDialog extends JDialog {
public TestDialog() {
setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));
//setLayout(new SpringLayout());
JTextField field1 = new JTextField();
JTextField field2 = new JTextField();
JTextField field3 = new JTextField();
JTextField field4 = new JTextField();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
panel1.setLayout(new BoxLayout(panel1, BoxLayout.PAGE_AXIS));
panel2.setLayout(new BoxLayout(panel2, BoxLayout.PAGE_AXIS));
panel1.add(field2);
panel2.add(field3);
panel2.add(field4);
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Tab 1", panel1);
tabs.addTab("Tab 2", panel2);
add(field1);
add(tabs);
//field1.setMaximumSize(field1.getPreferredSize());
//SpringUtilities.makeCompactGrid(this.getContentPane(), 2, 1, 2, 2, 2, 2);
this.pack();
this.setVisible(true);
}
public static void main(String[] args) {
new TestDialog();
}
}
I'm trying to create a custom JDialog
. I would like to have the components stacked on top of eachother with their preferred height, but the width should fill the container. Similar to LinearLayout
in Android. I want that the components keeps their preferred height when the window is resized.
From Using Layout Managers:
Scenario: You need to display a few components in a compact row at their natural size.
Consider using a JPanel to group the components and using either the JPanel's default FlowLayout manager or the BoxLayout manager. SpringLayout is also good for this.
E.g. I would like to have a JTextField
above a JTabbedPane
. I have tried with all the suggested layout managers FlowLayout, BoxLayout, SpringLayout but they don't preserve the natural size of my components when the JDialog
window get increased height.
Is there any Layout Manager in Java Swing that I can use for my situation?
Here is a small example that shows my problem with the Swing layouts:
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
public class TestDialog extends JDialog {
public TestDialog() {
setLayout(new BoxLayout(this.getContentPane(), BoxLayout.PAGE_AXIS));
//setLayout(new SpringLayout());
JTextField field1 = new JTextField();
JTextField field2 = new JTextField();
JTextField field3 = new JTextField();
JTextField field4 = new JTextField();
JPanel panel1 = new JPanel();
JPanel panel2 = new JPanel();
panel1.setLayout(new BoxLayout(panel1, BoxLayout.PAGE_AXIS));
panel2.setLayout(new BoxLayout(panel2, BoxLayout.PAGE_AXIS));
panel1.add(field2);
panel2.add(field3);
panel2.add(field4);
JTabbedPane tabs = new JTabbedPane();
tabs.addTab("Tab 1", panel1);
tabs.addTab("Tab 2", panel2);
add(field1);
add(tabs);
//field1.setMaximumSize(field1.getPreferredSize());
//SpringUtilities.makeCompactGrid(this.getContentPane(), 2, 1, 2, 2, 2, 2);
this.pack();
this.setVisible(true);
}
public static void main(String[] args) {
new TestDialog();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
垂直 BoxLayout 应该可以正常工作。如果当您增加框架大小时组件会增长,那么您可能需要添加:
如果您需要更多帮助,请发布 SSCCE说明了问题。
编辑:
您需要指定文本字段的首选大小。这是通过使用以下方法完成的:
A vertical BoxLayout should work fine. If the components grow when you increase the frame size then you may need to add:
If you need more help then post the SSCCE that demonstrates the problem.
Edit:
You need to specify your preferred size for text fields. This is done by using:
空布局(基本上是 x/y)可能就是您正在寻找的布局,或者可能是组布局。
MigLayout 还可以做您可能想要开箱即用的事情(您必须给它一个特定的指令以随窗口增长,否则它不会)。
从概念上讲,我认为您对布局最终决定组件大小这一事实感到困惑,因此“自然”大小有点误导。我猜你想要的是组件上设置的尺寸?或者您可能指的是组件上未调用任何 setSize 方法时的默认值?
无论哪种方式,对于 Swing,您都必须更加明确您的大小期望才能获得良好的结果。
The null layout (basically x/y) might be what you are looking for, or perhaps Group Layout.
MigLayout also does what you probably want out of the box (you have to give it a specific directive to grow with the window, otherwise it doesn't).
Conceptually I think you are confused by the fact that the layout ultimately decides the size of components, so the "natural" size is a bit misleading. I guess what you are after is the size as set on the component? Or perhaps you mean the default when none of the setSize methods have been called on the component?
Either way, with Swing you have to be more explicit in your sizing expectations to get good results.
我完全不明白你所说的组件的自然大小是什么意思。但如果您不希望布局管理器弄乱组件的大小,我建议您使用 setMaximumSize(int width,int height) 或将布局设置为 null 并使用 < code>setBounds(int x,int y,int width,int height) 方法来调整组件的大小。
如果您希望调整组件大小相对于彼此的变化方式,那么我建议查看 GridBagLayout 并使用weightx和weighty属性。
I quite didn't get what you meant by natural size of a component. But if you don't want the Layout manager messing up with the size of the components, i would suggest you use either the
setMaximumSize(int width,int height)
or set the layout to null and usesetBounds(int x,int y,int width,int height)
method to size your component.If you are looking to tweak how the component's sizes change relative to each other, then i would suggest looking at GridBagLayout and using weightx and weighty properties.
我最终实现了自己的 StackLayout,代码如下。这就是我的问题中相同应用程序的样子。组件从上到下堆叠,并占据整个宽度,类似于 Android 的 LinearLayout。
I ended up with implementing my own StackLayout, the code is below. This is how the same application in my question look like. The components are stacked from top to bottom, and takes up the full width, similar to
LinearLayout
for Android.如果您使用 GridBagLayout 且未指定填充或重量,您应该会得到您想要的。本质上,您将拥有 1 列 2 行网格袋布局。只需创建 GridBagConstraints 并在添加组件时仅设置 x 和 y 选项 - 不要设置任何其他选项。
If you use
GridBagLayout
and don't specify a fill or weight you should get what you want. Essentially you will have a 1 column 2 row grid bag layout. Just create yourGridBagConstraints
and set only the x and y options when adding the components - do not set any other options.根据您的描述,我建议使用一个更简单的布局管理器 - BorderLayout() 。代码如下:需要指定至少1个JTextField的宽度来设置JDialog的宽度。如果您想要一些间距,可以使用 EmptyBorder。希望这会有所帮助,- MS
import java.awt.*;
导入 javax.swing.*;
公共类 TestDialog 扩展 JDialog {
}}
I would suggest a much simpler layout manager - BorderLayout() - from what you are describing. Code follows: you need to specify width of at least 1 JTextField to set up the width of the JDialog. You can use EmptyBorder if you want some spacings. Hope this helps, - M.S.
import java.awt.*;
import javax.swing.*;
public class TestDialog extends JDialog {
}}