Сделать JPanel занимает всю ширину JFrame - PullRequest
3 голосов
/ 30 января 2020

У меня есть два JPanel для размещения внутри JFrame, я хочу, чтобы они оба занимали всю ширину кадра, но я не знаю как. Кроме того, я не большой поклонник метода setBounds(), поэтому мне было интересно, есть ли способ просто заставить компонент брать полную ширину и просто указать желаемую высоту после.

Вот мой код :

public class Test extends JFrame {
    public Test() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 400);
        setLocationRelativeTo(null);
        setLayout(new BorderLayout());

        JPanel header = new JPanel();
        header.setBounds(0,0,300,50);
        header.setLayout(new BorderLayout());
        header.setBackground(Color.gray);

        JPanel body = new JPanel();
        body.setBounds(0,50,300,300);
        body.setLayout(new BorderLayout());
        body.setBackground(Color.black);


        add(header, BorderLayout.NORTH);
        add(body, BorderLayout.CENTER);
        //setLayout(null);
        setVisible(true);


    }
}

Ответы [ 2 ]

1 голос
/ 30 января 2020

Вам необходимо удалить setLayout(null), это полностью изменяет работу более ранней setLayout(new BorderLayout())

Затем вам нужно установить предпочтительный размер заголовка и тела, используя setPreferredSize вместо использования setBounds()

public Test() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(400, 400);
    setLocationRelativeTo(null);
    setLayout(new BorderLayout());

    JPanel header = new JPanel();
    header.setPreferredSize(new Dimension(400, 50));
    header.setLayout(new BorderLayout());
    header.setBackground(Color.gray);

    JPanel body = new JPanel();
    body.setPreferredSize(new Dimension(400, 300));
    body.setLayout(new BorderLayout());
    body.setBackground(Color.black);

    add(header, BorderLayout.NORTH);
    add(body, BorderLayout.CENTER);
    setVisible(true);
}
0 голосов
/ 31 января 2020

Базовый c ответ заключается в том, что вам необходимо воспользоваться преимуществами инфраструктуры управления макетами.

Менеджеры компоновки работают с учетом предпочтительного / минимального / максимального размера компонента, но будьте осторожны, они являются только руководствами, и менеджеры по расположению могут игнорировать некоторые или все из них в зависимости от своих потребностей и доступного пространства.

Это простой пример, который переопределяет метод getPreferredSize header для возврата «желаемого» "size:

JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setLayout(new BorderLayout());

JPanel header = new JPanel() {
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(300, 50);
    }

};
header.setLayout(new BorderLayout());
header.setBackground(Color.gray);

// I would allow the content of the panel determine the actual size
// but I've overridden `getPreferredSize` for demonstration purposes
JPanel body = new JPanel() {
    @Override
    public Dimension getPreferredSize() {
        return new Dimension(200, 200);
    }
};
body.setLayout(new BorderLayout());
body.setBackground(Color.black);

frame.add(header, BorderLayout.NORTH);
frame.add(body, BorderLayout.CENTER);
// pack is preferred over setSize, as it will "pack" the window around
// the content, which will produce a more consistent result
frame.pack();
frame.setVisible(true);

Проблема заключается в том, что компонент больше не будет учитывать требования к размерам своих дочерних элементов, поэтому у вас могут возникнуть странные побочные эффекты.

Существуют и другие решения, которые могут предоставить некоторые другие преимущества и недостатки, и вам нужно будет рассмотреть их в вашем случае использования.

Почему следует переопределить getPreferredSize вместо вызова setPreferredSize?

В основном, контроль. Вы можете запретить другим частям кода изменять состояние, и вы контролируете, «как» выполняется вычисление. Конечно, ничто не мешает другим кодам расширять компонент и переопределять метод, но это более сложно и не учитывает сценарий ios, где предоставляется экземпляр компонента, а не создается.

Зачем использовать pack сверх setSize?

pack "упаковывает" рамку окна вокруг содержимого, поэтому содержимое всегда будет соответствовать своему предпочтительному размеру, а не уменьшаться содержание, так что украшения кадра могут быть размещены. В целом это приведет к более согласованному результату на нескольких платформах

...