/*
 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package com.apple.laf;

import java.awt.*;

import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.UIResource;

import apple.laf.JRSUIState;
import apple.laf.JRSUIConstants.*;

import com.apple.laf.AquaUtils.RecyclableSingleton;

public class AquaTableHeaderBorder extends AbstractBorder {
    protected static final int SORT_NONE = 0;
    protected static final int SORT_ASCENDING = 1;
    protected static final int SORT_DECENDING = -1;

    protected final Insets editorBorderInsets = new Insets(1, 3, 1, 3);
    protected final AquaPainter<JRSUIState> painter = AquaPainter.create(JRSUIState.getInstance());

    protected static AquaTableHeaderBorder getListHeaderBorder() {
        // we don't want to share this, because the .setSelected() state
        // would persist to all other JTable instances
        return new AquaTableHeaderBorder();
    }

    protected AquaTableHeaderBorder() {
        painter.state.set(AlignmentHorizontal.LEFT);
        painter.state.set(AlignmentVertical.TOP);
    }

    
Paints the border for the specified component with the specified position and size.
Params:
  • c – the component for which this border is being painted
  • g – the paint graphics
  • x – the x position of the painted border
  • y – the y position of the painted border
  • width – the width of the painted border
  • height – the height of the painted border
/** * Paints the border for the specified component with the specified * position and size. * @param c the component for which this border is being painted * @param g the paint graphics * @param x the x position of the painted border * @param y the y position of the painted border * @param width the width of the painted border * @param height the height of the painted border */
protected boolean doPaint = true; public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int width, final int height) { if (!doPaint) return; final JComponent jc = (JComponent)c; // if the developer wants to set their own color, we should // interpret this as "get out of the way", and don't draw aqua. final Color componentBackground = jc.getBackground(); if (!(componentBackground instanceof UIResource)) { doPaint = false; jc.paint(g); getAlternateBorder().paintBorder(jc, g, x, y, width, height); doPaint = true; return; } final State state = getState(jc); painter.state.set(state); painter.state.set(jc.hasFocus() ? Focused.YES : Focused.NO); painter.state.set(height > 16 ? Widget.BUTTON_BEVEL : Widget.BUTTON_LIST_HEADER); painter.state.set(selected ? BooleanValue.YES : BooleanValue.NO); switch (sortOrder) { case SORT_ASCENDING: painter.state.set(Direction.UP); break; case SORT_DECENDING: painter.state.set(Direction.DOWN); break; default: painter.state.set(Direction.NONE); break; } final int newX = x; final int newY = y; final int newWidth = width; final int newHeight = height; painter.paint(g, c, newX - 1, newY - 1, newWidth + 1, newHeight); // Draw the header g.clipRect(newX, y, newWidth, height); g.translate(fHorizontalShift, -1); doPaint = false; jc.paint(g); doPaint = true; } protected State getState(final JComponent jc) { if (!jc.isEnabled()) return State.DISABLED; final JRootPane rootPane = jc.getRootPane(); if (rootPane == null) return State.ACTIVE; if (!AquaFocusHandler.isActive(rootPane)) return State.INACTIVE; return State.ACTIVE; } static final RecyclableSingleton<Border> alternateBorder = new RecyclableSingleton<Border>() { @Override protected Border getInstance() { return BorderFactory.createRaisedBevelBorder(); } }; protected static Border getAlternateBorder() { return alternateBorder.get(); }
Returns the insets of the border.
Params:
  • c – the component for which this border insets value applies
/** * Returns the insets of the border. * @param c the component for which this border insets value applies */
public Insets getBorderInsets(final Component c) { // bad to create new one each time. For debugging only. return editorBorderInsets; } public Insets getBorderInsets(final Component c, final Insets insets) { insets.left = editorBorderInsets.left; insets.top = editorBorderInsets.top; insets.right = editorBorderInsets.right; insets.bottom = editorBorderInsets.bottom; return insets; }
Returns whether or not the border is opaque. If the border is opaque, it is responsible for filling in it's own background when painting.
/** * Returns whether or not the border is opaque. If the border * is opaque, it is responsible for filling in it's own * background when painting. */
public boolean isBorderOpaque() { return false; }
Sets whether or not this instance of Border draws selected or not. Used by AquaFileChooserUI
/** * Sets whether or not this instance of Border draws selected or not. Used by AquaFileChooserUI */
private boolean selected = false; protected void setSelected(final boolean inSelected) { selected = inSelected; }
Sets an amount to shift the position of the labels. Used by AquaFileChooserUI
/** * Sets an amount to shift the position of the labels. Used by AquaFileChooserUI */
private int fHorizontalShift = 0; protected void setHorizontalShift(final int inShift) { fHorizontalShift = inShift; } private int sortOrder = SORT_NONE; protected void setSortOrder(final int inSortOrder) { if (inSortOrder < SORT_DECENDING || inSortOrder > SORT_ASCENDING) { throw new IllegalArgumentException("Invalid sort order constant: " + inSortOrder); } sortOrder = inSortOrder; } }