首页 > 解决方案 > 如何使框架/面板适合具有固定宽度但可变高度的文本标签

问题描述

我有一个文本数量未知的标签。我需要在面板中显示此标签。面板必须具有固定的宽度,但需要更改高度以调整以完美包裹任何文本。

所以,假设我的宽度限制为 400 像素。它必须显示的文本原来是 80 个单词。我需要让这个文本换行到新的行,所以它基本上是一个 400 像素宽的段落,和一个以前未知的高度。容器的高度不能大于显示段落所需的高度。

我希望能够使用某种布局管理器来做到这一点,当我调整框架大小时,它会起作用,所以如果宽度限制更改为 500 像素,包含现有段落的标签的高度将调整大小,以便有不再需要显示标签的高度。

把它想象成有人在 Stack Overflow 上发布这个问题的答案。您的响应的宽度仅限于本网站 HTML 中 div 的宽度,但它会调整您的 div 的高度,使其适合您的整个答案,不多也不少。我觉得我在这里要疯了;这似乎是这样的基本功能,在 Java Swing 中必须有一种简单的方法。

这是我正在谈论的一个例子。这是一个单行的长句子,没有任何宽度限制。

在此处输入图像描述

但是,这太宽了,因为有 400 像素的宽度限制。它需要看起来像这样:

在此处输入图像描述

有没有办法可以使用布局管理器(希望是盒子管理器)完成这种包装+适合内容的高度?你能举一个代码的例子吗?它需要根据文本的数量为标签提供正确的高度,我真的希望它在框架调整大小时也能正常工作。

这就是我所拥有的。它不起作用,因为它根据示例文本指定高度,但我需要能够处理可变数量的文本,因此我可以插入任何段落并且标签的高度将是正确的。

public class Playground {

    public static void main(String[] args) {
        JFrame myFrame = new JFrame();      
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setBackground(Color.red);
                
        myFrame.setSize(new Dimension(400, 600));       
        
        JPanel groupPanel = new JPanel();
        myFrame.add(groupPanel);
        
        groupPanel.setLayout(new BoxLayout(groupPanel, BoxLayout.Y_AXIS));
        groupPanel.setBackground(Color.green);  

        JPanel itemPanel = new JPanel();
        groupPanel.add(itemPanel);
        
        itemPanel.setLayout(new GridLayout(1,1));
        
        String msg = "<html><p>This is going to be a really long message that says a lot of words but doesnt really say anything. ";
        msg += "We want label containing the message (and the itemPanel that contains it) to always have as much height as necessary ";
        msg += "to display the message given the width of the frame</p></html>";
        
        JLabel testLabel = new JLabel(msg);
        testLabel.setBackground(Color.yellow);
        testLabel.setOpaque(true);
        
        itemPanel.setPreferredSize(new Dimension(400, 64));
        itemPanel.setMinimumSize(new Dimension(400, 64));
        itemPanel.setMaximumSize(new Dimension(400, 64));
        
        itemPanel.add(testLabel);
        
        myFrame.pack();
        myFrame.setVisible(true);

    }
}

这是以前的答案,它通过让框架打包大约 400 像素的段落来帮助:

如果您需要 HTML 的唯一原因是包装,那么也许您可以使用 JTextArea 代替:

//JLabel testLabel = new JLabel(msg);
JTextArea testLabel = new JTextArea();
testLabel.setText(msg);
testLabel.setLineWrap( true );
testLabel.setWrapStyleWord( true );
testLabel.setSize(400, 1);

setSize(...) 语句将为文本区域提供何时换行的提示,以便计算其实际首选大小。

您始终可以设置文本区域的属性,以使其看起来像一个标签。

初始化框架时会有所帮助,但是当我调整框架大小时,标签的高度不会改变,所以也许我只需要继续调用 pack?我不确定如何将它放在事件处理程序中。

标签: javaswing

解决方案


回到 JLabel 和 HTML:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Playground {

    public static void main(String[] args) {
        JFrame myFrame = new JFrame();
        myFrame.setAlwaysOnTop(true);
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        myFrame.setPreferredSize(new Dimension(350, 130));
        JPanel groupPanel = new JPanel();
        groupPanel.setLayout(new GridLayout(1,1));
        String msg = "<html><p align='justify'>This is going to be a really long "
                + "message that says a lot of words but doesnt really say anything. "
                + "We want label containing the message (and the itemPanel that "
                + "contains it to always have as much height as necessary to display "
                + "the message given the width of the frame.</p></html>";
        JLabel testLabel = new JLabel(msg);
        testLabel.setBackground(Color.yellow);
        testLabel.setVerticalAlignment(JLabel.TOP);
        testLabel.setOpaque(true);
        groupPanel.add(testLabel);
        myFrame.add(groupPanel);
        myFrame.pack();
        myFrame.setVisible(true);
        myFrame.setLocationRelativeTo(null);
        
    }
}

这是代码的作用:

在此处输入图像描述


推荐阅读