home *** CD-ROM | disk | FTP | other *** search
Java Source | 1998-06-30 | 17.9 KB | 554 lines |
- /*
- * @(#)OrganicTabbedPaneUI.java 1.6 98/02/02
- *
- * Copyright (c) 1997 Sun Microsystems, Inc. All Rights Reserved.
- *
- * This software is the confidential and proprietary information of Sun
- * Microsystems, Inc. ("Confidential Information"). You shall not
- * disclose such Confidential Information and shall use it only in
- * accordance with the terms of the license agreement you entered into
- * with Sun.
- *
- * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
- * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
- * PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR ANY DAMAGES
- * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR DISTRIBUTING
- * THIS SOFTWARE OR ITS DERIVATIVES.
- *
- */
-
- package com.sun.java.swing.plaf.organic;
-
- import com.sun.java.swing.*;
- import com.sun.java.swing.event.*;
- import java.awt.*;
- import java.awt.event.*;
- import com.sun.java.swing.plaf.*;
- import java.io.Serializable;
- import com.sun.java.swing.plaf.basic.BasicTabbedPaneUI;
-
- /**
- * A Java L&F extension of BasicTabbedPaneUI.
- * <p>
- * Warning: serialized objects of this class will not be compatible with
- * future swing releases. The current serialization support is appropriate
- * for short term storage or RMI between Swing1.0 applications. It will
- * not be possible to load serialized Swing1.0 objects with future releases
- * of Swing. The JDK1.2 release of Swing will be the compatibility
- * baseline for the serialized form of Swing objects.
- *
- * @version 1.6 02/02/98
- * @author Tom Santos
- */
- public class OrganicTabbedPaneUI extends BasicTabbedPaneUI {
-
- protected static Insets tabsOnTopTabAreaInsets = new Insets(4,0,0,6);
- protected static Insets tabsOnLeftTabAreaInsets = new Insets(6,4,0,0);
- protected static Insets tabsOnBottomTabAreaInsets = new Insets(0,0,4,6);
- protected static Insets tabsOnRightTabAreaInsets = new Insets(0,0,6,4);
-
- protected int minTabWidth = 40;
- protected Color selectColor;
-
- public static ComponentUI createUI( JComponent x ) {
- return new OrganicTabbedPaneUI();
- }
-
-
- protected void installDefaults( JComponent c ) {
- JTabbedPane pane = (JTabbedPane)c;
- super.installDefaults(c);
-
- selectColor = UIManager.getColor("TabbedPane.selected");
- }
-
-
- protected void layoutLabel( int tabPlacement, FontMetrics metrics,
- String title, Icon icon,
- Rectangle tabRect, Rectangle iconRect,
- Rectangle textRect, boolean isSelected ) {
- super.layoutLabel( tabPlacement, metrics, title, icon, tabRect, iconRect, textRect, isSelected );
- int correctLabelLocation = tabRect.x + tabRect.height / 2 + 2 ;
- if ( iconRect.x < correctLabelLocation ) {
- int locationDelta = correctLabelLocation - iconRect.x;
- iconRect.x += locationDelta;
- textRect.x += locationDelta;
- }
- iconRect.y -= 1;
- }
-
-
- protected void paintTabBorder( Graphics g, JTabbedPane pane, int tabPlacement,
- int tabIndex, int x, int y, int w, int h,
- boolean isSelected) {
- int bottom = y + (h-1);
- int right = x + (w-1);
-
- switch(tabPlacement) {
- case LEFT:
- paintLeftTabBorder(pane, g, x, y, w, h, bottom, right, isSelected);
- break;
- case BOTTOM:
- paintBottomTabBorder(pane, g, x, y, w, h, bottom, right, isSelected);
- break;
- case RIGHT:
- paintRightTabBorder(pane, g, x, y, w, h, bottom, right, isSelected);
- break;
- case TOP:
- default:
- paintTopTabBorder(pane, g, x, y, w, h, bottom, right, isSelected);
- }
- }
-
-
- protected void paintTopTabBorder( JTabbedPane pane, Graphics g,
- int x, int y, int w, int h,
- int bottom, int right,
- boolean isSelected ) {
-
- // Paint left slant
- paintSlant(pane, TOP, g, x, y, w, h, bottom, right, isSelected);
-
- // Paint top
- if ( isSelected ) {
- g.setColor( tabHighlight );
- }
- else {
- g.setColor( selectColor );
- }
-
- int slantRight = x + h / 2;
- int tabRight = x + (w - 1);
- g.drawLine( slantRight, y, tabRight - 4, y );
-
- // Paint right
- g.setColor( tabDarkShadow );
- g.drawLine( tabRight - 3, y + 1, tabRight - 3, bottom );
- g.drawLine( tabRight - 2, y + 2, tabRight - 2, bottom );
- }
-
-
- protected void paintLeftTabBorder( JTabbedPane pane, Graphics g,
- int x, int y, int w, int h,
- int bottom, int right,
- boolean isSelected ) {
- // Paint left slant
- paintSlant(pane, LEFT, g, x, y, w, h, bottom, right, isSelected);
-
- // Paint top
- if ( isSelected ) {
- g.setColor( tabHighlight );
- }
- else {
- g.setColor( selectColor );
- }
-
- int slantRight = x + h / 2;
- g.drawLine( slantRight, y, right, y );
-
- // Paint bottom
- g.setColor( tabDarkShadow );
- g.drawLine( x + 1, bottom, right, bottom );
- }
-
-
- protected void paintBottomTabBorder( JTabbedPane pane, Graphics g,
- int x, int y, int w, int h,
- int bottom, int right,
- boolean isSelected ) {
- // paint left slant
- paintSlant(pane, BOTTOM, g, x, y, w, h, bottom, right, isSelected);
-
- // paint bottom
- int slantRight = x + h / 2;
- g.setColor(tabDarkShadow);
- g.drawLine(slantRight, bottom, right - 3, bottom);
-
- // Paint right
- g.setColor( tabDarkShadow );
- g.drawLine( right - 2, y, right - 2, bottom - 1);
- g.drawLine( right - 1, y, right - 1, bottom - 2 );
- }
-
-
- protected void paintRightTabBorder( JTabbedPane pane, Graphics g,
- int x, int y, int w, int h,
- int bottom, int right,
- boolean isSelected ) {
- // paint right slant
- paintSlant(pane, RIGHT, g, x, y, w, h, bottom, right, isSelected);
-
- // Paint top
- if ( isSelected ) {
- g.setColor( tabHighlight );
- }
- else {
- g.setColor( selectColor );
- }
-
- int slantRight = right - h / 2;
- g.drawLine(x, y, slantRight, y);
-
- // paint bottom
- g.setColor(tabDarkShadow);
- g.drawLine(x, bottom, right, bottom);
- }
-
-
- private void paintSlant( JTabbedPane pane, int tabPlacement, Graphics g,
- int x, int y, int w, int h, int bottom, int right,
- boolean isSelected ) {
-
- // Only tabs-on-right has a right slant
- boolean onLeft = tabPlacement != RIGHT;
-
- // Only tabs-on-bottom has slant starting at top:
- boolean startOnBottom = tabPlacement != BOTTOM;
-
- int sx = onLeft? x : right;
- int sy = startOnBottom? bottom - 2 : y;
-
- if ( isSelected ) {
- g.setColor( onLeft? tabHighlight : tabDarkShadow );
- g.drawLine( sx, sy, sx, sy + 2 );
-
- for ( int i = 1; i < h / 2; ++i ) {
- int lineX = onLeft? sx + i : sx - i;
- int lineY = startOnBottom? (sy - (i * 2)) :
- (sy + (i * 2));
- g.setColor( onLeft? tabHighlight : tabDarkShadow );
-
- if (startOnBottom && lineY < y) {
- g.drawLine( lineX, lineY + 1, lineX, lineY + 2 );
- }
- else if (!startOnBottom && lineY + 2 > bottom) {
- g.drawLine( lineX, lineY, lineX, bottom);
- }
- else {
- g.drawLine( lineX, lineY, lineX, lineY + 2 );
- }
- g.setColor( selectColor );
- if (startOnBottom) {
- g.drawLine( lineX, lineY + 3, lineX, bottom );
- } else {
- g.drawLine( lineX, lineY - 1, lineX, y);
- }
- }
- }
- else {
- g.setColor( selectColor );
- g.drawLine( sx, sy, sx, sy );
- g.drawLine( sx, sy + 2, sx, sy + 2 );
- g.setColor( onLeft? tabHighlight : tabDarkShadow);
- g.drawLine( sx, sy + 1, sx, sy + 1 );
-
- for ( int i = 1; i < h / 2; ++i ) {
- int lineX = onLeft? sx + i : sx - i;
- int lineY = startOnBottom? (sy - (i * 2)) :
- (sy + (i * 2));
-
- if ( lineY <= y ) {
- g.setColor( selectColor );
- }
- else {
- g.setColor( onLeft? tabHighlight : tabDarkShadow);
- }
-
- g.drawLine( lineX, lineY + 1, lineX, lineY + 1 );
-
- g.setColor( selectColor );
- if (!startOnBottom || lineY > y ) {
- g.drawLine( lineX, lineY, lineX, lineY );
- }
- if (startOnBottom || lineY + 2 <= bottom) {
- g.drawLine( lineX, lineY + 2, lineX, lineY + 2 );
- }
-
- g.setColor( pane.getBackground() );
- if (startOnBottom) {
- g.drawLine( lineX, lineY + 3, lineX, bottom );
- } else {
- g.drawLine( lineX, lineY - 1, lineX, y);
- }
- }
- }
- }
-
-
- protected void paintTabBackground( Graphics g, JTabbedPane pane, int tabPlacement,
- int tabIndex, int x, int y, int w, int h, boolean isSelected ) {
-
- int slantWidth = h / 2;
- if ( isSelected ) {
- g.setColor( selectColor );
- }
- else {
- g.setColor( pane.getBackground() );
- }
- switch(tabPlacement) {
- case LEFT:
- g.fillRect(x + slantWidth, y + 1, w - slantWidth, h - 2);
- break;
- case BOTTOM:
- g.fillRect(x + slantWidth, y, w - slantWidth - 3, h - 1);
- break;
- case RIGHT:
- g.fillRect(x, y + 1, w - slantWidth, h - 2);
- break;
- case TOP:
- default:
- g.fillRect( x + slantWidth, y, (w - slantWidth) - 4, h );
- }
- }
-
-
- protected Insets getTabAreaInsets( JTabbedPane pane, int tabPlacement ) {
- Insets insets;
- switch(tabPlacement) {
- case LEFT:
- insets = tabsOnLeftTabAreaInsets;
- break;
- case BOTTOM:
- insets = tabsOnBottomTabAreaInsets;
- break;
- case RIGHT:
- insets = tabsOnRightTabAreaInsets;
- break;
- case TOP:
- default:
- insets = tabsOnTopTabAreaInsets;
- }
- return insets;
- }
-
-
- /**
- * We add the width of the tab-angle.
- */
- protected int tabWidth( JTabbedPane pane, int index, FontMetrics metrics ) {
- int maxTabHeight = maxTabHeight( pane );
- int widthOfGapBetweenTabTops = maxTabHeight / 2;
-
- if ( widthOfGapBetweenTabTops > minTabWidth ) {
- minTabWidth = widthOfGapBetweenTabTops * 2;
- }
-
- return Math.max( super.tabWidth( pane, index, metrics) + maxTabHeight / 2, minTabWidth );
- }
-
-
- /**
- * Overidden to do nothing for the Java L&F.
- */
- protected int calculateXNudge( JTabbedPane pane, int tabPlacement,
- int tabIndex, boolean isSelected ) {
- return 0;
- }
-
-
- /**
- * Overidden to do nothing for the Java L&F.
- */
- protected int calculateYNudge( JTabbedPane pane, int tabPlacement,
- int tabIndex, boolean isSelected ) {
- return 0;
- }
-
-
- public void paint( Graphics g, JComponent c ) {
- JTabbedPane pane = (JTabbedPane)c;
- int tabPlacement = pane.getTabPlacement();
-
- Insets insets = c.getInsets();
- Dimension size = c.getSize();
-
- // Paint the background for the tab area
- g.setColor( c.getBackground() );
- switch(tabPlacement) {
- case LEFT:
- g.fillRect( insets.left, insets.top,
- totalTabWidth( pane, tabPlacement, runCount ),
- size.height - insets.bottom - insets.top );
- break;
- case BOTTOM:
- int totalTabHeight = totalTabHeight( pane, tabPlacement, runCount );
- g.fillRect( insets.left, size.height - insets.bottom - totalTabHeight, size.width - insets.left - insets.right,
- totalTabHeight );
- break;
- case RIGHT:
- int totalTabWidth = totalTabWidth( pane, tabPlacement, runCount );
- g.fillRect( size.width - insets.right - totalTabWidth,
- insets.top, totalTabWidth,
- size.height - insets.top - insets.bottom );
- break;
- case TOP:
- default:
- g.fillRect( insets.left, insets.top,
- size.width - insets.right - insets.left,
- totalTabHeight(pane, tabPlacement, runCount) );
- }
-
- int selectedTab = pane.getSelectedIndex();
-
- if ( runCount > 1 && selectedTab >= tabRuns[ 1 ] ) {
- Rectangle rect = rects[ selectedTab ];
- g.setColor( selectColor );
- g.drawLine( rect.x, rect.y + rect.height, (rect.x + rect.width) - 3, rect.y + rect.height );
-
- //
- // This block is commented out for now in case we want to highlight regions
- // below the selected tab again.
- //
- /*
- // Paint the selected area below the selected tab
- int maxTabHeight = maxTabHeight( pane );
- g.setColor( OrganicUtilities.Khaki1 );
-
- // Find the row that the selected tab is in
- int rowThatSelectedTabIsIn = runCount - 1;
-
- if ( selectedTab < tabRuns[ runCount - 1 ] ) {
- for ( int row = 1; row < runCount - 1; ++row ) {
- if ( selectedTab >= tabRuns[ row ] && selectedTab < tabRuns[ row+1 ] ) {
- rowThatSelectedTabIsIn = row;
- break;
- }
- }
- }
-
- // Iterate through the row below and see if the gaps between tabs
- // will cause the tab selection feedback to look strange.
- Rectangle rect = new Rectangle( rects[ selectedTab ] );
- rect.y += maxTabHeight;
- int rowStart = tabRuns[ rowThatSelectedTabIsIn - 1 ];
- int rowEnd = tabRuns[ rowThatSelectedTabIsIn ] - 1 ;
-
- for ( int tab = rowStart + 1; tab <= rowEnd; ++tab ) {
- int prevTabRight = (rects[ tab-1 ].x + (rects[ tab-1 ].width - 1)) - 4;
- int leftEdgeOfTabTop = rects[ tab ].x + (rects[ tab ].height / 2);
-
- if ( rect.x > prevTabRight && rect.x < leftEdgeOfTabTop - 1 ) {
- rect.x -= minTabWidth / 2;
- rect.width += minTabWidth / 2;
- }
-
- int rectRight = (rect.x + (rect.width - 1)) - 4;
- if ( rectRight > prevTabRight && rectRight < leftEdgeOfTabTop ) {
- rect.width += minTabWidth / 2;
- }
- }
-
- g.fillRect( rect.x, rect.y, rect.width - 4, rect.height );
- */
- }
-
- super.paint( g, c );
- }
-
-
- protected void paintFocusIndicator( Graphics g, JTabbedPane pane, int tabPlacement,
- Rectangle[] rects, int i,
- Rectangle iconRect, Rectangle textRect,
- boolean isSelected ) {
- Rectangle tabRect = new Rectangle( rects[i] );
-
- tabRect.width -= (tabRect.height / 2) + 6;
- g.setColor( tabHighlight );
- if (pane.hasFocus() && isSelected) {
- switch(tabPlacement) {
- case RIGHT:
- tabRect.x += 2;
- break;
- case TOP:
- case LEFT:
- case BOTTOM:
- default:
- tabRect.x += tabRect.height / 2;
- }
- g.drawRect( tabRect.x, tabRect.y + 2,
- tabRect.width - 1, tabRect.height - 5 );
- g.setColor(focus);
- OrganicUtilities.drawDashedRect(g, tabRect.x, tabRect.y + 2,
- tabRect.width, tabRect.height - 4);
-
- }
- }
-
-
- protected void paintContentBorderTopEdge( Graphics g, int tabPlacement,
- int selectedIndex,
- int x, int y, int width, int height ) {
- g.setColor( tabHighlight );
-
- if ( runCount == 1 || selectedIndex < tabRuns[ 1 ] ) {
- Rectangle rect = rects[ selectedIndex ];
- int tabRight = rect.x + (rect.width - 4);
- g.drawLine( x, y, rect.x, y );
- g.drawLine( tabRight, y, tabRight + (width - tabRight), y );
- }
- else {
- g.drawLine(x, y, width-2, y);
- }
- }
-
-
- protected int maxTabHeight( JTabbedPane pane, FontMetrics metrics ) {
- int height = metrics.getHeight();
- boolean tallerIcons = false;
-
- for ( int i = 0; i < pane.getTabCount(); ++i ) {
- Icon icon = pane.getIconAt( i );
- if ( icon != null ) {
- if ( icon.getIconHeight() > height ) {
- tallerIcons = true;
- break;
- }
- }
- }
- return super.maxTabHeight( pane, metrics ) - (tallerIcons ? (spacingHeight * 2) : 0);
- }
-
-
- protected int getTabOverlay( JTabbedPane pane, int tabPlacement ) {
- // Tab runs layed out vertically should overlap
- // at least as much as the largest slant
- if (tabPlacement == LEFT || tabPlacement == RIGHT) {
- int maxTabHeight = maxTabHeight(pane);
- return maxTabHeight / 2;
- }
- return 0;
- }
-
-
- protected void normalizeTabRuns( JTabbedPane pane, int tabPlacement, int tabCount,
- int start, int max ) {
- // Only normalize the runs for top & bottom; normalizing
- // doesn't look right for Organic's vertical tabs
- // because the last run isn't padded and it looks odd to have
- // fat tabs in the first vertical runs, but slimmer ones in the
- // last (this effect isn't noticable for horizontal tabs).
- if (tabPlacement == TOP || tabPlacement == BOTTOM) {
- super.normalizeTabRuns(pane, tabPlacement, tabCount, start, max);
- }
- }
-
-
- // Don't rotate runs!
- protected void rotateTabRuns( JTabbedPane pane, int tabPlacement, int selectedRun ) {
- }
-
-
- // Don't pad last run
- protected boolean shouldPadRun( JTabbedPane pane, int tabPlacement, int run ) {
- return runCount > 1 && run < runCount - 1;
- }
-
-
- // Don't pad selected tab
- protected void padSelectedTab( JTabbedPane pane, int tabPlacement, int selectedIndex ) {
- }
-
- }
-
-