开发者

Reflowing label widget for Swing

Is there a widget for Swing that behaves like a JLabel, that automatically reflows the text if its dimensions have changed? For example:

Large horizontal space available:
+--------------+
| Foo bar baz  |
+--------------+

Small horizontal space available:
+---------+
| Foo bar |
| baz     |
+---------+

I am currently using JEditorPane with setContentType("text/html") and HTML content. This wo开发者_JAVA技巧rks, but it does not use the System's default label font for displaying the text. Also, I would rather not put HTML tags into my text - at best, \n characters would be transformed into line breaks and everything else would be displayed as text.


You can use JTextArea, a multi-line plain-text widget.

JavaDoc: http://java.sun.com/j2se/1.5.0/docs/api/javax/swing/JTextArea.html

    JTextArea ta = new JTextArea("A JTextArea containing a long text");
    ta.setLineWrap(true);
    ta.setWrapStyleWord(true);
    ta.setOpaque(false);
    ta.setEditable(false);
    ta.setFocusable(false);
  • setLineWrap(true) enables the wrapping
  • setWrapStyleWord(true) changes wrapping from character- to word-based
  • setOpaque(true) renders it opaque, like a normal label
  • setEditable(false) hides the caret and disables the user to change the text
  • setFocusable(false) disables the user to select the text

It look like a nornal JLabel, but it will wrap the text, whenever the width is too small.


I'm not sure of this, but I think it's worth a try:

You can set a JLabel's text using HTML. This should take care of the font issue. Simply do something like

lbl.setText("<html><body>Foo bar baz</body></html>");

See how the text behaves then.

If that works for you, you can override JLabel's setText() method to convert \n into <br/> and wrap html and body tags around the text.


I have made a custom UI delegate for JLabel to support multiple lines. It will wrap your text to fit the available space and also respect hard line breaks. The wrapped text should reflow when the component size changes. The UI delegate listens for changes to the component's dimension and recalculates the line breaks automatically.

Using the UI delegate is as straight forward as:

JLabel label = new JLabel("Text that'll wrap if necessary");
label.setUI(MultiLineLabelUI.labelUI);

Or alternatively use the custom MultiLineLabel class that in addition to wrapping text supports vertical and horizontal text alignment.

Here's the project: https://github.com/sasjo/multiline

If you compile and try the demo, it should reflow fine on OS X. If I remember correctly there's some problem with reflowing upon resizing the frame on Windows. Didn't look in to it at the time, but it seemed that the resized event never propagated to the label.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