Java - Swing - 布局 - 忽略元素的所需大小

Java - Swing - Layout - Ignore Wanted Size of Elements

我有两个标签,一个我想占据可用水平空间的 30% space,另一个我想占据 70%。这是绝对的,所以我不希望它是布局感觉的 30%/70%,30%/70% total.

我最先使用 GridbagLayout 进行了测试,因为当您需要这些特定配置时,这通常是可行的方法,但我想不出一种方法来获得这些特定尺寸,并且仍然有数据来呈现部分假设占 30% 的标签。

没有任何布局修改的基本代码示例:

        frame = new JFrame();
        frame.setSize(200,200);
        JPanel panel = new JPanel();

        // 30% Label
        panel.add(new JLabel("Very long sentence that should be cut off"));
        // 70% Label
        panel.add(new JLabel("Text"));

        frame.setContentPane(panel);
        frame.setVisible(true);

None 标准布局管理器直接提供此功能。

查看 Relative Layout。它将 space 分配给每个组件,占可用总数 space 的百分比。分配将随着可用 space 的变化而动态变化。

基本逻辑:

RelativeLayout rl = new RelativeLayout(RelativeLayout.X_AXIS);
JPanel panel = new JPanel( rl );
panel.add(smallLabel, new Float(3));
panel.add(largeLabel, new Float(7));

使用标准布局管理器,您也许可以使用 BoxLayout。它尊重组件的“最大”大小,因此您可以覆盖 getMaximumSize() 大小方法来执行您想要的操作。

类似于:

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

public class SSCCE extends JPanel
{
    public SSCCE()
    {
        setLayout( new BoxLayout(this, BoxLayout.X_AXIS) );

        JLabel small = new JLabel("some long text that will get truncated")
        {
            @Override
            public Dimension getMaximumSize()
            {
                Dimension size = getParent().getSize();
                Dimension maximum = super.getMaximumSize();
                maximum.width = (int)(size.width * .3);

                return maximum;
            }
        };
        small.setOpaque(true);
        small.setBackground(Color.YELLOW);
        add(small);

        JLabel large = new JLabel("text")
        {
            @Override
            public Dimension getMaximumSize()
            {
                Dimension size = getParent().getSize();
                Dimension maximum = super.getMaximumSize();
                maximum.width = (int)(size.width * .7);

                return maximum;
            }
        };
        large.setOpaque(true);
        large.setBackground(Color.ORANGE);
        add(large);
    }

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

    public static void main(String[] args) throws Exception
    {
        java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
    }
}