Как использовать GridBagConstraints для создания макета?

Я хочу разместить свой JPane так:

-------
|     |
|     |
|     |
-------
|     |
-------

Таким образом, верхняя секция больше / выше, чем нижняя секция (верхняя секция состоит из другой панели JPanel и использует объект Graphics для отображения изображения, а нижняя секция также состоит из другой панели JPanel, но использует объект Graphics для рисования некоторых линий. и текст).

Я слышал, что лучший способ сделать это - использовать GridBagLayout и GridBagConstraints.

Я пытаюсь определить подходящие свойства для GridBagConstraints, и у меня возникают некоторые трудности. Это то, что у меня есть ...

Для верхней части у меня есть:

gridx = 0
gridy = 0
weighty = 1.0; // expand downwards, because the bottom should never expand in the Y direction
fill = GridBagConstraints.BOTH

Для нижней части у меня есть:

gridx = 0
gridy = 1
fill = GridBagConstraints.HORIZONTAL
anchor = GridBagConstraints.PAGE_END

К сожалению, все заканчивается тем, что появляется большой серый прямоугольник (у меня белый фон для приложения) - изображения не загружаются, строки / текст не появляются.

Что я должен делать? Что мне отрегулировать?

Я прочитал несколько руководств, но это кажется действительно сбивающим с толку, у меня это работало в моем первом приложении, но теперь, когда я пытаюсь сделать это, мне кажется, что это не работает.


person Bhaxy    schedule 26.01.2012    source источник
comment
Можете ли вы дать SSCCE, который показывает проблему? Из того, что вы перечислили, даже не ясно, добавляются ли панели к чему-либо ...   -  person Russell Zahniser    schedule 26.01.2012
comment
Опубликуйте весь код, который вы используете для настройки панели.   -  person Ted Hopp    schedule 26.01.2012
comment
-1, I've heard that the best way to do this was using the GridBagLayout and GridBagConstraints. Это не тот совет, который вы получили, когда задали этот вопрос 3 часа назад: stackoverflow.com/questions/9012976/   -  person camickr    schedule 26.01.2012
comment
@camickr Я не слышал об этом, и, более того, это неприменимо, потому что вы не можете указать высоту для GridLayout.   -  person Bhaxy    schedule 26.01.2012
comment
Используйте BorderLayout. Если один из двух компонентов должен расшириться, поместите его в CENTER, в противном случае используйте _3 _ / _ 4_. Я думаю, что GridBagLayout был плохим советом для этого макета. Где это вы это слышали?   -  person Andrew Thompson    schedule 26.01.2012
comment
@AndrewThompson Это было рекомендовано в другом ответе на другой вопрос ... что было бы лучшим выбором?   -  person Bhaxy    schedule 26.01.2012
comment
Это рекомендовалось в другом ответе на другой вопрос Какова ссылка на этот вопрос? Получать от вас информацию - все равно что рвать зубы. что было бы лучшим выбором? Я написал 4 предложения в своем первом комментарии. Жалко, что у тебя хватка внимания только на 2 года :(   -  person Andrew Thompson    schedule 26.01.2012


Ответы (3)


В общем, для разметки сетки

  • Если вам нужен масштаб компонента, вы должны указать его направление масштабирования, и любые размеры (ширина / высота), которые вы установили для этого направления, будут игнорироваться менеджером по расположению.

  • Если вы не хотите масштабировать компонент, размер компонента должен быть определен (при желании вы можете покопаться в этой теме в документах java). В вашем случае с нижней панелью вам нужно указать ее, по крайней мере, желаемую высоту.

Это может сработать, как вы ожидаете

pnlTop.setBackground(Color.WHITE);
pnlBottom.setBackground(Color.BLUE);

// Because you don't want the bottom panel scale, you need to give it a height.
// Because you want the bottom panel scale x, you can give it any width as the
// layout manager will ignore it.
pnlBottom.setPreferredSize(new Dimension(1, 20));


getContentPane().setLayout(new GridBagLayout());
GridBagConstraints cst = new GridBagConstraints();
cst.fill = GridBagConstraints.BOTH;
cst.gridx = 0;
cst.gridy = 0;
cst.weightx = 1.0; // --> You miss this for the top panel
cst.weighty = 1.0;
getContentPane().add(pnlTop, cst);

cst = new GridBagConstraints();
cst.fill = GridBagConstraints.HORIZONTAL;
cst.gridx = 0;
cst.gridy = 1;
cst.weightx = 1.0; // You miss this for the bottom panel
cst.weighty = 0.0;
getContentPane().add(pnlBottom, cst);

Более того, если вы хотите использовать макет gridbag, я рекомендую вам попробовать библиотеку безболезненного gridbag http://code.google.com/p/pcohol-gridbag/ (я являюсь автором этой библиотеки). Это не решает эту проблему для вас (поскольку ваша проблема касается управления размером компонента в компоновке gridbag), но это сэкономит вам много времени на ввод и упростит сопровождение кода.

pnlBottom.setPreferredSize(new Dimension(1, 20));

PainlessGridBag gbl = new PainlessGridBag(getContentPane(), false);
gbl.row().cell(pnlTop).fillXY();
gbl.row().cell(pnlBottom).fillX();
gbl.done();
person Bao Ho    schedule 26.01.2012

Не уверен в своем вопросе, может быть, поможет вам: верх на 70%, низ на 30%

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

public class BorderPanels extends JFrame {

    private static final long serialVersionUID = 1L;

    public BorderPanels() {
        getContentPane().setLayout(new GridBagLayout());
        GridBagConstraints gbc = new GridBagConstraints();
        JPanel panel1 = new JPanel();
        Border eBorder = BorderFactory.createEtchedBorder();
        panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "70pct"));
        gbc.gridx = gbc.gridy = 0;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.NORTHWEST;
        gbc.weightx = gbc.weighty = 70;
        getContentPane().add(panel1, gbc);
        JPanel panel2 = new JPanel();
        panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "30pct"));
        gbc.gridy = 1;
        gbc.weightx = 30;
        gbc.weighty = 30;
        gbc.insets = new Insets(2, 2, 2, 2);
        getContentPane().add(panel2, gbc);
        pack();
    }

    public static void main(String[] args) {
        new BorderPanels().setVisible(true);
    }
}
person mKorbel    schedule 26.01.2012

Если вы можете использовать сторонние библиотеки, вы также можете рассмотреть FormLayout. Он позволяет вам указать высоту каждой строки и поведение при изменении размера.

Я не тестировал это, но

FormLayout layout = new FormLayout( 
 "pref", //columns
 "50dlu:grow(0.2)","25dlu:grow(0.1)" //rows
);

может сделать свое дело. Дополнительную информацию о синтаксисе можно найти в PDF-файле JGoodies Forms.

person Robin    schedule 26.01.2012