为啥 BoxLayout 占用了额外的空间?

Posted

技术标签:

【中文标题】为啥 BoxLayout 占用了额外的空间?【英文标题】:Why BoxLayout is taking extra space?为什么 BoxLayout 占用了额外的空间? 【发布时间】:2020-11-01 23:39:55 【问题描述】:

我正在开发一个客户端-服务器聊天应用程序,我正在尝试像在 WhatsApp 中那样创建语音气泡

我想在框架的右侧显示发送的消息,在框架的左侧显示接收的消息,我正在尝试使用BoxLayout 来实现这一点,但它占用了额外的空间(如下图所示)

这就是我到目前为止所做的事情

a1.setLayout(new BoxLayout(a1, BoxLayout.Y_AXIS));
JPanel p1 = new JPanel(new FlowLayout(FlowLayout.RIGHT));
JPanel p2 = new JPanel(new FlowLayout(FlowLayout.LEFT));

您在两条消息之间看到的额外空间是因为我正在使用BoxLayout 在这种情况下该怎么办?以及任何替代方法我们如何通过不使用BoxLayout 来实现这一目标?

【问题讨论】:

创建一个使用FlowLayout的JPanel,将使用BoxLayout的JPanel放到FlowLaypout JPanel里面。 问题在于,当有额外的可用空间时,BoxLayout 将允许组件的大小增长(达到最大大小)。使用 FlowLayout 的面板将尊重添加到其中的组件的首选大小。 @camickr 是的!这正是 BoxLayout 的问题,我很难解决这个问题。请您抽出一些时间并详细说明解决方案。会很亲切的。 @GilbertLeBlanc 执行此操作后,消息未在屏幕上打印。将进行更多更改并检查该解决方案是否有效 - 以后发布minimal reproducible example 来说明问题。我的答案是“MRE”的形式。 【参考方案1】:

所以 FlowLayout 尊重首选高度,但也尊重首选宽度。

相反,您需要一个布局:

    尊重您添加到 BoxLayout 的组件的高度 填充可用空间的宽度。

您可以为此使用BorderLayout

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

public class SSCCE extends JPanel

    public SSCCE()
    
        setLayout( new BorderLayout() );

        Box vertical = Box.createVerticalBox();
        add(vertical, BorderLayout.PAGE_START);

        for (int i = 0; i < 10; i++)
        
            JPanel left = new JPanel( new BorderLayout() );
            left.add(new JLabel("left message " + i), BorderLayout.LINE_START);
            vertical.add( left );
            JPanel right = new JPanel( new BorderLayout() );
            right.add(new JLabel("right message " + i), BorderLayout.LINE_END);
            vertical.add( right );
        
    

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

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

【讨论】:

成功了,非常感谢。你是个传奇兄弟。你救了我几个小时的沮丧

以上是关于为啥 BoxLayout 占用了额外的空间?的主要内容,如果未能解决你的问题,请参考以下文章

不占用任何额外空间的情况下交换两个数的值

为啥 QuickSort 使用 O(log(n)) 额外空间?

如何确保 UILabel 只占用它需要的空间,而不需要额外的填充?

为啥 GridControl 在执行后会创建一个额外的列/空间?

为啥 TensorFlow 会在 TensorBoard 可视化中为我的变量创建额外的命名空间?

Android:折叠通知中的额外间距