View Javadoc

1   /*
2   Wotonomy: OpenStep design patterns for pure Java applications.
3   Copyright (C) 2000 Blacksmith, Inc.
4   
5   This library is free software; you can redistribute it and/or
6   modify it under the terms of the GNU Lesser General Public
7   License as published by the Free Software Foundation; either
8   version 2.1 of the License, or (at your option) any later version.
9   
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  Lesser General Public License for more details.
14  
15  You should have received a copy of the GNU Lesser General Public
16  License along with this library; if not, see http://www.gnu.org
17  */
18  
19  package net.wotonomy.ui.swing.components;
20  
21  import java.awt.Component;
22  import java.awt.Dimension;
23  
24  import javax.swing.JList;
25  import javax.swing.JViewport;
26  import javax.swing.ListCellRenderer;
27  import javax.swing.UIManager;
28  import javax.swing.border.Border;
29  import javax.swing.border.EmptyBorder;
30  import javax.swing.event.ChangeEvent;
31  import javax.swing.event.ChangeListener;
32  
33  /***
34  * A list cell renderer that wraps its text to subsequent lines
35  * depending on the length of text string and the width of the
36  * parent list. 
37  *
38  * This renderer depends on listening to the parent list's viewport
39  * and fixing the list's width to match the viewport's size.
40  *
41  * @author michael@mpowers.net
42  * @author $Author: cgruber $
43  * @date $Date: 2006-02-18 23:19:05 +0000 (Sat, 18 Feb 2006) $
44  * @revision $Revision: 904 $
45  */
46  public class LineWrappingRenderer extends MultiLineLabel
47      implements ListCellRenderer, ChangeListener
48  {
49      protected static Border noFocusBorder;
50  
51      protected JList list;
52      protected JViewport viewport;
53      protected int preferredWidth;
54  
55  /***
56  * Required constructor.  The renderer keeps a reference to
57  * the list in which it is used and its viewport.  This list
58  * is the only list that may use this renderer.  The renderer
59  * will use the current size of the list to determine where
60  * lines will initially break.
61  * @param containerList The list that will be using this renderer.
62  */
63      public LineWrappingRenderer( JList containerList )
64      {
65  	    super();
66          setLineWrap(true);
67         	noFocusBorder = new EmptyBorder(1, 1, 1, 1);
68  
69          list = containerList;
70          preferredWidth = 400;
71          if ( list.getParent() instanceof JViewport )
72          {
73              viewport = (JViewport) list.getParent();
74              viewport.addChangeListener( this );
75              int newWidth = viewport.getExtentSize().width;
76              if ( newWidth > 0 ) preferredWidth = newWidth;
77          }
78          else
79          {
80              // should function adequately in absence of a viewport
81              // System.err.println( "LineWrappingRenderer.init: list.getParent = " + list.getParent() );
82          }
83      }
84  
85  /***
86  * Returns the preferred size of the label, with width
87  * constrained to the current width.
88  * @return the size
89  */
90      public Dimension getPreferredSize()
91      {
92          int width = getWidth();
93          if ( width != preferredWidth )
94          {
95              // if component has not yet been placed within the list
96              if ( width < list.getWidth() / 2 ) width = list.getWidth();
97              preferredWidth = width;
98          } 
99          return new Dimension( preferredWidth, super.getPreferredSize().height );
100     }
101 
102 /***
103 * Returns this component with the width set to the
104 * width of the specified JList.
105 * @return this component.
106 */
107     public Component getListCellRendererComponent (
108         JList list,
109     	Object value,
110         int index,
111         boolean isSelected,
112         boolean cellHasFocus )
113     { // System.out.println( "LineWrappingRenderer.getListCellRendererComponent:" );
114 
115         if ( list != this.list )
116         {
117             System.err.println( "LineWrappingRenderer.getListCellRendererComponent: " +
118                 "warning: the list using the renderer is not the list specified in the constructor." );
119         }
120 
121         if (isSelected)
122         {
123             setBackground(this.list.getSelectionBackground());
124             setForeground(this.list.getSelectionForeground());
125         }
126         else
127         {
128             setBackground(this.list.getBackground());
129             setForeground(this.list.getForeground());
130         }
131 
132         setText((value == null) ? "" : value.toString());
133 
134         setEnabled(this.list.isEnabled());
135         setFont(this.list.getFont());
136         setBorder( (cellHasFocus) ? UIManager.getBorder("List.focusCellHighlightBorder") : noFocusBorder );
137 
138         return this;
139     }
140 
141 /***
142 * Overridden to respond to viewport changes.
143 */
144     public void stateChanged(ChangeEvent e)
145     {
146         int newWidth = viewport.getExtentSize().width;
147         if ( newWidth > 0 ) preferredWidth = newWidth;
148 
149         // set fixed width on list
150         list.setFixedCellWidth( preferredWidth );
151         setSize( preferredWidth, super.getSize().height );
152     }
153 
154 }