Java JLabel 多行高度
Java JLabel Height with multiple lines
您好,我在下面的代码中遇到了问题(主要是在方法 "append(String str)" 中)。我想显示以 HTML 格式收到的消息(因此我需要使用 JLabel)。
没有设置 tac.preferredSize 这就是我得到的:
但是使用不带空格的长字符串不起作用:
比如"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".
如果我设置 tac.preferredSize 气泡的高度不会增加:
如何克服这些问题? (处理 layout/sizes 而不是修改输入字符串)
代码如下:
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();
}
}
还有气泡class:
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);
}
}
如果你把太长的单词加空格打散,我想你的大部分问题都解决了。对 leftArrowBubble
和 tac
组件的尺寸进行一些小的更改也会很有用。
您可以在 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),但为了简单起见,我在这里使用了固定值。
link leftArrowBubble
、tac
的尺寸和 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>");
您好,我在下面的代码中遇到了问题(主要是在方法 "append(String str)" 中)。我想显示以 HTML 格式收到的消息(因此我需要使用 JLabel)。
没有设置 tac.preferredSize 这就是我得到的:
但是使用不带空格的长字符串不起作用: 比如"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa".
如果我设置 tac.preferredSize 气泡的高度不会增加:
如何克服这些问题? (处理 layout/sizes 而不是修改输入字符串)
代码如下:
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();
}
}
还有气泡class:
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);
}
}
如果你把太长的单词加空格打散,我想你的大部分问题都解决了。对 leftArrowBubble
和 tac
组件的尺寸进行一些小的更改也会很有用。
您可以在 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),但为了简单起见,我在这里使用了固定值。
link leftArrowBubble
、tac
的尺寸和 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>");