1 package net.sourceforge.jsh3modtool.gui.imagetable;
2
3 import java.awt.*;
4 import java.awt.geom.AffineTransform;
5 import java.awt.image.*;
6
7 import javax.swing.*;
8 import javax.swing.table.*;
9
10 import net.sourceforge.jsh3modtool.gui.imagetable.cache.ImageCache;
11
12 /***
13 * A table cell renderer that displays an ImagePanel as its cell
14 *
15 * @author redsolo
16 */
17 public class ImageCellRenderer extends ImagePanel implements TableCellRenderer
18 {
19 private final Font messageFont = (Font) UIManager.get("Label.font");
20 private final ImageCache imagesCache;
21
22 private String imageName;
23 private boolean imageHasFocus;
24 private boolean imageIsSelected;
25 private final ImageTable parentTable;
26
27 private ImageCell imageCell;
28
29 private int componentWidth;
30 private int componentHeight;
31
32 /***
33 * Creates an ImageCellRenderer
34 * @param table The table that this cellrenderer works with
35 * @param cache the image cache
36 */
37 public ImageCellRenderer(final ImageTable table, final ImageCache cache)
38 {
39 super();
40
41 imagesCache = cache;
42 parentTable = table;
43 }
44
45 /*** Returns the component used for drawing the cell. This method is
46 * used to configure the renderer appropriately before drawing.
47 * @param table the <code>JTable</code> that is asking the
48 * renderer to draw; can be <code>null</code>
49 * @param value the value of the cell to be rendered. It is
50 * up to the specific renderer to interpret
51 * and draw the value. For example, if
52 * <code>value</code>
53 * is the string "true", it could be rendered as a
54 * string or it could be rendered as a check
55 * box that is checked. <code>null</code> is a
56 * valid value
57 * @param isSelected true if the cell is to be rendered with the
58 * selection highlighted; otherwise false
59 * @param hasFocus if true, render cell appropriately. For
60 * example, put a special border on the cell, if
61 * the cell can be edited, render in the color used
62 * to indicate editing
63 * @param row the row index of the cell being drawn. When
64 * drawing the header, the value of
65 * <code>row</code> is -1
66 * @param column the column index of the cell being drawn
67 * @return a Component, can be null
68 */
69 public Component getTableCellRendererComponent(final JTable table, final Object value, final boolean isSelected, final boolean hasFocus, final int row, final int column)
70 {
71 Component component = null;
72
73 if ( ( value != null ) && ( value instanceof ImageCell ) )
74 {
75 imageCell = (ImageCell) value;
76 final BufferedImage cachedImage = (BufferedImage) imagesCache.getImage( imageCell );
77
78 if ( cachedImage == null )
79 {
80 setBufferedImage( null );
81 if ( imageCell.hasTriedToLoadImage() )
82 {
83 setMessage( imageCell.getErrorMessage() );
84 }
85 else
86 {
87 setMessage( "Loading..." );
88 }
89 }
90 else
91 {
92 setBufferedImage( cachedImage );
93 setMessage( null );
94 }
95
96 setToolTipText( imageCell.getTooltip() );
97
98 imageName = imageCell.getName();
99
100 imageIsSelected = imageCell.isSelected();
101 imageHasFocus = (parentTable.getActiveImage() == value ? true : false );
102
103 component = this;
104 }
105 return component;
106 }
107
108 /*** Paints the component, ie paints the background, the imagepanel, the text
109 * and the checkbox
110 * @param graphics graphics 2D object
111 */
112 public void paintComponent(final Graphics graphics)
113 {
114 componentWidth = getWidth();
115 componentHeight = getHeight();
116
117 final Graphics2D graphics2D = (Graphics2D) graphics;
118
119 if ( imageHasFocus )
120 {
121 setBackground(Color.BLACK);
122 }
123 else
124 {
125 if ( imageIsSelected )
126 {
127 setBackground(Color.BLUE);
128 }
129 else
130 {
131 setBackground(Color.white);
132 }
133 }
134
135 super.paintComponent( graphics2D );
136
137 paintFocusBorder( graphics2D );
138
139 if ( imageName != null )
140 {
141 drawImageName( graphics2D );
142 }
143 }
144
145 /***
146 * Paints the focus border.
147 * @param graphics2D graphics 2D object
148 */
149 private void paintFocusBorder( final Graphics2D graphics2D )
150 {
151 Stroke oldStroke=null;
152
153 if ( imageHasFocus )
154 {
155 graphics2D.setColor( Color.BLUE );
156 oldStroke = graphics2D.getStroke();
157 BasicStroke stroke = new BasicStroke(5);
158 graphics2D.setStroke(stroke);
159 }
160 else
161 {
162 graphics2D.setColor( Color.lightGray );
163 }
164 graphics2D.drawLine( 0,0, componentWidth-1, 0 );
165 graphics2D.drawLine( componentWidth-1,0, componentWidth-1, componentHeight-1 );
166 graphics2D.drawLine( componentWidth-1,componentHeight-1, 0, componentHeight-1 );
167 graphics2D.drawLine( 0,componentHeight-1, 0, 0 );
168
169 if ( oldStroke!=null )
170 {
171 graphics2D.setStroke(oldStroke);
172 }
173
174 }
175
176 /*** Draws the name of the image onto the graphics
177 * @param graphics2D graphics 2D object
178 */
179 protected void drawImageName( final Graphics2D graphics2D )
180 {
181 if ( imageHasFocus || imageIsSelected )
182 {
183 graphics2D.setColor(Color.white);
184 }
185 else
186 {
187 graphics2D.setColor(Color.black);
188 }
189
190 graphics2D.setFont(messageFont);
191
192 int leftPos = 0;
193 final int maxWidth = componentWidth - leftPos;
194
195 FontMetrics fontmetrics = graphics2D.getFontMetrics( messageFont );
196 if ( maxWidth != imageCell.getCachedNameMaxWidth() )
197 {
198 imageCell.recacheName( imageCell.getName(), maxWidth, fontmetrics );
199 }
200
201 final String string = imageCell.getCachedName();
202 int strSize = fontmetrics.stringWidth( string );
203 if ( (leftPos + strSize) < maxWidth )
204 {
205 leftPos = (componentWidth / 2) - (strSize / 2);
206 }
207
208 graphics2D.drawString( string, leftPos, componentHeight - 5);
209 }
210
211 /***
212 * Resets the panel.
213 */
214 public void resetPanel()
215 {
216 }
217
218 /***
219 * Overloaded the ImagePanel's redotransform so it is fooled that the imagepanel
220 * is smaller than the whole cell.
221 * @return an <code>AffineTransform</code> for the image.
222 */
223 protected AffineTransform redoTransform()
224 {
225 return redoTransform( componentWidth, componentHeight - 20 );
226 }
227
228
229
230
231 /*** Dummy implementation for performace reasons. */
232 public void validate() {}
233 /*** Dummy implementation for performace reasons. */
234 public void revalidate() {}
235 /*** Dummy implementation for performace reasons. {@inheritDoc} */
236 protected void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) {}
237 /*** Dummy implementation for performace reasons. {@inheritDoc} */
238 public void repaint(final long tm, final int x, final int y, final int width, final int height){}
239 /*** Dummy implementation for performace reasons. {@inheritDoc} */
240 public void repaint(final Rectangle r) {}
241 }