JScrollPanes внутри GridBagLayout изменяется случайным образом - PullRequest
3 голосов
/ 09 марта 2012

Вот сложный вопрос для вас, ребята:)

По сути, у меня есть GridBagLayout с 2 столбцами: список , завернутый в полосу прокрутки в каждом.Полосы прокрутки растянуты в направлении ОБА .

Если я постепенно уменьшу высоту этой панели (перетаскивая край окна), я вижу "случайное" изменение размера, происходящее на полосах прокрутки:

  • ширина второй уменьшается, когда появляется первая полоса прокрутки

  • затем ширина второго уменьшается снова без причины ...

Если я не упаковываю свои компоненты, не получайте такое поведение.

И если вы замените правый список на дерево , оно будет вести себя по-другому: при уменьшении высоты окна ниже 380-пикс., Дерево будет изменено в размере ...

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

Ребята, вы хоть представляете, что происходит ???

PS: фактический макет iЯ пытаюсь построить более сложный, чем этот пример.В то же время я использую SpringLayout, чтобы делать то, что я хочу, но это требует много (не так красиво) вещей для настройки

protected static ListModel newListModel(int n) {
    DefaultListModel lm = new DefaultListModel();

    for (int i = 0; i < n; ++i)
        lm.addElement("AAA");

    return lm;
}

protected static JComponent createContentPane() {
    JPanel  pane = new JPanel(new GridBagLayout());

    GridBagConstraints  gbc = new GridBagConstraints();

    gbc.anchor = GridBagConstraints.CENTER;
    gbc.fill = GridBagConstraints.BOTH;
    gbc.weightx = 1;
    gbc.weighty = 1;
    gbc.gridy = 0;
    gbc.gridx = 0;

    pane.add(new JScrollPane(new JList(newListModel(12))), gbc);

    ++gbc.gridx;

    pane.add(new JScrollPane(new JList(newListModel(4))), gbc);

    return pane;
}

public static void main(String[] args) {
    JFrame f = new JFrame();

    f.getContentPane().add(createContentPane());
    f.setSize(800, 400);
    f.setLocationRelativeTo(null);
    f.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    f.setVisible(true);
}

Ответы [ 2 ]

9 голосов
/ 09 марта 2012

У меня есть приложение с несколькими панелями ScrollPanes в GridBagLayout, и они также показывают внезапные изменения размера при изменении размера окна. Кажется, что скачок происходит, когда фактический размер ScrollPane переходит его «предпочтительный размер». Я нашел обходной путь: установите предпочтительный размер 1x1 пикселей. Если компонент имеет положительный вес и растягивается ОБА, он все равно будет занимать всю ячейку, но не будет прыгать. Если вам нужно несколько ячеек для изменения размера в разных пропорциях, вы можете установить предпочтительный размер другой, скажем, 2x1 пикселей.

2 голосов
/ 09 марта 2012
  • это базовые принципы GridBagLayout , вы забыли определить anchor, тогда вы сможете исправить JComponent для относительного Poin t, и я думаю, чтоGridBagLayout усложнил ваш графический интерфейс, этот LayoutManager лучше использовать для размещения лотов JComponents в один контейнер (без использования nested layout)

, например

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

public class BorderPanels extends JFrame {

    private static final long serialVersionUID = 1L;

    public BorderPanels() {
        setLayout(new GridBagLayout());// set LayoutManager
        GridBagConstraints gbc = new GridBagConstraints();
        JPanel panel1 = new JPanel();
        Border eBorder = BorderFactory.createEtchedBorder();

        panel1.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
        gbc.gridx = gbc.gridy = 0;
        gbc.gridwidth = gbc.gridheight = 1;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.NORTHWEST;
        gbc.weightx = gbc.weighty = 20;
        add(panel1, gbc); // add compoenet to the COntentPane

        JPanel panel2 = new JPanel();
        panel2.setBorder(BorderFactory.createTitledBorder(eBorder, "60pct"));
        gbc.gridy = 1;
        gbc.weightx = gbc.weighty = 60;
        //gbc.insets = new Insets(2, 2, 2, 2);
        add(panel2, gbc); // add component to the COntentPane

        JPanel panel3 = new JPanel();
        panel3.setBorder(BorderFactory.createTitledBorder(eBorder, "20pct"));
        gbc.gridy = 2;
        gbc.weightx = gbc.weighty = 20;
        gbc.insets = new Insets(2, 2, 2, 2);
        add(panel3, gbc);

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // important
        pack();
        setVisible(true); // important
    }

    public static void main(String[] args) {
        javax.swing.SwingUtilities.invokeLater(new Runnable() { // important

            public void run() {
                BorderPanels borderPanels = new BorderPanels();
            }
        });
    }
}

во избежание усложнения простых вещей

...