Как бы я расположил JComponent к истинному центру в BorderLayout?

Я разрабатываю приложение Swing, используя BorderLayout разместить компоненты. поскольку BorderLayout.CENTER позиционирует компоненты к тому, что осталось после размещения других компонентов, и этот факт заставляет мой GUI выглядеть странно, мне было интересно, есть ли способ расположить компоненты к истинному центру, а не между двумя сторонами. поскольку BorderLayout пробелы делают компонент заполнить все пространство, я думаю, что решение было бы заключить компонент в JPanel, Однако расположение компонента в центре этой панели сделает компонент ближе к одной стороне, чем к другой, если у вас есть компоненты на других сторонах. Как мне обойти это?

Эти изображения демонстрируют проблему и идеальное решение; серая рамка представляет BorderLayout.SOUTH (завернутый в JPanel) основного кадра. Черные квадраты представляют компоненты, которые отбрасывают центральный компонент. Красный квадрат представляет компонент, который должен быть центрирован.

Проблема:

Представление проблемы

Идеальное решение:

Представление решения

1 ответ

Решение

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

Возможно, вы сможете использовать относительный макет.

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

Например:

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

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        JPanel left = new JPanel( new FlowLayout(FlowLayout.LEFT) );
        JPanel leftBox = new JPanel();
        leftBox.setPreferredSize( new Dimension(200, 50) );
        leftBox.setBackground( Color.BLACK );
        left.add( leftBox );

        JPanel center = new JPanel( new FlowLayout(FlowLayout.CENTER) );
        JPanel centerBox = new JPanel();
        centerBox.setPreferredSize( new Dimension(50, 50) );
        centerBox.setBackground( Color.RED );
        center.add( centerBox );

        JPanel right = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
        JPanel rightBox = new JPanel();
        rightBox.setPreferredSize( new Dimension(50, 50) );
        rightBox.setBackground( Color.BLACK );
        right.add( rightBox );

        setLayout( new RelativeLayout(RelativeLayout.X_AXIS, 5) );
        add(left, new Float(1));
        add(center);
        add(right, new Float(1));
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}

Одна проблема с относительной компоновкой состоит в том, что при упаковке кадра компоненты будут отображаться слишком маленькими, поскольку предпочтительный размер представляет собой просто сумму компонентов. Таким образом, левая панель будет обрезана.

В приведенном выше примере вы можете добавить следующее, чтобы обойти эту проблему:

right.add( rightBox );
right.setPreferredSize( left.getPreferredSize() ); // added

Другим вариантом может быть использование OverlayLayout который может быть настроен для отображения красной панели поверх панели, содержащей два других компонента:

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

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        JPanel left = new JPanel( new FlowLayout(FlowLayout.LEFT) );
        JPanel leftBox = new JPanel();
        leftBox.setPreferredSize( new Dimension(200, 50) );
        leftBox.setBackground( Color.BLACK );
        left.add( leftBox );

        JPanel center = new JPanel( new FlowLayout(FlowLayout.CENTER) );
        center.setOpaque(false);
        JPanel centerBox = new JPanel();
        centerBox.setPreferredSize( new Dimension(50, 50) );
        centerBox.setBackground( Color.RED );
        center.add( centerBox );

        JPanel right = new JPanel( new FlowLayout(FlowLayout.RIGHT) );
        JPanel rightBox = new JPanel();
        rightBox.setPreferredSize( new Dimension(50, 50) );
        rightBox.setBackground( Color.BLACK );
        right.add( rightBox );

        JPanel main = new JPanel( new BorderLayout() );
        main.add(left, BorderLayout.LINE_START);
        main.add(right, BorderLayout.LINE_END);

        setLayout( new OverlayLayout(this) );
        add(center);
        add(main);
    }

    private static void createAndShowGUI()
    {
        JFrame frame = new JFrame("SSCCE");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new SSCCE());
        frame.setLocationByPlatform( true );
        frame.pack();
        frame.setVisible( true );
    }

    public static void main(String[] args)
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                createAndShowGUI();
            }
        });
    }
}
Другие вопросы по тегам