home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 1998 November
/
Chip_1998-11_cd.bin
/
tema
/
Cafe
/
jfc.bin
/
OrganicTabbedPaneUI.java
< prev
next >
Wrap
Text File
|
1998-02-26
|
18KB
|
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 ) {
}
}