【问题标题】:Java JLabel Height with multiple lines具有多行的 Java JLabel 高度
【发布时间】:2015-04-17 14:22:24
【问题描述】:

嗨,我在下面的代码中遇到了问题(主要是在方法“append(String str)”中)。我想以 HTML 格式显示收到的消息(所以我需要使用 JLabel)。 没有设置 tac.preferredSize 这里是我得到的:

但它不能使用没有空格的长字符串: 比如“啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊啊”

如果我设置 tac.preferredSize 气泡的高度不会增加:

我该如何克服这些问题? (处理布局/大小而不修改输入字符串)

代码如下:

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class ClientGUI extends JFrame implements ActionListener {

private static final long serialVersionUID = 1L;
private JLabel label;
private JTextField tf;
private JPanel chatPanel;
private JScrollPane scroll;

ClientGUI() {
    super("Chat Client");
    label = new JLabel("You can write messages below:", SwingConstants.CENTER);
    chatPanel = new JPanel();

    tf = new JTextField("");
    tf.setBackground(Color.WHITE);
    tf.requestFocus();
    tf.setVisible(true);
    tf.addActionListener(this);

    chatPanel.setLayout(new BoxLayout(chatPanel, BoxLayout.PAGE_AXIS));
    chatPanel.add(Box.createVerticalGlue());
    JPanel centerPanel = new JPanel(new GridLayout(1,1));

    scroll = new JScrollPane();
    scroll.setViewportView(chatPanel);
    scroll.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
    scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);

    centerPanel.add(scroll);

    add(centerPanel, BorderLayout.CENTER);

    JPanel southPanel = new JPanel(new BorderLayout());
    JPanel writeChatPanel = new JPanel(new GridLayout(2,1));
    writeChatPanel.add(label);
    writeChatPanel.add(tf);
    southPanel.add(writeChatPanel, BorderLayout.NORTH);

    add(southPanel, BorderLayout.SOUTH);

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(600, 600);
    setVisible(true);

    chatPanel.scrollRectToVisible(new Rectangle(chatPanel.getSize()));

}

void append(String str) {
    LeftArrowBubble leftArrowBubble = new LeftArrowBubble();
    leftArrowBubble.setMaximumSize(new Dimension(400,350));
    JLabel tac = new JLabel();
    tac.setMaximumSize(new Dimension(350,400));
    //tac.setPreferredSize(new Dimension(350,50)); //<----------
    System.out.println(str);
    tac.setText("<html><body style='width:  350px; padding:15px;display:block;'>"+str+"</body></html>");

    tac.setOpaque(false);
    leftArrowBubble.add(tac, BorderLayout.NORTH);

    chatPanel.add(leftArrowBubble);     

    chatPanel.add(Box.createRigidArea(new Dimension(0,5)));
    Rectangle rect = chatPanel.getBounds();
    Rectangle r2 = scroll.getViewport().getVisibleRect();
    chatPanel.scrollRectToVisible(new Rectangle((int) rect.getWidth(), 
            (int) rect.getHeight(), (int) r2.getWidth(), (int) r2.getHeight()));
    revalidate();
    repaint();
}
public void actionPerformed(ActionEvent e) {    
        // just have to send the message
        append(tf.getText());               
        tf.setText("");
        return;
}
public static void main(String[] args) {
    new ClientGUI();
}
}

还有泡泡课:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.GeneralPath;
import javax.swing.BoxLayout;
import javax.swing.JPanel;

public class LeftArrowBubble extends JPanel {
private static final long serialVersionUID = -5389178141802153305L;

public LeftArrowBubble() {
   this.setLayout(new BoxLayout(this,BoxLayout.PAGE_AXIS));
}

@Override
protected void paintComponent(final Graphics g) {
   final Graphics2D graphics2D = (Graphics2D) g;
   RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
   qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
   graphics2D.setRenderingHints(qualityHints);
   graphics2D.setPaint(new Color(80, 150, 180));
   int width = getWidth();
   int height = getHeight();
   GeneralPath path = new GeneralPath();
   path.moveTo(5, 10);
   path.curveTo(5, 10, 7, 5, 0, 0);
   path.curveTo(0, 0, 12, 0, 12, 5);
   path.curveTo(12, 5, 12, 0, 20, 0);
   path.lineTo(width - 10, 0);
   path.curveTo(width - 10, 0, width, 0, width, 10);
   path.lineTo(width, height - 10);
   path.curveTo(width, height - 10, width, height, width - 10, height);
   path.lineTo(15, height);
   path.curveTo(15, height, 5, height, 5, height - 10);
   path.lineTo(5, 15);
   path.closePath();
   graphics2D.fill(path);
}
}

【问题讨论】:

  • 1) 为了尽快获得更好的帮助,请发布MCVE(最小完整可验证示例)或SSCCE(简短、自包含、正确示例)。 2)是应用程序。接收一个完整的 HTML 字符串(从 &lt;HTML ..&gt;&lt;/HTML&gt;)还是只是一个 HTML 格式的字符串(例如文档正文的一部分)?如果是后者,在styles中设置BODY元素的宽度,让需要的高度由label计算出来。

标签: java swing jlabel boxlayout


【解决方案1】:

如果你通过添加空格将太长的单词分开,我认为你的大部分问题都解决了。对leftArrowBubbletac 组件的尺寸进行一些小的更改也会很有用。

您可以在append 方法中替换以下行:

leftArrowBubble.setMaximumSize(new Dimension(400,350));
JLabel tac = new JLabel();
tac.setMaximumSize(new Dimension(350,400));
//tac.setPreferredSize(new Dimension(350,50)); //<----------
System.out.println(str);
tac.setText("<html><body style='width:350px;padding:15px;display:block;'>"
            + str + "</body></html>");

通过以下代码(您也可以查看Split string to equal length substrings in Java,了解更多将字符串分成等份的方法):

leftArrowBubble.setMaximumSize(new Dimension(500, 500));
JLabel tac = new JLabel();
tac.setMaximumSize(new Dimension(450, 450));
//tac.setPreferredSize(new Dimension(350, 50)); //<----------

final int maximumSize = 56;
String textWithSeparators = "";
final StringTokenizer textTokenizer
    = new StringTokenizer(str, " \t\n\r", true);

while (textTokenizer.hasMoreTokens()) {
    final String part = textTokenizer.nextToken();
    for (int beginIndex = 0; beginIndex < part.length();
         beginIndex += maximumSize)
        textWithSeparators += (beginIndex == 0 ? "" : " ")
            + part.substring(beginIndex,
                             Math.min(part.length(),
                                      beginIndex + maximumSize));
}

System.out.println(textWithSeparators);

tac.setText("<html><body style='width:350px;padding:15px;display:block;'>"
            + textWithSeparators + "</body></html>");

maximumSize 的值可以使用字体度量来计算(有关更多信息,请参阅How to get the correct String width from FontMetrics in JAVA),但为了简单起见,我在这里使用了一个固定值。

最好将leftArrowBubbletac的尺寸和html字符串中的宽度联系起来,比如:

final int size = 500;
leftArrowBubble.setMaximumSize(new Dimension(size, size));
JLabel tac = new JLabel();
tac.setMaximumSize(new Dimension(size - 50, size - 50));
// [...]
tac.setText("<html><body style='width:" + (size - 150)
            + "px;padding:15px;display:block;'>"
            + textWithSeparators + "</body></html>");

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-03-08
    • 2015-06-15
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 2017-02-13
    • 2016-08-05
    相关资源
    最近更新 更多