001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: /**
018: * @author Anton Avtamonov
019: * @version $Revision$
020: */package javax.swing.table;
021:
022: import java.awt.Color;
023: import java.awt.Component;
024: import java.awt.Cursor;
025: import java.awt.Dimension;
026: import java.awt.Font;
027: import java.awt.FontMetrics;
028: import java.awt.Point;
029: import java.awt.Rectangle;
030: import java.awt.event.FocusListener;
031: import java.awt.event.MouseEvent;
032: import java.beans.PropertyChangeListener;
033: import java.util.Locale;
034:
035: import javax.accessibility.Accessible;
036: import javax.accessibility.AccessibleAction;
037: import javax.accessibility.AccessibleComponent;
038: import javax.accessibility.AccessibleContext;
039: import javax.accessibility.AccessibleRole;
040: import javax.accessibility.AccessibleSelection;
041: import javax.accessibility.AccessibleStateSet;
042: import javax.accessibility.AccessibleText;
043: import javax.accessibility.AccessibleValue;
044: import javax.swing.JComponent;
045: import javax.swing.JLabel;
046: import javax.swing.JTable;
047: import javax.swing.SwingConstants;
048: import javax.swing.ToolTipManager;
049: import javax.swing.UIManager;
050: import javax.swing.event.ChangeEvent;
051: import javax.swing.event.ListSelectionEvent;
052: import javax.swing.event.TableColumnModelEvent;
053: import javax.swing.event.TableColumnModelListener;
054: import javax.swing.plaf.TableHeaderUI;
055:
056: import org.apache.harmony.x.swing.internal.nls.Messages;
057:
058: public class JTableHeader extends JComponent implements
059: TableColumnModelListener, Accessible {
060: protected class AccessibleJTableHeader extends AccessibleJComponent {
061: protected class AccessibleJTableHeaderEntry extends
062: AccessibleContext implements Accessible,
063: AccessibleComponent {
064: public AccessibleJTableHeaderEntry(final int c,
065: final JTableHeader p, final JTable t) {
066: throw new UnsupportedOperationException(Messages
067: .getString("swing.27")); //$NON-NLS-1$
068: }
069:
070: public AccessibleContext getAccessibleContext() {
071: return this ;
072: }
073:
074: public String getAccessibleName() {
075: throw new UnsupportedOperationException(Messages
076: .getString("swing.27")); //$NON-NLS-1$
077: }
078:
079: public void setAccessibleName(final String s) {
080: throw new UnsupportedOperationException(Messages
081: .getString("swing.27")); //$NON-NLS-1$
082: }
083:
084: public String getAccessibleDescription() {
085: throw new UnsupportedOperationException(Messages
086: .getString("swing.27")); //$NON-NLS-1$
087: }
088:
089: public void setAccessibleDescription(final String s) {
090: throw new UnsupportedOperationException(Messages
091: .getString("swing.27")); //$NON-NLS-1$
092: }
093:
094: public AccessibleRole getAccessibleRole() {
095: throw new UnsupportedOperationException(Messages
096: .getString("swing.27")); //$NON-NLS-1$
097: }
098:
099: public AccessibleStateSet getAccessibleStateSet() {
100: throw new UnsupportedOperationException(Messages
101: .getString("swing.27")); //$NON-NLS-1$
102: }
103:
104: public int getAccessibleIndexInParent() {
105: throw new UnsupportedOperationException(Messages
106: .getString("swing.27")); //$NON-NLS-1$
107: }
108:
109: public int getAccessibleChildrenCount() {
110: throw new UnsupportedOperationException(Messages
111: .getString("swing.27")); //$NON-NLS-1$
112: }
113:
114: public Accessible getAccessibleChild(final int i) {
115: throw new UnsupportedOperationException(Messages
116: .getString("swing.27")); //$NON-NLS-1$
117: }
118:
119: public Locale getLocale() {
120: throw new UnsupportedOperationException(Messages
121: .getString("swing.27")); //$NON-NLS-1$
122: }
123:
124: public void addPropertyChangeListener(
125: final PropertyChangeListener l) {
126: throw new UnsupportedOperationException(Messages
127: .getString("swing.27")); //$NON-NLS-1$
128: }
129:
130: public void removePropertyChangeListener(
131: final PropertyChangeListener l) {
132: throw new UnsupportedOperationException(Messages
133: .getString("swing.27")); //$NON-NLS-1$
134: }
135:
136: public AccessibleAction getAccessibleAction() {
137: throw new UnsupportedOperationException(Messages
138: .getString("swing.27")); //$NON-NLS-1$
139: }
140:
141: public AccessibleComponent getAccessibleComponent() {
142: throw new UnsupportedOperationException(Messages
143: .getString("swing.27")); //$NON-NLS-1$
144: }
145:
146: public AccessibleSelection getAccessibleSelection() {
147: throw new UnsupportedOperationException(Messages
148: .getString("swing.27")); //$NON-NLS-1$
149: }
150:
151: public AccessibleText getAccessibleText() {
152: throw new UnsupportedOperationException(Messages
153: .getString("swing.27")); //$NON-NLS-1$
154: }
155:
156: public AccessibleValue getAccessibleValue() {
157: throw new UnsupportedOperationException(Messages
158: .getString("swing.27")); //$NON-NLS-1$
159: }
160:
161: public Color getBackground() {
162: throw new UnsupportedOperationException(Messages
163: .getString("swing.27")); //$NON-NLS-1$
164: }
165:
166: public void setBackground(final Color c) {
167: throw new UnsupportedOperationException(Messages
168: .getString("swing.27")); //$NON-NLS-1$
169: }
170:
171: public Color getForeground() {
172: throw new UnsupportedOperationException(Messages
173: .getString("swing.27")); //$NON-NLS-1$
174: }
175:
176: public void setForeground(final Color c) {
177: throw new UnsupportedOperationException(Messages
178: .getString("swing.27")); //$NON-NLS-1$
179: }
180:
181: public Cursor getCursor() {
182: throw new UnsupportedOperationException(Messages
183: .getString("swing.27")); //$NON-NLS-1$
184: }
185:
186: public void setCursor(final Cursor c) {
187: throw new UnsupportedOperationException(Messages
188: .getString("swing.27")); //$NON-NLS-1$
189: }
190:
191: public Font getFont() {
192: throw new UnsupportedOperationException(Messages
193: .getString("swing.27")); //$NON-NLS-1$
194: }
195:
196: public void setFont(final Font f) {
197: throw new UnsupportedOperationException(Messages
198: .getString("swing.27")); //$NON-NLS-1$
199: }
200:
201: public FontMetrics getFontMetrics(final Font f) {
202: throw new UnsupportedOperationException(Messages
203: .getString("swing.27")); //$NON-NLS-1$
204: }
205:
206: public boolean isEnabled() {
207: throw new UnsupportedOperationException(Messages
208: .getString("swing.27")); //$NON-NLS-1$
209: }
210:
211: public void setEnabled(final boolean b) {
212: throw new UnsupportedOperationException(Messages
213: .getString("swing.27")); //$NON-NLS-1$
214: }
215:
216: public boolean isVisible() {
217: throw new UnsupportedOperationException(Messages
218: .getString("swing.27")); //$NON-NLS-1$
219: }
220:
221: public void setVisible(final boolean b) {
222: throw new UnsupportedOperationException(Messages
223: .getString("swing.27")); //$NON-NLS-1$
224: }
225:
226: public boolean isShowing() {
227: throw new UnsupportedOperationException(Messages
228: .getString("swing.27")); //$NON-NLS-1$
229: }
230:
231: public boolean contains(final Point p) {
232: throw new UnsupportedOperationException(Messages
233: .getString("swing.27")); //$NON-NLS-1$
234: }
235:
236: public Point getLocationOnScreen() {
237: throw new UnsupportedOperationException(Messages
238: .getString("swing.27")); //$NON-NLS-1$
239: }
240:
241: public Point getLocation() {
242: throw new UnsupportedOperationException(Messages
243: .getString("swing.27")); //$NON-NLS-1$
244: }
245:
246: public void setLocation(final Point p) {
247: throw new UnsupportedOperationException(Messages
248: .getString("swing.27")); //$NON-NLS-1$
249: }
250:
251: public Rectangle getBounds() {
252: throw new UnsupportedOperationException(Messages
253: .getString("swing.27")); //$NON-NLS-1$
254: }
255:
256: public void setBounds(final Rectangle r) {
257: throw new UnsupportedOperationException(Messages
258: .getString("swing.27")); //$NON-NLS-1$
259: }
260:
261: public Dimension getSize() {
262: throw new UnsupportedOperationException(Messages
263: .getString("swing.27")); //$NON-NLS-1$
264: }
265:
266: public void setSize(final Dimension d) {
267: throw new UnsupportedOperationException(Messages
268: .getString("swing.27")); //$NON-NLS-1$
269: }
270:
271: public Accessible getAccessibleAt(final Point p) {
272: throw new UnsupportedOperationException(Messages
273: .getString("swing.27")); //$NON-NLS-1$
274: }
275:
276: public boolean isFocusTraversable() {
277: throw new UnsupportedOperationException(Messages
278: .getString("swing.27")); //$NON-NLS-1$
279: }
280:
281: public void requestFocus() {
282: throw new UnsupportedOperationException(Messages
283: .getString("swing.27")); //$NON-NLS-1$
284: }
285:
286: public void addFocusListener(final FocusListener l) {
287: throw new UnsupportedOperationException(Messages
288: .getString("swing.27")); //$NON-NLS-1$
289: }
290:
291: public void removeFocusListener(final FocusListener l) {
292: throw new UnsupportedOperationException(Messages
293: .getString("swing.27")); //$NON-NLS-1$
294: }
295: }
296:
297: public AccessibleRole getAccessibleRole() {
298: return AccessibleRole.TABLE;
299: }
300:
301: public Accessible getAccessibleAt(final Point p) {
302: throw new UnsupportedOperationException(Messages
303: .getString("swing.27")); //$NON-NLS-1$
304: }
305:
306: public int getAccessibleChildrenCount() {
307: throw new UnsupportedOperationException(Messages
308: .getString("swing.27")); //$NON-NLS-1$
309: }
310:
311: public Accessible getAccessibleChild(final int i) {
312: throw new UnsupportedOperationException(Messages
313: .getString("swing.27")); //$NON-NLS-1$
314: }
315: }
316:
317: private class DefaultHeaderRendererUIResource extends
318: DefaultTableCellRenderer.UIResource {
319: private JTable defaultTable;
320:
321: public Component getTableCellRendererComponent(
322: final JTable table, final Object value,
323: final boolean isSelected, final boolean hasFocus,
324: final int row, final int column) {
325:
326: JLabel result = (JLabel) super
327: .getTableCellRendererComponent(
328: table != null ? table : getDefaultTable(),
329: value, isSelected, hasFocus, row, column);
330: result.setHorizontalAlignment(SwingConstants.CENTER);
331: result.setBorder(UIManager
332: .getBorder("TableHeader.cellBorder"));
333: setFont(JTableHeader.this .getFont());
334: setForeground(JTableHeader.this .getForeground());
335: setBackground(JTableHeader.this .getBackground());
336:
337: return result;
338: }
339:
340: private JTable getDefaultTable() {
341: if (defaultTable == null) {
342: defaultTable = new JTable();
343: }
344:
345: return defaultTable;
346: }
347: }
348:
349: protected JTable table;
350: protected TableColumnModel columnModel;
351: protected boolean reorderingAllowed;
352: protected boolean resizingAllowed;
353: protected transient TableColumn resizingColumn;
354: protected transient TableColumn draggedColumn;
355: protected transient int draggedDistance;
356: protected boolean updateTableInRealTime;
357: private TableCellRenderer defaultRenderer;
358:
359: private static final String UI_CLASS_ID = "TableHeaderUI";
360: private static final String TABLE_PROPERTY = "table";
361: private static final String REORDERING_ALLOWED_PROPERTY = "reorderingAllowed";
362: private static final String RESIZING_ALLOWED_PROPERTY = "resizingAllowed";
363: private static final String COLUMN_MODEL_PROPERTY = "columnModel";
364:
365: public JTableHeader() {
366: this (null);
367: }
368:
369: public JTableHeader(final TableColumnModel model) {
370: columnModel = model != null ? model
371: : createDefaultColumnModel();
372: columnModel.addColumnModelListener(this );
373: initializeLocalVars();
374: ToolTipManager.sharedInstance().registerComponent(this );
375:
376: updateUI();
377: }
378:
379: public void setTable(final JTable table) {
380: JTable oldValue = this .table;
381: this .table = table;
382: firePropertyChange(TABLE_PROPERTY, oldValue, table);
383: }
384:
385: public JTable getTable() {
386: return table;
387: }
388:
389: public void setReorderingAllowed(final boolean allowed) {
390: boolean oldValue = reorderingAllowed;
391: reorderingAllowed = allowed;
392: firePropertyChange(REORDERING_ALLOWED_PROPERTY, oldValue,
393: allowed);
394: }
395:
396: public boolean getReorderingAllowed() {
397: return reorderingAllowed;
398: }
399:
400: public void setResizingAllowed(final boolean allowed) {
401: boolean oldValue = resizingAllowed;
402: resizingAllowed = allowed;
403: firePropertyChange(RESIZING_ALLOWED_PROPERTY, oldValue, allowed);
404: }
405:
406: public boolean getResizingAllowed() {
407: return resizingAllowed;
408: }
409:
410: public TableColumn getDraggedColumn() {
411: return draggedColumn;
412: }
413:
414: public void setDraggedColumn(final TableColumn column) {
415: draggedColumn = column;
416: }
417:
418: public int getDraggedDistance() {
419: return draggedDistance;
420: }
421:
422: public void setDraggedDistance(final int distance) {
423: draggedDistance = distance;
424: }
425:
426: public TableColumn getResizingColumn() {
427: return resizingColumn;
428: }
429:
430: public void setResizingColumn(final TableColumn column) {
431: resizingColumn = column;
432: }
433:
434: public void setUpdateTableInRealTime(final boolean update) {
435: updateTableInRealTime = update;
436: }
437:
438: public boolean getUpdateTableInRealTime() {
439: return updateTableInRealTime;
440: }
441:
442: public void setDefaultRenderer(final TableCellRenderer renderer) {
443: defaultRenderer = renderer;
444: }
445:
446: public TableCellRenderer getDefaultRenderer() {
447: return defaultRenderer;
448: }
449:
450: public int columnAtPoint(final Point p) {
451: if (table == null
452: || table.getComponentOrientation().isLeftToRight()) {
453: return columnModel.getColumnIndexAtX(p.x);
454: } else {
455: int width = 0;
456: for (int i = 0; i < columnModel.getColumnCount(); i++) {
457: width += columnModel.getColumn(i).width;
458: }
459: int offset = width;
460: for (int result = 0; result < columnModel.getColumnCount(); result++) {
461: offset -= columnModel.getColumn(result).width;
462: if (p.x >= offset
463: && p.x < offset
464: + columnModel.getColumn(result).width) {
465: return result;
466: }
467: }
468: return p.x < 0 ? columnModel.getColumnCount() - 1 : 0;
469: }
470: }
471:
472: public Rectangle getHeaderRect(final int column) {
473: if (column >= columnModel.getColumnCount()) {
474: return new Rectangle();
475: }
476:
477: return new Rectangle(getOffset(column), 0, columnModel
478: .getColumn(column).width, getHeight());
479: }
480:
481: public String getToolTipText(final MouseEvent me) {
482: int columnIndex = columnAtPoint(me.getPoint());
483: if (columnIndex == -1) {
484: return null;
485: }
486:
487: TableColumn column = columnModel.getColumn(columnIndex);
488: if (column.getHeaderRenderer() != null) {
489: return getToolTipText(column.getHeaderRenderer(),
490: columnIndex);
491: }
492: if (getDefaultRenderer() != null) {
493: return getToolTipText(getDefaultRenderer(), columnIndex);
494: }
495:
496: return null;
497: }
498:
499: public void setColumnModel(final TableColumnModel cm) {
500: if (cm == null) {
501: throw new IllegalArgumentException(Messages
502: .getString("swing.7D")); //$NON-NLS-1$
503: }
504:
505: columnModel.removeColumnModelListener(this );
506:
507: TableColumnModel oldValue = columnModel;
508: columnModel = cm;
509: columnModel.addColumnModelListener(this );
510: firePropertyChange(COLUMN_MODEL_PROPERTY, oldValue, cm);
511: }
512:
513: public TableColumnModel getColumnModel() {
514: return columnModel;
515: }
516:
517: public TableHeaderUI getUI() {
518: return (TableHeaderUI) ui;
519: }
520:
521: public void setUI(final TableHeaderUI ui) {
522: super .setUI(ui);
523: }
524:
525: public void updateUI() {
526: setUI((TableHeaderUI) UIManager.getUI(this ));
527: }
528:
529: public String getUIClassID() {
530: return UI_CLASS_ID;
531: }
532:
533: public void columnAdded(final TableColumnModelEvent e) {
534: repaint();
535: }
536:
537: public void columnRemoved(final TableColumnModelEvent e) {
538: repaint();
539: }
540:
541: public void columnMoved(final TableColumnModelEvent e) {
542: repaint();
543: }
544:
545: public void columnMarginChanged(final ChangeEvent e) {
546: repaint();
547: }
548:
549: public void columnSelectionChanged(final ListSelectionEvent e) {
550: }
551:
552: protected TableColumnModel createDefaultColumnModel() {
553: return new DefaultTableColumnModel();
554: }
555:
556: protected TableCellRenderer createDefaultRenderer() {
557: return new DefaultHeaderRendererUIResource();
558: }
559:
560: protected void initializeLocalVars() {
561: reorderingAllowed = true;
562: resizingAllowed = true;
563: updateTableInRealTime = true;
564: defaultRenderer = createDefaultRenderer();
565: table = null;
566: resizingColumn = null;
567: draggedColumn = null;
568: draggedDistance = 0;
569: }
570:
571: public void resizeAndRepaint() {
572: table.doLayout();
573: repaint();
574: }
575:
576: public AccessibleContext getAccessibleContext() {
577: if (accessibleContext == null) {
578: accessibleContext = new AccessibleJTableHeader();
579: }
580:
581: return accessibleContext;
582: }
583:
584: private int getOffset(final int column) {
585: int result = 0;
586: if (table == null
587: || table.getComponentOrientation().isLeftToRight()) {
588: for (int i = 0; i < column; i++) {
589: result += columnModel.getColumn(i).width;
590: }
591: } else {
592: for (int i = 0; i < columnModel.getColumnCount(); i++) {
593: result += columnModel.getColumn(i).width;
594: }
595: for (int i = 0; i <= column; i++) {
596: result -= columnModel.getColumn(i).width;
597: }
598: }
599:
600: return result;
601: }
602:
603: private String getToolTipText(final TableCellRenderer renderer,
604: final int column) {
605: Component renderingComponent = renderer
606: .getTableCellRendererComponent(getTable(), columnModel
607: .getColumn(column).getHeaderValue(), false,
608: false, -1, columnModel.getColumn(column)
609: .getModelIndex());
610: if (!(renderingComponent instanceof JComponent)) {
611: return null;
612: }
613:
614: return ((JComponent) renderingComponent).getToolTipText();
615: }
616: }
|