簡體   English   中英

如何使用 GridLayout 設置組件大小? 有更好的方法嗎?

[英]How to set the component size with GridLayout? Is there a better way?

我正在用 Java 開發一個更大的 GUI,我對布局管理器很生氣。

我有一個“設置面板”,其中包含可變數量的 JComponent(標簽、按鈕、JSpinner、JSlider 等)。 我只想要以下內容:

JLabel <-> JComponent

JLabel <-> JComponent

JLabel <-> JComponent

...

我的面板大小為 500px,這樣就有足夠的空間容納很多組件。 不幸的是 GridLayout 總是將組件的大小拉伸到整個面板,即使我為每個組件設置了 MaximumSize。 如果只有兩個按鈕,每個按鈕的高度為 250 像素,這看起來很愚蠢。

我嘗試了流布局,但我無法找到正確制作新線條的方法。 我試過BoxLayout.Y_AXIS,但是Components總是居中,Label和Component不在同一行。

有沒有人知道 LayoutManagers 正確處理這個問題的好方法?

其他布局的替代方案可能是將帶有 GridLayout 的面板放在另一個 FlowLayout 面板中。 這樣,您的間距將保持不變,但不會擴展到整個可用空間。

不要將 GridLayout 用於它不應該做的事情。 在我看來,GridBagLayout 更適合您,無論是它還是 MigLayout(盡管您必須先下載它,因為它不是標准 Java 的一部分)。 或者組合布局管理器,例如用於行的 BoxLayout 和用於保存所有行的 GridLayout。

例如,使用 GridBagLayout:

import java.awt.*;
import javax.swing.*;

public class LayoutEg1 extends JPanel{
    private static final int ROWS = 10;

    public LayoutEg1() {
        setLayout(new GridBagLayout());
        for (int i = 0; i < ROWS; i++) {
            GridBagConstraints gbc = makeGbc(0, i);
            JLabel label = new JLabel("Row Label " + (i + 1));
            add(label, gbc);

            JPanel panel = new JPanel();
            panel.add(new JCheckBox("check box"));
            panel.add(new JTextField(10));
            panel.add(new JButton("Button"));
            panel.setBorder(BorderFactory.createEtchedBorder());
            gbc = makeGbc(1, i);
            add(panel, gbc);
        }
    }

    private GridBagConstraints makeGbc(int x, int y) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.gridwidth = 1;
        gbc.gridheight = 1;
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.weightx = x;
        gbc.weighty = 1.0;
        gbc.insets = new Insets(5, 5, 5, 5);
        gbc.anchor = (x == 0) ? GridBagConstraints.LINE_START : GridBagConstraints.LINE_END;
        gbc.fill = GridBagConstraints.HORIZONTAL;
        return gbc;
    }

    private static void createAndShowUI() {
        JFrame frame = new JFrame("Layout Eg1");
        frame.getContentPane().add(new LayoutEg1());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                createAndShowUI();
            }
        });
    }
}

在我的項目中,我設法使用 GridLayout 並且結果非常穩定,沒有閃爍,並且垂直滾動條工作正常。

首先,我為設置創建了一個 JPanel; 在我的情況下,它是一個網格,每個參數一行和兩列:左列用於標簽,右列用於組件。 我相信你的情況是相似的。

JPanel yourSettingsPanel = new JPanel();
yourSettingsPanel.setLayout(new GridLayout(numberOfParams, 2));

然后我通過迭代我的參數並在添加 JLabel 和添加組件之間交替來填充這個面板。

for (int i = 0; i < numberOfParams; ++i) {
    yourSettingsPanel.add(labels[i]);
    yourSettingsPanel.add(components[i]);
}

為了防止 yourSettingsPanel 擴展到整個容器,我首先將它包裹在一個虛擬面板的北部區域,我稱之為 northOnlyPanel。

JPanel northOnlyPanel = new JPanel();
northOnlyPanel.setLayout(new BorderLayout());
northOnlyPanel.add(yourSettingsPanel, BorderLayout.NORTH);

最后,我將 northOnlyPanel 包裝在 JScrollPane 中,它在任何地方都應該表現良好。

JScrollPane scroll = new JScrollPane(northOnlyPanel,
                                     JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                                     JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

您很可能希望在 JFrame 中顯示此擴展的 JScrollPane; 您可以將它添加到一個 BorderLayout JFrame,在 CENTER 區域:

window.add(scroll, BorderLayout.CENTER);

就我而言,我將它放在 GridLayout(1, 2) 面板的左列,並使用右列顯示每個參數的上下文幫助。

JTextArea help = new JTextArea();
help.setLineWrap(true);
help.setWrapStyleWord(true);
help.setEditable(false);

JPanel split = new JPanel();
split.setLayout(new GridLayout(1, 2));
split.add(scroll);
split.add(help);

對於更復雜的布局,我經常使用GridBagLayout ,它更復雜,但這就是代價。 今天,我可能會查看MiGLayout

您需要嘗試以下方法之一:

  1. 網格包布局
  2. 遷移布局
  3. 彈簧布局

它們提供了更多功能,並且更容易獲得您正在尋找的內容。

我改用了WrapFlowLayout

JPanel yourPanel = new JPanel(new WrapFlowLayout(10, 10);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM