具有多行的Java JLabel高度

时间:2015-04-17 14:22:25

标签: java swing jlabel boxlayout

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

但是如果没有空格,则无法使用长字符串: 例如“aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa

如果我设置了tac.preferredSize,则气泡的高度不会增加: enter image description here

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

以下是代码:

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 个答案:

答案 0 :(得分: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>");