Как изменить размер JPanel, чтобы он соответствовал JFrame в док-норте, не мешая остальным JPanels

Я делаю небольшой тест демонстрационного графического интерфейса Swing. В этой демонстрации JFrame состоит из 3 "главных" JPanel. Если хотите, первый (jp1) состоит из JLabels, а два других состоят из нескольких других JPanels. Я использую MigLayout.

Вот мой пример кода:

    // All the jPanels  
    JFrame frame = new JFrame();
    frame.setLayout(new MigLayout());
    JPanel jp1 = new JPanel();
    jp1.setLayout(new MigLayout());
    jp1.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    JPanel jp2 = new JPanel();
    jp2.setLayout(new MigLayout());
    jp2.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    JPanel jp3 = new JPanel();
    jp3.setLayout(new MigLayout());
    jp3.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    JPanel jp4 = new JPanel();
    jp4.setLayout(new MigLayout());
    jp4.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    JPanel jp5 = new JPanel();
    jp5.setLayout(new MigLayout());
    jp5.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    JPanel jp6 = new JPanel();
    jp6.setLayout(new MigLayout());
    jp6.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    JPanel jp7 = new JPanel();
    jp7.setLayout(new MigLayout());
    jp7.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));

    JPanel bigPanel1 = new JPanel();
    bigPanel1.setLayout(new MigLayout());
    bigPanel1.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));

    JPanel bigPanel2 = new JPanel();
    bigPanel2.setLayout(new MigLayout());
    bigPanel2.setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY, 1));
    //All the labels to be added to JPanel jp1
    JLabel label1 = new JLabel();
    label1.setText("LABEL1");
    JLabel label2 = new JLabel();
    label2.setText("LABEL2");
    JLabel label3 = new JLabel();
    label3.setText("LABEL3");
    JLabel label4 = new JLabel();
    label4.setText("LABEL4");
    jp1.add(label1);
    jp1.add(label2);
    jp1.add(label3);
    jp1.add(label4,"wrap");
    bigPanel1.add(jp2);
    bigPanel1.add(jp6);
    bigPanel1.add(jp3,"grow,wrap");
    bigPanel2.add(jp4);
    bigPanel2.add(jp7);
    bigPanel2.add(jp5,"grow,wrap");
    frame.getContentPane().add(jp1,"dock north, wrap");
    frame.getContentPane().add(bigPanel1,"span,grow,wrap");
    frame.getContentPane().add(bigPanel2,"span,grow,wrap");
    frame.pack();
    frame.setVisible(true);

В результате получается следующий вывод: ГРАФИЧЕСКИЙ ИНТЕРФЕЙС

Чего я хочу добиться, так это возможности добавлять метки в 1-й JPanel (jp1), не связываясь с оставшейся шириной JPanels. Кроме того, я хочу, чтобы несколько JPanel внутри bigPanel занимали всю его ширину, а также jp2, jp6 и jp3 заполняли bigPanel1.

Как мне это сделать? Заранее спасибо.


person Ivo    schedule 30.01.2013    source источник
comment
По вашему снимку экрана кажется, что все может быть одним с дефолтным JPanel Layout - FlowLayout. зачем вообще возиться с дополнительными библиотеками, когда в Java все это включено и доступна дополнительная помощь? ... Или я просто сторонний LayoutManager ненавистник: P   -  person David Kroukamp    schedule 30.01.2013
comment
Во что бы то ни стало, если это то, что нужно. Итак, в сценарии FlowLayout, как настроить мою демонстрацию?   -  person Ivo    schedule 30.01.2013
comment
Использование Mig на самом деле не является обязательным требованием. Я использую его, как я думал, что это будет лучше. Спасибо.   -  person Ivo    schedule 30.01.2013


Ответы (2)


Я никогда не использовал MigLayout и лично не вижу причин, если это можно сделать с помощью java по умолчанию LayoutManager.

Итак, я использовал комбинацию FlowLayout и GridBagLayout для достижения этой цели. , а также gc.fill=GridBagConstraints.NONE и gc.anchor=GridBagConstraints.WEST для тех панелей, которые мы не хотим заполнять ширину contentpane, также обновлены в соответствии с вашим комментарием, чтобы JPanel/JFrame не превышали заданную максимальную ширину, когда больше JLabel добавлено, что это было сделано с помощью JScrollPane:

