1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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
81
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
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 {
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
150 list.setFixedCellWidth( preferredWidth );
151 setSize( preferredWidth, super.getSize().height );
152 }
153
154 }