2015-04-17 5 views
0

Привет У меня проблема в коде ниже (в основном методе «append (String str)»). Я хочу показывать сообщения, полученные в формате HTML (поэтому мне нужно использовать JLabel). Без установки tac.preferredSize вот что я получаю: enter image description hereJava JLabel Высота с несколькими строками

НО он не работает, используя длинную строку без пробелов: , такие как «aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa».

Если установить 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); 
} 
} 
+0

1) Для лучшей помощи раньше, опубликовать [MCVE] (HTTP: // stackoverflow.com/help/mcve) (минимальный полный проверяемый пример) или [SSCCE] (http://www.sscce.org/) (Short, Self Contained, Correct Example). 2) Это приложение. получая полную строку HTML (от '' до '') или только строку в формате HTML (например, часть тела документа)? Если последний, установите ширину элемента 'BODY' в стилях, и пусть требуемая высота будет вычислена по метке. –

ответ

1

Если разбить слова, которые слишком долго добавив пространства, я думаю, что большинство ваших проблем решены. Было бы полезно также внести небольшие изменения в размеры компонентов 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 для получения дополнительной информации), но я использовал фиксированное значение здесь для простоты.

Было бы неплохо, чтобы связать размеры 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>"); 

 Смежные вопросы

  • Нет связанных вопросов^_^