введите здесь описание изображения

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class Test {

    public Test() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new GridBagLayout());

        final JPanel labelPanel = new JPanel();
        labelPanel.setBorder(new LineBorder(Color.black));
        for (int i = 0; i < 5; i++) {
            labelPanel.add(new JLabel("Label" + (i + 1)));
        }

        final int maxWidth = 200;
        final JScrollPane jsp = new JScrollPane(labelPanel) {
            @Override
            public Dimension getPreferredSize() {
                //we set the height by checking if we exceeed the wanted ith thus a scrollbar will appear an we must incoprate that or labels wont be shpwn nicely
                return new Dimension(maxWidth, labelPanel.getPreferredSize().width < maxWidth ? (labelPanel.getPreferredSize().height + 5) : ((labelPanel.getPreferredSize().height + getHorizontalScrollBar().getPreferredSize().height) + 5));
            }
        };

        JPanel otherPanel = new JPanel();
        otherPanel.add(new JLabel("label"));
        otherPanel.setBorder(new LineBorder(Color.black));

        JPanel otherPanel2 = new JPanel();
        otherPanel2.add(new JLabel("label 1"));
        otherPanel2.add(new JLabel("label 2"));
        otherPanel2.setBorder(new LineBorder(Color.black));

        GridBagConstraints gc = new GridBagConstraints();

        gc.fill = GridBagConstraints.BOTH;
        gc.weightx = 1.0;
        gc.weighty = 1.0;
        gc.gridx = 0;
        gc.gridy = 0;
        frame.add(jsp, gc);

        gc.fill = GridBagConstraints.NONE;
        gc.anchor = GridBagConstraints.WEST;
        gc.gridy = 1;
        frame.add(otherPanel, gc);
        gc.anchor = GridBagConstraints.WEST;
        gc.gridy = 2;
        frame.add(otherPanel2, gc);

        frame.pack();
        frame.setVisible(true);
        frame.revalidate();
        frame.repaint();
    }

    public static void main(String[] args) {
        //Create Swing components on EDT
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Test();
            }
        });
    }
}
person David Kroukamp    schedule 30.01.2013
comment
Большое спасибо. На самом деле это позволяет добавлять метки к labelPanel, не вмешиваясь в другую ширину JPanels. Есть ли способ заставить labelPanel соответствовать определенному размеру, например полноэкранному размеру, и перестать увеличиваться в ширину, заставляя предстоящие метки растягиваться? - person Ivo; 30.01.2013
comment
Я чувствую себя таким глупым сейчас. Просто добавьте JScrollPane, и он сделает свое дело еще лучше. Большое спасибо за твою помощь. - person Ivo; 31.01.2013

Я использую BorderLayout и FlowLayout для управления макетами. В кадре два JPanel's и один JPanel, в нем есть еще два JPanel's. Все внутренние панели используют FlowLayout для выравнивания JLabels. Для размещения этих панелей на JFrame я использовал BorderLayout.

Диспетчер компоновки

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.GridBagLayout;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.border.LineBorder;

public class LayoutTest {

    public LayoutTest() {

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.setLayout(new GridBagLayout());

        JPanel motherPanel = new JPanel(new BorderLayout());

        JPanel topPanel = new JPanel(new BorderLayout());
        JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

        motherPanel.add(topPanel, BorderLayout.NORTH);
        motherPanel.add(bottomPanel, BorderLayout.CENTER);

        JPanel topUpperPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        JPanel topBottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));

        topUpperPanel.setBorder(new LineBorder(Color.BLACK));
        topBottomPanel.setBorder(new LineBorder(Color.BLACK));
        bottomPanel.setBorder(new LineBorder(Color.BLACK));

        topPanel.add(topUpperPanel, BorderLayout.PAGE_START);
        topPanel.add(topBottomPanel, BorderLayout.CENTER);

        for(int i = 0; i < 3; i++) {
            JLabel label = new JLabel("Label-" + String.valueOf(i));
            label.setBorder(new LineBorder(Color.BLACK));
            topUpperPanel.add(label);
        }

        for(int i = 0; i < 2; i++) {
            JLabel label = new JLabel("Label-" + String.valueOf(i));
            label.setBorder(new LineBorder(Color.BLACK));
            topBottomPanel.add(label);
        }

        for(int i = 0; i < 5; i++) {
            JLabel label = new JLabel("Label-" + String.valueOf(i));
            label.setBorder(new LineBorder(Color.BLACK));
            bottomPanel.add(label);
        }

        frame.add(motherPanel);
        frame.setTitle("Layout Manager");
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new LayoutTest();
            }
        });
    }
}

P.S. Я бы посоветовал вам разделить панели таким образом, чтобы они не мешали остальным панелям JPanel.

person Amarnath    schedule 30.01.2013
comment
хорошо и использует мою первоначальную идею FlowLayout, хотя у OP была граница с JPanel, а не с JLabel, поэтому вопрос OP о том, как заставить JPanel не заполнять ширину - person David Kroukamp; 30.01.2013
comment
@DavidKroukamp Является ли то, что OP хочет только Border размером до JLabel или Border для всей панели каждой строки? - person Amarnath; 30.01.2013
comment
Вся панель насколько я понимаю - person David Kroukamp; 30.01.2013
comment
@Che Большое спасибо за ваш ответ. Оба ответа были очень полезными. - person Ivo; 31.01.2013