【发布时间】:2011-12-11 16:13:35
【问题描述】:
我有以下布局:
红蓝绿部分是JPanel。在红色部分我有四个 JLabel。现在,如果我调整 JFrame 的大小,标题标签始终位于中心。但我更喜欢它们在红色部分水平均匀分布。我应该使用哪种布局?
【问题讨论】:
标签: java swing layout-manager
我有以下布局:
红蓝绿部分是JPanel。在红色部分我有四个 JLabel。现在,如果我调整 JFrame 的大小,标题标签始终位于中心。但我更喜欢它们在红色部分水平均匀分布。我应该使用哪种布局?
【问题讨论】:
标签: java swing layout-manager
对顶部的 JPanel 使用 GridLayout(1, 0)。这两个数字表示 1 行和可变数量的列。如果您使用的是 JLabels,这就足够了,尤其是当您将 JLabels 对齐常量设置为 SwingConstants.CENTER 时。如果您正在使用填充网格槽的组件,例如 JButtons,那么您可能需要使用 GridLayout 构造函数的其他变体,例如 GridLayout(1, 0, ?, 0)是一个数字,它告诉 GridLayout 插槽之间应该有多少水平间距。
整个 GUI 当然会使用 BorderLayout。
如需更多更好的信息,请查看Lesson: Laying Out Components Within a Container和A Visual Guide to Layout Managers
例如:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.*;
public class LayoutEg {
private static void createAndShowGui() {
String[] labelStrings = {"One", "Two", "Three", "Four"};
JPanel topPanel = new JPanel(new GridLayout(1, 0));
for (String labelString : labelStrings) {
// create labels and center the text
topPanel.add(new JLabel(labelString, SwingConstants.CENTER));
}
topPanel.setBackground(Color.red);
JPanel centerPanel = new JPanel();
centerPanel.setBackground(Color.blue);
// setting preferred size for demonstration purposes only
centerPanel.setPreferredSize(new Dimension(700, 400));
JPanel bottomPanel = new JPanel();
bottomPanel.setBackground(Color.green);
// main panel uses BorderLayout
JPanel mainPanel = new JPanel(new BorderLayout());
mainPanel.add(centerPanel, BorderLayout.CENTER);
mainPanel.add(topPanel, BorderLayout.PAGE_START);
mainPanel.add(bottomPanel, BorderLayout.PAGE_END);
JFrame frame = new JFrame("LayoutEg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
【讨论】:
框架的内容窗格使用 BorderLayout,标题面板使用 1 行 4 列的 GridLayout。
有关教程,请参阅 http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html 和 http://docs.oracle.com/javase/tutorial/uiswing/layout/grid.html。
如果你不想为每个标签分配相同的宽度,但实际上希望每个标签之间有相同的空间,你也可以使用 BoxLayout,并在每个标签之间(以及面板的边框之间)添加胶水和标签:
p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
p.add(Box.createHorizontalGlue());
p.add(new JLabel("Label"));
p.add(Box.createHorizontalGlue());
p.add(new JLabel("Long Label"));
p.add(Box.createHorizontalGlue());
p.add(new JLabel("Very long Label"));
p.add(Box.createHorizontalGlue());
p.add(new JLabel("Extremely long Label"));
p.add(Box.createHorizontalGlue());
【讨论】:
BorderLayout 用于主框架并使用NORTH、CENTER 和SOUTH 位置。Box.createVerticalStrut(size)。BoxLayout 将包装好的标签排成一行。GridBagLayout 将一个面板置于另一个面板的中心。 这是一个简短的例子:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Prototype extends JFrame {
public Prototype() {
JPanel labelPanel = new JPanel();
labelPanel.setLayout(new BoxLayout(labelPanel, BoxLayout.LINE_AXIS));
labelPanel.add(new JLabel("First"));
labelPanel.add(Box.createHorizontalStrut(10));
labelPanel.add(new JLabel("Second"));
labelPanel.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
labelPanel.setOpaque(false);
JPanel bottomPanel = new JPanel();
bottomPanel.add(Box.createVerticalStrut(15));
bottomPanel.setBackground(Color.GREEN);
JPanel centerPanel = new JPanel();
centerPanel.add(Box.createRigidArea(new Dimension(200, 300)));
centerPanel.setBackground(Color.BLUE);
JPanel northPanel = new JPanel(new GridBagLayout());
northPanel.add(labelPanel);
northPanel.setBackground(Color.RED);
JPanel panel = new JPanel(new BorderLayout());
panel.add(northPanel, BorderLayout.NORTH);
panel.add(centerPanel, BorderLayout.CENTER);
panel.add(bottomPanel, BorderLayout.SOUTH);
add(panel);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
new Prototype();
}
}
【讨论】:
使用MigLayout。
不,说真的,我曾经疯狂地试图让 Java 布局正常工作。然后我开始维护一些使用 MigLayouts 的软件,大约一周后,我可以做任何我想做的事情。有一个很棒的 cheat sheet 看起来很吓人,但它非常有用。
使用 MigLayout,要在 JPanel 中均匀分布标签,您可以:
// the "fillx" means that the layout will expand to take up all available horizontal space
JPanel panel = new JPanel(new Miglayout("fillx"));
// the "growx" means that the component will expand to take up all available horizontal space
add(new JLabel("Work items"), "growx");
add(new JLabel("Change set"), "growx");
add(new JLabel("Files"), "growx");
add(new JLabel("Source code"), "growx");
【讨论】:
gridLayout,将标签放入网格布局,设置行1列4(每个标签1行)
http://www.javabeginner.com/java-swing/java-gridlayout-class-example
【讨论】:
GridBagLayout 是一种方法。将 weightx 值设置为 1.0。
【讨论】:
为了使标签水平均匀分布 - 在红色面板中 - 使用带有 X_AXIS 方向的 BoxLayout 并在每个标签之间放置“胶水” - 更多内容 -
http://docs.oracle.com/javase/tutorial/uiswing/layout/box.html
【讨论】: