FileDocCategorySizeDatePackage
BasicTableHeaderUI.javaAPI DocJava SE 6 API32858Tue Jun 10 00:26:48 BST 2008javax.swing.plaf.basic

BasicTableHeaderUI

public class BasicTableHeaderUI extends TableHeaderUI
BasicTableHeaderUI implementation
version
1.78 07/16/07
author
Alan Chung
author
Philip Milne

Fields Summary
private static Cursor
resizeCursor
protected JTableHeader
header
The JTableHeader that is delegating the painting to this UI.
protected CellRendererPane
rendererPane
protected MouseInputListener
mouseInputListener
private int
rolloverColumn
private int
selectedColumnIndex
private static FocusListener
focusListener
Constructors Summary
Methods Summary
private static booleancanResize(javax.swing.table.TableColumn column, javax.swing.table.JTableHeader header)

 
        return (column != null) && header.getResizingAllowed()
                                && column.getResizable(); 
    
private intchangeColumnWidth(javax.swing.table.TableColumn resizingColumn, javax.swing.table.JTableHeader th, int oldWidth, int newWidth)

        resizingColumn.setWidth(newWidth);
        
        Container container;
        JTable table;

        if ((th.getParent() == null) ||
            ((container = th.getParent().getParent()) == null) ||
            !(container instanceof JScrollPane) ||
            ((table = th.getTable()) == null)) {
            return 0;
        }

        if (!container.getComponentOrientation().isLeftToRight() &&
                !th.getComponentOrientation().isLeftToRight()) {
                JViewport viewport = ((JScrollPane)container).getViewport();
                int viewportWidth = viewport.getWidth();
                int diff = newWidth - oldWidth;
                int newHeaderWidth = table.getWidth() + diff;

                /* Resize a table */
                Dimension tableSize = table.getSize();
                tableSize.width += diff;
                table.setSize(tableSize);

                /* If this table is in AUTO_RESIZE_OFF mode and
                 * has a horizontal scrollbar, we need to update
                 * a view's position.
                 */
                if ((newHeaderWidth >= viewportWidth) &&
                    (table.getAutoResizeMode() == JTable.AUTO_RESIZE_OFF)) {
                    Point p = viewport.getViewPosition();
                    p.x = Math.max(0, Math.min(newHeaderWidth - viewportWidth,
                                               p.x + diff));
                    viewport.setViewPosition(p);
                    return diff;
            }
        }
        return 0;
    
private java.awt.DimensioncreateHeaderSize(long width)

        TableColumnModel columnModel = header.getColumnModel();
        // None of the callers include the intercell spacing, do it here.
        if (width > Integer.MAX_VALUE) {
            width = Integer.MAX_VALUE;
        }
        return new Dimension((int)width, getHeaderHeight());
    
protected javax.swing.event.MouseInputListenercreateMouseInputListener()
Creates the mouse listener for the JTableHeader.

        return new MouseInputHandler();
    
public static javax.swing.plaf.ComponentUIcreateUI(javax.swing.JComponent h)

        return new BasicTableHeaderUI();
    
public intgetBaseline(javax.swing.JComponent c, int width, int height)
Returns the baseline.

throws
NullPointerException {@inheritDoc}
throws
IllegalArgumentException {@inheritDoc}
see
javax.swing.JComponent#getBaseline(int, int)
since
1.6

        super.getBaseline(c, width, height);
        int baseline = -1;
        TableColumnModel columnModel = header.getColumnModel();
        for(int column = 0; column < columnModel.getColumnCount();
            column++) { 
            TableColumn aColumn = columnModel.getColumn(column); 
            Component comp = getHeaderRenderer(column); 
            Dimension pref = comp.getPreferredSize();
            int columnBaseline = comp.getBaseline(pref.width, height);
            if (columnBaseline >= 0) {
                if (baseline == -1) {
                    baseline = columnBaseline;
                }
                else if (baseline != columnBaseline) {
                    baseline = -1;
                    break;
                }
            }
        }
        return baseline;
    
