以下是我当前GUI的屏幕截图:
我不知道哪个LayoutManager可用于我的主框架的内容窗格。在图片中,您可以看到主窗口在逻辑上分为左侧和右侧部分 - 左侧部分包含搜索组件,右侧部分是输出。
从我所看到的,它看起来像BorderLayout或GridBagLayout都可以工作,但后来我进一步阅读了这个MigLayout,看起来它也可以工作。我也对在每一方内部使用的LayoutManagers感到困惑。基本上我现在只是对信息过载感到困惑,并且不知道该使用什么,所以我想我会问专业程序员在这种情况下会使用什么。
答案 0 :(得分:4)
我应该将哪个布局管理器用于主框架的内容窗格?
这是一个简单的问题。您应该使用FlowLayout
或BorderLayout
,因为大多数Swing GUI都应该有一个主JPanel
。
你真正的问题有点困难。您有一个复杂的GUI布局,这将需要多个JPanel
和多个布局管理器。
以下评论是我的第一印象。我保留根据测试GUI的实际编码进行更改的权利。
GUI的右侧需要JTabbedPane
。我只能在JPanel
中看到其中一个JTabbedPane
。 JPanel
的布局管理器是GridBagLayout
。
GUI的左侧需要JPanel
内的JPanel
个JPanel
。左侧BoxLayout
的布局管理器是JPanel
,Y轴。
左侧4 JPanel
的顶部GridBagLayout
使用JPanel
。
中上JPanel
由两个JPanel
组成。第一个BoxLayout
使用JLabel
,Y轴来保存JList
和JPanel
。第二个GridBagLayout
使用GridBagLayout
来保存3个按钮。获得按钮间距需要JPanel
。
中下方FlowLayout
使用JLabel
来保存JTextField
和JPanel
。
底部JPanel
包含2个按钮组。第一组有标题,而第二组没有。BoxLayout
的布局管理器是JPanel
,X轴。
如果你理解了这一切,那很好。为每个Java类构建一个JFrame
的GUI,进行测试以确保Swing组件按照您期望的方式布局。最大化并手动更改{{1}}窗口的大小,以查看GUI是否以您期望的方式发生变化。
我猜我需要32到40个小时才能将这个GUI放在一起。如果您要使用窗口构建器,则可能需要400到600小时的时间才能将此GUI组合在一起。
不要使用窗口构建器。它只会使连接Swing组件变得复杂。
如果你不理解我的评论,我不知道你是否已将其归结为我的答案的底部。 : - )
研究Oracle Swing tutorial。不要跳过任何事情。如有必要,请多次查看整个教程,以便了解Swing。学习需要时间。
答案 1 :(得分:2)
正如已经提到的,我不是嵌套面板的忠实粉丝(不再是,因为我发现了强大且易于掌握的第三方经理:-)我目前最喜欢的是MigLayout,所以这里是全部 - 一体化版本:
垂直线突出了嵌套布局确实存在的一个臭名昭着的问题:不支持跨面板对齐(尽管有实现它的技巧)。我的建议是学习掌握三巨头中的一个(MigLayout,JGoodies FormLayout,DesignGridbagLayout),然后做大多数布局而不嵌套。
MigLayout layout = new MigLayout(
// auto-wrap after 4 columns
"wrap 5",
// 5 columns:
// 1. labels, 2./3. radiobuttons,
// 4. buttons, 5. tabbedPane
"[][fill, sg][fill, sg]u[fill]para[fill, grow]",
// 7 rows:
// 1. - 6. default for combos/buttons,
// 7. growing table
// > 7 default
// unrelated gaps before/after the table
"[][][]u[][][][grow, fill]u[]r[]");
JComponent content = new JPanel(layout);
JTabbedPane tabbedPane = new JTabbedPane();
tabbedPane.addTab("SomeTab", new JPanel());
String[] labels = { "Company:", "Product Type:", "Product:" };
for (String string : labels) {
JLabel label = new JLabel(string);
JComboBox combo = new JComboBox();
content.add(label);
if (string.equals(labels[0])) {
content.add(combo, "span 2");
// make span all rows,
// force a min width
content.add(tabbedPane, "skip 1, spany, grow, wmin 500");
} else {
content.add(combo, "span 2, wrap");
}
};
// JXTable supports specifying the visibleRowCount
JXTable table = new JXTable(0, 1);
table.setVisibleRowCount(10);
content.add(new JScrollPane(table), "span 3, spany 4, grow");
String[] buttons = {"Add", "Remove", "Edit"};
for (String string : buttons) {
content.add(new JButton(string));
}
content.add(new JLabel("Search:"), "newline, skip 2");
JTextField field = new JTextField(12);
content.add(field, "span 2");
content.add(new JLabel("Show only:"), "newline");
String[] checks = {"A", "B", "C"};
String skip = "";
for (String string : checks) {
content.add(new JCheckBox(string), skip);
content.add(new JRadioButton(string.toLowerCase()), "wrap");
skip = "skip";
}
// decorate to show vertical alignment line
DebugLayerUI ui = new DebugLayerUI(field);
JLayer layer = new JLayer(content, ui);
// just for fun, a layerUI which can be used to debug component alignement
public class DebugLayerUI extends LayerUI {
private Map<JComponent, Integer> markThem;
public DebugLayerUI(JComponent child) {
markThem = new HashMap<>();
markThem.put(child, SwingConstants.VERTICAL);
}
public void add(JComponent child, int direction) {
markThem.put(child, direction);
}
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
g.setColor(Color.MAGENTA);
for ( Entry<JComponent, Integer> entry : markThem.entrySet()) {
JComponent child = entry.getKey();
if (SwingConstants.VERTICAL == entry.getValue()) {
Point p = SwingUtilities.convertPoint(child,
new Point(0, 0),
c);
g.drawLine(p.x, 0, p.x, c.getHeight());
} else if (SwingConstants.HORIZONTAL == entry.getValue()) {
int baseline = child.getBaseline(child.getWidth(), child.getHeight());
if (baseline > 0) {
Point p = SwingUtilities.convertPoint(child,
new Point(0, baseline), c);
g.drawLine(0, p.y, c.getWidth(), p.y);
}
}
}
}
}