Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/flexstor/common/awt/field/WrappingLabel.java


1   /*
2    * WrappingLabel.java
3    *
4    * Copyright $Date: 2003/08/12 04:19:53 $ FLEXSTOR.net Inc.
5    *
6    * This work is licensed for use and distribution under license terms found at
7    * http://www.flexstor.org/license.html
8    *
9    */
10  
11  package com.flexstor.common.awt.field;
12  
13  import java.awt.Canvas;
14  import java.awt.Dimension;
15  import java.awt.FontMetrics;
16  
17  /**
18   * This class displays lines of text and wraps them around.
19   * To work properly, one dimension (width or height) must be set
20   * with setPreferredWidth/Height methods. The other dimension will
21   * be calculated.
22   */
23  public class WrappingLabel extends Canvas 
24  {
25     protected Dimension dimPreferred = new Dimension(-1, -1);
26  
27     protected String text = "";
28  
29     protected int align = ALIGN_LEFT;
30  
31     protected int baseline;
32  
33     transient protected FontMetrics fm;
34     public static final int ALIGN_LEFT = 0;
35     public static final int ALIGN_CENTERED = 1;
36     public static final int ALIGN_RIGHT = 2;
37     
38   
39    /**
40      * This method returns reasonable values after addNotify has been called.
41      * This works fine when a layout manager is used, otherwise the method
42      * should be called AFTER the peer is realized.
43      */
44     public Dimension getPreferredSize()
45     { 
46        if (dimPreferred.width > 0 && dimPreferred.height > 0)
47        // both values valid, return that dimension
48           return new Dimension(dimPreferred);
49        
50        else if (dimPreferred.width < 0 && dimPreferred.height < 0)
51        // default, neither width nor height set
52           return new Dimension(100,25);
53           
54        else if (dimPreferred.height < 0)
55        //calculate height
56              dimPreferred.height = calculatePreferredHeight(dimPreferred.width);
57  
58        else if (dimPreferred.width < 0)
59        //calculate width
60              dimPreferred.width = calculatePreferredWidth(dimPreferred.height);
61  
62        return new Dimension(dimPreferred);
63        
64        // use parent's width as basis for height calculation
65        //return new Dimension(getParent().getSize().width, calculatePreferredHeight(getParent().getSize().width));
66     }
67  
68     public Dimension getMinimumSize()
69     {
70        return getPreferredSize();
71     }
72  
73     // for compatibility with JDK 1.0 layout managers
74     //public Dimension minimumSize()   {return getMinimumSize();}
75     //public Dimension preferredSize() {return getPreferredSize();}
76  
77     /**
78      * Sets the preferred width. The height will be calculated.
79      * @param the new preferred width
80      */
81     public void setPreferredWidth(int width)
82     {
83        dimPreferred.width  = width;
84        dimPreferred.height = -1;  // indicates need to recalculate
85     }
86  
87     /**
88      * Sets the preferred height. The width will be calculated.
89      * @param the new preferred height
90      */
91     public void setPreferredHeight(int height)
92     {
93        dimPreferred.height = height;
94        dimPreferred.width  = -1;  // indicates need to recalculate
95     }
96  
97     /**
98      * Calculates width for a given height. This only works approximate
99      * because stringWidth does not consider line breaks etc.
100     * For now, there is no need to improve this method.
101     */
102    protected int calculatePreferredWidth(int nHeight)
103    {
104       if (text == null || nHeight < 0 || getFont() == null) 
105          return -1;
106          
107       fm = getToolkit().getFontMetrics(getFont());
108       int nLines = (nHeight / fm.getHeight()) + 1;
109       return fm.stringWidth(text) / nLines;
110    }
111 
112    /**
113     * Calculates height for a given width.
114     * (modified code from Symantec's paint method)
115     */
116    protected int calculatePreferredHeight(int nWidth)
117    {
118       int y = -1;
119 
120       if (text != null && nWidth > 0 && getFont() != null)
121       {
122          int fromIndex = 0;
123          int pos = 0;
124          int bestpos;
125          String largestString;
126          String s;
127 
128          fm = getToolkit().getFontMetrics(getFont());
129          baseline = fm.getMaxAscent();
130 
131          // X and Y represent the coordinates of the upper left portion
132          // of the next text line.
133          y = 0;
134 
135          while (fromIndex != -1)
136          {
137             // Automatically skip any spaces at the beginning of the line
138             while (fromIndex < text.length() && text.charAt(fromIndex) == ' ')
139             {
140                ++fromIndex;
141                // If we hit the end of line while skipping spaces, we're done.
142                if (fromIndex >= text.length()) break;
143             }
144 
145             // fromIndex represents the beginning of the line
146             pos = fromIndex;
147             bestpos = -1;
148             largestString = null;
149 
150             while (pos >= fromIndex)
151             {
152                pos = text.indexOf(' ', pos);
153                // Couldn't find another space?
154                if (pos == -1)
155                {
156                   s = text.substring(fromIndex);
157                }
158                else
159                {
160                   s = text.substring(fromIndex, pos);
161                }
162                // If the string fits, keep track of it.
163                if (fm.stringWidth(s) < nWidth)
164                {
165                   largestString = s;
166                   bestpos = pos;
167                   // If we've hit the end of the string, use it.
168                   if (pos == -1) break;
169                }
170                else
171                {
172                    break;
173                }
174 
175                ++pos;
176             }
177 
178             if (largestString == null)
179             {
180                // Couldn't wrap at a space, so find the largest line
181                // that fits and print that.  Note that this will be
182                // slightly off -- the width of a string will not necessarily
183                // be the sum of the width of its characters, due to kerning.
184                int totalWidth = 0;
185                int oneCharWidth = 0;
186 
187                pos = fromIndex;
188 
189                while (pos < text.length())
190                {
191                   oneCharWidth = fm.charWidth(text.charAt(pos));
192                   if ((totalWidth + oneCharWidth) >= nWidth) break;
193                   totalWidth += oneCharWidth;
194                   ++pos;
195                }
196 
197 //RD           drawAlignedString(g, text.substring(fromIndex, pos), x, y, nWidth);
198                fromIndex = pos;
199             }
200             else
201             {
202 //RD           drawAlignedString(g, largestString, x, y, nWidth);
203 
204                fromIndex = bestpos;
205             }
206             y += fm.getHeight();
207          }
208 
209          // We're done with the font metrics...
210 //RD         fm = null;
211       }
212       return y;
213    }
214    
215    public void setText(String newText)
216    {
217     text = newText;
218     repaint();
219    }
220 
221    public void setAlignStyle(int newAlignStyle)
222    {
223      if (align != newAlignStyle)
224      {
225        align = newAlignStyle;
226        repaint();
227      }
228    }
229 
230 }