source: josm/trunk/src/org/openstreetmap/josm/gui/JMultilineLabel.java@ 2234

Last change on this file since 2234 was 2154, checked in by xeen, 15 years ago

Rewrite JMultilineLabel to support HTML markup.
this closes #3500

File size: 2.7 KB
Line 
1// License: GPL. For details, see LICENSE file.
2
3package org.openstreetmap.josm.gui;
4
5import java.awt.Dimension;
6import java.awt.Rectangle;
7
8import javax.swing.JLabel;
9import javax.swing.plaf.basic.BasicHTML;
10import javax.swing.text.View;
11
12/**
13 * Creates a normal label that will wrap its contents if there less width than
14 * required to print it in one line. Additionally the maximum width of the text
15 * can be set using <code>setMaxWidth</code>.
16 *
17 * Note that this won't work if JMultilineLabel is put into a JScrollBox or
18 * similar as the bounds will never change. Instead scrollbars will be displayed.
19 */
20public class JMultilineLabel extends JLabel {
21 private int maxWidth = Integer.MAX_VALUE;
22 private Dimension superPreferred = null;
23 private Rectangle oldbounds = null;
24 private Dimension oldPreferred = null;
25
26 /**
27 * Constructs a normal label but adds HTML tags if not already done so.
28 * Supports both newline characters (<code>\n</code>) as well as the HTML
29 * <code>&lt;br&gt;</code> to insert new lines.
30 *
31 * Use setMaxWidth to limit the width of the label.
32 * @param text
33 */
34 public JMultilineLabel(String text)
35 {
36 super();
37 text = text.trim().replaceAll("\n", "<br>");
38 if(!text.startsWith("<html>")) {
39 text = "<html>" + text + "</html>";
40 }
41 super.setText(text);
42 }
43
44 /**
45 * Set the maximum width. Use this method instead of setMaximumSize because
46 * this saves a little bit of overhead and is actually taken into account.
47 *
48 * @param width
49 */
50 public void setMaxWidth(int width) {
51 this.maxWidth = width;
52 }
53
54 /**
55 * Tries to determine a suitable height for the given contents and return
56 * that dimension.
57 */
58 @Override
59 public Dimension getPreferredSize()
60 {
61 // Without this check it will result in an infinite loop calling
62 // getPreferredSize. Remember the old bounds and only recalculate if
63 // the size actually changed.
64 if(this.getBounds().equals(oldbounds) && oldPreferred != null)
65 return oldPreferred;
66 oldbounds = this.getBounds();
67
68 this.superPreferred = super.getPreferredSize();
69 // Make it not larger than required
70 int width = Math.min(superPreferred.width, maxWidth);
71
72 // Calculate suitable width and height
73 final View v = (View) super.getClientProperty(BasicHTML.propertyKey);
74
75 if(v == null)
76 return superPreferred;
77
78 v.setSize(width, 0);
79 int w = (int) Math.ceil(v.getPreferredSpan(View.X_AXIS));
80 int h = (int) Math.ceil(v.getPreferredSpan(View.Y_AXIS));
81
82 oldPreferred = new Dimension(w, h);
83 return oldPreferred;
84 }
85}
Note: See TracBrowser for help on using the repository browser.