Почему эти три панели, использующие GridBagLayout, по-разному используют дополнительное пространство, и как сделать их однородными
У меня есть приложение, которое имеет несколько панелей; Я хотел бы иметь возможность использовать разные менеджеры компоновки для разных панелей, но хотел бы, чтобы они вели себя одинаково, поскольку размер окна изменяется пользователем.
package example;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextField;
public class TP1 extends JFrame
{
public static void main(String[] args)
{
TP1 tp1 = new TP1();
tp1.go();
}
public void go()
{
setDefaultCloseOperation(EXIT_ON_CLOSE);
// create a panel with some labels on it
JPanel innerFirst = new JPanel();
innerFirst.setLayout(new BoxLayout(innerFirst, BoxLayout.PAGE_AXIS));
innerFirst.add(new JLabel("one"));
innerFirst.add(new JLabel("two"));
innerFirst.add(new JLabel("three"));
innerFirst.add(new JLabel("four"));
// put that panel in a scroll pane
JScrollPane firstSP = new JScrollPane(innerFirst);
// make another panel and put our scrolled panel in it
JPanel outerFirst = new JPanel();
outerFirst.setLayout(new BoxLayout(outerFirst, BoxLayout.PAGE_AXIS));
outerFirst.add(firstSP);
// create a GridBagLayout panel with some text fields on it
JPanel innerSecond = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = .25;
gbc.anchor = GridBagConstraints.LINE_START;
innerSecond.add(new JTextField(8), gbc);
gbc.gridx = 0;
gbc.gridy = 1;
innerSecond.add(new JTextField(10), gbc);
gbc.gridx =0;
gbc.gridy = 2;
innerSecond.add(new JTextField(12), gbc);
// put that panel in a scroll pane
JScrollPane secondSP = new JScrollPane(innerSecond);
// make another panel and put our second scrolled panel in it
JPanel outerSecond = new JPanel();
outerSecond.setLayout(new BoxLayout(outerSecond, BoxLayout.LINE_AXIS));
outerSecond.add(secondSP);
JPanel innerThird = new JPanel(new GridBagLayout());
GridBagConstraints gbc3 = new GridBagConstraints();
gbc3.anchor = GridBagConstraints.LINE_END;
gbc.weightx = .25;
gbc3.gridx = 0;
gbc3.gridy = 0;
innerThird.add(new JLabel("1st label"), gbc3);
gbc3.gridy = 1;
innerThird.add(new JLabel("second label"), gbc3);
gbc3.gridy = 2;
innerThird.add(new JLabel("IIIrd label"), gbc3);
gbc3.anchor = GridBagConstraints.LINE_START;
gbc3.gridx = 1;
gbc3.gridy = 0;
innerThird.add(new JTextField(8), gbc3);
gbc3.gridy = 1;
innerThird.add(new JTextField(12), gbc3);
gbc3.gridy = 2;
innerThird.add(new JTextField(14), gbc3);
JScrollPane thirdSP = new JScrollPane(innerThird);
JPanel outerThird = new JPanel();
outerThird.setLayout(new BoxLayout(outerThird, BoxLayout.LINE_AXIS));
outerThird.add(thirdSP);
// put the scrolled panes onto a tabbed pane
JTabbedPane tp = new JTabbedPane();
tp.add("text fields", outerSecond);
tp.add("labels", outerFirst);
tp.add("mixed", outerThird);
// add the tabbed pane to the frame
this.add(tp);
// pack it and ship it.
pack();
setVisible(true);
}
}
Запустив приведенный выше код, мы получим окно с панелью с вкладками в нем с тремя вкладками. Если мы сделаем окно меньше, все они получат полосы прокрутки, как и предполагалось. Если мы увеличим его, три будут вести себя по-разному: вкладка с метками оставляет их только в левом верхнем углу окна, вкладка с полями центрирует их только по левому краю, а та, что с мешком сетки из смешанных меток и полей центрирует их как горизонтально, так и вертикально в увеличенном окне.
Это не приемлемо для приложения; Мне нужно как-то заставить все панели вести себя одинаково. Мне нужно, чтобы у всех них были полосы прокрутки, и я бы хотел, чтобы все они оставались в верхнем левом углу, если окно сделано больше, чем внутренняя панель.
Еще одно требование: мои вкладки заняты чем-то, что расширяет JPanel, мне уже говорили, что я не могу поместить JScrollPane прямо во вкладку, но для своего приложения я тоже не хочу этого делать. Это просто делает другие вещи более сложными, чем они должны быть.
В дополнение к желанию, чтобы все дополнительное пространство было расположено снизу и справа, мне бы очень хотелось понять, ПОЧЕМУ эти три ситуации ведут себя по-разному. Я все еще верю, что нам всем было бы лучше, если бы мы понимали принципы, лежащие в основе того, что мы делаем, вместо того, чтобы просто копировать примеры вправо и влево и делать вещи методом проб и ошибок, пока они не сработают.
(Между прочим, у меня есть панель GroupLayout, которая, кажется, тяготеет к верхнему левому углу, но не думала, что это было необходимо для моего вопроса, и это 100 строк кода как есть.)
2 ответа
Похоже, для того, чтобы понять, почему это происходит в вашем коде, вам нужно понять определенные термины. Например, PAGE_AXIS, LINE_AXIS, LINE_END, LINE_START и так далее. Поскольку вы предоставляете их в качестве ограничений, это то, что описывает ориентацию компонентов, добавляемых в контейнер, и их начальную точку, как вы пишете:
innerFirst.setLayout(new BoxLayout(innerFirst, BoxLayout.PAGE_AXIS));
Здесь вы говорите своему BoxLayout начать добавление компонентов с того места, которое относится к началу страницы. (Когда вы запускаете блокнот, курсор помещается в PAGE_AXIS в новом документе). Но когда вы пишете это:
JPanel innerSecond = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 0;
gbc.gridy = 0;
gbc.weightx = .25;
gbc.anchor = GridBagConstraints.LINE_START;
Здесь термин якорь используется, когда компонент меньше, чем его область отображения. Он определяет, где в области отображения разместить компонент. Но здесь, так как вы упомянули, что это имеет значение LINE_START
что значит:
Place the component centered along the edge of its display area where lines of text
would normally begin for the current ComponentOrientation. Equal to WEST for horizontal,
left-to-right orientations and EAST for horizontal, right-to-left orientations.
Вот почему три JTextFields
вы создали, вы видите их в центре на левой стороне.
Я все еще верю, что нам всем было бы лучше, если бы мы поняли принципы того, что мы делаем,
См . Визуальное руководство по менеджерам по расположению для рабочих примеров и объяснений различных менеджеров по расположению. Вам нужно узнать, как различные ограничения используются для конкретного менеджера компоновки.