KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > columba > core > gui > base > MultiLineLabel


1 //The contents of this file are subject to the Mozilla Public License Version 1.1
2
//(the "License"); you may not use this file except in compliance with the
3
//License. You may obtain a copy of the License at http://www.mozilla.org/MPL/
4
//
5
//Software distributed under the License is distributed on an "AS IS" basis,
6
//WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
7
//for the specific language governing rights and
8
//limitations under the License.
9
//
10
//The Original Code is "The Columba Project"
11
//
12
//The Initial Developers of the Original Code are Frederik Dietz and Timo Stich.
13
//Portions created by Frederik Dietz and Timo Stich are Copyright (C) 2003.
14
//
15
//All Rights Reserved.
16

17 package org.columba.core.gui.base;
18
19 import java.awt.Container JavaDoc;
20 import java.awt.Dimension JavaDoc;
21 import java.awt.Graphics JavaDoc;
22 import java.awt.Graphics2D JavaDoc;
23 import java.awt.Insets JavaDoc;
24 import java.awt.Point JavaDoc;
25 import java.awt.Toolkit JavaDoc;
26 import java.awt.font.LineBreakMeasurer JavaDoc;
27 import java.awt.font.TextAttribute JavaDoc;
28 import java.awt.font.TextLayout JavaDoc;
29 import java.text.AttributedString JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.LinkedList JavaDoc;
32 import java.util.List JavaDoc;
33
34 import javax.swing.JComponent JavaDoc;
35 import javax.swing.UIManager JavaDoc;
36
37 /**
38  * A Swing component capable of displaying text in multiple lines.
39  */

40 public class MultiLineLabel extends JComponent JavaDoc {
41     private String JavaDoc text;
42     private int[] lineBreaks;
43     protected LineBreakMeasurer JavaDoc measurer;
44     protected int lineSpacing = 4;
45     
46     /**
47      * Creates a new label with the given text.
48      */

49     public MultiLineLabel(String JavaDoc text) {
50         setForeground(UIManager.getColor("Label.foreground"));
51         setFont(UIManager.getFont("Label.font"));
52         setAlignmentX(LEFT_ALIGNMENT);
53         setPreferredSize(new Dimension JavaDoc(
54                 Toolkit.getDefaultToolkit().getScreenSize().width / 3, 50));
55         setText(text);
56     }
57     
58     /**
59      * Returns the label's text.
60      */

61     public String JavaDoc getText() {
62         return text;
63     }
64     
65     /**
66      * Sets the label's text.
67      */

68     public void setText(String JavaDoc text) {
69         String JavaDoc oldValue = this.text;
70         this.text = text;
71         measurer = null;
72         firePropertyChange("text", oldValue, text);
73         revalidate();
74         repaint();
75     }
76     
77     /**
78      * Returns the amount of space between the lines.
79      */

80     public int getLineSpacing() {
81         return lineSpacing;
82     }
83     
84     /**
85      * Sets the amount of space between the lines.
86      */

87     public void setLineSpacing(int lineSpacing) {
88         Integer JavaDoc oldValue = new Integer JavaDoc(this.lineSpacing);
89         this.lineSpacing = lineSpacing;
90         firePropertyChange("lineSpacing", oldValue, new Integer JavaDoc(lineSpacing));
91         revalidate();
92         repaint();
93     }
94     
95     /**
96      * Overridden to return appropriate values. This method takes the parent
97      * component's size into account.
98      */

99     public Dimension JavaDoc getMinimumSize() {
100         int height = 5;
101         int width = 0;
102         Container JavaDoc parent = getParent();
103         if (parent != null) {
104             width = parent.getWidth();
105         }
106         if (width == 0) {
107             width = Toolkit.getDefaultToolkit().getScreenSize().width / 3;
108         }
109         LineBreakMeasurer JavaDoc measurer = getLineBreakMeasurer();
110         TextLayout JavaDoc layout;
111         int i = 0;
112         while (measurer != null && measurer.getPosition() < text.length()) {
113             layout = measurer.nextLayout(width - 20, lineBreaks[i], false);
114             
115             //if we stopped at line break, increase array index pointer
116
if (measurer.getPosition() == lineBreaks[i]) {
117                 i++;
118             }
119             
120             //increase minimum height by line height and line spacing
121
height += layout.getAscent() + layout.getDescent() +
122                         layout.getLeading() + lineSpacing;
123         }
124         
125         //add the component's border insets to our minimum dimension
126
Insets JavaDoc insets = getInsets();
127         return new Dimension JavaDoc(width + insets.left + insets.right,
128                 height + insets.top + insets.bottom);
129     }
130     
131     protected LineBreakMeasurer JavaDoc getLineBreakMeasurer() {
132         if (measurer == null) {
133             if (text != null && text.length() > 0) {
134                 AttributedString JavaDoc string = new AttributedString JavaDoc(text);
135                 string.addAttribute(TextAttribute.FONT, getFont());
136                 measurer = new LineBreakMeasurer JavaDoc(string.getIterator(),
137                         ((Graphics2D JavaDoc)getGraphics()).getFontRenderContext());
138                 
139                 //check for line breaks
140
List JavaDoc temp = new LinkedList JavaDoc();
141                 int i;
142                 char c;
143                 for (i = 0; i < text.length(); i++) {
144                     c = text.charAt(i);
145                     if (c == '\r' || c == '\n') {
146                         temp.add(new Integer JavaDoc(i + 1));
147                     }
148                 }
149                 //put them into the array
150
i = 0;
151                 lineBreaks = new int[temp.size() + 1];
152                 Iterator JavaDoc iterator = temp.iterator();
153                 while (iterator.hasNext()) {
154                     lineBreaks[i++] = ((Integer JavaDoc)iterator.next()).intValue();
155                 }
156                 lineBreaks[i] = text.length();
157             }
158         } else {
159             measurer.setPosition(0);
160         }
161         return measurer;
162     }
163     
164     protected void paintComponent(Graphics JavaDoc graphics) {
165         super.paintComponent(graphics);
166         graphics.setColor(getForeground());
167         Graphics2D JavaDoc g = (Graphics2D JavaDoc)graphics;
168         LineBreakMeasurer JavaDoc measurer = getLineBreakMeasurer();
169         float wrappingWidth = getWidth() - 15;
170         if (wrappingWidth <= 0 || measurer == null) {
171             return;
172         }
173         Insets JavaDoc insets = getInsets();
174         Point JavaDoc pen = new Point JavaDoc(5 + insets.left, 5 + insets.top);
175         TextLayout JavaDoc layout;
176         int i = 0;
177         while (measurer.getPosition() < text.length()) {
178             layout = measurer.nextLayout(wrappingWidth, lineBreaks[i], false);
179             
180             //if we stopped at line break, increase array index pointer
181
if (measurer.getPosition() == lineBreaks[i]) {
182                 i++;
183             }
184             
185             //draw line
186
pen.y += layout.getAscent();
187             float dx = layout.isLeftToRight() ?
188                     0 : (wrappingWidth - layout.getAdvance());
189             layout.draw(g, pen.x + dx, pen.y);
190             pen.y += layout.getDescent() + layout.getLeading() + lineSpacing;
191         }
192     }
193     
194     
195     /**
196      * @see java.awt.Component#getPreferredSize()
197      */

198     public Dimension JavaDoc getPreferredSize() {
199         
200         return getMinimumSize();
201     }
202 }
203
Popular Tags