Как правильно центрировать JPanel (FIXED SIZE) внутри JFrame?

Всем привет! Я пытаюсь решить, казалось бы, простую проблему, но не могу ее исправить. Я работаю над примером приложения с библиотеками Java/Swing; У меня есть JFrame и JPanel. Я просто хочу достичь следующих целей:

  1. JPanel ДОЛЖЕН располагаться по центру внутри JFrame.

  2. JPanel ДОЛЖЕН иметь ВСЕГДА размер, указанный с помощью метода
    setPreferredSize(). Он НЕ ДОЛЖЕН быть уменьшен ниже этого размера.

Я попытался использовать GridBagLayout: это ЕДИНСТВЕННЫЙ способ, которым я могу это сделать.

См. образец ниже:

/* file StackSample01.java */

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

public class StackSample01 {
    public static void main(String [] args) {

        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(100, 100));
        panel.setBackground(Color.RED);  

        frame.setLayout(new GridBagLayout());
        frame.add(panel, new GridBagConstraints());
        frame.setSize(new Dimension(200, 200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

Вот скриншот:

Я бы не стал использовать GridBagLayout для слишком простых вещей. Я попробовал простейшее решение с помощью Box, но это не работает:

Образец кода:

/* file StackSample02.java */

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

public class StackSample02 {
    public static void main(String [] args) {

        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
        panel.setPreferredSize(new Dimension(100, 100));
        panel.setBackground(Color.RED); // for debug 

        panel.setAlignmentX(JComponent.CENTER_ALIGNMENT); // have no effect

        Box box = new Box(BoxLayout.Y_AXIS);

        box.add(Box.createVerticalGlue());
        box.add(panel);     
        box.add(Box.createVerticalGlue()); // causes a deformation

        frame.add(box);
        frame.setSize(new Dimension(200, 200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

Вот скриншот,

Любые идеи? Спасибо всем :-)


person IT.    schedule 28.08.2011    source источник
comment
Вы пытались использовать класс BorderFactory, чтобы поместить границу вокруг панели? Я не слишком знаком с этим, иначе я бы привел более конкретный пример.   -  person Tony    schedule 29.08.2011
comment
Я бы не стал использовать GridBagLayout для слишком простых вещей. Почему бы и нет? У меня глубокая и стойкая неприязнь к GBL, но в этой ситуации это будет первая раскладка, которую я попробую.   -  person Andrew Thompson    schedule 29.08.2011
comment
@Andrew - полный ack, за исключением использования GBL, никогда бы его не использовал :-) Вместо этого выберите одну из трех больших форм, Mig, Design, что бы вы ни предпочли.   -  person kleopatra    schedule 29.08.2011
comment
@kleopatra вы проголосовали против ответов за использование setXxxSize (), не могли бы вы предоставить нам правильный ответ или ссылку на правильный ответ? Я устал читать ваши комментарии -1 за это, -1 за это.   -  person mostruash    schedule 22.04.2013
comment
@mostruash подсказка: есть частая вкладка .. Честно говоря, я устал от разработчиков, которые мало что делают, чтобы найти ответ на свои вопросы или причины для голосования за ответы (вверх столько же, сколько вниз, не на самом деле ничего не меняет) — в конце концов, суть их работы — найти что-то.   -  person kleopatra    schedule 22.04.2013


Ответы (6)


BoxLayout может содержать ваш setXxxSize(), а затем просто добавить panel.setMaximumSize(new Dimension(100, 100));

и ваш вывод будет

Удалено setMinimumSize(обратите внимание, если Container имеет больший размер, чем ...)

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

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

public class CustomComponent12 extends JFrame {

    private static final long serialVersionUID = 1L;

    public CustomComponent12() {
        Box box = new Box(BoxLayout.Y_AXIS);
        box.setAlignmentX(JComponent.CENTER_ALIGNMENT);
        box.add(Box.createVerticalGlue());
        box.add(new CustomComponents12());
        box.add(Box.createVerticalGlue());
        add(box);
        pack();
        setTitle("Custom Component Test / BoxLayout");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setMaximumSize(getMinimumSize());
        setMinimumSize(getMinimumSize());
        setPreferredSize(getPreferredSize());
        setLocation(150, 150);
        setVisible(true);
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                CustomComponent12 main = new CustomComponent12();
            }
        };
        javax.swing.SwingUtilities.invokeLater(r);
    }
}

class CustomComponents12 extends JPanel {

    private static final long serialVersionUID = 1L;

    @Override
    public Dimension getMinimumSize() {
        return new Dimension(100, 100);
    }

    @Override
    public Dimension getMaximumSize() {
        return new Dimension(100, 100);
    }

    @Override
    public Dimension getPreferredSize() {
        return new Dimension(100, 100);
    }

    @Override
    public void paintComponent(Graphics g) {
        int margin = 10;
        Dimension dim = getSize();
        super.paintComponent(g);
        g.setColor(Color.red);
        g.fillRect(margin, margin, dim.width - margin * 2, dim.height - margin * 2);
    }
}
person mKorbel    schedule 28.08.2011
comment
@kleopatra кто-то может читать между моими собственными строками :-), мое любопытство (и мы говорим только о самых глубоких JComponents без каких-либо дочерних элементов), как это, или, если возможно, возвращает setXxxSize другим способом - person mKorbel; 29.08.2011

Прежде всего, спасибо всем.

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

/* file StackResponse.java */

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

public class StackResponse {
    public static void main(String [] args) {

        JPanel panel = new JPanel();
        Dimension expectedDimension = new Dimension(100, 100);

        panel.setPreferredSize(expectedDimension);
        panel.setMaximumSize(expectedDimension);
        panel.setMinimumSize(expectedDimension);

        panel.setBackground(Color.RED); // for debug only

        Box box = new Box(BoxLayout.Y_AXIS);

        box.add(Box.createVerticalGlue());
        box.add(panel);     
        box.add(Box.createVerticalGlue());

        JFrame frame = new JFrame();
        frame.add(box);
        frame.setSize(new Dimension(200, 200));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.setMinimumSize(frame.getMinimumSize());   // cannot be resized-

        frame.setVisible(true);

    }
}

Здесь вы можете увидеть снимок экрана.

Проблема решена. Еще раз большое спасибо всем.

IT

person Community    schedule 03.09.2011

создайте панель с именем «FixedPanel» с помощью GridBagLayout и установите предпочтительный размер для размера кадра, затем добавьте свой кадр в FixedPanel.

Frame = new JFrame("CenterFrame");         
Frame.setLocation(0, 0);
Frame.setSize(new Dimension(400,400));//dim

JPanel FixedPanel = new JPanel(new GridBagLayout());
FixedPanel.setPreferredSize(Frame.getSize());

JPanel myPanel = new JPanel();
myPanel.setPreferredSize(new Dimension(100,100));
myPanel.setBackground(Color.BLACK);

FixedPanel.add(myPanel);
Frame.add(FixedPanel);
Frame.setVisible(true);  
person Ehsan Jelodar    schedule 05.09.2014

Ты можешь это сделать. Мне нужно было сделать шахматную партию, и я хотел, чтобы шахматная фигура всегда находилась в центре ячейки, которая была JlayeredPane:

private void formMouseReleased(java.awt.event.MouseEvent evt) {
    // TODO add your handling code here:
    if (jl != null)
    {
        jl.setLocation(evt.getX()+10, evt.getY()+10);
        Component com = findComponentAt(evt.getPoint());
        if (com instanceof JPanel)
        {
            // System.out.println("Yes, it's a jpanel");
            ((JPanel)com).add(jl);
            ((JPanel)com).validate();
        }
    }
}
person andrew    schedule 24.10.2011

Это просто наличие

jPanel.setBounds(x, y, 1046, 503);

Где x — место для правой стороны, а y — место для левой стороны. вы должны рассчитать пространство с обеих сторон в соответствии с высотой и шириной экрана

person Shivling    schedule 12.04.2014

использовать

panel.setMaximumSize(new Dimension(200,200));
panel.setResizable(false)

вместо?

person confucius    schedule 28.08.2011
comment
JPanel не имеет метода setResizable (boolean resizable). - person IT.; 29.08.2011
comment
-1 за setXXSize и изобретение API - вы знаете, что нет обязательства отвечать, если вы этого не знаете? Дикие догадки _определенно неправильные. - person kleopatra; 29.08.2011