private intgetHeaderHeight()

        int height = 0; 
	boolean accomodatedDefault = false; 
        TableColumnModel columnModel = header.getColumnModel();
        for(int column = 0; column < columnModel.getColumnCount(); column++) { 
	    TableColumn aColumn = columnModel.getColumn(column); 
            boolean isDefault = (aColumn.getHeaderRenderer() == null);

            if (!isDefault || !accomodatedDefault) { 
		Component comp = getHeaderRenderer(column); 
		int rendererHeight = comp.getPreferredSize().height; 
		height = Math.max(height, rendererHeight); 

                // Configuring the header renderer to calculate its preferred size
                // is expensive. Optimise this by assuming the default renderer
                // always has the same height as the first non-zero height that
                // it returns for a non-null/non-empty value.
                if (isDefault && rendererHeight > 0) {
                    Object headerValue = aColumn.getHeaderValue();
                    if (headerValue != null) {
                        headerValue = headerValue.toString();

                        if (headerValue != null && !headerValue.equals("")) {
                            accomodatedDefault = true; 
                        }
                    }
                }
	    }
        }
        return height;
    
private java.awt.ComponentgetHeaderRenderer(int columnIndex)

 
        TableColumn aColumn = header.getColumnModel().getColumn(columnIndex); 
	TableCellRenderer renderer = aColumn.getHeaderRenderer(); 
        if (renderer == null) { 
	    renderer = header.getDefaultRenderer(); 
	}
        
        boolean hasFocus = !header.isPaintingForPrint()
                           && (columnIndex == getSelectedColumnIndex())
                           && header.hasFocus();
        return renderer.getTableCellRendererComponent(header.getTable(), 
						aColumn.getHeaderValue(),
                                                false, hasFocus, 
                                                -1, columnIndex);
    
public java.awt.DimensiongetMaximumSize(javax.swing.JComponent c)
Return the maximum size of the header. The maximum width is the sum of the maximum widths of each column (plus inter-cell spacing).

        long width = 0;
        Enumeration enumeration = header.getColumnModel().getColumns();
        while (enumeration.hasMoreElements()) {
            TableColumn aColumn = (TableColumn)enumeration.nextElement();
            width = width + aColumn.getMaxWidth();
        }
        return createHeaderSize(width);
    
public java.awt.DimensiongetMinimumSize(javax.swing.JComponent c)
Return the minimum size of the header. The minimum width is the sum of the minimum widths of each column (plus inter-cell spacing).

        long width = 0;
        Enumeration enumeration = header.getColumnModel().getColumns();
        while (enumeration.hasMoreElements()) {
            TableColumn aColumn = (TableColumn)enumeration.nextElement();
            width = width + aColumn.getMinWidth();
        }
        return createHeaderSize(width);
    
public java.awt.DimensiongetPreferredSize(javax.swing.JComponent c)
Return the preferred size of the header. The preferred height is the maximum of the preferred heights of all of the components provided by the header renderers. The preferred width is the sum of the preferred widths of each column (plus inter-cell spacing).

        long width = 0;
        Enumeration enumeration = header.getColumnModel().getColumns();
        while (enumeration.hasMoreElements()) {
            TableColumn aColumn = (TableColumn)enumeration.nextElement();
            width = width + aColumn.getPreferredWidth();
        }
        return createHeaderSize(width);
    
protected intgetRolloverColumn()
Returns the index of the column header over which the mouse currently is. When the mouse is not over the table header, -1 is returned.

see
#rolloverColumnUpdated(int, int)
return
the index of the current rollover column
since
1.6

        return rolloverColumn;
    
private intgetSelectedColumnIndex()

        int numCols = header.getColumnModel().getColumnCount();
        if (selectedColumnIndex >= numCols && numCols > 0) {
            selectedColumnIndex = numCols - 1;
        }
        return selectedColumnIndex;
    
protected voidinstallDefaults()
Initialize JTableHeader properties, e.g. font, foreground, and background. The font, foreground, and background properties are only set if their current value is either null or a UIResource, other properties are set if the current value is null.

see
#installUI

        LookAndFeel.installColorsAndFont(header, "TableHeader.background",
                                         "TableHeader.foreground", "TableHeader.font");
        LookAndFeel.installProperty(header, "opaque", Boolean.TRUE);
    
