0

这是我当前 GUI 的屏幕截图:

当前图形用户界面

我不知道将哪个 LayoutManager 用于我的主框架的内容窗格。在图中,您可以看到主窗口在逻辑上分为左右两部分——左边部分是搜索组件,右边部分是输出。

从我读过的内容来看,BorderLayout 或 GridBagLayout 似乎都可以工作,但后来我进一步阅读了这个 MigLayout 并且似乎它也可以工作。我也对在每一侧内部使用什么 LayoutManagers 感到困惑。基本上我现在只是对信息过载感到困惑,并且不知道该使用什么,所以我想我会问专业程序员他们在这种情况下会使用什么。

4

2 回答 2

4

我应该为我的主框架的内容窗格使用哪个布局管理器?

这是一个简单的问题。您应该使用 aFlowLayout或 a BorderLayout,因为大多数 Swing GUI 应该有一个 main JPanel

复杂的图形用户界面

你真正的问题有点难。您有一个复杂的 GUI 布局,这将需要一个JPanel以上的布局管理器。

以下评论是我的第一印象。我保留根据测试 GUI 的实际编码进行更改的权利。

右边

GUI 的右侧需要一个JTabbedPane. 我只能看到JPanels 中的一个JTabbedPane。布局管理器JPanel是一个GridBagLayout.

左边

GUI 的左侧需要 4JPanel秒内的JPanel. 左侧的布局管理器JPanel是一个BoxLayoutY 轴。

左侧JPanel4 s的顶部使用.JPanelGridBagLayout

上中部JPanel由两个JPanels组成。第一个JPanel使用 a BoxLayout,Y 轴来保存 aJLabel和 a JList。第二个JPanel使用 aGridBagLayout来按住 3 个按钮。这GridBagLayout是获得按钮间距所必需的。

中下部JPanel使用 aFlowLayout来容纳 aJLabelJTextField

底部JPanel有 2 个按钮组。第一组有一个标题,而第二组没有 布局管理器JPanel是一个BoxLayoutX 轴。

结论

如果您了解所有这些,那就太好了。为每个 Java 类构建一个 GUI JPanel,进行测试以确保 Swing 组件的布局符合您的期望。最大化并手动更改JFrame窗口大小以查看 GUI 是否按照您期望的方式更改。

我猜我需要 32 到 40 个小时的工作才能把这个 GUI 放在一起。如果您要使用窗口构建器,可能需要 400 到 600 个小时的工作才能将这个 GUI 组合在一起。

不要使用窗口生成器。它只会使 Swing 组件的连接变得复杂。

如果您不理解我的评论,我不知道您是否已将其归结为我的答案的底部来阅读此内容。:-)

学习Oracle Swing 教程。不要跳过任何内容。通读整个教程,必要时不止一次,这样您就可以理解 Swing。学习需要时间。

于 2013-07-19T08:14:38.110 回答
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);
               }
           }
        }
    }

}
于 2013-07-21T09:51:15.020 回答