简体   繁体   English

如何在BorderLayout中将JComponent定位到真正的中心?

[英]How would I position a JComponent to true center in a BorderLayout?

I am developing a Swing application using BorderLayout to position the components. 我正在开发使用BorderLayout定位组件的Swing应用程序。 Since BorderLayout.CENTER positions components to whatever is left after the other components are placed, and that fact is making my GUI look weird, I was wondering if there was a way to position components to true center, rather than in between the two sides. 由于BorderLayout.CENTER将组件放置到放置其他组件之后剩下的任何位置,并且事实使我的GUI看起来很奇怪,所以我想知道是否有一种方法可以将组件放置到真正的中心,而不是放置在两侧之间。 Since BorderLayout spaces make a component fill an entire space, I'm guessing the solution would be to wrap the component into a JPanel . 由于BorderLayout空间使组件填充了整个空间,所以我猜解决方案是将组件包装到JPanel However, positioning the component to the center of this panel will make the component be closer to one side than another if you have components on other sides. 但是,如果将组件放置在此面板的中央,则如果组件的另一侧比另一侧更靠近一侧,则该组件将比另一侧更靠近一侧。 How do I work around this? 我该如何解决?

These images demonstrate the problem and the ideal solution; 这些图像说明了问题和理想的解决方案。 the gray border represents the BorderLayout.SOUTH (wrapped in a JPanel ) of the main frame. 灰色边框表示主框架的BorderLayout.SOUTH (包装在JPanel )。 The black squares represents components that are throwing the center component off. 黑色正方形表示将中心组件丢掉的组件。 The red square represents the component that needs to be centered. 红色方块代表需要居中的组件。

Problem: 问题:

问题表示

Ideal solution: 理想的解决方案:

解决方案表示

As I see the problem, in order for the red component to be centered the right and left components must be of equal size. 如我所见,要使红色分量居中,左右分量必须相等。

You might be able to use the Relative Layout . 您可能可以使用相对布局

The RelativeLayout will allow you to make the right/left components the same size while keeping the center component at its preferred size. RelativeLayout允许您将左右组件的大小设为相同,同时将中心组件的大小保持在首选大小。 As the frame is resized space will be added/removed from the right/left components. 调整框架大小后,将在左右组件中添加/删除空间。

For example: 例如:

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();
            }
        });
    }
}

The one problem with the relative layout is that when you pack the frame the components will be dislayed too small since the preferred size is simply the sum of the components. 相对布局的一个问题是,当打包框架时,组件的布局将变得太小,因为首选大小仅仅是组件的总和。 So the left panel will be truncated. 因此,左侧面板将被截断。

In the example above you can add the following to get around this problem: 在上面的示例中,您可以添加以下内容来解决此问题:

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

Another option might be to use the OverlayLayout which can be set up to display the red panel over top of a panel containing the two other components: 另一个选择是使用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();
            }
        });
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM