2009-06-26 2 views
8

Я хочу создать диалоговое окно, содержащее какой-то текстовый элемент (JLabel/JTextArea и т. Д.), Который многолирован и завершает слова. Я хочу, чтобы диалог имел фиксированную ширину, но изменял высоту в зависимости от того, насколько большой текст. У меня есть этот код:Получите высоту многострочного текста с фиксированной шириной, чтобы изменить размер диалогового окна

import static javax.swing.GroupLayout.DEFAULT_SIZE; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 

public class TextSizeProblem extends JFrame { 
    public TextSizeProblem() { 

    String dummyString = ""; 
    for (int i = 0; i < 100; i++) { 
     dummyString += " word" + i; //Create a long text 
    } 
    JLabel text = new JLabel(); 
    text.setText("<html>" + dummyString + "</html>"); 

    JButton packMeButton = new JButton("pack"); 
    packMeButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
     pack(); 
     } 
    }); 

    GroupLayout layout = new GroupLayout(this.getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setVerticalGroup(layout.createParallelGroup() 
     .addComponent(packMeButton) 
     .addComponent(text) 
    ); 
    layout.setHorizontalGroup(layout.createSequentialGroup() 
     .addComponent(packMeButton) 
     .addComponent(text, DEFAULT_SIZE, 400, 400) //Lock the width to 400 
    ); 

    pack(); 
    } 

    public static void main(String args[]) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     JFrame frame = new TextSizeProblem(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     } 
    }); 
    } 
} 

При запуске программы она выглядит следующим образом: alt text http://lesc.se/stackoverflow/multiline_size_1.png

Но я хотел бы, чтобы диалог выглядеть следующим образом (как при нажатии кнопки пакета): alt text http://lesc.se/stackoverflow/multiline_size_2.png

Я предполагаю, что проблема заключается в том, что менеджер макета не смог определить правильную высоту текста, прежде чем отображать его на экране. Я пробовал различные validate(), invalidate(), validateTree() и т. Д., Но не удалось.

ответ

4

Я нашел решение моей проблемы. Заменяя JLabel с JTextArea:

JTextArea text = new JTextArea(); 
text.setText(dummyString); 
text.setLineWrap(true); 
text.setWrapStyleWord(true); 

И называя пакет() с последующим вызовом для менеджера компоновки макет компоненты снова следуют другой пакет:

pack(); 
layout.invalidateLayout(this.getContentPane()); 
pack(); 

Это приведет к тому, что менеджер макета будет адаптироваться к ширине.

Полный код:

import static javax.swing.GroupLayout.DEFAULT_SIZE; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 

public class TextSizeProblem3 extends JFrame { 
    public TextSizeProblem3() { 

    String dummyString = ""; 
    for (int i = 0; i < 100; i++) { 
     dummyString += " word" + i; //Create a long text 
    } 
    JTextArea text = new JTextArea(); 
    text.setText(dummyString); 
    text.setLineWrap(true); 
    text.setWrapStyleWord(true); 

    JButton packMeButton = new JButton("pack"); 
    packMeButton.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
     pack(); 
     } 
    }); 

    GroupLayout layout = new GroupLayout(this.getContentPane()); 
    getContentPane().setLayout(layout); 
    layout.setVerticalGroup(layout.createParallelGroup() 
     .addComponent(packMeButton) 
     .addComponent(text) 
    ); 
    layout.setHorizontalGroup(layout.createSequentialGroup() 
     .addComponent(packMeButton) 
     .addComponent(text, DEFAULT_SIZE, 400, 400) //Lock the width to 400 
    ); 

    pack(); 
    layout.invalidateLayout(this.getContentPane()); 
    pack(); 
    } 

    public static void main(String args[]) { 
    SwingUtilities.invokeLater(new Runnable() { 
     public void run() { 
     JFrame frame = new TextSizeProblem3(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     } 
    }); 
    } 
} 

(вы можете добавить некоторые настройки (границы, цвет и т.д.), поэтому он выглядит точно так же, как JLabel, но я опустил, что)

+0

Выдает ли HTML-теги? Нет! – Soley

10

Адаптация вашего кода делает то, что вы хотите. Но для вычисления размера ярлыка и настройки его предпочтительного размера требуется небольшой трюк.

I found the solution here

import static javax.swing.GroupLayout.DEFAULT_SIZE; 

import java.awt.Dimension; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.*; 
import javax.swing.text.View; 

public class TextSizeProblem extends JFrame { 
    public TextSizeProblem() { 

     String dummyString = ""; 
     for (int i = 0; i < 100; i++) { 
      dummyString += " word" + i; // Create a long text 
     } 
     JLabel text = new JLabel(); 
     text.setText("<html>" + dummyString + "</html>"); 

     Dimension prefSize = getPreferredSize(text.getText(), true, 400); 

     JButton packMeButton = new JButton("pack"); 
     packMeButton.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       pack(); 
      } 
     }); 



     GroupLayout layout = new GroupLayout(this.getContentPane()); 
     getContentPane().setLayout(layout); 
     layout.setVerticalGroup(layout.createParallelGroup().addComponent(packMeButton) 
       .addComponent(text,DEFAULT_SIZE, prefSize.height, prefSize.height)); 
     layout.setHorizontalGroup(layout.createSequentialGroup().addComponent(packMeButton) 
       .addComponent(text, DEFAULT_SIZE, prefSize.width, prefSize.width) // Lock the width to 400 
       ); 

     pack(); 
    } 

    public static void main(String args[]) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       JFrame frame = new TextSizeProblem(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    private static final JLabel resizer = new JLabel(); 

    /** 
    * Returns the preferred size to set a component at in order to render an html string. You can 
    * specify the size of one dimension. 
    */ 
    public static java.awt.Dimension getPreferredSize(String html, boolean width, int prefSize) { 

     resizer.setText(html); 

     View view = (View) resizer.getClientProperty(javax.swing.plaf.basic.BasicHTML.propertyKey); 

     view.setSize(width ? prefSize : 0, width ? 0 : prefSize); 

     float w = view.getPreferredSpan(View.X_AXIS); 
     float h = view.getPreferredSpan(View.Y_AXIS); 

     return new java.awt.Dimension((int) Math.ceil(w), (int) Math.ceil(h)); 
    } 
} 
+0

Да, это решение работает! –

+0

Боже, я бы хотел проголосовать за это время. – Burimi

5

Я думаю, что это то, что вы хочу:

JLabel label = new JLabel("<html><div style=\"width:200px;\">Lots of text here...</div></html>"); 
// add the label to some Container. 

Это ограничит JLabel, чтобы быть 200 пикселей в ширину и автоматически регулировать высоту в соответствии с текстом.

+0

См. Пример в [LabelRenderTest.java] (http://stackoverflow.com/questions/5853879/java-swing-obtain-image-of-jframe/5853992#5853992) (показано выше). –

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