为啥 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 在执行后会创建一个额外的列/空间?