2009-06-26 79 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

我猜测问题是布局管理器在将文本显示到屏幕之前未能确定正确的文本高度。我已经尝试过各种验证(),invalidate(),validateTree()等,但没有成功。

回答

4

我找到了解决我的问题。通过与一个JTextArea替换的JLabel:

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

(你可以加一些定制(边框,颜色等),因此它看起来就像一个JL​​abel但我省略了)

+0

它呈现HTML标记吗?没有! – Soley 2015-02-21 07:22:10

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

是的,这个解决方案的工作原理! – 2009-06-26 12:15:44

+0

上帝,我希望我能投票这吨时间。 – Burimi 2011-10-25 12:05:23

5

我想这就是你想要:

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

这将限制JLabel为200像素宽,并自动调整高度以适应文本。

相关问题