2009-06-26 15 views
8

Chcę utworzyć okno dialogowe zawierające element tekstowy (JLabel/JTextArea itp.), Który jest wieloliniowy i zawija słowa. Chcę, aby okno dialogowe miało stałą szerokość, ale dostosuj wysokość w zależności od wielkości tekstu. Mam ten kod:Uzyskaj wysokość tekstu wielowierszowego o stałej szerokości, aby zmienić rozmiar okna dialogowego.

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); 
     } 
    }); 
    } 
} 

Po uruchomieniu programu wygląda to tak: alt text http://lesc.se/stackoverflow/multiline_size_1.png

Ale chciałbym okno wyglądać tak (jak po naciśnięciu Pack-przycisk): alt text http://lesc.se/stackoverflow/multiline_size_2.png

Zgaduję, że problem polega na tym, że menedżer układu nie był w stanie określić prawidłowej wysokości tekstu przed wyświetleniem go na ekranie. Próbowałem różnych validate(), invalidate(), validateTree() itp., Ale nie udało się.

Odpowiedz

4

znalazłem rozwiązania mojego problemu. Zastępując JLabel z JTextArea:

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

i nazywając pakiet(), a następnie inwokacji do menedżera układu do układu komponentów znowu po innej paczki:

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

Spowoduje to dostosowanie menedżera układu do szerokości.

Kompletny kod:

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); 
     } 
    }); 
    } 
} 

(można dodać trochę dostosowanie (obramowanie, kolor itp), więc wygląda jak JLabel ale pominięto to)

+0

Czy renderuje znaczniki HTML? Nie! – Soley

10

Oto adaptacja kodu, robienie tego, co chcesz. Potrzebny jest jednak mały trik, aby obliczyć rozmiar etykiety i ustawić preferowany rozmiar.

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

Tak, to rozwiązanie działa! –

+0

Boże, chciałbym móc głosować na te czasy Ton. – Burimi

5

myślę, że to jest to, czego chcesz:

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

Spowoduje to ograniczenie szerokości JLabel do 200 pikseli i automatyczne dostosowanie wysokości w celu dopasowania do tekstu.

+0

Zobacz przykład w [LabelRenderTest.java] (http://stackoverflow.com/questions/5853879/java-swing-obtain-image-f-jame/5853992#5853992) (pokazany powyżej). –

Powiązane problemy