protected voidinstallKeyboardActions()
Register all keyboard actions on the JTableHeader.

        InputMap keyMap = (InputMap)DefaultLookup.get(header, this,
                "TableHeader.ancestorInputMap");
	SwingUtilities.replaceUIInputMap(header,                
                                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, keyMap);
        LazyActionMap.installLazyActionMap(header, BasicTableHeaderUI.class,
                "TableHeader.actionMap");
    
protected voidinstallListeners()
Attaches listeners to the JTableHeader.

        mouseInputListener = createMouseInputListener();

        header.addMouseListener(mouseInputListener);
        header.addMouseMotionListener(mouseInputListener);
        header.addFocusListener(focusListener);
    
public voidinstallUI(javax.swing.JComponent c)

        header = (JTableHeader)c;

        rendererPane = new CellRendererPane();
        header.add(rendererPane);

        installDefaults();
        installListeners();
        installKeyboardActions();
    
static voidloadActionMap(javax.swing.plaf.basic.LazyActionMap map)
Populates TableHeader's actions.

        map.put(new Actions(Actions.TOGGLE_SORT_ORDER));
        map.put(new Actions(Actions.SELECT_COLUMN_TO_LEFT));
        map.put(new Actions(Actions.SELECT_COLUMN_TO_RIGHT));
        map.put(new Actions(Actions.MOVE_COLUMN_LEFT));
        map.put(new Actions(Actions.MOVE_COLUMN_RIGHT));
        map.put(new Actions(Actions.RESIZE_LEFT));
        map.put(new Actions(Actions.RESIZE_RIGHT));
        map.put(new Actions(Actions.FOCUS_TABLE));
    
public voidpaint(java.awt.Graphics g, javax.swing.JComponent c)

	if (header.getColumnModel().getColumnCount() <= 0) { 
	    return; 
	}
        boolean ltr = header.getComponentOrientation().isLeftToRight();

	Rectangle clip = g.getClipBounds(); 
        Point left = clip.getLocation();
        Point right = new Point( clip.x + clip.width - 1, clip.y );
	TableColumnModel cm = header.getColumnModel(); 
        int cMin = header.columnAtPoint( ltr ? left : right );
        int cMax = header.columnAtPoint( ltr ? right : left );
        // This should never happen. 
        if (cMin == -1) {
	    cMin =  0;
        }
        // If the table does not have enough columns to fill the view we'll get -1.
        // Replace this with the index of the last column.
        if (cMax == -1) {
	    cMax = cm.getColumnCount()-1;  
        }

	TableColumn draggedColumn = header.getDraggedColumn(); 
	int columnWidth;
        Rectangle cellRect = header.getHeaderRect(ltr ? cMin : cMax); 
	TableColumn aColumn;
	if (ltr) {
	    for(int column = cMin; column <= cMax ; column++) { 
		aColumn = cm.getColumn(column); 
		columnWidth = aColumn.getWidth();
		cellRect.width = columnWidth;
		if (aColumn != draggedColumn) {
		    paintCell(g, cellRect, column);
		} 
		cellRect.x += columnWidth;
	    }
	} else {
	    for(int column = cMax; column >= cMin; column--) {
		aColumn = cm.getColumn(column);
		columnWidth = aColumn.getWidth();
		cellRect.width = columnWidth;
		if (aColumn != draggedColumn) {
		    paintCell(g, cellRect, column);
		}
                cellRect.x += columnWidth;
	    }
	} 

        // Paint the dragged column if we are dragging. 
        if (draggedColumn != null) { 
            int draggedColumnIndex = viewIndexForColumn(draggedColumn); 
	    Rectangle draggedCellRect = header.getHeaderRect(draggedColumnIndex); 
            
            // Draw a gray well in place of the moving column. 
            g.setColor(header.getParent().getBackground());
            g.fillRect(draggedCellRect.x, draggedCellRect.y,
                               draggedCellRect.width, draggedCellRect.height);

            draggedCellRect.x += header.getDraggedDistance();

	    // Fill the background. 
	    g.setColor(header.getBackground());
	    g.fillRect(draggedCellRect.x, draggedCellRect.y,
		       draggedCellRect.width, draggedCellRect.height);
 
            paintCell(g, draggedCellRect, draggedColumnIndex);
        }

	// Remove all components in the rendererPane. 
	rendererPane.removeAll(); 
    
