Как установить размер компонента с помощью GridLayout?Есть ли способ лучше? - PullRequest
10 голосов
/ 15 января 2011

Я работаю над большим графическим интерфейсом с Java и злюсь на менеджеров по расположению.

У меня есть «Панель настроек» с переменным количеством JComponents в ней (Метки, Кнопки, JSpinners,JSliders, ...).Я просто хочу следующее:

JLabel <-> JComponent

JLabel <-> JComponent

JLabel <-> JComponent

...

Размер моей панели составляет 500 пикселей, поэтому места достаточно для множества компонентов.К сожалению, GridLayout всегда растягивает размер Компонентов до всей Панели, даже если я установил MaximumSize для каждого компонента.Это выглядит глупо, если есть только две кнопки, каждая из которых имеет высоту 250 пикселей.

Я пробовал Layout потока, но я не могу найти способ правильно создавать новые линии.Я пробовал BoxLayout.Y_AXIS, но Компоненты всегда центрированы, а Метка и Компонент не в одной строке.

Кто-нибудь знает хороший и короткий путь с LayoutManager для правильной обработки?

Ответы [ 5 ]

14 голосов
/ 15 января 2011

Альтернативой другим макетам может быть размещение вашей панели с GridLayout внутри другой панели, которая является FlowLayout.Таким образом, ваш интервал останется без изменений, но не будет расширяться по всему доступному пространству.

4 голосов
/ 27 января 2013

В моем проекте мне удалось использовать 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]);
}

Чтобы предотвратить распространение вашей панели настроек на весь контейнер, я сначала обертываю ее в северной области фиктивной панели, которую я назвал 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);

Скорее всего, вы хотите отобразить эту JScrollPane, расширенную внутри JFrame; Вы можете добавить его в JFrame BorderLayout в регионе 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);
4 голосов
/ 15 января 2011

Для более сложных макетов я часто использовал GridBagLayout , что более сложно, но это цена.Сегодня я бы, наверное, проверил MiGLayout .

4 голосов
/ 15 января 2011

Не используйте 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();
            }
        });
    }
}
2 голосов
/ 15 января 2011

Вам необходимо выполнить одно из следующих действий:

  1. GridBagLayout
  2. MigLayout
  3. SpringLayout

Они предлагают гораздо больше функций и вам будет проще получить то, что вы ищете.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...