xref: /titanic_41/usr/src/cmd/krb5/kadmin/gui/visualrt/sunsoft/jws/visual/rt/awt/MultiLineLabel.java (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * ident	"%Z%%M%	%I%	%E% SMI"
24  *
25  * Copyright (c) 2000 by Sun Microsystems, Inc.
26  * All rights reserved.
27  */
28 
29 /* BEGIN JSTYLED */
30         /**
31          * MultiLineLabel.java
32          *
33          * This example is from the book _Java in a
34 	 * Nutshell_ by David Flanagan.
35          * Written by David Flanagan.
36 	 * Copyright (c) 1996 O'Reilly & Associates.
37          * You may study, use, modify, and distribute
38 	 * this example for any purpose.
39          * This example is provided WITHOUT WARRANTY either
40 	 * expressed or implied.
41          *
42          * Tilman 05/07/96: added a maxChars parameter to
43 	 * specify a maximum line
44          * length. If any of the lines is longer, it will be cut
45          * at the last space character before maxChars, until it fits
46          * into maxChars. Set maxChars to -1 if you don't care.
47          *
48          * Van 07/30/96: added the removal of backslash-r
49 	 * from the multi-line string
50          * that might have been added by strings in Windows (which
51          * expect newlines to be indicated by backslash-r backslash-n)
52          *
53          * Van 10/18/96: changed the way lines are tokenized so that multiple
54          * consequetive newline characters create a blank line(s).
55          *
56          * Van 10/21/96: added interfaces to the maxChars variable
57          *
58          * @version @(#)MultiLineLabel.java 1.15 97/07/25
59          */
60 /* END JSTYLED */
61 
62 package sunsoft.jws.visual.rt.awt;
63 
64 import sunsoft.jws.visual.rt.base.Global;
65 import java.awt.*;
66 import java.util.*;
67 
68 public class MultiLineLabel extends Canvas {
69     public static final int LEFT = Label.LEFT; // Alignment constants
70     public static final int CENTER = Label.CENTER;
71     public static final int RIGHT = Label.RIGHT;
72 
73     protected String label;
74     protected Vector lines;         // The lines of text to display
75     protected int num_lines;          // The number of lines
76     protected int maxChars;           // maximum width of lines
77     protected int margin_width;       // Left and right margins
78     protected int margin_height;      // Top and bottom margins
79     protected int line_height;        // Total height of the font
80     protected int line_ascent;        // Font height above baseline
81     protected int[] line_widths;      // How wide each line is
82     protected int max_width;          // The width of the widest line
83     protected int alignment = LEFT;   // The alignment of the text.
84 
85     /**
86      * This method breaks a specified label up into an array of lines.
87      * It uses the StringTokenizer utility class.
88      */
newLabel(String label)89     protected void newLabel(String label) {
90         if (label == null)
91             label = /* NOI18N */"";
92         this.label = label;
93 
94         lines = new Vector();
95         int len = label.length();
96         int startFrom = 0;
97         while (startFrom != -1 && startFrom < len) {
98             // determine next line
99             String line;
100             int index = label.indexOf(/* NOI18N */"\n", startFrom);
101             if (index == -1) {
102                 line = label.substring(startFrom);
103                 startFrom = -1;
104             } else {
105                 line = label.substring(startFrom, index);
106                 startFrom = index + 1;
107             }
108 
109             // wrap the words in the line
110             if ((maxChars == -1) || (line.length() <= maxChars))
111                 lines.addElement(line);
112             else {
113                 while (line.length() > maxChars) {
114                     int offset = line.lastIndexOf(/* NOI18N */ ' ',
115 						  maxChars);
116                     if (offset == -1) {
117                         // didn't get one within maxChars!
118                         offset = line.indexOf(/* NOI18N */ ' ');
119                         if (offset == -1)
120                             break;
121                     }
122                     lines.addElement(line.substring(0, offset));
123                     line = line.substring(offset + 1);
124                 }
125                 lines.addElement(line);
126             }
127         }
128         num_lines = lines.size();
129         line_widths = new int[num_lines];
130     }
131 
132     /**
133      * This method figures out how the font is, and how wide each
134      * line of the label is, and how wide the widest line is.
135      */
measure()136     protected void measure() {
137         /* JSTYLED */
138 	if (this.getFont() == null) return;
139         FontMetrics fm = this.getFontMetrics(this.getFont());
140         // If we don't have font metrics yet, just return.
141         /* JSTYLED */
142 	if (fm == null) return;
143 
144         line_height = fm.getHeight();
145         line_ascent = fm.getAscent();
146         max_width = 0;
147         for (int i = 0; i < num_lines; i++) {
148             line_widths[i] = fm.stringWidth(
149 					    (String) lines.elementAt(i));
150             if (line_widths[i] > max_width) max_width = line_widths[i];
151         }
152         Dimension d = preferredSize();
153         setSize(d);
154     }
155 
156     // Here are four versions of the constructor.
157 
158     /**
159      * Break the label up into separate lines, and save the other info.
160      */
MultiLineLabel(String label, int maxChars, int margin_width, int margin_height, int alignment)161     public MultiLineLabel(String label, int maxChars,
162 			  int margin_width, int margin_height,
163 			  int alignment) {
164         this.maxChars = maxChars;
165         newLabel(label);
166         this.margin_width = margin_width;
167         this.margin_height = margin_height;
168         this.alignment = alignment;
169     }
MultiLineLabel(String label, int maxChars, int margin_width, int margin_height)170     public MultiLineLabel(String label, int maxChars,
171 			  int margin_width, int margin_height) {
172         this(label, maxChars, margin_width, margin_height, LEFT);
173     }
MultiLineLabel(String label, int maxChars, int alignment)174     public MultiLineLabel(String label, int maxChars,
175 			  int alignment) {
176         this(label, maxChars, 10, 10, alignment);
177     }
MultiLineLabel(String label, int maxChars)178     public MultiLineLabel(String label, int maxChars) {
179         this(label, maxChars, 10, 10, LEFT);
180     }
181 
MultiLineLabel(String label)182     public MultiLineLabel(String label) {
183         this(label, -1, 10, 10, LEFT);
184     }
185 
MultiLineLabel()186     public MultiLineLabel() {
187         this(/* NOI18N */"MultiLineLabel");
188     }
189 
190     // Methods to set the various attributes of the component
setLabel(String label)191     public void setLabel(String label) {
192         newLabel(label);
193         measure();
194         repaint();
195     }
196 
getLabel()197     public String getLabel() {
198         return label;
199     }
200 
setMaxColumns(int w)201     public void setMaxColumns(int w) {
202         if (w < 0)
203             w = -1;
204         maxChars = w;
205         newLabel(label);
206         measure();
207         repaint();
208     }
209 
getMaxColumns()210     public int getMaxColumns() {
211         return (maxChars);
212     }
213 
setFont(Font f)214     public void setFont(Font f) {
215         super.setFont(f);
216         measure();
217         repaint();
218     }
219 
setForeground(Color c)220     public void setForeground(Color c) {
221         super.setForeground(c);
222         repaint();
223     }
224 
setAlignment(int a)225     public void setAlignment(int a) { alignment = a; repaint(); }
setMarginWidth(int mw)226     public void setMarginWidth(int mw) { margin_width = mw; repaint(); }
setMarginHeight(int mh)227     public void setMarginHeight(int mh) { margin_height = mh;
228     repaint(); }
getAlignment()229     public int getAlignment() { return alignment; }
getMarginWidth()230     public int getMarginWidth() { return margin_width; }
getMarginHeight()231     public int getMarginHeight() { return margin_height; }
232 
233     /**
234      * This method is invoked after our Canvas is first created
235      * but before it can actually be displayed.  After we've
236      * invoked our superclass's addNotify() method, we have font
237      * metrics and can successfully call measure() to figure out
238      * how big the label is.
239      */
addNotify()240     public void addNotify() { super.addNotify(); measure(); }
241 
242     /**
243      * This method is called by a layout manager when it wants to
244      * know how big we'd like to be.
245      */
preferredSize()246     public Dimension preferredSize() {
247         return new Dimension(max_width + 2*margin_width,
248 			     num_lines * line_height + 2*margin_height);
249     }
250 
251     /**
252      * This method is called when the layout manager wants to know
253      * the bare minimum amount of space we need to get by.
254      */
minimumSize()255     public Dimension minimumSize() {
256         return new Dimension(max_width, num_lines * line_height);
257     }
258 
259     /**
260      * This method draws the label (applets use the same method).
261      * Note that it handles the margins and the alignment, but that
262      * it doesn't have to worry about the color or font--the superclass
263      * takes care of setting those in the Graphics object we're passed.
264      */
paint(Graphics g)265     public void paint(Graphics g) {
266         if (Global.isWindows())
267             g = getGraphics();
268         int x, y;
269         Dimension d = this.size();
270 
271         int mw = Math.max((d.width - max_width)/2, 0);
272         g.setColor(getForeground());
273 
274         y = line_ascent + (d.height - num_lines * line_height)/2;
275         for (int i = 0; i < num_lines; i++, y += line_height) {
276             switch (alignment) {
277 	    case LEFT:
278                 x = mw;
279                 break;
280 	    case CENTER:
281 	    default:
282                 x = (d.width - line_widths[i])/2;
283                 break;
284 	    case RIGHT:
285                 x = d.width - mw - line_widths[i];
286                 break;
287             }
288             g.drawString(((String) lines.elementAt(i)).trim(), x, y);
289         }
290     }
291 }
292