private voidpaintCell(java.awt.Graphics g, java.awt.Rectangle cellRect, int columnIndex)

        Component component = getHeaderRenderer(columnIndex); 
        rendererPane.paintComponent(g, component, header, cellRect.x, cellRect.y,
                            cellRect.width, cellRect.height, true);
    
protected voidrolloverColumnUpdated(int oldColumn, int newColumn)
This method gets called every time the rollover column in the table header is updated. Every look and feel supporting rollover effect in table header should override this method and repaint the header.

param
oldColumn the index of the previous rollover column or -1 if the mouse was not over a column
param
newColumn the index of the new rollover column or -1 if the mouse is not over a column
see
#getRolloverColumn()
see
JTableHeader#getHeaderRect(int)
since
1.6

    
private voidscrollToColumn(int col)
Used by selectColumn to scroll horizontally, if necessary, to ensure that the newly selected column is visible.

        Container container;
        JTable table;
        
        //Test whether the header is in a scroll pane and has a table.
        if ((header.getParent() == null) ||
            ((container = header.getParent().getParent()) == null) ||
            !(container instanceof JScrollPane) ||
            ((table = header.getTable()) == null)) {
            return;
        }

        //Now scroll, if necessary.
        Rectangle vis = table.getVisibleRect();
        Rectangle cellBounds = table.getCellRect(0, col, true);
        vis.x = cellBounds.x;
        vis.width = cellBounds.width;
        table.scrollRectToVisible(vis);
    
voidselectColumn(int newColIndex)
Selects the specified column in the table header. Repaints the affected header cells and makes sure the newly selected one is visible.

        selectColumn(newColIndex, true);
    
voidselectColumn(int newColIndex, boolean doScroll)

        Rectangle repaintRect = header.getHeaderRect(selectedColumnIndex);
        header.repaint(repaintRect);
        selectedColumnIndex = newColIndex;
        repaintRect = header.getHeaderRect(newColIndex);
        header.repaint(repaintRect);
        if (doScroll) {
            scrollToColumn(newColIndex);
        }
        return;
    
private intselectNextColumn(boolean doIt)

        int newIndex = getSelectedColumnIndex();
        if (newIndex < header.getColumnModel().getColumnCount() - 1) {
            newIndex++;
            if (doIt) {
                selectColumn(newIndex);
            }
        }
        return newIndex;
    
private intselectPreviousColumn(boolean doIt)

        int newIndex = getSelectedColumnIndex();
        if (newIndex > 0) {
            newIndex--;
            if (doIt) {
                selectColumn(newIndex);
            }
        }
        return newIndex;
    
protected voiduninstallDefaults()

protected voiduninstallKeyboardActions()
Unregisters default key actions.

        SwingUtilities.replaceUIInputMap(header, JComponent.WHEN_FOCUSED, null);
        SwingUtilities.replaceUIActionMap(header, null);
    
protected voiduninstallListeners()

        header.removeMouseListener(mouseInputListener);
        header.removeMouseMotionListener(mouseInputListener);

        mouseInputListener = null;
    
public voiduninstallUI(javax.swing.JComponent c)

        uninstallDefaults();
        uninstallListeners();
        uninstallKeyboardActions();

        header.remove(rendererPane);
        rendererPane = null;
        header = null;
    
private voidupdateRolloverColumn(java.awt.event.MouseEvent e)

        if (header.getDraggedColumn() == null &&
            header.contains(e.getPoint())) {

            int col = header.columnAtPoint(e.getPoint());
            if (col != rolloverColumn) {
                int oldRolloverColumn = rolloverColumn;
                rolloverColumn = col;
                rolloverColumnUpdated(oldRolloverColumn, rolloverColumn);
            }
        }
    
private intviewIndexForColumn(javax.swing.table.TableColumn aColumn)

        TableColumnModel cm = header.getColumnModel();
        for (int column = 0; column < cm.getColumnCount(); column++) {
            if (cm.getColumn(column) == aColumn) {
                return column;
            }
        }
        return -1;