KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > swing > plaf > synth > SynthTableUI


1 /*
2  * @(#)SynthTableUI.java 1.17 04/07/23
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8 package javax.swing.plaf.synth;
9
10 import javax.swing.table.*;
11 import javax.swing.*;
12 import javax.swing.event.*;
13 import java.util.Enumeration JavaDoc;
14 import java.util.Hashtable JavaDoc;
15 import java.util.TooManyListenersException JavaDoc;
16 import java.awt.event.*;
17 import java.awt.*;
18 import java.awt.datatransfer.*;
19 import java.awt.dnd.*;
20 import java.text.*;
21 import javax.swing.border.*;
22 import javax.swing.plaf.*;
23 import javax.swing.plaf.basic.*;
24 import java.util.Date JavaDoc;
25 import java.util.EventObject JavaDoc;
26
27 import javax.swing.text.*;
28
29 import java.beans.PropertyChangeEvent JavaDoc;
30 import java.beans.PropertyChangeListener JavaDoc;
31 import sun.swing.plaf.synth.SynthUI;
32
33 /**
34  * SynthTableUI implementation
35  *
36  * @version 1.17, 07/23/04
37  * @author Philip Milne
38  */

39 class SynthTableUI extends BasicTableUI implements SynthUI,
40         PropertyChangeListener JavaDoc {
41 //
42
// Instance Variables
43
//
44

45     private SynthStyle JavaDoc style;
46
47     private boolean useTableColors;
48     private boolean useUIBorder;
49
50     // TableCellRenderer installed on the JTable at the time we're installed,
51
// cached so that we can reinstall them at uninstallUI time.
52
private TableCellRenderer dateRenderer;
53     private TableCellRenderer numberRenderer;
54     private TableCellRenderer doubleRender;
55     private TableCellRenderer floatRenderer;
56     private TableCellRenderer iconRenderer;
57     private TableCellRenderer imageIconRenderer;
58     private TableCellRenderer booleanRenderer;
59     private TableCellRenderer objectRenderer;
60
61 //
62
// The installation/uninstall procedures and support
63
//
64

65     public static ComponentUI createUI(JComponent c) {
66         return new SynthTableUI JavaDoc();
67     }
68
69     /**
70      * Initialize JTable properties, e.g. font, foreground, and background.
71      * The font, foreground, and background properties are only set if their
72      * current value is either null or a UIResource, other properties are set
73      * if the current value is null.
74      *
75      * @see #installUI
76      */

77     protected void installDefaults() {
78         dateRenderer = installRendererIfPossible(Date JavaDoc.class, null);
79         numberRenderer = installRendererIfPossible(Number JavaDoc.class, null);
80         doubleRender = installRendererIfPossible(Double JavaDoc.class, null);
81         floatRenderer = installRendererIfPossible(Float JavaDoc.class, null);
82         iconRenderer = installRendererIfPossible(Icon.class, null);
83         imageIconRenderer = installRendererIfPossible(ImageIcon.class, null);
84         booleanRenderer = installRendererIfPossible(Boolean JavaDoc.class,
85                                  new SynthBooleanTableCellRenderer());
86         objectRenderer = installRendererIfPossible(Object JavaDoc.class,
87                                         new SynthTableCellRenderer());
88         updateStyle(table);
89     }
90
91     private TableCellRenderer installRendererIfPossible(Class JavaDoc objectClass,
92                                      TableCellRenderer renderer) {
93         TableCellRenderer currentRenderer = table.getDefaultRenderer(
94                                  objectClass);
95         if (currentRenderer instanceof UIResource) {
96             table.setDefaultRenderer(objectClass, renderer);
97         }
98         return currentRenderer;
99     }
100
101     private void updateStyle(JTable c) {
102         SynthContext JavaDoc context = getContext(c, ENABLED);
103         SynthStyle JavaDoc oldStyle = style;
104         style = SynthLookAndFeel.updateStyle(context, this);
105         if (style != oldStyle) {
106             context.setComponentState(ENABLED | SELECTED);
107
108             Color sbg = table.getSelectionBackground();
109             if (sbg == null || sbg instanceof UIResource) {
110                 table.setSelectionBackground(style.getColor(
111                                         context, ColorType.TEXT_BACKGROUND));
112             }
113
114             Color sfg = table.getSelectionForeground();
115             if (sfg == null || sfg instanceof UIResource) {
116                 table.setSelectionForeground(style.getColor(
117                                   context, ColorType.TEXT_FOREGROUND));
118             }
119
120             context.setComponentState(ENABLED);
121
122             Color gridColor = table.getGridColor();
123             if (gridColor == null || gridColor instanceof UIResource) {
124                 gridColor = (Color)style.get(context, "Table.gridColor");
125                 if (gridColor == null) {
126                     gridColor = style.getColor(context, ColorType.FOREGROUND);
127                 }
128                 table.setGridColor(gridColor);
129             }
130
131             useTableColors = style.getBoolean(context,
132                                   "Table.rendererUseTableColors", true);
133             useUIBorder = style.getBoolean(context,
134                                   "Table.rendererUseUIBorder", true);
135
136             Object JavaDoc rowHeight = style.get(context, "Table.rowHeight");
137             if (rowHeight != null) {
138                 LookAndFeel.installProperty(table, "rowHeight", rowHeight);
139             }
140             if (oldStyle != null) {
141                 uninstallKeyboardActions();
142                 installKeyboardActions();
143             }
144         }
145         context.dispose();
146     }
147
148     /**
149      * Attaches listeners to the JTable.
150      */

151     protected void installListeners() {
152         super.installListeners();
153         table.addPropertyChangeListener(this);
154     }
155
156     protected void uninstallDefaults() {
157         table.setDefaultRenderer(Date JavaDoc.class, dateRenderer);
158         table.setDefaultRenderer(Number JavaDoc.class, numberRenderer);
159         table.setDefaultRenderer(Double JavaDoc.class, doubleRender);
160         table.setDefaultRenderer(Float JavaDoc.class, floatRenderer);
161         table.setDefaultRenderer(Icon.class, iconRenderer);
162         table.setDefaultRenderer(ImageIcon.class, imageIconRenderer);
163         table.setDefaultRenderer(Boolean JavaDoc.class, booleanRenderer);
164         table.setDefaultRenderer(Object JavaDoc.class, objectRenderer);
165
166     if (table.getTransferHandler() instanceof UIResource) {
167         table.setTransferHandler(null);
168     }
169         SynthContext JavaDoc context = getContext(table, ENABLED);
170         style.uninstallDefaults(context);
171         context.dispose();
172         style = null;
173     }
174
175     protected void uninstallListeners() {
176         table.removePropertyChangeListener(this);
177         super.uninstallListeners();
178     }
179
180     //
181
// SynthUI
182
//
183
public SynthContext JavaDoc getContext(JComponent c) {
184         return getContext(c, getComponentState(c));
185     }
186
187     private SynthContext JavaDoc getContext(JComponent c, int state) {
188         return SynthContext.getContext(SynthContext JavaDoc.class, c,
189                     SynthLookAndFeel.getRegion(c), style, state);
190     }
191
192     private Region JavaDoc getRegion(JComponent c) {
193         return SynthLookAndFeel.getRegion(c);
194     }
195
196     private int getComponentState(JComponent c) {
197         return SynthLookAndFeel.getComponentState(c);
198     }
199
200 //
201
// Paint methods and support
202
//
203

204     public void update(Graphics g, JComponent c) {
205         SynthContext JavaDoc context = getContext(c);
206
207         SynthLookAndFeel.update(context, g);
208         context.getPainter().paintTableBackground(context,
209                           g, 0, 0, c.getWidth(), c.getHeight());
210         paint(context, g);
211         context.dispose();
212     }
213
214     public void paintBorder(SynthContext JavaDoc context, Graphics g, int x,
215                             int y, int w, int h) {
216         context.getPainter().paintTableBorder(context, g, x, y, w, h);
217     }
218
219     public void paint(Graphics g, JComponent c) {
220         SynthContext JavaDoc context = getContext(c);
221
222         paint(context, g);
223         context.dispose();
224     }
225
226     protected void paint(SynthContext JavaDoc context, Graphics g) {
227     if (table.getRowCount() <= 0 || table.getColumnCount() <= 0) {
228         return;
229     }
230     Rectangle clip = g.getClipBounds();
231     Point upperLeft = clip.getLocation();
232     Point lowerRight = new Point(clip.x + clip.width - 1, clip.y + clip.height - 1);
233         int rMin = table.rowAtPoint(upperLeft);
234         int rMax = table.rowAtPoint(lowerRight);
235         // This should never happen.
236
if (rMin == -1) {
237         rMin = 0;
238         }
239         // If the table does not have enough rows to fill the view we'll get -1.
240
// Replace this with the index of the last row.
241
if (rMax == -1) {
242         rMax = table.getRowCount()-1;
243         }
244
245         boolean ltr = table.getComponentOrientation().isLeftToRight();
246         int cMin = table.columnAtPoint(ltr ? upperLeft : lowerRight);
247         int cMax = table.columnAtPoint(ltr ? lowerRight : upperLeft);
248         // This should never happen.
249
if (cMin == -1) {
250         cMin = 0;
251         }
252     // If the table does not have enough columns to fill the view we'll get -1.
253
// Replace this with the index of the last column.
254
if (cMax == -1) {
255         cMax = table.getColumnCount()-1;
256         }
257
258         // Paint the grid.
259
paintGrid(context, g, rMin, rMax, cMin, cMax);
260
261         // Paint the cells.
262
paintCells(context, g, rMin, rMax, cMin, cMax);
263     }
264
265     /*
266      * Paints the grid lines within <I>aRect</I>, using the grid
267      * color set with <I>setGridColor</I>. Paints vertical lines
268      * if <code>getShowVerticalLines()</code> returns true and paints
269      * horizontal lines if <code>getShowHorizontalLines()</code>
270      * returns true.
271      */

272     private void paintGrid(SynthContext JavaDoc context, Graphics g, int rMin,
273                            int rMax, int cMin, int cMax) {
274         g.setColor(table.getGridColor());
275
276     Rectangle minCell = table.getCellRect(rMin, cMin, true);
277     Rectangle maxCell = table.getCellRect(rMax, cMax, true);
278         Rectangle damagedArea = minCell.union( maxCell );
279         SynthGraphicsUtils JavaDoc synthG = context.getStyle().getGraphicsUtils(
280                      context);
281
282         if (table.getShowHorizontalLines()) {
283         int tableWidth = damagedArea.x + damagedArea.width;
284         int y = damagedArea.y;
285         for (int row = rMin; row <= rMax; row++) {
286         y += table.getRowHeight(row);
287                 synthG.drawLine(context, "Table.grid",
288                                 g, damagedArea.x, y - 1, tableWidth - 1,y - 1);
289         }
290     }
291         if (table.getShowVerticalLines()) {
292         TableColumnModel cm = table.getColumnModel();
293         int tableHeight = damagedArea.y + damagedArea.height;
294         int x;
295         if (table.getComponentOrientation().isLeftToRight()) {
296         x = damagedArea.x;
297         for (int column = cMin; column <= cMax; column++) {
298             int w = cm.getColumn(column).getWidth();
299             x += w;
300                     synthG.drawLine(context, "Table.grid", g, x - 1, 0,
301                                     x - 1, tableHeight - 1);
302         }
303         } else {
304         x = damagedArea.x + damagedArea.width;
305         for (int column = cMin; column < cMax; column++) {
306             int w = cm.getColumn(column).getWidth();
307             x -= w;
308                     synthG.drawLine(context, "Table.grid", g, x - 1, 0, x - 1,
309                                     tableHeight - 1);
310         }
311         x -= cm.getColumn(cMax).getWidth();
312                 synthG.drawLine(context, "Table.grid", g, x, 0, x,
313                                 tableHeight - 1);
314         }
315     }
316     }
317
318     private int viewIndexForColumn(TableColumn aColumn) {
319         TableColumnModel cm = table.getColumnModel();
320         for (int column = 0; column < cm.getColumnCount(); column++) {
321             if (cm.getColumn(column) == aColumn) {
322                 return column;
323             }
324         }
325         return -1;
326     }
327
328     private void paintCells(SynthContext JavaDoc context, Graphics g, int rMin,
329                             int rMax, int cMin, int cMax) {
330     JTableHeader header = table.getTableHeader();
331     TableColumn draggedColumn = (header == null) ? null : header.getDraggedColumn();
332
333     TableColumnModel cm = table.getColumnModel();
334     int columnMargin = cm.getColumnMargin();
335
336         Rectangle cellRect;
337     TableColumn aColumn;
338     int columnWidth;
339     if (table.getComponentOrientation().isLeftToRight()) {
340         for(int row = rMin; row <= rMax; row++) {
341         cellRect = table.getCellRect(row, cMin, false);
342                 for(int column = cMin; column <= cMax; column++) {
343                     aColumn = cm.getColumn(column);
344                     columnWidth = aColumn.getWidth();
345                     cellRect.width = columnWidth - columnMargin;
346                     if (aColumn != draggedColumn) {
347                         paintCell(context, g, cellRect, row, column);
348                     }
349                     cellRect.x += columnWidth;
350             }
351         }
352     } else {
353         for(int row = rMin; row <= rMax; row++) {
354                 cellRect = table.getCellRect(row, cMin, false);
355                 aColumn = cm.getColumn(cMin);
356                 if (aColumn != draggedColumn) {
357                     columnWidth = aColumn.getWidth();
358                     cellRect.width = columnWidth - columnMargin;
359                     paintCell(context, g, cellRect, row, cMin);
360                 }
361                 for(int column = cMin+1; column <= cMax; column++) {
362                     aColumn = cm.getColumn(column);
363                     columnWidth = aColumn.getWidth();
364                     cellRect.width = columnWidth - columnMargin;
365                     cellRect.x -= columnWidth;
366                     if (aColumn != draggedColumn) {
367                         paintCell(context, g, cellRect, row, column);
368                     }
369             }
370         }
371     }
372
373         // Paint the dragged column if we are dragging.
374
if (draggedColumn != null) {
375         paintDraggedArea(context, g, rMin, rMax, draggedColumn, header.getDraggedDistance());
376     }
377
378     // Remove any renderers that may be left in the rendererPane.
379
rendererPane.removeAll();
380     }
381
382     private void paintDraggedArea(SynthContext JavaDoc context, Graphics g, int rMin, int rMax, TableColumn draggedColumn, int distance) {
383         int draggedColumnIndex = viewIndexForColumn(draggedColumn);
384
385         Rectangle minCell = table.getCellRect(rMin, draggedColumnIndex, true);
386     Rectangle maxCell = table.getCellRect(rMax, draggedColumnIndex, true);
387
388     Rectangle vacatedColumnRect = minCell.union(maxCell);
389
390     // Paint a gray well in place of the moving column.
391
g.setColor(table.getParent().getBackground());
392     g.fillRect(vacatedColumnRect.x, vacatedColumnRect.y,
393            vacatedColumnRect.width, vacatedColumnRect.height);
394
395     // Move to the where the cell has been dragged.
396
vacatedColumnRect.x += distance;
397
398     // Fill the background.
399
g.setColor(context.getStyle().getColor(context, ColorType.BACKGROUND));
400     g.fillRect(vacatedColumnRect.x, vacatedColumnRect.y,
401            vacatedColumnRect.width, vacatedColumnRect.height);
402
403         SynthGraphicsUtils JavaDoc synthG = context.getStyle().getGraphicsUtils(
404                                             context);
405         
406
407     // Paint the vertical grid lines if necessary.
408
if (table.getShowVerticalLines()) {
409         g.setColor(table.getGridColor());
410         int x1 = vacatedColumnRect.x;
411         int y1 = vacatedColumnRect.y;
412         int x2 = x1 + vacatedColumnRect.width - 1;
413         int y2 = y1 + vacatedColumnRect.height - 1;
414         // Left
415
synthG.drawLine(context, "Table.grid", g, x1-1, y1, x1-1, y2);
416         // Right
417
synthG.drawLine(context, "Table.grid", g, x2, y1, x2, y2);
418     }
419
420     for(int row = rMin; row <= rMax; row++) {
421         // Render the cell value
422
Rectangle r = table.getCellRect(row, draggedColumnIndex, false);
423         r.x += distance;
424         paintCell(context, g, r, row, draggedColumnIndex);
425
426         // Paint the (lower) horizontal grid line if necessary.
427
if (table.getShowHorizontalLines()) {
428         g.setColor(table.getGridColor());
429         Rectangle rcr = table.getCellRect(row, draggedColumnIndex, true);
430         rcr.x += distance;
431         int x1 = rcr.x;
432         int y1 = rcr.y;
433         int x2 = x1 + rcr.width - 1;
434         int y2 = y1 + rcr.height - 1;
435         synthG.drawLine(context, "Table.grid", g, x1, y2, x2, y2);
436         }
437     }
438     }
439
440     private void paintCell(SynthContext JavaDoc context, Graphics g,
441             Rectangle cellRect, int row, int column) {
442         if (table.isEditing() && table.getEditingRow()==row &&
443                                  table.getEditingColumn()==column) {
444             Component component = table.getEditorComponent();
445             component.setBounds(cellRect);
446             component.validate();
447         }
448         else {
449             TableCellRenderer renderer = table.getCellRenderer(row, column);
450             Component component = table.prepareRenderer(renderer, row, column);
451             rendererPane.paintComponent(g, component, table, cellRect.x,
452                     cellRect.y, cellRect.width, cellRect.height, true);
453         }
454     }
455
456     public void propertyChange(PropertyChangeEvent JavaDoc event) {
457         if (SynthLookAndFeel.shouldUpdateStyle(event)) {
458             updateStyle((JTable)event.getSource());
459         }
460     }
461
462
463     private class SynthBooleanTableCellRenderer extends JCheckBox implements
464                       TableCellRenderer {
465     public SynthBooleanTableCellRenderer() {
466         super();
467         setHorizontalAlignment(JLabel.CENTER);
468     }
469
470         public String JavaDoc getName() {
471             String JavaDoc name = super.getName();
472             if (name == null) {
473                 return "Table.cellRenderer";
474             }
475             return name;
476         }
477
478         public Component getTableCellRendererComponent(
479                             JTable table, Object JavaDoc value, boolean isSelected,
480                             boolean hasFocus, int row, int column) {
481         if (isSelected) {
482             setForeground(table.getSelectionForeground());
483             setBackground(table.getSelectionBackground());
484         }
485         else {
486             setForeground(table.getForeground());
487             setBackground(table.getBackground());
488         }
489             setSelected((value != null && ((Boolean JavaDoc)value).booleanValue()));
490             // NOTE: We don't do this as otherwise the the JCheckBox will
491
// think it is selected when it may not be. This means JCheckBox
492
// renderers don't render the selection correctly.
493
/*
494             if (!useTableColors && (isSelected || hasFocus)) {
495                 SynthLookAndFeel.setSelectedUI((SynthButtonUI)SynthLookAndFeel.
496                              getUIOfType(getUI(), SynthButtonUI.class),
497                                    isSelected, hasFocus, table.isEnabled());
498             }
499             else {
500                 SynthLookAndFeel.resetSelectedUI();
501             }
502 */

503             return this;
504         }
505
506         public void paint(Graphics g) {
507             super.paint(g);
508             // Refer to comment above for why this is commented out.
509
// SynthLookAndFeel.resetSelectedUI();
510
}
511     }
512
513     private class SynthTableCellRenderer extends DefaultTableCellRenderer {
514         private Object JavaDoc numberFormat;
515         private Object JavaDoc dateFormat;
516         private boolean opaque;
517
518         public void setOpaque(boolean isOpaque) {
519             opaque = isOpaque;
520         }
521
522         public boolean isOpaque() {
523             return opaque;
524         }
525
526         public String JavaDoc getName() {
527             String JavaDoc name = super.getName();
528             if (name == null) {
529                 return "Table.cellRenderer";
530             }
531             return name;
532         }
533
534         public void setBorder(Border b) {
535             if (useUIBorder || b instanceof SynthBorder JavaDoc) {
536                 super.setBorder(b);
537             }
538         }
539
540         public Component getTableCellRendererComponent(
541                   JTable table, Object JavaDoc value, boolean isSelected,
542                   boolean hasFocus, int row, int column) {
543             if (!useTableColors && (isSelected || hasFocus)) {
544                 SynthLookAndFeel.setSelectedUI((SynthLabelUI JavaDoc)SynthLookAndFeel.
545                              getUIOfType(getUI(), SynthLabelUI JavaDoc.class),
546                                    isSelected, hasFocus, table.isEnabled());
547             }
548             else {
549                 SynthLookAndFeel.resetSelectedUI();
550             }
551             super.getTableCellRendererComponent(table, value, isSelected,
552                                                 hasFocus, row, column);
553
554             setIcon(null);
555             Class JavaDoc columnClass = table.getColumnClass(column);
556             configureValue(value, columnClass);
557
558             return this;
559         }
560
561         private void configureValue(Object JavaDoc value, Class JavaDoc columnClass) {
562             if (columnClass == Object JavaDoc.class || columnClass == null) {
563                 setHorizontalAlignment(JLabel.LEADING);
564             } else if (columnClass == Float JavaDoc.class || columnClass == Double JavaDoc.class) {
565                 if (numberFormat == null) {
566                     numberFormat = NumberFormat.getInstance();
567                 }
568                 setHorizontalAlignment(JLabel.TRAILING);
569                 setText((value == null) ? "" : ((NumberFormat)numberFormat).format(value));
570             }
571             else if (columnClass == Number JavaDoc.class) {
572                 setHorizontalAlignment(JLabel.TRAILING);
573                 // Super will have set value.
574
}
575             else if (columnClass == Icon.class || columnClass == ImageIcon.class) {
576                 setHorizontalAlignment(JLabel.CENTER);
577                 setIcon((Icon)value);
578                 setText("");
579             }
580             else if (columnClass == Date JavaDoc.class) {
581                 if (dateFormat == null) {
582                     dateFormat = DateFormat.getDateInstance();
583                 }
584                 setHorizontalAlignment(JLabel.LEADING);
585                 setText((value == null) ? "" : ((Format)dateFormat).format(value));
586             }
587             else {
588                 configureValue(value, columnClass.getSuperclass());
589             }
590         }
591
592         public void paint(Graphics g) {
593             super.paint(g);
594             SynthLookAndFeel.resetSelectedUI();
595         }
596     }
597 }
598
Popular Tags