0001: /* @(#)BasicJideTabbedPaneUI.java
0002: *
0003: * Copyright 2002 JIDE Software Inc. All rights reserved.
0004: */
0005:
0006: package com.jidesoft.plaf.basic;
0007:
0008: import com.jidesoft.plaf.JideTabbedPaneUI;
0009: import com.jidesoft.plaf.UIDefaultsLookup;
0010: import com.jidesoft.popup.JidePopup;
0011: import com.jidesoft.swing.JideSwingUtilities;
0012: import com.jidesoft.swing.JideTabbedPane;
0013: import com.jidesoft.swing.Sticky;
0014: import com.jidesoft.utils.PortingUtils;
0015: import com.jidesoft.utils.SecurityUtils;
0016: import com.jidesoft.utils.SystemInfo;
0017:
0018: import javax.swing.*;
0019: import javax.swing.event.ChangeEvent;
0020: import javax.swing.event.ChangeListener;
0021: import javax.swing.event.DocumentEvent;
0022: import javax.swing.event.DocumentListener;
0023: import javax.swing.plaf.*;
0024: import javax.swing.plaf.basic.BasicGraphicsUtils;
0025: import javax.swing.plaf.basic.BasicHTML;
0026: import javax.swing.text.View;
0027: import java.awt.*;
0028: import java.awt.dnd.*;
0029: import java.awt.event.*;
0030: import java.awt.geom.AffineTransform;
0031: import java.beans.PropertyChangeEvent;
0032: import java.beans.PropertyChangeListener;
0033: import java.util.Hashtable;
0034: import java.util.Locale;
0035: import java.util.Vector;
0036:
0037: /**
0038: * A basic L&f implementation of JideTabbedPaneUI
0039: */
0040: public class BasicJideTabbedPaneUI extends JideTabbedPaneUI implements
0041: SwingConstants, DocumentListener {
0042:
0043: // pixels
0044: protected int _tabRectPadding;// distance from tab rect to icon/text
0045:
0046: protected int _closeButtonMarginHorizon; // when tab is on top or bottom, and each tab has close button, the gap around the close button
0047:
0048: protected int _closeButtonMarginVertical;// when tab is on left or right, and each tab has close button, the gap around the close button
0049:
0050: protected int _textMarginVertical;// tab area and text area gap
0051:
0052: protected int _noIconMargin;// gap around text area when there is no icon
0053:
0054: protected int _iconMargin;// distance from icon to tab rect start x
0055:
0056: protected int _textPadding;// distance from text to tab rect start
0057:
0058: protected int _buttonSize;// scroll button size
0059:
0060: protected int _buttonMargin;// scroll button margin
0061:
0062: protected int _fitStyleBoundSize;// margin for the whole tab area
0063:
0064: protected int _fitStyleFirstTabMargin;// the first tab position
0065:
0066: protected int _fitStyleIconMinWidth;// minimum width to display icon
0067:
0068: protected int _fitStyleTextMinWidth;// minimum width to display text
0069:
0070: protected int _compressedStyleNoIconRectSize;// tab size when there is no icon and tab not selected
0071:
0072: protected int _compressedStyleIconMargin;// margin around icon
0073:
0074: protected int _compressedStyleCloseButtonMarginHorizon;// the close button margin on the left or right when the tab is on the top or bottom
0075:
0076: protected int _compressedStyleCloseButtonMarginVertical;// the close button margin on the top or bottom when the tab is on the left or right
0077:
0078: protected int _fixedStyleRectSize;// tab rect size
0079:
0080: protected int _closeButtonMargin;// margin around close button
0081:
0082: protected int _gripLeftMargin;// left margin
0083:
0084: protected int _closeButtonMarginSize;// margin around the close button
0085:
0086: protected int _closeButtonLeftMargin;// the close button gap when the tab is on the left
0087:
0088: protected int _closeButtonRightMargin;// the close button gap when the tab is on the right
0089:
0090: protected Component _tabLeadingComponent = null;
0091:
0092: protected Component _tabTrailingComponent = null;
0093:
0094: protected JideTabbedPane _tabPane;
0095:
0096: protected Color _tabBackground;
0097:
0098: protected Color _background;
0099:
0100: protected Color _highlight;
0101:
0102: protected Color _lightHighlight;
0103:
0104: protected Color _shadow;
0105:
0106: protected Color _darkShadow;
0107:
0108: protected Color _focus;
0109:
0110: protected Color _inactiveTabForeground;
0111: protected Color _activeTabForeground;
0112:
0113: protected Color _selectedColor;
0114:
0115: protected int _textIconGap;
0116:
0117: protected int _tabRunOverlay;
0118:
0119: protected boolean _showIconOnTab;
0120:
0121: protected boolean _showCloseButtonOnTab;
0122:
0123: protected int _closeButtonAlignment = SwingConstants.TRAILING;
0124:
0125: protected Insets _tabInsets;
0126:
0127: protected Insets _selectedTabPadInsets;
0128:
0129: protected Insets _tabAreaInsets;
0130:
0131: protected boolean _ignoreContentBorderInsetsIfNoTabs;
0132:
0133: // Transient variables (recalculated each time TabbedPane is layed out)
0134:
0135: protected int _tabRuns[] = new int[10];
0136:
0137: protected int _runCount = 0;
0138:
0139: protected int _selectedRun = -1;
0140:
0141: protected Rectangle _rects[] = new Rectangle[0];
0142:
0143: protected int _maxTabHeight;
0144:
0145: protected int _maxTabWidth;
0146:
0147: protected int _gripperWidth = 6;
0148:
0149: protected int _gripperHeight = 6;
0150:
0151: // Listeners
0152:
0153: protected ChangeListener _tabChangeListener;
0154: protected FocusListener _tabFocusListener;
0155:
0156: protected PropertyChangeListener _propertyChangeListener;
0157:
0158: protected MouseListener _mouseListener;
0159:
0160: protected MouseMotionListener _mousemotionListener;
0161:
0162: // PENDING(api): See comment for ContainerHandler
0163: private ContainerListener _containerListener;
0164:
0165: private ComponentListener _componentListener;
0166:
0167: // Private instance data
0168:
0169: private Insets _currentTabInsets = new Insets(0, 0, 0, 0);
0170:
0171: private Insets _currentPadInsets = new Insets(0, 0, 0, 0);
0172:
0173: private Insets _currentTabAreaInsets = new Insets(2, 4, 0, 4);
0174:
0175: private Insets _currentContentBorderInsets = new Insets(3, 0, 0, 0);
0176:
0177: private Component visibleComponent;
0178:
0179: // PENDING(api): See comment for ContainerHandler
0180: private Vector htmlViews;
0181:
0182: private Hashtable _mnemonicToIndexMap;
0183:
0184: /**
0185: * InputMap used for mnemonics. Only non-null if the JTabbedPane has
0186: * mnemonics associated with it. Lazily created in initMnemonics.
0187: */
0188: private InputMap _mnemonicInputMap;
0189:
0190: // For use when tabLayoutPolicy = SCROLL_TAB_LAYOUT
0191: public ScrollableTabSupport _tabScroller;
0192:
0193: /**
0194: * A rectangle used for general layout calculations in order to avoid
0195: * constructing many new Rectangles on the fly.
0196: */
0197: protected transient Rectangle _calcRect = new Rectangle(0, 0, 0, 0);
0198:
0199: /**
0200: * Number of tabs. When the count differs, the mnemonics are updated.
0201: */
0202: // PENDING: This wouldn't be necessary if JTabbedPane had a better
0203: // way of notifying listeners when the count changed.
0204: private int _tabCount;
0205:
0206: protected TabCloseButton[] _closeButtons;
0207:
0208: // UI creation
0209:
0210: private ThemePainter _painter;
0211:
0212: private Painter _gripperPainter;
0213:
0214: private DropTargetListener _dropListener;
0215:
0216: public DropTarget _dt;
0217:
0218: // the left margin of the first tab according to the style
0219: public final static int DEFAULT_LEFT_MARGIN = 0;
0220: public final static int OFFICE2003_LEFT_MARGIN = 18;
0221: public final static int EXCEL_LEFT_MARGIN = 6;
0222:
0223: protected int _rectSizeExtend = 0;//when the style is eclipse,
0224: //we should extend the size of the rects for hold the title
0225:
0226: protected Polygon tabRegion = null;
0227:
0228: protected Color _selectColor1 = null;
0229: protected Color _selectColor2 = null;
0230: protected Color _selectColor3 = null;
0231: protected Color _unselectColor1 = null;
0232: protected Color _unselectColor2 = null;
0233: protected Color _unselectColor3 = null;
0234:
0235: protected Color _officeTabBorderColor;
0236: protected Color _defaultTabBorderShadowColor;
0237:
0238: protected boolean _mouseEnter = false;
0239:
0240: protected int _indexMouseOver = -1;
0241:
0242: protected boolean _alwaysShowLineBorder = false;
0243: protected boolean _showFocusIndicator = false;
0244:
0245: public static ComponentUI createUI(JComponent c) {
0246: return new BasicJideTabbedPaneUI();
0247: }
0248:
0249: // UI Installation/De-installation
0250:
0251: @Override
0252: public void installUI(JComponent c) {
0253: if (c == null) {
0254: return;
0255: }
0256:
0257: _tabPane = (JideTabbedPane) c;
0258:
0259: if (_tabPane.isTabShown()
0260: && _tabPane.getTabLeadingComponent() != null) {
0261: _tabLeadingComponent = _tabPane.getTabLeadingComponent();
0262: }
0263: if (_tabPane.isTabShown()
0264: && _tabPane.getTabTrailingComponent() != null) {
0265: _tabTrailingComponent = _tabPane.getTabTrailingComponent();
0266: }
0267:
0268: c.setLayout(createLayoutManager());
0269: installComponents();
0270: installDefaults();
0271: installColorTheme();
0272: installListeners();
0273: installKeyboardActions();
0274: }
0275:
0276: public void installColorTheme() {
0277: switch (getTabShape()) {
0278: case JideTabbedPane.SHAPE_EXCEL:
0279: _selectColor1 = _darkShadow;
0280: _selectColor2 = _lightHighlight;
0281: _selectColor3 = _shadow;
0282: _unselectColor1 = _darkShadow;
0283: _unselectColor2 = _lightHighlight;
0284: _unselectColor3 = _shadow;
0285: break;
0286: case JideTabbedPane.SHAPE_WINDOWS:
0287: case JideTabbedPane.SHAPE_WINDOWS_SELECTED:
0288: _selectColor1 = _lightHighlight;
0289: _selectColor2 = _shadow;
0290: _selectColor3 = _defaultTabBorderShadowColor;
0291: _unselectColor1 = _selectColor1;
0292: _unselectColor2 = _selectColor2;
0293: _unselectColor3 = _selectColor3;
0294: break;
0295: case JideTabbedPane.SHAPE_VSNET:
0296: _selectColor1 = _shadow;
0297: _selectColor2 = _shadow;
0298: _unselectColor1 = getPainter().getControlShadow();
0299: break;
0300: case JideTabbedPane.SHAPE_ROUNDED_VSNET:
0301: _selectColor1 = _shadow;
0302: _selectColor2 = _selectColor1;
0303: _unselectColor1 = _selectColor1;
0304: break;
0305: case JideTabbedPane.SHAPE_FLAT:
0306: _selectColor1 = _shadow;
0307: _unselectColor1 = _selectColor1;
0308: break;
0309: case JideTabbedPane.SHAPE_ROUNDED_FLAT:
0310: _selectColor1 = _shadow;
0311: _selectColor2 = _shadow;
0312: _unselectColor1 = _selectColor1;
0313: _unselectColor2 = _selectColor2;
0314: break;
0315: case JideTabbedPane.SHAPE_BOX:
0316: _selectColor1 = _shadow;
0317: _selectColor2 = _lightHighlight;
0318: _unselectColor1 = getPainter().getControlShadow();
0319: _unselectColor2 = _lightHighlight;
0320: break;
0321: case JideTabbedPane.SHAPE_OFFICE2003:
0322: default:
0323: _selectColor1 = _shadow;
0324: _selectColor2 = _lightHighlight;
0325: _unselectColor1 = _shadow;
0326: _unselectColor2 = null;
0327: _unselectColor3 = null;
0328: }
0329:
0330: }
0331:
0332: @Override
0333: public void uninstallUI(JComponent c) {
0334: uninstallKeyboardActions();
0335: uninstallListeners();
0336: uninstallColorTheme();
0337: uninstallDefaults();
0338: uninstallComponents();
0339: c.setLayout(null);
0340: _tabTrailingComponent = null;
0341: _tabLeadingComponent = null;
0342: _tabPane = null;
0343: }
0344:
0345: public void uninstallColorTheme() {
0346: _selectColor1 = null;
0347: _selectColor2 = null;
0348: _selectColor3 = null;
0349: _unselectColor1 = null;
0350: _unselectColor2 = null;
0351: _unselectColor3 = null;
0352: }
0353:
0354: /**
0355: * Invoked by <code>installUI</code> to create
0356: * a layout manager object to manage
0357: * the <code>JTabbedPane</code>.
0358: *
0359: * @return a layout manager object
0360: * @see TabbedPaneLayout
0361: * @see JTabbedPane#getTabLayoutPolicy
0362: */
0363: protected LayoutManager createLayoutManager() {
0364: if (_tabPane.getTabLayoutPolicy() == JideTabbedPane.SCROLL_TAB_LAYOUT) {
0365: return new TabbedPaneScrollLayout();
0366: } else { /* WRAP_TAB_LAYOUT */
0367: return new TabbedPaneLayout();
0368: }
0369: }
0370:
0371: /* In an attempt to preserve backward compatibility for programs
0372: * which have extended VsnetJideTabbedPaneUI to do their own layout, the
0373: * UI uses the installed layoutManager (and not tabLayoutPolicy) to
0374: * determine if scrollTabLayout is enabled.
0375: */
0376: protected boolean scrollableTabLayoutEnabled() {
0377: return (_tabPane.getLayout() instanceof TabbedPaneScrollLayout);
0378: }
0379:
0380: /**
0381: * Creates and installs any required subcomponents for the JTabbedPane.
0382: * Invoked by installUI.
0383: */
0384: protected void installComponents() {
0385: if (scrollableTabLayoutEnabled()) {
0386: if (_tabScroller == null) {
0387: _tabScroller = new ScrollableTabSupport(_tabPane
0388: .getTabPlacement());
0389: _tabPane.add(_tabScroller.viewport);
0390: _tabPane.add(_tabScroller.scrollForwardButton);
0391: _tabPane.add(_tabScroller.scrollBackwardButton);
0392: _tabPane.add(_tabScroller.listButton);
0393: _tabPane.add(_tabScroller.closeButton);
0394: if (_tabLeadingComponent != null) {
0395: _tabPane.add(_tabLeadingComponent);
0396: }
0397: if (_tabTrailingComponent != null) {
0398: _tabPane.add(_tabTrailingComponent);
0399: }
0400: }
0401: }
0402: }
0403:
0404: /**
0405: * Removes any installed subcomponents from the JTabbedPane. Invoked by
0406: * uninstallUI.
0407: */
0408: protected void uninstallComponents() {
0409: if (scrollableTabLayoutEnabled()) {
0410: _tabPane.remove(_tabScroller.viewport);
0411: _tabPane.remove(_tabScroller.scrollForwardButton);
0412: _tabPane.remove(_tabScroller.scrollBackwardButton);
0413: _tabPane.remove(_tabScroller.listButton);
0414: _tabPane.remove(_tabScroller.closeButton);
0415: if (_tabLeadingComponent != null) {
0416: _tabPane.remove(_tabLeadingComponent);
0417: }
0418: if (_tabTrailingComponent != null) {
0419: _tabPane.remove(_tabTrailingComponent);
0420: }
0421: _tabScroller = null;
0422: }
0423: }
0424:
0425: protected void installDefaults() {
0426: _painter = (ThemePainter) UIDefaultsLookup.get("Theme.painter");
0427: _gripperPainter = (Painter) UIDefaultsLookup
0428: .get("JideTabbedPane.gripperPainter");
0429:
0430: LookAndFeel.installColorsAndFont(_tabPane,
0431: "JideTabbedPane.background",
0432: "JideTabbedPane.foreground", "JideTabbedPane.font");
0433: LookAndFeel.installBorder(_tabPane, "JideTabbedPane.border");
0434: Font f = _tabPane.getSelectedTabFont();
0435: if (f == null || f instanceof UIResource) {
0436: _tabPane.setSelectedTabFont(UIDefaultsLookup
0437: .getFont("JideTabbedPane.selectedTabFont"));
0438: }
0439:
0440: _highlight = UIDefaultsLookup.getColor("JideTabbedPane.light");
0441: _lightHighlight = UIDefaultsLookup
0442: .getColor("JideTabbedPane.highlight");
0443: _shadow = UIDefaultsLookup.getColor("JideTabbedPane.shadow");
0444: _darkShadow = UIDefaultsLookup
0445: .getColor("JideTabbedPane.darkShadow");
0446: _focus = UIDefaultsLookup.getColor("TabbedPane.focus");
0447:
0448: if (getTabShape() == JideTabbedPane.SHAPE_BOX) {
0449: _background = UIDefaultsLookup
0450: .getColor("JideTabbedPane.selectedTabBackground");
0451: _tabBackground = UIDefaultsLookup
0452: .getColor("JideTabbedPane.selectedTabBackground");
0453: _inactiveTabForeground = UIDefaultsLookup
0454: .getColor("JideTabbedPane.foreground"); // text is black
0455: _activeTabForeground = UIDefaultsLookup
0456: .getColor("JideTabbedPane.foreground"); // text is black
0457: _selectedColor = _lightHighlight;
0458: } else {
0459: _background = UIDefaultsLookup
0460: .getColor("JideTabbedPane.background");
0461: _tabBackground = UIDefaultsLookup
0462: .getColor("JideTabbedPane.tabAreaBackground");
0463: _inactiveTabForeground = UIDefaultsLookup
0464: .getColor("JideTabbedPane.unselectedTabTextForeground");
0465: _activeTabForeground = UIDefaultsLookup
0466: .getColor("JideTabbedPane.selectedTabTextForeground");
0467: _selectedColor = UIDefaultsLookup
0468: .getColor("JideTabbedPane.selectedTabBackground");
0469: }
0470:
0471: _textIconGap = UIDefaultsLookup
0472: .getInt("JideTabbedPane.textIconGap");
0473: _tabInsets = UIDefaultsLookup
0474: .getInsets("JideTabbedPane.tabInsets");
0475: _selectedTabPadInsets = UIDefaultsLookup
0476: .getInsets("TabbedPane.selectedTabPadInsets");
0477: _tabAreaInsets = UIDefaultsLookup
0478: .getInsets("JideTabbedPane.tabAreaInsets");
0479: Insets insets = _tabPane.getContentBorderInsets();
0480: if (insets == null || insets instanceof UIResource) {
0481: _tabPane.setContentBorderInsets(UIDefaultsLookup
0482: .getInsets("JideTabbedPane.contentBorderInsets"));
0483: }
0484:
0485: _ignoreContentBorderInsetsIfNoTabs = UIDefaultsLookup
0486: .getBoolean("JideTabbedPane.ignoreContentBorderInsetsIfNoTabs");
0487: _tabRunOverlay = UIDefaultsLookup
0488: .getInt("JideTabbedPane.tabRunOverlay");
0489: _showIconOnTab = UIDefaultsLookup
0490: .getBoolean("JideTabbedPane.showIconOnTab");
0491: _showCloseButtonOnTab = UIDefaultsLookup
0492: .getBoolean("JideTabbedPane.showCloseButtonOnTab");
0493: _closeButtonAlignment = UIDefaultsLookup
0494: .getInt("JideTabbedPane.closeButtonAlignment");
0495: _gripperWidth = UIDefaultsLookup.getInt("Gripper.size");
0496:
0497: _tabRectPadding = UIDefaultsLookup
0498: .getInt("JideTabbedPane.tabRectPadding");
0499: _closeButtonMarginHorizon = UIDefaultsLookup
0500: .getInt("JideTabbedPane.closeButtonMarginHorizonal");
0501: _closeButtonMarginVertical = UIDefaultsLookup
0502: .getInt("JideTabbedPane.closeButtonMarginVertical");
0503: _textMarginVertical = UIDefaultsLookup
0504: .getInt("JideTabbedPane.textMarginVertical");
0505: _noIconMargin = UIDefaultsLookup
0506: .getInt("JideTabbedPane.noIconMargin");
0507: _iconMargin = UIDefaultsLookup
0508: .getInt("JideTabbedPane.iconMargin");
0509: _textPadding = UIDefaultsLookup
0510: .getInt("JideTabbedPane.textPadding");
0511: _buttonSize = UIDefaultsLookup
0512: .getInt("JideTabbedPane.buttonSize");
0513: _buttonMargin = UIDefaultsLookup
0514: .getInt("JideTabbedPane.buttonMargin");
0515: _fitStyleBoundSize = UIDefaultsLookup
0516: .getInt("JideTabbedPane.fitStyleBoundSize");
0517: _fitStyleFirstTabMargin = UIDefaultsLookup
0518: .getInt("JideTabbedPane.fitStyleFirstTabMargin");
0519: _fitStyleIconMinWidth = UIDefaultsLookup
0520: .getInt("JideTabbedPane.fitStyleIconMinWidth");
0521: _fitStyleTextMinWidth = UIDefaultsLookup
0522: .getInt("JideTabbedPane.fitStyleTextMinWidth");
0523: _compressedStyleNoIconRectSize = UIDefaultsLookup
0524: .getInt("JideTabbedPane.compressedStyleNoIconRectSize");
0525: _compressedStyleIconMargin = UIDefaultsLookup
0526: .getInt("JideTabbedPane.compressedStyleIconMargin");
0527: _compressedStyleCloseButtonMarginHorizon = UIDefaultsLookup
0528: .getInt("JideTabbedPane.compressedStyleCloseButtonMarginHorizontal");
0529: _compressedStyleCloseButtonMarginVertical = UIDefaultsLookup
0530: .getInt("JideTabbedPane.compressedStyleCloseButtonMarginVertical");
0531: _fixedStyleRectSize = UIDefaultsLookup
0532: .getInt("JideTabbedPane.fixedStyleRectSize");
0533: _closeButtonMargin = UIDefaultsLookup
0534: .getInt("JideTabbedPane.closeButtonMargin");
0535: _gripLeftMargin = UIDefaultsLookup
0536: .getInt("JideTabbedPane.gripLeftMargin");
0537: _closeButtonMarginSize = UIDefaultsLookup
0538: .getInt("JideTabbedPane.closeButtonMarginSize");
0539: _closeButtonLeftMargin = UIDefaultsLookup
0540: .getInt("JideTabbedPane.closeButtonLeftMargin");
0541: _closeButtonRightMargin = UIDefaultsLookup
0542: .getInt("JideTabbedPane.closeButtonRightMargin");
0543:
0544: _defaultTabBorderShadowColor = UIDefaultsLookup
0545: .getColor("JideTabbedPane.defaultTabBorderShadowColor");
0546: _alwaysShowLineBorder = UIDefaultsLookup
0547: .getBoolean("JideTabbedPane.alwaysShowLineBorder");
0548: _showFocusIndicator = UIDefaultsLookup
0549: .getBoolean("JideTabbedPane.showFocusIndicator");
0550: }
0551:
0552: protected void uninstallDefaults() {
0553: _painter = null;
0554: _gripperPainter = null;
0555:
0556: _highlight = null;
0557: _lightHighlight = null;
0558: _shadow = null;
0559: _darkShadow = null;
0560: _focus = null;
0561: _inactiveTabForeground = null;
0562: _selectedColor = null;
0563: _tabInsets = null;
0564: _selectedTabPadInsets = null;
0565: _tabAreaInsets = null;
0566:
0567: _defaultTabBorderShadowColor = null;
0568: }
0569:
0570: protected void installListeners() {
0571: if (_propertyChangeListener == null) {
0572: _propertyChangeListener = createPropertyChangeListener();
0573: _tabPane.addPropertyChangeListener(_propertyChangeListener);
0574: }
0575: if (_tabChangeListener == null) {
0576: _tabChangeListener = createChangeListener();
0577: _tabPane.addChangeListener(_tabChangeListener);
0578: }
0579: if (_tabFocusListener == null) {
0580: _tabFocusListener = createFocusListener();
0581: _tabPane.addFocusListener(_tabFocusListener);
0582: }
0583: if (_mouseListener == null) {
0584: _mouseListener = createMouseListener();
0585: if (scrollableTabLayoutEnabled()) {
0586: _tabScroller.tabPanel.addMouseListener(_mouseListener);
0587: // woraround for swing bug
0588: // http://developer.java.sun.com/developer/bugParade/bugs/4668865.html
0589: ToolTipManager.sharedInstance().registerComponent(
0590: _tabScroller.tabPanel);
0591: } else { // WRAP_TAB_LAYOUT
0592: _tabPane.addMouseListener(_mouseListener);
0593: }
0594: }
0595:
0596: if (_mousemotionListener == null) {
0597: _mousemotionListener = createMouseMotionListener();
0598: if (scrollableTabLayoutEnabled()) {
0599: _tabScroller.tabPanel
0600: .addMouseMotionListener(_mousemotionListener);
0601: // woraround for swing bug
0602: // http://developer.java.sun.com/developer/bugParade/bugs/4668865.html
0603: ToolTipManager.sharedInstance().registerComponent(
0604: _tabScroller.tabPanel);
0605: } else { // WRAP_TAB_LAYOUT
0606: _tabPane.addMouseMotionListener(_mousemotionListener);
0607: }
0608: }
0609:
0610: // PENDING(api) : See comment for ContainerHandler
0611: if (_containerListener == null) {
0612: _containerListener = new ContainerHandler();
0613: _tabPane.addContainerListener(_containerListener);
0614: if (_tabPane.getTabCount() > 0) {
0615: htmlViews = createHTMLVector();
0616: }
0617: }
0618: if (_componentListener == null) {
0619: _componentListener = new ComponentHandler();
0620: _tabPane.addComponentListener(_componentListener);
0621: }
0622:
0623: if (!_tabPane.isDragOverDisabled()) {
0624: if (_dropListener == null) {
0625: _dropListener = createDropListener();
0626: _dt = new DropTarget(getTabPanel(), _dropListener);
0627: }
0628: }
0629: }
0630:
0631: protected DropListener createDropListener() {
0632: return new DropListener();
0633: }
0634:
0635: protected void uninstallListeners() {
0636: if (_mouseListener != null) {
0637: if (scrollableTabLayoutEnabled()) { // SCROLL_TAB_LAYOUT
0638: _tabScroller.tabPanel
0639: .removeMouseListener(_mouseListener);
0640: } else { // WRAP_TAB_LAYOUT
0641: _tabPane.removeMouseListener(_mouseListener);
0642: }
0643: _mouseListener = null;
0644: }
0645:
0646: // PENDING(api): See comment for ContainerHandler
0647: if (_containerListener != null) {
0648: _tabPane.removeContainerListener(_containerListener);
0649: _containerListener = null;
0650: if (htmlViews != null) {
0651: htmlViews.removeAllElements();
0652: htmlViews = null;
0653: }
0654: }
0655:
0656: if (_componentListener != null) {
0657: _tabPane.removeComponentListener(_componentListener);
0658: _componentListener = null;
0659: }
0660:
0661: if (_tabChangeListener != null) {
0662: _tabPane.removeChangeListener(_tabChangeListener);
0663: _tabChangeListener = null;
0664: }
0665:
0666: if (_tabFocusListener != null) {
0667: _tabPane.removeFocusListener(_tabFocusListener);
0668: _tabFocusListener = null;
0669: }
0670:
0671: if (_propertyChangeListener != null) {
0672: _tabPane
0673: .removePropertyChangeListener(_propertyChangeListener);
0674: _propertyChangeListener = null;
0675: }
0676:
0677: if (_dt != null && _dropListener != null) {
0678: _dt.removeDropTargetListener(_dropListener);
0679: _dropListener = null;
0680: _dt = null;
0681: getTabPanel().setDropTarget(null);
0682: }
0683: }
0684:
0685: protected ChangeListener createChangeListener() {
0686: return new TabSelectionHandler();
0687: }
0688:
0689: protected FocusListener createFocusListener() {
0690: return new TabFocusListener();
0691: }
0692:
0693: protected PropertyChangeListener createPropertyChangeListener() {
0694: return new PropertyChangeHandler();
0695: }
0696:
0697: protected void installKeyboardActions() {
0698: InputMap km = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
0699: SwingUtilities.replaceUIInputMap(_tabPane,
0700: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, km);
0701: km = getInputMap(JComponent.WHEN_FOCUSED);
0702: SwingUtilities.replaceUIInputMap(_tabPane,
0703: JComponent.WHEN_FOCUSED, km);
0704: ActionMap am = getActionMap();
0705:
0706: SwingUtilities.replaceUIActionMap(_tabPane, am);
0707:
0708: ensureCloseButtonCreated();
0709:
0710: if (scrollableTabLayoutEnabled()) {
0711: _tabScroller.scrollForwardButton.setAction(am
0712: .get("scrollTabsForwardAction"));
0713: _tabScroller.scrollBackwardButton.setAction(am
0714: .get("scrollTabsBackwardAction"));
0715: _tabScroller.listButton.setAction(am
0716: .get("scrollTabsListAction"));
0717: _tabScroller.closeButton
0718: .setAction(am.get("closeTabAction"));
0719: }
0720:
0721: }
0722:
0723: InputMap getInputMap(int condition) {
0724: if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
0725: return (InputMap) UIDefaultsLookup
0726: .get("JideTabbedPane.ancestorInputMap");
0727: } else if (condition == JComponent.WHEN_FOCUSED) {
0728: return (InputMap) UIDefaultsLookup
0729: .get("JideTabbedPane.focusInputMap");
0730: }
0731: return null;
0732: }
0733:
0734: ActionMap getActionMap() {
0735: ActionMap map = (ActionMap) UIDefaultsLookup
0736: .get("JideTabbedPane.actionMap");
0737:
0738: if (map == null) {
0739: map = createActionMap();
0740: if (map != null) {
0741: UIManager.getLookAndFeelDefaults().put(
0742: "JideTabbedPane.actionMap", map);
0743: }
0744: }
0745: return map;
0746: }
0747:
0748: ActionMap createActionMap() {
0749: ActionMap map = new ActionMapUIResource();
0750: map.put("navigateNext", new NextAction());
0751: map.put("navigatePrevious", new PreviousAction());
0752: map.put("navigateRight", new RightAction());
0753: map.put("navigateLeft", new LeftAction());
0754: map.put("navigateUp", new UpAction());
0755: map.put("navigateDown", new DownAction());
0756: map.put("navigatePageUp", new PageUpAction());
0757: map.put("navigatePageDown", new PageDownAction());
0758: map.put("requestFocus", new RequestFocusAction());
0759: map.put("requestFocusForVisibleComponent",
0760: new RequestFocusForVisibleAction());
0761: map.put("setSelectedIndex", new SetSelectedIndexAction());
0762: map.put("scrollTabsForwardAction",
0763: new ScrollTabsForwardAction());
0764: map.put("scrollTabsBackwardAction",
0765: new ScrollTabsBackwardAction());
0766: map.put("scrollTabsListAction", new ScrollTabsListAction());
0767: Action action = _tabPane.getCloseAction();
0768: map.put("closeTabAction", action != null ? action
0769: : new CloseTabAction());
0770: return map;
0771: }
0772:
0773: protected void uninstallKeyboardActions() {
0774: SwingUtilities.replaceUIActionMap(_tabPane, null);
0775: SwingUtilities.replaceUIInputMap(_tabPane,
0776: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
0777: SwingUtilities.replaceUIInputMap(_tabPane,
0778: JComponent.WHEN_FOCUSED, null);
0779:
0780: if (_closeButtons != null) {
0781: for (int i = 0; i < _closeButtons.length; i++) {
0782: _closeButtons[i] = null;
0783: }
0784: _closeButtons = null;
0785: }
0786: }
0787:
0788: /**
0789: * Reloads the mnemonics. This should be invoked when a memonic changes,
0790: * when the title of a mnemonic changes, or when tabs are added/removed.
0791: */
0792: private void updateMnemonics() {
0793: resetMnemonics();
0794: for (int counter = _tabPane.getTabCount() - 1; counter >= 0; counter--) {
0795: int mnemonic = _tabPane.getMnemonicAt(counter);
0796:
0797: if (mnemonic > 0) {
0798: addMnemonic(counter, mnemonic);
0799: }
0800: }
0801: }
0802:
0803: /**
0804: * Resets the mnemonics bindings to an empty state.
0805: */
0806: private void resetMnemonics() {
0807: if (_mnemonicToIndexMap != null) {
0808: _mnemonicToIndexMap.clear();
0809: _mnemonicInputMap.clear();
0810: }
0811: }
0812:
0813: /**
0814: * Adds the specified mnemonic at the specified index.
0815: */
0816: private void addMnemonic(int index, int mnemonic) {
0817: if (_mnemonicToIndexMap == null) {
0818: initMnemonics();
0819: }
0820: _mnemonicInputMap.put(KeyStroke.getKeyStroke(mnemonic,
0821: Event.ALT_MASK), "setSelectedIndex");
0822: _mnemonicToIndexMap.put(mnemonic, index);
0823: }
0824:
0825: /**
0826: * Installs the state needed for mnemonics.
0827: */
0828: private void initMnemonics() {
0829: _mnemonicToIndexMap = new Hashtable();
0830: _mnemonicInputMap = new InputMapUIResource();
0831: _mnemonicInputMap.setParent(SwingUtilities
0832: .getUIInputMap(_tabPane,
0833: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT));
0834: SwingUtilities.replaceUIInputMap(_tabPane,
0835: JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
0836: _mnemonicInputMap);
0837: }
0838:
0839: // Geometry
0840:
0841: @Override
0842: public Dimension getPreferredSize(JComponent c) {
0843: // Default to LayoutManager's preferredLayoutSize
0844: return null;
0845: }
0846:
0847: @Override
0848: public Dimension getMinimumSize(JComponent c) {
0849: // Default to LayoutManager's minimumLayoutSize
0850: return null;
0851: }
0852:
0853: @Override
0854: public Dimension getMaximumSize(JComponent c) {
0855: // Default to LayoutManager's maximumLayoutSize
0856: return null;
0857: }
0858:
0859: // UI Rendering
0860:
0861: @Override
0862: public void paint(Graphics g, JComponent c) {
0863: int tc = _tabPane.getTabCount();
0864:
0865: paintBackground(g, c);
0866:
0867: if (tc == 0) {
0868: return;
0869: }
0870:
0871: if (_tabCount != tc) {
0872: _tabCount = tc;
0873: updateMnemonics();
0874: }
0875:
0876: int selectedIndex = _tabPane.getSelectedIndex();
0877: int tabPlacement = _tabPane.getTabPlacement();
0878:
0879: ensureCurrentLayout();
0880:
0881: // Paint tab area
0882: // If scrollable tabs are enabled, the tab area will be
0883: // painted by the scrollable tab panel instead.
0884: //
0885: if (!scrollableTabLayoutEnabled()) { // WRAP_TAB_LAYOUT
0886: paintTabArea(g, tabPlacement, selectedIndex);
0887: }
0888:
0889: // Paint content border
0890: // if (_tabPane.isTabShown())
0891: paintContentBorder(g, tabPlacement, selectedIndex);
0892: }
0893:
0894: public void paintBackground(Graphics g, Component c) {
0895: if (_tabPane.isOpaque()) {
0896: int width = c.getWidth();
0897: int height = c.getHeight();
0898: g.setColor(_background);
0899: g.fillRect(0, 0, width, height);
0900: }
0901: }
0902:
0903: /**
0904: * Paints the tabs in the tab area.
0905: * Invoked by paint().
0906: * The graphics parameter must be a valid <code>Graphics</code>
0907: * object. Tab placement may be either:
0908: * <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>,
0909: * <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>.
0910: * The selected index must be a valid tabbed pane tab index (0 to
0911: * tab count - 1, inclusive) or -1 if no tab is currently selected.
0912: * The handling of invalid parameters is unspecified.
0913: *
0914: * @param g the graphics object to use for rendering
0915: * @param tabPlacement the placement for the tabs within the JTabbedPane
0916: * @param selectedIndex the tab index of the selected component
0917: */
0918: protected void paintTabArea(Graphics g, int tabPlacement,
0919: int selectedIndex) {
0920:
0921: if (!PAINT_TABAREA) {
0922: return;
0923: }
0924:
0925: int tabCount = _tabPane.getTabCount();
0926:
0927: Rectangle iconRect = new Rectangle(), textRect = new Rectangle();
0928: Rectangle clipRect = g.getClipBounds();
0929:
0930: paintTabAreaBackground(g, clipRect, tabPlacement);
0931:
0932: // Paint tabRuns of tabs from back to front
0933: for (int i = _runCount - 1; i >= 0; i--) {
0934: int start = _tabRuns[i];
0935: int next = _tabRuns[(i == _runCount - 1) ? 0 : i + 1];
0936: int end = (next != 0 ? next - 1 : tabCount - 1);
0937: for (int j = start; j <= end; j++) {
0938: if (_rects[j].intersects(clipRect)
0939: && j != selectedIndex) {
0940: paintTab(g, tabPlacement, _rects, j, iconRect,
0941: textRect);
0942: }
0943: }
0944: }
0945:
0946: // Paint selected tab if its in the front run
0947: // since it may overlap other tabs
0948: if (selectedIndex >= 0
0949: && getRunForTab(tabCount, selectedIndex) == 0) {
0950: if (_rects[selectedIndex].intersects(clipRect)) {
0951: paintTab(g, tabPlacement, _rects, selectedIndex,
0952: iconRect, textRect);
0953: }
0954: }
0955: }
0956:
0957: protected void paintTabAreaBackground(Graphics g, Rectangle rect,
0958: int tabPlacement) {
0959: if (_tabPane.isOpaque()) {
0960: if (getTabShape() == JideTabbedPane.SHAPE_BOX) {
0961: g
0962: .setColor(UIDefaultsLookup
0963: .getColor("JideTabbedPane.selectedTabBackground"));
0964: } else {
0965: g.setColor(UIDefaultsLookup
0966: .getColor("JideTabbedPane.tabAreaBackground"));
0967: }
0968: g.fillRect(rect.x, rect.y, rect.width, rect.height);
0969: }
0970: }
0971:
0972: protected void paintTab(Graphics g, int tabPlacement,
0973: Rectangle[] rects, int tabIndex, Rectangle iconRect,
0974: Rectangle textRect) {
0975:
0976: if (!PAINT_TAB) {
0977: return;
0978: }
0979:
0980: Rectangle tabRect = rects[tabIndex];
0981:
0982: int selectedIndex = _tabPane.getSelectedIndex();
0983: boolean isSelected = selectedIndex == tabIndex;
0984: Graphics2D g2 = null;
0985: Polygon cropShape = null;
0986: Shape save = null;
0987: int cropx = 0;
0988: int cropy = 0;
0989:
0990: paintTabBackground(g, tabPlacement, tabIndex, tabRect.x,
0991: tabRect.y, tabRect.width, tabRect.height, isSelected);
0992:
0993: Object savedHints = JideSwingUtilities
0994: .setupShapeAntialiasing(g);
0995: paintTabBorder(g, tabPlacement, tabIndex, tabRect.x, tabRect.y,
0996: tabRect.width, tabRect.height, isSelected);
0997: JideSwingUtilities.restoreShapeAntialiasing(g, savedHints);
0998:
0999: Icon icon = getIconForTab(tabIndex);
1000:
1001: Rectangle tempTabRect = new Rectangle(tabRect);
1002:
1003: if (_tabPane.isShowGripper()) {
1004: tempTabRect.x += _gripperWidth;
1005: tempTabRect.width -= _gripperWidth;
1006: Rectangle gripperRect = new Rectangle(tabRect);
1007: gripperRect.x += _gripLeftMargin;
1008: gripperRect.width = _gripperWidth;
1009: if (_gripperPainter != null) {
1010: _gripperPainter.paint(_tabPane, g, gripperRect,
1011: SwingConstants.HORIZONTAL,
1012: isSelected ? ThemePainter.STATE_SELECTED
1013: : ThemePainter.STATE_DEFAULT);
1014: } else {
1015: getPainter().paintGripper(
1016: _tabPane,
1017: g,
1018: gripperRect,
1019: SwingConstants.HORIZONTAL,
1020: isSelected ? ThemePainter.STATE_SELECTED
1021: : ThemePainter.STATE_DEFAULT);
1022: }
1023: }
1024:
1025: if (isShowCloseButton()
1026: && isShowCloseButtonOnTab()
1027: && _tabPane.isTabClosableAt(tabIndex)
1028: && (!_tabPane.isShowCloseButtonOnSelectedTab() || isSelected)) {
1029: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
1030: int buttonWidth = _closeButtons[tabIndex]
1031: .getPreferredSize().width
1032: + _closeButtonMargin;
1033: if (_closeButtonAlignment == SwingConstants.LEADING) {
1034: tempTabRect.x += buttonWidth;
1035: tempTabRect.width -= buttonWidth;
1036: } else {
1037: tempTabRect.width -= buttonWidth;
1038: }
1039: } else {
1040: int buttonHeight = _closeButtons[tabIndex]
1041: .getPreferredSize().height
1042: + _closeButtonMargin;
1043: if (_closeButtonAlignment == SwingConstants.LEADING) {
1044: tempTabRect.y += buttonHeight;
1045: tempTabRect.height -= buttonHeight;
1046: } else {
1047: tempTabRect.height -= buttonHeight;
1048: }
1049: }
1050: }
1051:
1052: String title = _tabPane.getDisplayTitleAt(tabIndex);
1053: Font font = null;
1054:
1055: if (isSelected && _tabPane.getSelectedTabFont() != null) {
1056: font = _tabPane.getSelectedTabFont();
1057: } else {
1058: font = _tabPane.getFont();
1059: }
1060:
1061: if (isSelected && _tabPane.isBoldActiveTab()
1062: && font.getStyle() != Font.BOLD) {
1063: font = font.deriveFont(Font.BOLD);
1064: }
1065:
1066: FontMetrics metrics = g.getFontMetrics(font);
1067:
1068: layoutLabel(tabPlacement, metrics, tabIndex, title, icon,
1069: tempTabRect, iconRect, textRect, isSelected);
1070:
1071: paintText(g, tabPlacement, font, metrics, tabIndex, title,
1072: textRect, isSelected);
1073:
1074: paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected);
1075:
1076: paintFocusIndicator(g, tabPlacement, rects, tabIndex, iconRect,
1077: textRect, isSelected);
1078:
1079: if (cropShape != null) {
1080: paintCroppedTabEdge(g, tabPlacement, tabIndex, isSelected,
1081: cropx, cropy);
1082: g2.setClip(save);
1083: }
1084: }
1085:
1086: /* This method will create and return a polygon shape for the given tab rectangle
1087: * which has been cropped at the specified cropline with a torn edge visual.
1088: * e.g. A "File" tab which has cropped been cropped just after the "i":
1089: * -------------
1090: * | ..... |
1091: * | . |
1092: * | ... . |
1093: * | . . |
1094: * | . . |
1095: * | . . |
1096: * --------------
1097: *
1098: * The x, y arrays below define the pattern used to create a "torn" edge
1099: * segment which is repeated to fill the edge of the tab.
1100: * For tabs placed on TOP and BOTTOM, this righthand torn edge is created by
1101: * line segments which are defined by coordinates obtained by
1102: * subtracting xCropLen[i] from (tab.x + tab.width) and adding yCroplen[i]
1103: * to (tab.y).
1104: * For tabs placed on LEFT or RIGHT, the bottom torn edge is created by
1105: * subtracting xCropLen[i] from (tab.y + tab.height) and adding yCropLen[i]
1106: * to (tab.x).
1107: */
1108: private int xCropLen[] = { 1, 1, 0, 0, 1, 1, 2, 2 };
1109:
1110: private int yCropLen[] = { 0, 3, 3, 6, 6, 9, 9, 12 };
1111:
1112: private static final int CROP_SEGMENT = 12;
1113:
1114: private Polygon createCroppedTabClip(int tabPlacement,
1115: Rectangle tabRect, int cropline) {
1116: int rlen = 0;
1117: int start = 0;
1118: int end = 0;
1119: int ostart = 0;
1120:
1121: switch (tabPlacement) {
1122: case LEFT:
1123: case RIGHT:
1124: rlen = tabRect.width;
1125: start = tabRect.x;
1126: end = tabRect.x + tabRect.width;
1127: ostart = tabRect.y;
1128: break;
1129: case TOP:
1130: case BOTTOM:
1131: default:
1132: rlen = tabRect.height;
1133: start = tabRect.y;
1134: end = tabRect.y + tabRect.height;
1135: ostart = tabRect.x;
1136: }
1137: int rcnt = rlen / CROP_SEGMENT;
1138: if (rlen % CROP_SEGMENT > 0) {
1139: rcnt++;
1140: }
1141: int npts = 2 + (rcnt << 3);
1142: int xp[] = new int[npts];
1143: int yp[] = new int[npts];
1144: int pcnt = 0;
1145:
1146: xp[pcnt] = ostart;
1147: yp[pcnt++] = end;
1148: xp[pcnt] = ostart;
1149: yp[pcnt++] = start;
1150: for (int i = 0; i < rcnt; i++) {
1151: for (int j = 0; j < xCropLen.length; j++) {
1152: xp[pcnt] = cropline - xCropLen[j];
1153: yp[pcnt] = start + (i * CROP_SEGMENT) + yCropLen[j];
1154: if (yp[pcnt] >= end) {
1155: yp[pcnt] = end;
1156: pcnt++;
1157: break;
1158: }
1159: pcnt++;
1160: }
1161: }
1162: if (tabPlacement == JideTabbedPane.TOP
1163: || tabPlacement == JideTabbedPane.BOTTOM) {
1164: return new Polygon(xp, yp, pcnt);
1165:
1166: } else { // LEFT or RIGHT
1167: return new Polygon(yp, xp, pcnt);
1168: }
1169: }
1170:
1171: /* If tabLayoutPolicy == SCROLL_TAB_LAYOUT, this method will paint an edge
1172: * indicating the tab is cropped in the viewport display
1173: */
1174: private void paintCroppedTabEdge(Graphics g, int tabPlacement,
1175: int tabIndex, boolean isSelected, int x, int y) {
1176: switch (tabPlacement) {
1177: case LEFT:
1178: case RIGHT:
1179: int xx = x;
1180: g.setColor(_shadow);
1181: while (xx <= x + _rects[tabIndex].width) {
1182: for (int i = 0; i < xCropLen.length; i += 2) {
1183: g.drawLine(xx + yCropLen[i], y - xCropLen[i], xx
1184: + yCropLen[i + 1] - 1, y - xCropLen[i + 1]);
1185: }
1186: xx += CROP_SEGMENT;
1187: }
1188: break;
1189: case TOP:
1190: case BOTTOM:
1191: default:
1192: int yy = y;
1193: g.setColor(_shadow);
1194: while (yy <= y + _rects[tabIndex].height) {
1195: for (int i = 0; i < xCropLen.length; i += 2) {
1196: g
1197: .drawLine(x - xCropLen[i],
1198: yy + yCropLen[i], x
1199: - xCropLen[i + 1], yy
1200: + yCropLen[i + 1] - 1);
1201: }
1202: yy += CROP_SEGMENT;
1203: }
1204: }
1205: }
1206:
1207: protected void layoutLabel(int tabPlacement, FontMetrics metrics,
1208: int tabIndex, String title, Icon icon, Rectangle tabRect,
1209: Rectangle iconRect, Rectangle textRect, boolean isSelected) {
1210: textRect.x = textRect.y = iconRect.x = iconRect.y = 0;
1211:
1212: View v = getTextViewForTab(tabIndex);
1213: if (v != null) {
1214: _tabPane.putClientProperty("html", v);
1215: }
1216:
1217: SwingUtilities.layoutCompoundLabel(_tabPane, metrics, title,
1218: icon, SwingUtilities.CENTER, SwingUtilities.CENTER,
1219: SwingUtilities.CENTER, SwingUtilities.TRAILING,
1220: tabRect, iconRect, textRect, _textIconGap);
1221:
1222: _tabPane.putClientProperty("html", null);
1223:
1224: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
1225: // iconRect.x = tabRect.x + _iconMargin;
1226: // textRect.x = (icon != null ? iconRect.x + iconRect.width + _textIconGap : tabRect.x + _textPadding);
1227: // iconRect.width = Math.min(iconRect.width, tabRect.width - _tabRectPadding);
1228: // textRect.width = tabRect.width - _tabRectPadding - iconRect.width - (icon != null ? _textIconGap + _iconMargin : _noIconMargin);
1229:
1230: if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_COMPRESSED
1231: && isShowCloseButton() && isShowCloseButtonOnTab()) {
1232: if (!_tabPane.isShowCloseButtonOnSelectedTab()) {
1233: if (!isSelected) {
1234: iconRect.width = iconRect.width
1235: + _closeButtons[tabIndex]
1236: .getPreferredSize().width
1237: + _closeButtonMarginHorizon;
1238: textRect.width = 0;
1239: }
1240: }
1241: }
1242: } else {// tabplacement is left or right
1243: iconRect.y = tabRect.y + _iconMargin;
1244: textRect.y = (icon != null ? iconRect.y + iconRect.height
1245: + _textIconGap : tabRect.y + _textPadding);
1246: iconRect.x = tabRect.x + 2;
1247: textRect.x = tabRect.x + 2;
1248: textRect.width = tabRect.width - _textMarginVertical;
1249: textRect.height = tabRect.height
1250: - _tabRectPadding
1251: - iconRect.height
1252: - (icon != null ? _textIconGap + _iconMargin
1253: : _noIconMargin);
1254:
1255: if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_COMPRESSED
1256: && isShowCloseButton() && isShowCloseButtonOnTab()) {
1257: if (!_tabPane.isShowCloseButtonOnSelectedTab()) {
1258: if (!isSelected) {
1259: iconRect.height = iconRect.height
1260: + _closeButtons[tabIndex]
1261: .getPreferredSize().height
1262: + _closeButtonMarginVertical;
1263: textRect.height = 0;
1264: }
1265: }
1266: }
1267: }
1268: }
1269:
1270: protected void paintIcon(Graphics g, int tabPlacement,
1271: int tabIndex, Icon icon, Rectangle iconRect,
1272: boolean isSelected) {
1273: if (icon != null && iconRect.width >= icon.getIconWidth()) {
1274: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
1275: icon.paintIcon(_tabPane, g, iconRect.x, iconRect.y);
1276: } else {
1277: if (iconRect.height < _rects[tabIndex].height
1278: - _gripperHeight) {
1279: icon.paintIcon(_tabPane, g, iconRect.x, iconRect.y);
1280: }
1281: }
1282: }
1283: }
1284:
1285: protected void paintText(Graphics g, int tabPlacement, Font font,
1286: FontMetrics metrics, int tabIndex, String title,
1287: Rectangle textRect, boolean isSelected) {
1288: Graphics2D g2d = (Graphics2D) g;
1289: if (isSelected && _tabPane.isBoldActiveTab()) {
1290: g.setFont(font.deriveFont(Font.BOLD));
1291: } else {
1292: g.setFont(font);
1293: }
1294:
1295: String actualText = title;
1296:
1297: if (tabPlacement == JideTabbedPane.TOP
1298: || tabPlacement == JideTabbedPane.BOTTOM) {
1299: if (textRect.width <= 0)
1300: return;
1301:
1302: while (SwingUtilities.computeStringWidth(metrics,
1303: actualText) > textRect.width) {
1304: actualText = actualText.substring(0, actualText
1305: .length() - 1);
1306: }
1307: if (!actualText.equals(title)) {
1308: if (actualText.length() >= 2)
1309: actualText = actualText.substring(0, actualText
1310: .length() - 2)
1311: + "..";
1312: else
1313: actualText = "";
1314: }
1315: } else {
1316: if (textRect.height <= 0)
1317: return;
1318:
1319: while (SwingUtilities.computeStringWidth(metrics,
1320: actualText) > textRect.height) {
1321: actualText = actualText.substring(0, actualText
1322: .length() - 1);
1323: }
1324: if (!actualText.equals(title)) {
1325: if (actualText.length() >= 2)
1326: actualText = actualText.substring(0, actualText
1327: .length() - 2)
1328: + "..";
1329: else
1330: actualText = "";
1331: }
1332: }
1333:
1334: View v = getTextViewForTab(tabIndex);
1335: if (v != null) {
1336: // html
1337: v.paint(g, textRect);
1338: } else {
1339: // plain text
1340: int mnemIndex = _tabPane
1341: .getDisplayedMnemonicIndexAt(tabIndex);
1342: JideTabbedPane.ColorProvider colorProvider = _tabPane
1343: .getTabColorProvider();
1344: if (_tabPane.isEnabled() && _tabPane.isEnabledAt(tabIndex)) {
1345: if (colorProvider != null) {
1346: g.setColor(colorProvider.getForegroudAt(tabIndex));
1347: } else {
1348: Color color = _tabPane.getForegroundAt(tabIndex);
1349: if (isSelected && showFocusIndicator()) {
1350: if (!(color instanceof ColorUIResource)) {
1351: g.setColor(color);
1352: } else {
1353: g.setColor(_activeTabForeground);
1354: }
1355: } else {
1356: if (!(color instanceof ColorUIResource)) {
1357: g.setColor(color);
1358: } else {
1359: g.setColor(_inactiveTabForeground);
1360: }
1361: }
1362: }
1363:
1364: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
1365: JideSwingUtilities.drawStringUnderlineCharAt(
1366: _tabPane, g, actualText, mnemIndex,
1367: textRect.x, textRect.y
1368: + metrics.getAscent());
1369: } else {// draw string from top to bottom
1370: AffineTransform old = g2d.getTransform();
1371: g2d.rotate(Math.PI / 2);
1372: g2d.translate(0, -textRect.x - textRect.width);
1373: JideSwingUtilities.drawStringUnderlineCharAt(
1374: _tabPane, g, actualText, mnemIndex,
1375: textRect.y, ((textRect.width - metrics
1376: .getHeight()) / 2)
1377: + metrics.getAscent());
1378: g2d.setTransform(old);
1379: }
1380: } else { // tab disabled
1381: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
1382: g.setColor(_tabPane.getBackgroundAt(tabIndex)
1383: .brighter());
1384: JideSwingUtilities.drawStringUnderlineCharAt(
1385: _tabPane, g, actualText, mnemIndex,
1386: textRect.x, textRect.y
1387: + metrics.getAscent());
1388: g.setColor(_tabPane.getBackgroundAt(tabIndex)
1389: .darker());
1390: JideSwingUtilities.drawStringUnderlineCharAt(
1391: _tabPane, g, actualText, mnemIndex,
1392: textRect.x - 1, textRect.y
1393: + metrics.getAscent() - 1);
1394: } else {// draw string from top to bottom
1395: AffineTransform old = g2d.getTransform();
1396: g2d.rotate(Math.PI / 2);
1397: g2d.translate(0, 0 - textRect.x - textRect.width);
1398: g.setColor(_tabPane.getBackgroundAt(tabIndex)
1399: .brighter());
1400: JideSwingUtilities.drawStringUnderlineCharAt(
1401: _tabPane, g, actualText, mnemIndex,
1402: textRect.y, ((textRect.width - metrics
1403: .getHeight()) / 2)
1404: + metrics.getAscent());
1405: g.setColor(_tabPane.getBackgroundAt(tabIndex)
1406: .darker());
1407: JideSwingUtilities.drawStringUnderlineCharAt(
1408: _tabPane, g, actualText, mnemIndex,
1409: textRect.y - 1, ((textRect.width - metrics
1410: .getHeight()) / 2)
1411: + metrics.getAscent() - 1);
1412: g2d.setTransform(old);
1413: }
1414: }
1415: }
1416: }
1417:
1418: /**
1419: * this function draws the border around each tab note that this function
1420: * does now draw the background of the tab. that is done elsewhere
1421: */
1422: protected void paintTabBorder(Graphics g, int tabPlacement,
1423: int tabIndex, int x, int y, int w, int h, boolean isSelected) {
1424: if (!PAINT_TAB_BORDER) {
1425: return;
1426: }
1427:
1428: switch (getTabShape()) {
1429: case JideTabbedPane.SHAPE_BOX:
1430: paintBoxTabBorder(g, tabPlacement, tabIndex, x, y, w, h,
1431: isSelected);
1432: break;
1433: case JideTabbedPane.SHAPE_EXCEL:
1434: paintExcelTabBorder(g, tabPlacement, tabIndex, x, y, w, h,
1435: isSelected);
1436: break;
1437: case JideTabbedPane.SHAPE_WINDOWS:
1438: paintWindowsTabBorder(g, tabPlacement, tabIndex, x, y, w,
1439: h, isSelected);
1440: break;
1441: case JideTabbedPane.SHAPE_WINDOWS_SELECTED:
1442: if (isSelected) {
1443: paintWindowsTabBorder(g, tabPlacement, tabIndex, x, y,
1444: w, h, isSelected);
1445: }
1446: break;
1447: case JideTabbedPane.SHAPE_VSNET:
1448: paintVsnetTabBorder(g, tabPlacement, tabIndex, x, y, w, h,
1449: isSelected);
1450: break;
1451: case JideTabbedPane.SHAPE_ROUNDED_VSNET:
1452: paintRoundedVsnetTabBorder(g, tabPlacement, tabIndex, x, y,
1453: w, h, isSelected);
1454: break;
1455: case JideTabbedPane.SHAPE_FLAT:
1456: paintFlatTabBorder(g, tabPlacement, tabIndex, x, y, w, h,
1457: isSelected);
1458: break;
1459: case JideTabbedPane.SHAPE_ROUNDED_FLAT:
1460: paintRoundedFlatTabBorder(g, tabPlacement, tabIndex, x, y,
1461: w, h, isSelected);
1462: break;
1463: case JideTabbedPane.SHAPE_OFFICE2003:
1464: default:
1465: paintOffice2003TabBorder(g, tabPlacement, tabIndex, x, y,
1466: w, h, isSelected);
1467: }
1468:
1469: int tabShape = getTabShape();
1470: if (tabShape == JideTabbedPane.SHAPE_WINDOWS) {
1471: if (_mouseEnter
1472: && _tabPane.getColorTheme() == JideTabbedPane.COLOR_THEME_WINXP
1473: && tabIndex == _indexMouseOver && !isSelected
1474: && _tabPane.isEnabledAt(_indexMouseOver)) {
1475: paintTabBorderMouseOver(g, tabPlacement, tabIndex, x,
1476: y, w, h, isSelected);
1477: }
1478: } else if (tabShape == JideTabbedPane.SHAPE_WINDOWS_SELECTED) {
1479: if (_mouseEnter && tabIndex == _indexMouseOver
1480: && !isSelected
1481: && _tabPane.isEnabledAt(_indexMouseOver)) {
1482: paintTabBorderMouseOver(g, tabPlacement, tabIndex, x,
1483: y, w, h, isSelected);
1484: }
1485: }
1486: }
1487:
1488: protected void paintOffice2003TabBorder(Graphics g,
1489: int tabPlacement, int tabIndex, int x, int y, int w, int h,
1490: boolean isSelected) {
1491: switch (tabPlacement) {
1492: case LEFT:// when the tab on the left
1493: y += 2;
1494: if (isSelected) {// the tab is selected
1495: g.setColor(_selectColor1);
1496:
1497: g.drawLine(x, y + 3, x, y + h - 5);// left
1498: g.drawLine(x + 1, y + h - 4, x + 1, y + h - 4);// bottom
1499: // arc
1500: g.drawLine(x + 2, y + h - 3, x + w - 1, y + h - 3);// bottom
1501:
1502: g.drawLine(x + 1, y + 2, x + 1, y + 1);// top arc
1503: g.drawLine(x + 2, y, x + 2, y - 1);
1504:
1505: for (int i = 0; i < w - 4; i++) {// top
1506: g.drawLine(x + 3 + i, y - 2 - i, x + 3 + i, y - 2
1507: - i);
1508: }
1509:
1510: g.drawLine(x + w - 1, y - w + 1, x + w - 1, y - w + 2);
1511:
1512: g.setColor(_selectColor2);
1513:
1514: g.drawLine(x + 1, y + 3, x + 1, y + h - 5);// left
1515: g.drawLine(x + 2, y + h - 4, x + w - 1, y + h - 4);// bottom
1516:
1517: g.drawLine(x + 2, y + 2, x + 2, y + 1);// top arc
1518: g.drawLine(x + 3, y, x + 3, y - 1);
1519:
1520: for (int i = 0; i < w - 4; i++) {// top
1521: g.drawLine(x + 4 + i, y - 2 - i, x + 4 + i, y - 2
1522: - i);
1523: }
1524:
1525: } else {
1526: if (tabIndex == 0) {
1527: g.setColor(_unselectColor1);
1528:
1529: g.drawLine(x, y + 3, x, y + h - 5);// left
1530: g.drawLine(x + 1, y + h - 4, x + 1, y + h - 4);// bottom
1531: // arc
1532: g.drawLine(x + 2, y + h - 3, x + w - 1, y + h - 3);// bottom
1533:
1534: g.drawLine(x + 1, y + 2, x + 1, y + 1);// top arc
1535: g.drawLine(x + 2, y, x + 2, y - 1);
1536:
1537: for (int i = 0; i < w - 4; i++) {// top
1538: g.drawLine(x + 3 + i, y - 2 - i, x + 3 + i, y
1539: - 2 - i);
1540: }
1541:
1542: g.drawLine(x + w - 1, y - w + 1, x + w - 1, y - w
1543: + 2);
1544:
1545: if (_unselectColor2 != null) {
1546: g.setColor(_unselectColor2);
1547:
1548: g.drawLine(x + 1, y + 3, x + 1, y + h - 6);// left
1549:
1550: g.drawLine(x + 2, y + 2, x + 2, y + 1);// top arc
1551: g.drawLine(x + 3, y, x + 3, y - 1);
1552:
1553: for (int i = 0; i < w - 4; i++) {// top
1554: g.drawLine(x + 4 + i, y - 2 - i, x + 4 + i,
1555: y - 2 - i);
1556: }
1557:
1558: g.setColor(getPainter().getControlDk());
1559: }
1560:
1561: if (_unselectColor3 != null) {
1562: g.setColor(_unselectColor3);
1563:
1564: g.drawLine(x + 2, y + h - 4, x + w - 1, y + h
1565: - 4);// bottom
1566: g.drawLine(x + 1, y + h - 5, x + 1, y + h - 5);// bottom
1567: // arc
1568: }
1569: } else {
1570: g.setColor(_unselectColor1);
1571:
1572: g.drawLine(x, y + 3, x, y + h - 5);// left
1573: g.drawLine(x + 1, y + h - 4, x + 1, y + h - 4);// bottom
1574: // arc
1575: g.drawLine(x + 2, y + h - 3, x + w - 1, y + h - 3);// bottom
1576:
1577: g.drawLine(x + 1, y + 2, x + 1, y + 1);// top arc
1578: g.drawLine(x + 2, y, x + 2, y - 1);
1579: g.drawLine(x + 3, y - 2, x + 3, y - 2);
1580:
1581: if (_unselectColor2 != null) {
1582: g.setColor(_unselectColor2);
1583:
1584: g.drawLine(x + 1, y + 3, x + 1, y + h - 6);// left
1585:
1586: g.drawLine(x + 2, y + 2, x + 2, y + 1);// top arc
1587: g.drawLine(x + 3, y, x + 3, y - 1);
1588: g.drawLine(x + 4, y - 2, x + 4, y - 2);
1589:
1590: }
1591:
1592: if (_unselectColor3 != null) {
1593: g.setColor(_unselectColor3);
1594:
1595: g.drawLine(x + 2, y + h - 4, x + w - 1, y + h
1596: - 4);// bottom
1597: g.drawLine(x + 1, y + h - 5, x + 1, y + h - 5);
1598: }
1599: }
1600: }
1601: break;
1602: case RIGHT:
1603: if (isSelected) {// the tab is selected
1604: g.setColor(_selectColor1);
1605:
1606: g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 3);// right
1607: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h - 2);// bottom
1608: // arc
1609: g.drawLine(x + w - 3, y + h - 1, x, y + h - 1);// bottom
1610:
1611: g.drawLine(x + w - 2, y + 4, x + w - 2, y + 3);// top arc
1612: g.drawLine(x + w - 3, y + 2, x + w - 3, y + 1);// top arc
1613:
1614: for (int i = 0; i < w - 4; i++) {// top
1615: g.drawLine(x + w - 4 - i, y - i, x + w - 4 - i, y
1616: - i);
1617: }
1618:
1619: g.drawLine(x, y - w + 3, x, y - w + 4);
1620:
1621: g.setColor(_selectColor2);
1622:
1623: g.drawLine(x + w - 2, y + 5, x + w - 2, y + h - 3);// right
1624: g.drawLine(x + w - 3, y + h - 2, x, y + h - 2);// bottom
1625:
1626: g.drawLine(x + w - 3, y + 4, x + w - 3, y + 3);// top arc
1627: g.drawLine(x + w - 4, y + 2, x + w - 4, y + 1);
1628:
1629: for (int i = 0; i < w - 4; i++) {// top
1630: g.drawLine(x + w - 5 - i, y - i, x + w - 5 - i, y
1631: - i);
1632: }
1633: } else {
1634: if (tabIndex == 0) {
1635: g.setColor(_unselectColor1);
1636:
1637: g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 3);// right
1638: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h
1639: - 2);// bottom
1640: // arc
1641: g.drawLine(x + w - 3, y + h - 1, x, y + h - 1);// bottom
1642:
1643: g.drawLine(x + w - 2, y + 4, x + w - 2, y + 3);// top arc
1644: g.drawLine(x + w - 3, y + 2, x + w - 3, y + 1);// top arc
1645:
1646: for (int i = 0; i < w - 4; i++) {// top
1647: g.drawLine(x + w - 4 - i, y - i, x + w - 4 - i,
1648: y - i);
1649: }
1650:
1651: g.drawLine(x, y - w + 3, x, y - w + 4);
1652:
1653: if (_unselectColor2 != null) {
1654: g.setColor(_unselectColor2);
1655:
1656: g.drawLine(x + w - 2, y + 5, x + w - 2, y + h
1657: - 4);// right
1658:
1659: g.drawLine(x + w - 3, y + 4, x + w - 3, y + 3);// top
1660: // arc
1661: g.drawLine(x + w - 4, y + 2, x + w - 4, y + 1);
1662:
1663: for (int i = 0; i < w - 4; i++) {// top
1664: g.drawLine(x + w - 5 - i, y - i, x + w - 5
1665: - i, y - i);
1666: }
1667: }
1668:
1669: if (_unselectColor3 != null) {
1670: g.setColor(_unselectColor3);
1671:
1672: g.drawLine(x + w - 2, y + h - 3, x + w - 2, y
1673: + h - 3);// bottom
1674: // arc
1675: g.drawLine(x + w - 3, y + h - 2, x, y + h - 2);// bottom
1676:
1677: }
1678: } else {
1679: g.setColor(_unselectColor1);
1680:
1681: g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 3);// right
1682: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h
1683: - 2);// bottom
1684: // arc
1685: g.drawLine(x + w - 3, y + h - 1, x, y + h - 1);// bottom
1686:
1687: g.drawLine(x + w - 2, y + 4, x + w - 2, y + 3);// top arc
1688: g.drawLine(x + w - 3, y + 2, x + w - 3, y + 1);// top arc
1689: g.drawLine(x + w - 4, y, x + w - 4, y);// top arc
1690:
1691: if (_unselectColor2 != null) {
1692: g.setColor(_unselectColor2);
1693:
1694: g.drawLine(x + w - 2, y + 5, x + w - 2, y + h
1695: - 4);// right
1696:
1697: g.drawLine(x + w - 3, y + 4, x + w - 3, y + 3);// top
1698: // arc
1699: g.drawLine(x + w - 4, y + 2, x + w - 4, y + 1);
1700: g.drawLine(x + w - 5, y, x + w - 5, y);
1701: }
1702:
1703: if (_unselectColor3 != null) {
1704: g.setColor(_unselectColor3);
1705:
1706: g.drawLine(x + w - 2, y + h - 3, x + w - 2, y
1707: + h - 3);// bottom
1708: // arc
1709: g.drawLine(x + w - 3, y + h - 2, x, y + h - 2);// bottom
1710: }
1711: }
1712: }
1713: break;
1714: case BOTTOM:
1715: if (isSelected) {// the tab is selected
1716: g.setColor(_selectColor1);
1717:
1718: g.drawLine(x + w - 1, y + h - 3, x + w - 1, y);// right
1719:
1720: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h - 2);// right
1721: // arc
1722:
1723: g.drawLine(x + 5, y + h - 1, x + w - 3, y + h - 1);// bottom
1724:
1725: g.drawLine(x + 3, y + h - 2, x + 4, y + h - 2);// left arc
1726: g.drawLine(x + 1, y + h - 3, x + 2, y + h - 3);// left arc
1727: g.drawLine(x, y + h - 4, x, y + h - 4);// left arc
1728:
1729: // left
1730: for (int i = 3; i < h - 2; i++) {
1731: g.drawLine(x + 2 - i, y + h - 2 - i, x + 2 - i, y
1732: + h - 2 - i);
1733: }
1734:
1735: g.drawLine(x - h + 3, y, x - h + 4, y);
1736:
1737: g.setColor(_selectColor2);
1738:
1739: g.drawLine(x + 5, y + h - 2, x + w - 3, y + h - 2);// bottom
1740:
1741: g.drawLine(x + w - 2, y, x + w - 2, y + h - 3);// right
1742:
1743: g.drawLine(x + 3, y + h - 3, x + 4, y + h - 3);// left arc
1744: g.drawLine(x + 1, y + h - 4, x + 2, y + h - 4);// left arc
1745: g.drawLine(x, y + h - 5, x, y + h - 5);// left arc
1746:
1747: for (int i = 3; i < h - 2; i++) {// left
1748: g.drawLine(x + 2 - i, y + h - 3 - i, x + 2 - i, y
1749: + h - 3 - i);
1750: }
1751:
1752: } else {
1753: if (tabIndex == 0) {
1754: g.setColor(_unselectColor1);
1755:
1756: g.drawLine(x + w - 1, y + h - 3, x + w - 1, y);// right
1757:
1758: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h
1759: - 2);// right
1760: // arc
1761:
1762: g.drawLine(x + 5, y + h - 1, x + w - 3, y + h - 1);// bottom
1763:
1764: g.drawLine(x + 3, y + h - 2, x + 4, y + h - 2);// left arc
1765: g.drawLine(x + 1, y + h - 3, x + 2, y + h - 3);// left arc
1766: g.drawLine(x, y + h - 4, x, y + h - 4);// left arc
1767:
1768: // left
1769: for (int i = 3; i < h - 2; i++) {
1770: g.drawLine(x + 2 - i, y + h - 2 - i, x + 2 - i,
1771: y + h - 2 - i);
1772: }
1773:
1774: g.drawLine(x - h + 3, y, x - h + 4, y);
1775:
1776: if (_unselectColor2 != null) {
1777: g.setColor(_unselectColor2);
1778:
1779: g.drawLine(x + 3, y + h - 3, x + 4, y + h - 3);// left
1780: // arc
1781: g.drawLine(x + 1, y + h - 4, x + 2, y + h - 4);// left
1782: // arc
1783: g.drawLine(x, y + h - 5, x, y + h - 5);// left arc
1784:
1785: // left
1786: for (int i = 3; i < h - 2; i++) {
1787: g.drawLine(x + 2 - i, y + h - 3 - i, x + 2
1788: - i, y + h - 3 - i);
1789: }
1790:
1791: g.drawLine(x + 5, y + h - 2, x + w - 4, y + h
1792: - 2);// bottom
1793:
1794: }
1795:
1796: if (_unselectColor3 != null) {
1797: g.setColor(_unselectColor3);
1798:
1799: g.drawLine(x + w - 3, y + h - 2, x + w - 3, y
1800: + h - 2);
1801: g.drawLine(x + w - 2, y + h - 3, x + w - 2, y);// right
1802: }
1803: } else {
1804: g.setColor(_unselectColor1);
1805:
1806: g.drawLine(x + 5, y + h - 1, x + w - 3, y + h - 1);// bottom
1807:
1808: g.drawLine(x + w - 1, y + h - 3, x + w - 1, y);// right
1809:
1810: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h
1811: - 2);// right
1812: // arc
1813:
1814: g.drawLine(x + 3, y + h - 2, x + 4, y + h - 2);// left arc
1815: g.drawLine(x + 1, y + h - 3, x + 2, y + h - 3);// left arc
1816: g.drawLine(x, y + h - 4, x, y + h - 4);// left arc
1817:
1818: if (_unselectColor2 != null) {
1819: g.setColor(_unselectColor2);
1820:
1821: g.drawLine(x + 3, y + h - 3, x + 4, y + h - 3);// left
1822: // arc
1823: g.drawLine(x + 1, y + h - 4, x + 2, y + h - 4);// left
1824: // arc
1825: g.drawLine(x, y + h - 5, x, y + h - 5);// left arc
1826:
1827: g.drawLine(x + 5, y + h - 2, x + w - 4, y + h
1828: - 2);// bottom
1829: }
1830:
1831: if (_unselectColor3 != null) {
1832: g.setColor(_unselectColor3);
1833:
1834: g.drawLine(x + w - 3, y + h - 2, x + w - 3, y
1835: + h - 2);
1836: g.drawLine(x + w - 2, y + h - 3, x + w - 2, y);// right
1837: }
1838: }
1839: }
1840: break;
1841: case TOP:
1842: default:
1843: if (isSelected) {// the tab is selected
1844: g.setColor(_selectColor1);
1845:
1846: g.drawLine(x + 3, y + 1, x + 4, y + 1);// left arc
1847: g.drawLine(x + 1, y + 2, x + 2, y + 2);// left arc
1848: g.drawLine(x, y + 3, x, y + 3);
1849:
1850: g.drawLine(x + 5, y, x + w - 3, y);// top
1851:
1852: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);// right arc
1853:
1854: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 1);// right
1855:
1856: // left
1857: for (int i = 3; i < h - 2; i++) {
1858: g.drawLine(x + 2 - i, y + 1 + i, x + 2 - i, y + 1
1859: + i);
1860: }
1861: g.drawLine(x - h + 3, y + h - 1, x - h + 4, y + h - 1);
1862:
1863: g.setColor(_selectColor2);
1864:
1865: g.drawLine(x + 3, y + 2, x + 4, y + 2);// left arc
1866: g.drawLine(x + 1, y + 3, x + 2, y + 3);// left arc
1867: g.drawLine(x, y + 4, x, y + 4);
1868:
1869: g.drawLine(x + 5, y + 1, x + w - 3, y + 1);// top
1870:
1871: g.drawLine(x + w - 2, y + 2, x + w - 2, y + h - 1);// right
1872:
1873: // left
1874: for (int i = 3; i < h - 2; i++) {
1875: g.drawLine(x + 2 - i, y + 2 + i, x + 2 - i, y + 2
1876: + i);
1877: }
1878:
1879: } else {
1880: if (tabIndex == 0) {
1881: g.setColor(_unselectColor1);
1882:
1883: g.drawLine(x + 3, y + 1, x + 4, y + 1);// left arc
1884: g.drawLine(x + 1, y + 2, x + 2, y + 2);// left arc
1885: g.drawLine(x, y + 3, x, y + 3);
1886:
1887: g.drawLine(x + 5, y, x + w - 3, y);// top
1888:
1889: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);// right arc
1890:
1891: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 1);// right
1892:
1893: // left
1894: for (int i = 3; i < h - 2; i++) {
1895: g.drawLine(x + 2 - i, y + 1 + i, x + 2 - i, y
1896: + 1 + i);
1897: }
1898: g.drawLine(x - h + 3, y + h - 1, x - h + 4, y + h
1899: - 1);
1900:
1901: if (_unselectColor2 != null) {
1902: g.setColor(_unselectColor2);
1903:
1904: g.drawLine(x + 3, y + 2, x + 4, y + 2);// left arc
1905: g.drawLine(x + 1, y + 3, x + 2, y + 3);// left arc
1906: g.drawLine(x, y + 4, x, y + 4);
1907:
1908: // left
1909: for (int i = 3; i < h - 2; i++) {
1910: g.drawLine(x + 2 - i, y + 2 + i, x + 2 - i,
1911: y + 2 + i);
1912: }
1913:
1914: g.drawLine(x + 5, y + 1, x + w - 4, y + 1);// top
1915: }
1916:
1917: if (_unselectColor3 != null) {
1918: g.setColor(_unselectColor3);
1919:
1920: g.drawLine(x + w - 3, y + 1, x + w - 3, y + 1);
1921: g.drawLine(x + w - 2, y + 2, x + w - 2, y + h
1922: - 1);// right
1923: }
1924:
1925: } else {
1926: g.setColor(_unselectColor1);
1927:
1928: g.drawLine(x + 3, y + 1, x + 4, y + 1);// left arc
1929: g.drawLine(x + 1, y + 2, x + 2, y + 2);// left arc
1930: g.drawLine(x, y + 3, x, y + 3);
1931:
1932: g.drawLine(x + 5, y, x + w - 3, y);// top
1933:
1934: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);// right arc
1935:
1936: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 1);// right
1937:
1938: if (_unselectColor2 != null) {
1939: g.setColor(_unselectColor2);
1940:
1941: g.drawLine(x + 3, y + 2, x + 4, y + 2);// left arc
1942: g.drawLine(x + 1, y + 3, x + 2, y + 3);// left arc
1943: g.drawLine(x, y + 4, x, y + 4);
1944:
1945: g.drawLine(x + 5, y + 1, x + w - 4, y + 1);// top
1946: }
1947:
1948: if (_unselectColor3 != null) {
1949: g.setColor(_unselectColor3);
1950:
1951: g.drawLine(x + w - 3, y + 1, x + w - 3, y + 1);
1952: g.drawLine(x + w - 2, y + 2, x + w - 2, y + h
1953: - 1);// right
1954: }
1955:
1956: }
1957: }
1958: }
1959:
1960: }
1961:
1962: protected void paintExcelTabBorder(Graphics g, int tabPlacement,
1963: int tabIndex, int x, int y, int w, int h, boolean isSelected) {
1964: switch (tabPlacement) {
1965: case LEFT:
1966: if (isSelected) {
1967: g.setColor(_selectColor1);
1968: g.drawLine(x, y + 5, x, y + h - 5);// left
1969: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// top
1970: g.drawLine(x + 1 + j, y + 4 - i, x + 2 + j, y + 4
1971: - i);
1972: }
1973: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// bottom
1974: g.drawLine(x + j, y + h - 4 + i, x + 1 + j, y + h
1975: - 4 + i);
1976: }
1977:
1978: if (_selectColor2 != null) {
1979: g.setColor(_selectColor2);
1980: g.drawLine(x + 1, y + 6, x + 1, y + h - 6);// left
1981: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// top
1982: g.drawLine(x + 1 + j, y + 5 - i, x + 2 + j, y
1983: + 5 - i);
1984: }
1985: }
1986:
1987: if (_selectColor3 != null) {
1988: g.setColor(_selectColor3);
1989: g.drawLine(x + 1, y + h - 5, x + 1, y + h - 5);// a point
1990: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// bottom
1991: g.drawLine(x + 2 + j, y + h - 4 + i, x + 3 + j,
1992: y + h - 4 + i);
1993: }
1994: }
1995: } else {
1996: if (tabIndex == 0) {
1997: g.setColor(_unselectColor1);
1998: g.drawLine(x, y + 5, x, y + h - 5);// left
1999: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// top
2000: g.drawLine(x + 1 + j, y + 4 - i, x + 2 + j, y
2001: + 4 - i);
2002: }
2003:
2004: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// bottom
2005: g.drawLine(x + j, y + h - 4 + i, x + 1 + j, y
2006: + h - 4 + i);
2007: }
2008:
2009: if (_unselectColor2 != null) {
2010: g.setColor(_unselectColor2);
2011: g.drawLine(x + 1, y + 6, x + 1, y + h - 6);// left
2012: for (int i = 0, j = 0; i < w / 2; i++, j = j + 2) {// top
2013: g.drawLine(x + 1 + j, y + 5 - i, x + 2 + j,
2014: y + 5 - i);
2015: }
2016: }
2017:
2018: if (_unselectColor3 != null) {
2019: g.setColor(_unselectColor3);
2020: g.drawLine(x + 1, y + h - 5, x + 1, y + h - 5);// a point
2021: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// bottom
2022: g.drawLine(x + 2 + j, y + h - 4 + i, x + 3
2023: + j, y + h - 4 + i);
2024: }
2025: }
2026: } else if (tabIndex == _tabPane.getSelectedIndex() - 1) {
2027: g.setColor(_unselectColor1);
2028: g.drawLine(x, y + 5, x, y + h - 5);// left
2029: for (int i = 0, j = 0; i < 4; i++, j = j + 2) {// top
2030: g.drawLine(x + 1 + j, y + 4 - i, x + 2 + j, y
2031: + 4 - i);
2032: }
2033:
2034: for (int i = 0, j = 0; i < 5; i++, j = j + 2) {// bottom
2035: g.drawLine(x + j, y + h - 4 + i, x + 1 + j, y
2036: + h - 4 + i);
2037: }
2038:
2039: if (_unselectColor2 != null) {
2040: g.setColor(_unselectColor2);
2041: g.drawLine(x + 1, y + 6, x + 1, y + h - 6);// left
2042: for (int i = 0, j = 0; i < 4; i++, j = j + 2) {// top
2043: g.drawLine(x + 1 + j, y + 5 - i, x + 2 + j,
2044: y + 5 - i);
2045: }
2046: }
2047:
2048: if (_unselectColor3 != null) {
2049: g.setColor(_unselectColor3);
2050: g.drawLine(x + 1, y + h - 5, x + 1, y + h - 5);// a point
2051: for (int i = 0, j = 0; i < 5; i++, j = j + 2) {// bottom
2052: g.drawLine(x + 2 + j, y + h - 4 + i, x + 3
2053: + j, y + h - 4 + i);
2054: }
2055: }
2056: } else if (tabIndex != _tabPane.getSelectedIndex() - 1) {
2057: g.setColor(_unselectColor1);
2058: g.drawLine(x, y + 5, x, y + h - 5);// left
2059: for (int i = 0, j = 0; i < 4; i++, j = j + 2) {// top
2060: g.drawLine(x + 1 + j, y + 4 - i, x + 2 + j, y
2061: + 4 - i);
2062: }
2063: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// bottom
2064: g.drawLine(x + j, y + h - 4 + i, x + 1 + j, y
2065: + h - 4 + i);
2066: }
2067:
2068: if (_unselectColor2 != null) {
2069: g.setColor(_unselectColor2);
2070: g.drawLine(x + 1, y + 6, x + 1, y + h - 6);// left
2071: for (int i = 0, j = 0; i < 4; i++, j = j + 2) {// top
2072: g.drawLine(x + 1 + j, y + 5 - i, x + 2 + j,
2073: y + 5 - i);
2074: }
2075: }
2076:
2077: if (_unselectColor3 != null) {
2078: g.setColor(_unselectColor3);
2079: g.drawLine(x + 1, y + h - 5, x + 1, y + h - 5);// a point
2080: for (int i = 0, j = 0; i < w / 2 + 1; i++, j = j + 2) {// bottom
2081: g.drawLine(x + 2 + j, y + h - 4 + i, x + 3
2082: + j, y + h - 4 + i);
2083: }
2084: }
2085: }
2086: }
2087: break;
2088: case RIGHT:
2089: if (isSelected) {
2090: g.setColor(_selectColor1);
2091: g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 5);// right
2092: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// top
2093: g.drawLine(x + w - 2 - j, y + 4 - i, x + w - 3 - j,
2094: y + 4 - i);
2095: }
2096: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// bottom
2097: g.drawLine(x + w - 1 - j, y + h - 4 + i, x + w - 2
2098: - j, y + h - 4 + i);
2099: }
2100:
2101: if (_selectColor2 != null) {
2102: g.setColor(_selectColor2);
2103: g.drawLine(x + w - 2, y + 6, x + w - 2, y + h - 6);// right
2104: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// top
2105: g.drawLine(x + w - 2 - j, y + 5 - i, x + w - 3
2106: - j, y + 5 - i);
2107: }
2108: }
2109:
2110: if (_selectColor3 != null) {
2111: g.setColor(_selectColor3);
2112: g.drawLine(x + w - 2, y + h - 5, x + w - 2, y + h
2113: - 5);// a point
2114: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// bottom
2115: g.drawLine(x + w - 3 - j, y + h - 4 + i, x + w
2116: - 4 - j, y + h - 4 + i);
2117: }
2118: }
2119: } else {
2120: if (tabIndex == 0) {
2121: g.setColor(_unselectColor1);
2122: g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 5);// right
2123: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// top
2124: g.drawLine(x + w - 2 - j, y + 4 - i, x + w - 3
2125: - j, y + 4 - i);
2126: }
2127:
2128: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// bottom
2129: g.drawLine(x + w - 1 - j, y + h - 4 + i, x + w
2130: - 2 - j, y + h - 4 + i);
2131: }
2132:
2133: if (_unselectColor2 != null) {
2134: g.setColor(_unselectColor2);
2135: g.drawLine(x + w - 2, y + 6, x + w - 2, y + h
2136: - 6);// right
2137:
2138: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// top
2139: g.drawLine(x + w - 2 - j, y + 5 - i, x + w
2140: - 3 - j, y + 5 - i);
2141: }
2142: }
2143:
2144: if (_unselectColor3 != null) {
2145: g.setColor(_unselectColor3);
2146:
2147: g.drawLine(x + w - 2, y + h - 5, x + w - 2, y
2148: + h - 5);// a
2149: // point
2150:
2151: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// bottom
2152: g.drawLine(x + w - 3 - j, y + h - 4 + i, x
2153: + w - 4 - j, y + h - 4 + i);
2154: }
2155: }
2156: } else if (tabIndex == _tabPane.getSelectedIndex() - 1) {
2157: g.setColor(_unselectColor1);
2158: g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 5);// right
2159: for (int i = 0, j = 0; i < 4; i++, j += 2) {// top
2160: g.drawLine(x + w - 2 - j, y + 4 - i, x + w - 3
2161: - j, y + 4 - i);
2162: }
2163:
2164: for (int i = 0, j = 0; i < 5; i++, j += 2) {// bottom
2165: g.drawLine(x + w - 1 - j, y + h - 4 + i, x + w
2166: - 2 - j, y + h - 4 + i);
2167: }
2168:
2169: if (_unselectColor2 != null) {
2170: g.setColor(_unselectColor2);
2171: g.drawLine(x + w - 2, y + 6, x + w - 2, y + h
2172: - 6);// right
2173: for (int i = 0, j = 0; i < 4; i++, j += 2) {// top
2174: g.drawLine(x + w - 2 - j, y + 5 - i, x + w
2175: - 3 - j, y + 5 - i);
2176: }
2177:
2178: }
2179:
2180: if (_unselectColor3 != null) {
2181: g.setColor(_unselectColor3);
2182:
2183: g.drawLine(x + w - 2, y + h - 5, x + w - 2, y
2184: + h - 5);// a point
2185:
2186: for (int i = 0, j = 0; i < 5; i++, j += 2) {// bottom
2187: g.drawLine(x + w - 3 - j, y + h - 4 + i, x
2188: + w - 4 - j, y + h - 4 + i);
2189: }
2190: }
2191: } else if (tabIndex != _tabPane.getSelectedIndex() - 1) {
2192: g.setColor(_unselectColor1);
2193: g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 5);// right
2194: for (int i = 0, j = 0; i < 4; i++, j += 2) {// top
2195: g.drawLine(x + w - 2 - j, y + 4 - i, x + w - 3
2196: - j, y + 4 - i);
2197: }
2198:
2199: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// bottom
2200: g.drawLine(x + w - 1 - j, y + h - 4 + i, x + w
2201: - 2 - j, y + h - 4 + i);
2202: }
2203:
2204: if (_unselectColor2 != null) {
2205: g.setColor(_unselectColor2);
2206: g.drawLine(x + w - 2, y + 6, x + w - 2, y + h
2207: - 6);// right
2208: for (int i = 0, j = 0; i < 4; i++, j += 2) {// top
2209: g.drawLine(x + w - 2 - j, y + 5 - i, x + w
2210: - 3 - j, y + 5 - i);
2211: }
2212: }
2213:
2214: if (_unselectColor3 != null) {
2215: g.setColor(_unselectColor3);
2216: g.drawLine(x + w - 2, y + h - 5, x + w - 2, y
2217: + h - 5);// a point
2218: for (int i = 0, j = 0; i < w / 2 + 1; i++, j += 2) {// bottom
2219: g.drawLine(x + w - 3 - j, y + h - 4 + i, x
2220: + w - 4 - j, y + h - 4 + i);
2221: }
2222: }
2223: }
2224: }
2225: break;
2226: case BOTTOM:
2227: if (isSelected) {
2228: g.setColor(_selectColor1);
2229: g.drawLine(x + 5, y + h - 1, x + w - 5, y + h - 1);// bottom
2230: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// left
2231: g.drawLine(x + 4 - i, y + h - 2 - j, x + 4 - i, y
2232: + h - 3 - j);
2233: }
2234:
2235: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2236: g.drawLine(x + w - 4 - 1 + i, y + h - 1 - j, x + w
2237: - 4 - 1 + i, y + h - 2 - j);
2238: }
2239:
2240: if (_selectColor2 != null) {
2241: g.setColor(_selectColor2);
2242:
2243: g.drawLine(x + 5, y + h - 3, x + 5, y + h - 3);// bottom
2244:
2245: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// left
2246: g.drawLine(x + 4 - i, y + h - 4 - j, x + 4 - i,
2247: y + h - 5 - j);
2248: }
2249:
2250: }
2251:
2252: if (_selectColor3 != null) {
2253: g.setColor(_selectColor3);
2254: g.drawLine(x + 5, y + h - 2, x + w - 6, y + h - 2);// a point
2255: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2256: g.drawLine(x + w - 5 + i, y + h - 3 - j, x + w
2257: - 5 + i, y + h - 4 - j);
2258: }
2259: }
2260: } else {
2261: if (tabIndex == 0) {
2262: g.setColor(_unselectColor1);
2263: g.drawLine(x + 5, y + h - 1, x + w - 5, y + h - 1);// bottom
2264: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// left
2265: g.drawLine(x + 4 - i, y + h - 2 - j, x + 4 - i,
2266: y + h - 3 - j);
2267: }
2268:
2269: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2270: g.drawLine(x + w - 4 - 1 + i, y + h - 1 - j, x
2271: + w - 4 - 1 + i, y + h - 2 - j);
2272: }
2273:
2274: if (_unselectColor2 != null) {
2275: g.setColor(_unselectColor2);
2276: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// left
2277: g.drawLine(x + 5 - i, y + h - 2 - j, x + 5
2278: - i, y + h - 3 - j);
2279: }
2280: }
2281:
2282: if (_unselectColor3 != null) {
2283: g.setColor(_unselectColor3);
2284: g.drawLine(x + w - 6, y + h - 2, x + w - 6, y
2285: + h - 2);// a point
2286: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2287: g.drawLine(x + w - 5 + i, y + h - 3 - j, x
2288: + w - 5 + i, y + h - 4 - j);
2289: }
2290: }
2291: } else if (tabIndex == _tabPane.getSelectedIndex() - 1) {
2292: g.setColor(_unselectColor1);
2293: g.drawLine(x + 5, y + h - 1, x + w - 6, y + h - 1);// bottom
2294: for (int i = 0, j = 0; i < 5; i++, j += 2) {// left
2295: g.drawLine(x + 4 - i, y + h - 2 - j, x + 4 - i,
2296: y + h - 3 - j);
2297: }
2298: for (int i = 0, j = 0; i < 5; i++, j += 2) {// right
2299: g.drawLine(x + w - 5 + i, y + h - 1 - j, x + w
2300: - 5 + i, y + h - 2 - j);
2301: }
2302:
2303: if (_unselectColor2 != null) {
2304: g.setColor(_unselectColor2);
2305: for (int i = 0, j = 0; i < 5; i++, j += 2) {// left
2306: g.drawLine(x + 5 - i, y + h - 2 - j, x + 5
2307: - i, y + h - 3 - j);
2308: }
2309: }
2310:
2311: if (_unselectColor3 != null) {
2312: g.setColor(_unselectColor3);
2313: g.drawLine(x + w - 6, y + h - 2, x + w - 6, y
2314: + h - 2);// a point
2315: for (int i = 0, j = 0; i < 5; i++, j += 2) {// right
2316: g.drawLine(x + w - 5 + i, y + h - 3 - j, x
2317: + w - 5 + i, y + h - 4 - j);
2318: }
2319: }
2320: } else if (tabIndex != _tabPane.getSelectedIndex() - 1) {
2321: g.setColor(_unselectColor1);
2322: g.drawLine(x + 5, y + h - 1, x + w - 6, y + h - 1);// bottom
2323: for (int i = 0, j = 0; i < 5; i++, j += 2) {// left
2324: g.drawLine(x + 4 - i, y + h - 2 - j, x + 4 - i,
2325: y + h - 3 - j);
2326: }
2327:
2328: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2329: g.drawLine(x + w - 5 + i, y + h - 1 - j, x + w
2330: - 5 + i, y + h - 2 - j);
2331: }
2332:
2333: if (_unselectColor2 != null) {
2334: g.setColor(_unselectColor2);
2335: for (int i = 0, j = 0; i < 5; i++, j += 2) {// left
2336: g.drawLine(x + 5 - i, y + h - 2 - j, x + 5
2337: - i, y + h - 3 - j);
2338: }
2339: }
2340:
2341: if (_unselectColor3 != null) {
2342: g.setColor(_unselectColor3);
2343: g.drawLine(x + w - 6, y + h - 2, x + w - 6, y
2344: + h - 2);// a point
2345: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2346: g.drawLine(x + w - 5 + i, y + h - 3 - j, x
2347: + w - 5 + i, y + h - 4 - j);
2348: }
2349: }
2350: }
2351: }
2352: break;
2353: case TOP:
2354: default:
2355: if (isSelected) {
2356: g.setColor(_selectColor1);
2357: g.drawLine(x + 5, y, x + w - 5, y);// top
2358: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// left
2359: g.drawLine(x + 4 - i, y + 1 + j, x + 4 - i, y + 2
2360: + j);
2361: }
2362: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2363: g.drawLine(x + w - 4 - 1 + i, y + j, x + w - 4 - 1
2364: + i, y + 1 + j);
2365: }
2366:
2367: if (_selectColor2 != null) {
2368: g.setColor(_selectColor2);
2369: g.drawLine(x + 6, y + 1, x + w - 7, y + 1);// top
2370: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// left
2371: g.drawLine(x + 5 - i, y + 1 + j, x + 5 - i, y
2372: + 2 + j);
2373: }
2374: }
2375:
2376: if (_selectColor3 != null) {
2377: g.setColor(_selectColor3);
2378: g.drawLine(x + w - 6, y + 1, x + w - 6, y + 1);// a point
2379: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2380: g.drawLine(x + w - 5 + i, y + 2 + j, x + w - 5
2381: + i, y + 3 + j);
2382: }
2383: }
2384: } else {
2385: if (tabIndex == 0) {
2386: g.setColor(_unselectColor1);
2387: g.drawLine(x + 5, y, x + w - 5, y);// top
2388: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// left
2389: g.drawLine(x + 4 - i, y + 1 + j, x + 4 - i, y
2390: + 2 + j);
2391: }
2392: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2393: g.drawLine(x + w - 4 - 1 + i, y + j, x + w - 4
2394: - 1 + i, y + 1 + j);
2395: }
2396: if (_unselectColor2 != null) {
2397: g.setColor(_unselectColor2);
2398: g.drawLine(x + 6, y + 1, x + w - 7, y + 1);// top
2399: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// left
2400: g.drawLine(x + 5 - i, y + 1 + j, x + 5 - i,
2401: y + 2 + j);
2402: }
2403: }
2404: if (_unselectColor3 != null) {
2405: g.setColor(_unselectColor3);
2406: g.drawLine(x + w - 6, y + 1, x + w - 6, y + 1);// a point
2407: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2408: g.drawLine(x + w - 5 + i, y + 2 + j, x + w
2409: - 5 + i, y + 3 + j);
2410: }
2411: }
2412: } else if (tabIndex == _tabPane.getSelectedIndex() - 1) {
2413: g.setColor(_unselectColor1);
2414: g.drawLine(x + 5, y, x + w - 5, y);// top
2415: for (int i = 0, j = 0; i < 5; i++, j += 2) {// left
2416: g.drawLine(x + 4 - i, y + 1 + j, x + 4 - i, y
2417: + 2 + j);
2418: }
2419: for (int i = 0, j = 0; i < 5; i++, j += 2) {// right
2420: g.drawLine(x + w - 4 - 1 + i, y + j, x + w - 4
2421: - 1 + i, y + 1 + j);
2422: }
2423:
2424: if (_unselectColor2 != null) {
2425: g.setColor(_unselectColor2);
2426: g.drawLine(x + 6, y + 1, x + w - 7, y + 1);// top
2427: for (int i = 0, j = 0; i < 5; i++, j += 2) {// left
2428: g.drawLine(x + 5 - i, y + 1 + j, x + 5 - i,
2429: y + 2 + j);
2430: }
2431: }
2432: if (_unselectColor3 != null) {
2433: g.setColor(_unselectColor3);
2434: g.drawLine(x + w - 6, y + 1, x + w - 6, y + 1);// a point
2435: for (int i = 0, j = 0; i < 5; i++, j += 2) {// right
2436: g.drawLine(x + w - 5 + i, y + 2 + j, x + w
2437: - 5 + i, y + 3 + j);
2438: }
2439: }
2440: } else if (tabIndex != _tabPane.getSelectedIndex() - 1) {
2441: g.setColor(_unselectColor1);
2442: g.drawLine(x + 5, y, x + w - 5, y);// top
2443: for (int i = 0, j = 0; i < 5; i++, j += 2) {// left
2444: g.drawLine(x + 4 - i, y + 1 + j, x + 4 - i, y
2445: + 2 + j);
2446: }
2447: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2448: g.drawLine(x + w - 4 - 1 + i, y + j, x + w - 4
2449: - 1 + i, y + 1 + j);
2450: }
2451: if (_unselectColor2 != null) {
2452: g.setColor(_unselectColor2);
2453: g.drawLine(x + 6, y + 1, x + w - 7, y + 1);// top
2454: for (int i = 0, j = 0; i < 5; i++, j += 2) {// left
2455: g.drawLine(x + 5 - i, y + 1 + j, x + 5 - i,
2456: y + 2 + j);
2457: }
2458: }
2459:
2460: if (_unselectColor3 != null) {
2461: g.setColor(_unselectColor3);
2462: g.drawLine(x + w - 6, y + 1, x + w - 6, y + 1);// a point
2463: for (int i = 0, j = 0; i < h / 2 + 1; i++, j += 2) {// right
2464: g.drawLine(x + w - 5 + i, y + 2 + j, x + w
2465: - 5 + i, y + 3 + j);
2466: }
2467: }
2468: }
2469: }
2470: }
2471: }
2472:
2473: protected void paintWindowsTabBorder(Graphics g, int tabPlacement,
2474: int tabIndex, int x, int y, int w, int h, boolean isSelected) {
2475: int colorTheme = getColorTheme();
2476: switch (tabPlacement) {
2477: case LEFT:
2478: if (colorTheme == JideTabbedPane.COLOR_THEME_OFFICE2003
2479: || colorTheme == JideTabbedPane.COLOR_THEME_WIN2K) {
2480: if (isSelected) {
2481: g.setColor(_selectColor1);
2482: g.drawLine(x - 2, y + 1, x - 2, y + h - 1);// left
2483: g.drawLine(x - 1, y, x - 1, y);// top arc
2484: g.drawLine(x, y - 1, x + w - 1, y - 1);// top
2485:
2486: g.setColor(_selectColor2);
2487: g.drawLine(x - 1, y + h, x - 1, y + h);// bottom arc
2488: g.drawLine(x, y + h + 1, x, y + h + 1);// bottom arc
2489: g.drawLine(x + 1, y + h, x + w - 1, y + h);// bottom
2490:
2491: g.setColor(_selectColor3);
2492: g.drawLine(x, y + h, x, y + h);// bottom arc
2493: g.drawLine(x + 1, y + h + 1, x + w - 1, y + h + 1);// bottom
2494: } else {
2495: if (tabIndex > _tabPane.getSelectedIndex()) {
2496: g.setColor(_unselectColor1);
2497: g.drawLine(x, y + 2, x, y + h - 3);// left
2498: g.drawLine(x + 1, y + 1, x + 1, y + 1);// top arc
2499: g.drawLine(x + 2, y, x + w - 1, y);// top
2500:
2501: g.setColor(_unselectColor2);
2502: g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);// bottom arc
2503: g.drawLine(x + 2, y + h - 1, x + 2, y + h - 1);// bottom arc
2504: g.drawLine(x + 3, y + h - 2, x + w - 1, y + h
2505: - 2);// bottom
2506:
2507: g.setColor(_unselectColor3);
2508: g.drawLine(x + 2, y + h - 2, x + 2, y + h - 2);// bottom arc
2509: g.drawLine(x + 3, y + h - 1, x + w - 1, y + h
2510: - 1);// bottom
2511: } else if (tabIndex < _tabPane.getSelectedIndex()) {
2512: g.setColor(_unselectColor1);
2513: g.drawLine(x, y + 3, x, y + h - 2);// left
2514: g.drawLine(x + 1, y + 2, x + 1, y + 2);// top arc
2515: g.drawLine(x + 2, y + 1, x + w - 1, y + 1);// top
2516:
2517: g.setColor(_unselectColor2);
2518: g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);// bottom arc
2519: g.drawLine(x + 2, y + h, x + 2, y + h);// bottom arc
2520: g.drawLine(x + 3, y + h - 1, x + w - 1, y + h
2521: - 1);// bottom
2522:
2523: g.setColor(_unselectColor3);
2524: g.drawLine(x + 2, y + h - 1, x + 2, y + h - 1);// bottom arc
2525: g.drawLine(x + 3, y + h, x + w - 1, y + h);// bottom
2526: }
2527: }
2528: } else {
2529: if (isSelected) {
2530: g.setColor(_selectColor1);
2531: g.drawLine(x - 2, y + 1, x - 2, y + h - 1);// left
2532: g.drawLine(x - 1, y, x - 1, y);// top arc
2533: g.drawLine(x, y - 1, x, y - 1);// top arc
2534: g.drawLine(x - 1, y + h, x - 1, y + h);// bottom arc
2535: g.drawLine(x, y + h + 1, x, y + h + 1);// bottom arc
2536:
2537: g.setColor(_selectColor2);
2538: g.drawLine(x - 1, y + 1, x - 1, y + h - 1);// left
2539: g.drawLine(x, y, x, y + h);// left
2540:
2541: g.setColor(_selectColor3);
2542: g.drawLine(x + 1, y - 2, x + w - 1, y - 2);// top
2543: g.drawLine(x + 1, y + h + 2, x + w - 1, y + h + 2);// bottom
2544: } else {
2545: if (tabIndex > _tabPane.getSelectedIndex()) {
2546: g.setColor(_unselectColor1);
2547: g.drawLine(x, y + 2, x, y + h - 4);// left
2548: g.drawLine(x + 1, y + 1, x + 1, y + 1);// top arc
2549: g.drawLine(x + 2, y, x + w - 1, y);// top
2550: g.drawLine(x + 1, y + h - 3, x + 1, y + h - 3);// bottom arc
2551: g.drawLine(x + 2, y + h - 2, x + w - 1, y + h
2552: - 2);// bottom
2553: } else if (tabIndex < _tabPane.getSelectedIndex()) {
2554: g.setColor(_unselectColor1);
2555: g.drawLine(x, y + 4, x, y + h - 2);// left
2556: g.drawLine(x + 1, y + 3, x + 1, y + 3);// top arc
2557: g.drawLine(x + 2, y + 2, x + w - 1, y + 2);// top
2558: g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);// bottom arc
2559: g.drawLine(x + 2, y + h, x + w - 1, y + h);// bottom
2560: }
2561: }
2562: }
2563: break;
2564: case RIGHT:
2565: if (colorTheme == JideTabbedPane.COLOR_THEME_OFFICE2003
2566: || colorTheme == JideTabbedPane.COLOR_THEME_WIN2K) {
2567: if (isSelected) {
2568: g.setColor(_selectColor1);
2569: g.drawLine(x + w - 1, y - 1, x, y - 1);// top
2570:
2571: g.setColor(_selectColor2);
2572: g.drawLine(x + w, y + 1, x + w, y + h - 1);// right
2573: g.drawLine(x + w - 1, y + h, x, y + h);// bottom
2574:
2575: g.setColor(_selectColor3);
2576: g.drawLine(x + w, y, x + w, y);// top arc
2577: g.drawLine(x + w + 1, y + 1, x + w + 1, y + h - 1);// right
2578: g.drawLine(x + w, y + h, x + w, y + h);// bottom arc
2579: g.drawLine(x + w - 1, y + h + 1, x, y + h + 1);// bottom
2580: } else {
2581: if (tabIndex > _tabPane.getSelectedIndex()) {
2582: g.setColor(_unselectColor1);
2583: g.drawLine(x + w - 3, y, x, y);// top
2584:
2585: g.setColor(_unselectColor2);
2586: g.drawLine(x + w - 2, y + 2, x + w - 2, y + h
2587: - 3);// right
2588: g.drawLine(x + w - 3, y + h - 2, x, y + h - 2);// bottom
2589:
2590: g.setColor(_unselectColor3);
2591: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);// top arc
2592: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h
2593: - 3);// right
2594: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y
2595: + h - 2);// bottom arc
2596: g.drawLine(x + w - 3, y + h - 1, x, y + h - 1);// bottom
2597: } else if (tabIndex < _tabPane.getSelectedIndex()) {
2598: g.setColor(_unselectColor1);
2599: g.drawLine(x + w - 3, y + 1, x, y + 1);// top
2600:
2601: g.setColor(_unselectColor2);
2602: g.drawLine(x + w - 2, y + 3, x + w - 2, y + h
2603: - 2);// right
2604: g.drawLine(x + w - 3, y + h - 1, x, y + h - 1);// bottom
2605:
2606: g.setColor(_unselectColor3);
2607: g.drawLine(x + w - 2, y + 2, x + w - 2, y + 2);// top arc
2608: g.drawLine(x + w - 1, y + 3, x + w - 1, y + h
2609: - 2);// right
2610: g.drawLine(x + w - 2, y + h - 1, x + w - 2, y
2611: + h - 1);// bottom arc
2612: g.drawLine(x + w - 3, y + h, x, y + h);// bottom
2613: }
2614: }
2615: } else {
2616: if (isSelected) {
2617: g.setColor(_selectColor1);
2618: g.drawLine(x + w + 1, y + 1, x + w + 1, y + h - 1);// right
2619: g.drawLine(x + w, y, x + w, y);// top arc
2620: g.drawLine(x + w - 1, y - 1, x + w - 1, y - 1);// top arc
2621: g.drawLine(x + w, y + h, x + w, y + h);// bottom arc
2622: g.drawLine(x + w - 1, y + h + 1, x + w - 1, y + h
2623: + 1);// bottom arc
2624:
2625: g.setColor(_selectColor2);
2626: g.drawLine(x + w, y + 1, x + w, y + h - 1);// right
2627: g.drawLine(x + w - 1, y, x + w - 1, y + h);// right
2628:
2629: g.setColor(_selectColor3);
2630: g.drawLine(x + w - 2, y - 2, x, y - 2);// top
2631: g.drawLine(x + w - 2, y + h + 2, x, y + h + 2);// bottom
2632: } else {
2633: if (tabIndex > _tabPane.getSelectedIndex()) {
2634: g.setColor(_unselectColor1);
2635: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h
2636: - 4);// right
2637: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);// top arc
2638: g.drawLine(x + w - 2, y + h - 3, x + w - 2, y
2639: + h - 3);// bottom arc
2640: g.drawLine(x + w - 3, y, x, y);// top
2641: g.drawLine(x + w - 3, y + h - 2, x, y + h - 2);// bottom
2642: } else if (tabIndex < _tabPane.getSelectedIndex()) {
2643: g.setColor(_unselectColor1);
2644: g.drawLine(x + w - 1, y + 4, x + w - 1, y + h
2645: - 2);// right
2646: g.drawLine(x + w - 2, y + 3, x + w - 2, y + 3);// top arc
2647: g.drawLine(x + w - 3, y + 2, x, y + 2);// top
2648: g.drawLine(x + w - 2, y + h - 1, x + w - 2, y
2649: + h - 1);// bottom arc
2650: g.drawLine(x + w - 3, y + h, x, y + h);// bottom
2651: }
2652: }
2653: }
2654: break;
2655: case BOTTOM:
2656: if (colorTheme == JideTabbedPane.COLOR_THEME_OFFICE2003
2657: || colorTheme == JideTabbedPane.COLOR_THEME_WIN2K) {
2658: if (isSelected) {
2659: g.setColor(_selectColor1);
2660: g.drawLine(x, y + h, x, y + h);// left arc
2661: g.drawLine(x - 1, y + h - 1, x - 1, y);// left
2662:
2663: g.setColor(_selectColor2);
2664: g.drawLine(x + 1, y + h, x + w - 2, y + h);// bottom
2665: g.drawLine(x + w - 1, y + h - 1, x + w - 1, y - 1);// right
2666:
2667: g.setColor(_selectColor3);
2668: g.drawLine(x + 1, y + h + 1, x + w - 2, y + h + 1);// bottom
2669: g.drawLine(x + w - 1, y + h, x + w - 1, y + h);// right arc
2670: g.drawLine(x + w, y + h - 1, x + w, y - 1);// right
2671: } else {
2672: if (tabIndex > _tabPane.getSelectedIndex()) {
2673: g.setColor(_unselectColor1);
2674: g.drawLine(x, y + h - 2, x, y + h - 2);// left arc
2675: g.drawLine(x - 1, y + h - 3, x - 1, y);// left
2676:
2677: g.setColor(_unselectColor2);
2678: g.drawLine(x + 1, y + h - 2, x + w - 4, y + h
2679: - 2);// bottom
2680: g.drawLine(x + w - 3, y + h - 3, x + w - 3,
2681: y - 1);// right
2682:
2683: g.setColor(_unselectColor3);
2684: g.drawLine(x + 1, y + h - 1, x + w - 4, y + h
2685: - 1);// bottom
2686: g.drawLine(x + w - 3, y + h - 2, x + w - 3, y
2687: + h - 2);// right arc
2688: g.drawLine(x + w - 2, y + h - 3, x + w - 2,
2689: y - 1);// right
2690: } else if (tabIndex < _tabPane.getSelectedIndex()) {
2691: g.setColor(_unselectColor1);
2692: g.drawLine(x + 2, y + h - 2, x + 2, y + h - 2);// left arc
2693: g.drawLine(x + 1, y + h - 3, x + 1, y);// left
2694:
2695: g.setColor(_unselectColor2);
2696: g.drawLine(x + 3, y + h - 2, x + w - 2, y + h
2697: - 2);// bottom
2698: g.drawLine(x + w - 1, y + h - 3, x + w - 1, y);// right
2699:
2700: g.setColor(_unselectColor3);
2701: g.drawLine(x + 3, y + h - 1, x + w - 2, y + h
2702: - 1);// bottom
2703: g.drawLine(x + w - 1, y + h - 2, x + w - 1, y
2704: + h - 2);// right arc
2705: g.drawLine(x + w, y + h - 3, x + w, y);// right
2706: }
2707: }
2708: } else {
2709: if (isSelected) {
2710: g.setColor(_selectColor1);
2711: g.drawLine(x + 1, y + h + 1, x + w, y + h + 1);// bottom
2712: g.drawLine(x, y + h, x, y + h);// right arc
2713: g.drawLine(x - 1, y + h - 1, x - 1, y + h - 1);// right arc
2714: g.drawLine(x + w + 1, y + h, x + w + 1, y + h);// left arc
2715: g.drawLine(x + w + 2, y + h - 1, x + w + 2, y + h
2716: - 1);// left arc
2717:
2718: g.setColor(_selectColor2);
2719: g.drawLine(x + 1, y + h, x + w, y + h);// bottom
2720: g.drawLine(x, y + h - 1, x + w + 1, y + h - 1);// bottom
2721:
2722: g.setColor(_selectColor3);
2723: g.drawLine(x - 1, y + h - 2, x - 1, y);// left
2724: g.drawLine(x + w + 2, y + h - 2, x + w + 2, y);// right
2725: } else {
2726: if (tabIndex > _tabPane.getSelectedIndex()) {
2727: g.setColor(_unselectColor1);
2728: g.drawLine(x + 3, y + h - 1, x + w - 3, y + h
2729: - 1);// bottom
2730: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y
2731: + h - 2);// right arc
2732: g.drawLine(x + w - 1, y + h - 3, x + w - 1,
2733: y - 1);// right
2734: g.drawLine(x + 2, y + h - 2, x + 2, y + h - 2);// left arc
2735: g.drawLine(x + 1, y + h - 3, x + 1, y);// left
2736: } else if (tabIndex < _tabPane.getSelectedIndex()) {
2737: g.setColor(_unselectColor1);
2738: g.drawLine(x + 3, y + h - 1, x + w - 3, y + h
2739: - 1);// bottom
2740: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y
2741: + h - 2);// right arc
2742: g.drawLine(x + w - 1, y + h - 3, x + w - 1,
2743: y - 1);// right
2744: g.drawLine(x + 2, y + h - 2, x + 2, y + h - 2);// left arc
2745: g.drawLine(x + 1, y + h - 3, x + 1, y);// left
2746: }
2747: }
2748: }
2749: break;
2750: case TOP:
2751: default:
2752: if (colorTheme == JideTabbedPane.COLOR_THEME_OFFICE2003
2753: || colorTheme == JideTabbedPane.COLOR_THEME_WIN2K) {
2754: if (isSelected) {
2755: g.setColor(_selectColor1);
2756: g.drawLine(x, y - 1, x, y - 1); // left arc
2757: g.drawLine(x - 1, y, x - 1, y + h - 1);// left
2758: g.drawLine(x + 1, y - 2, x + w + 1, y - 2);// top
2759:
2760: g.setColor(_selectColor2);
2761: g.drawLine(x + w + 2, y - 1, x + w + 2, y + h - 1);// right
2762:
2763: g.setColor(_selectColor3);
2764: g.drawLine(x + w + 2, y - 1, x + w + 2, y - 1);// right arc
2765: g.drawLine(x + w + 3, y, x + w + 3, y + h - 1);// right
2766: } else {
2767: if (tabIndex > _tabPane.getSelectedIndex()) {
2768: g.setColor(_unselectColor1);
2769: g.drawLine(x + 2, y + 1, x + 2, y + 1); // left arc
2770: g.drawLine(x + 1, y + 2, x + 1, y + h - 1); // left
2771: g.drawLine(x + 3, y, x + w - 2, y); // top
2772:
2773: g.setColor(_unselectColor2);
2774: g.drawLine(x + w - 1, y + 1, x + w - 1, y + h
2775: - 1);// right
2776:
2777: g.setColor(_unselectColor3);
2778: g.drawLine(x + w - 1, y + 1, x + w - 1, y + 1);// right arc
2779: g.drawLine(x + w, y + 2, x + w, y + h - 1);// right
2780: } else if (tabIndex < _tabPane.getSelectedIndex()) {
2781: g.setColor(_unselectColor1);
2782: g.drawLine(x + 2, y + 1, x + 2, y + 1); // left arc
2783: g.drawLine(x + 1, y + 2, x + 1, y + h - 1); // left
2784: g.drawLine(x + 3, y, x + w - 2, y); // top
2785:
2786: g.setColor(_unselectColor2);
2787: g.drawLine(x + w - 1, y + 1, x + w - 1, y + h
2788: - 1);// right
2789:
2790: g.setColor(_unselectColor3);
2791: g.drawLine(x + w - 1, y + 1, x + w - 1, y + 1);// right arc
2792: g.drawLine(x + w, y + 2, x + w, y + h - 1);// right
2793: }
2794: }
2795: } else {
2796: if (isSelected) {
2797: g.setColor(_selectColor1);
2798: g.drawLine(x + 1, y - 2, x + w, y - 2); // top
2799: g.drawLine(x, y - 1, x, y - 1); // left arc
2800: g.drawLine(x - 1, y, x - 1, y); // left arc
2801: g.drawLine(x + w + 1, y - 1, x + w + 1, y - 1);// right arc
2802: g.drawLine(x + w + 2, y, x + w + 2, y);// right arc
2803:
2804: g.setColor(_selectColor2);
2805: g.drawLine(x + 1, y - 1, x + w, y - 1);// top
2806: g.drawLine(x, y, x + w + 1, y);// top
2807:
2808: g.setColor(_selectColor3);
2809: g.drawLine(x - 1, y + 1, x - 1, y + h - 1);// left
2810: g.drawLine(x + w + 2, y + 1, x + w + 2, y + h - 1);// right
2811: } else {
2812: if (tabIndex > _tabPane.getSelectedIndex()) {
2813: g.setColor(_unselectColor1);
2814: g.drawLine(x + 1, y + 2, x + 1, y + h - 1); // left
2815: g.drawLine(x + 2, y + 1, x + 2, y + 1); // left arc
2816: g.drawLine(x + 3, y, x + w - 3, y); // top
2817: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);// right arc
2818: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h
2819: - 1);// right
2820: } else if (tabIndex < _tabPane.getSelectedIndex()) {
2821: g.setColor(_unselectColor1);
2822: g.drawLine(x + 1, y + 2, x + 1, y + h - 1); // left
2823: g.drawLine(x + 2, y + 1, x + 2, y + 1); // left arc
2824: g.drawLine(x + 3, y, x + w - 3, y); // top
2825: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);// right arc
2826: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h
2827: - 1);// right
2828: }
2829: }
2830: }
2831: }
2832: }
2833:
2834: protected void paintTabBorderMouseOver(Graphics g,
2835: int tabPlacement, int tabIndex, int x, int y, int w, int h,
2836: boolean isSelected) {
2837: if (getTabShape() == JideTabbedPane.SHAPE_WINDOWS) {
2838: switch (tabPlacement) {
2839: case LEFT:
2840: if (tabIndex > _tabPane.getSelectedIndex()) {
2841: y = y - 2;
2842: }
2843:
2844: g.setColor(_selectColor1);
2845: g.drawLine(x, y + 4, x, y + h - 2);
2846: g.drawLine(x + 1, y + 3, x + 1, y + 3);
2847: g.drawLine(x + 2, y + 2, x + 2, y + 2);
2848: g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);
2849: g.drawLine(x + 2, y + h, x + 2, y + h);
2850:
2851: g.setColor(_selectColor2);
2852: g.drawLine(x + 1, y + 4, x + 1, y + h - 2);
2853: g.drawLine(x + 2, y + 3, x + 2, y + h - 1);
2854: break;
2855: case RIGHT:
2856: if (tabIndex > _tabPane.getSelectedIndex()) {
2857: y = y - 2;
2858: }
2859:
2860: g.setColor(_selectColor1);
2861: g.drawLine(x + w - 1, y + 4, x + w - 1, y + h - 2);
2862: g.drawLine(x + w - 2, y + 3, x + w - 2, y + 3);
2863: g.drawLine(x + w - 3, y + 2, x + w - 3, y + 2);
2864: g.drawLine(x + w - 2, y + h - 1, x + w - 2, y + h - 1);
2865: g.drawLine(x + w - 3, y + h, x + w - 3, y + h);
2866:
2867: g.setColor(_selectColor2);
2868: g.drawLine(x + w - 2, y + 4, x + w - 2, y + h - 2);
2869: g.drawLine(x + w - 3, y + 3, x + w - 3, y + h - 1);
2870: break;
2871: case BOTTOM:
2872: g.setColor(_selectColor1);
2873: g.drawLine(x + 3, y + h - 1, x + w - 3, y + h - 1);
2874: g.drawLine(x + 2, y + h - 2, x + 2, y + h - 2);
2875: g.drawLine(x + 1, y + h - 3, x + 1, y + h - 3);
2876: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h - 2);
2877: g.drawLine(x + w - 1, y + h - 3, x + w - 1, y + h - 3);
2878:
2879: g.setColor(_selectColor2);
2880: g.drawLine(x + 3, y + h - 2, x + w - 3, y + h - 2);
2881: g.drawLine(x + 2, y + h - 3, x + w - 2, y + h - 3);
2882: break;
2883: case TOP:
2884: default:
2885: g.setColor(_selectColor1);
2886: g.drawLine(x + 3, y, x + w - 3, y);
2887: g.drawLine(x + 2, y + 1, x + 2, y + 1);
2888: g.drawLine(x + 1, y + 2, x + 1, y + 2);
2889: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
2890: g.drawLine(x + w - 1, y + 2, x + w - 1, y + 2);
2891:
2892: g.setColor(_selectColor2);
2893: g.drawLine(x + 3, y + 1, x + w - 3, y + 1);
2894: g.drawLine(x + 2, y + 2, x + w - 2, y + 2);
2895: }
2896: } else if (getTabShape() == JideTabbedPane.SHAPE_WINDOWS_SELECTED) {
2897: switch (tabPlacement) {
2898: case LEFT:
2899: if (getColorTheme() == JideTabbedPane.COLOR_THEME_WINXP) {
2900: if (tabIndex > _tabPane.getSelectedIndex()) {
2901: y -= 2;
2902: }
2903:
2904: g.setColor(_selectColor1);
2905: g.drawLine(x, y + 4, x, y + h - 2);
2906: g.drawLine(x + 1, y + 3, x + 1, y + 3);
2907: g.drawLine(x + 2, y + 2, x + 2, y + 2);
2908: g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);
2909: g.drawLine(x + 2, y + h, x + 2, y + h);
2910:
2911: g.setColor(_selectColor2);
2912: g.drawLine(x + 1, y + 4, x + 1, y + h - 2);
2913: g.drawLine(x + 2, y + 3, x + 2, y + h - 1);
2914:
2915: g.setColor(_selectColor3);
2916: g.drawLine(x + 3, y + 2, x + w - 1, y + 2);
2917: g.drawLine(x + 3, y + h, x + w - 1, y + h);
2918: } else {
2919: if (tabIndex > _tabPane.getSelectedIndex()) {
2920: y = y - 1;
2921: }
2922: g.setColor(_selectColor1);
2923: g.drawLine(x, y + 3, x, y + h - 2);// left
2924: g.drawLine(x + 1, y + 2, x + 1, y + 2);// top arc
2925: g.drawLine(x + 2, y + 1, x + w - 1, y + 1);// top
2926:
2927: g.setColor(_selectColor2);
2928: g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);// bottom arc
2929: g.drawLine(x + 2, y + h, x + 2, y + h);// bottom arc
2930: g.drawLine(x + 3, y + h - 1, x + w - 1, y + h - 1);// bottom
2931:
2932: g.setColor(_selectColor3);
2933: g.drawLine(x + 2, y + h - 1, x + 2, y + h - 1);// bottom arc
2934: g.drawLine(x + 3, y + h, x + w - 1, y + h);// bottom
2935: }
2936: break;
2937: case RIGHT:
2938: if (getColorTheme() == JideTabbedPane.COLOR_THEME_WINXP) {
2939: if (tabIndex > _tabPane.getSelectedIndex()) {
2940: y = y - 2;
2941: }
2942:
2943: g.setColor(_selectColor1);
2944: g.drawLine(x + w - 1, y + 4, x + w - 1, y + h - 2);
2945: g.drawLine(x + w - 2, y + 3, x + w - 2, y + 3);
2946: g.drawLine(x + w - 3, y + 2, x + w - 3, y + 2);
2947: g.drawLine(x + w - 2, y + h - 1, x + w - 2, y + h
2948: - 1);
2949: g.drawLine(x + w - 3, y + h, x + w - 3, y + h);
2950:
2951: g.setColor(_selectColor2);
2952: g.drawLine(x + w - 2, y + 4, x + w - 2, y + h - 2);
2953: g.drawLine(x + w - 3, y + 3, x + w - 3, y + h - 1);
2954:
2955: g.setColor(_selectColor3);
2956: g.drawLine(x + w - 4, y + 2, x, y + 2);
2957: g.drawLine(x + w - 4, y + h, x, y + h);
2958: } else {
2959: if (tabIndex > _tabPane.getSelectedIndex()) {
2960: y = y - 1;
2961: }
2962:
2963: g.setColor(_selectColor3);
2964: g.drawLine(x + w - 1, y + 3, x + w - 1, y + h - 2);// right
2965: g.drawLine(x + w - 2, y + h - 1, x + w - 2, y + h
2966: - 1);// bottom arc
2967: g.drawLine(x + w - 3, y + h, x, y + h);// bottom
2968:
2969: g.setColor(_selectColor2);
2970: g.drawLine(x + w - 2, y + 3, x + w - 2, y + h - 2);// right
2971: g.drawLine(x + w - 3, y + h - 1, x, y + h - 1);// bottom
2972:
2973: g.setColor(_selectColor1);
2974: g.drawLine(x + w - 2, y + 2, x + w - 2, y + 2);// top arc
2975: g.drawLine(x + w - 3, y + 1, x, y + 1);// top
2976: }
2977: break;
2978: case BOTTOM:
2979: if (getColorTheme() == JideTabbedPane.COLOR_THEME_WINXP) {
2980: g.setColor(_selectColor1);
2981: g.drawLine(x + 3, y + h - 1, x + w - 3, y + h - 1);
2982: g.drawLine(x + 2, y + h - 2, x + 2, y + h - 2);
2983: g.drawLine(x + 1, y + h - 3, x + 1, y + h - 3);
2984: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h
2985: - 2);
2986: g.drawLine(x + w - 1, y + h - 3, x + w - 1, y + h
2987: - 3);
2988:
2989: g.setColor(_selectColor2);
2990: g.drawLine(x + 3, y + h - 2, x + w - 3, y + h - 2);
2991: g.drawLine(x + 2, y + h - 3, x + w - 2, y + h - 3);
2992:
2993: g.setColor(_selectColor3);
2994: g.drawLine(x + 1, y, x + 1, y + h - 4); // left
2995: g.drawLine(x + w - 1, y, x + w - 1, y + h - 4);// right
2996: } else {
2997: if (tabIndex > _tabPane.getSelectedIndex()) {
2998: x = x - 2;
2999: }
3000:
3001: g.setColor(_selectColor3);
3002: g.drawLine(x + 3, y + h - 1, x + w - 2, y + h - 1);// bottom
3003: g.drawLine(x + w - 1, y + h - 2, x + w - 1, y + h
3004: - 2);// right arc
3005: g.drawLine(x + w, y + h - 3, x + w, y);// right
3006:
3007: g.setColor(_selectColor1);
3008: g.drawLine(x + 2, y + h - 2, x + 2, y + h - 2);// left
3009: g.drawLine(x + 1, y + h - 3, x + 1, y);// left arc
3010:
3011: g.setColor(_selectColor2);
3012: g.drawLine(x + 3, y + h - 2, x + w - 2, y + h - 2);// bottom
3013: g.drawLine(x + w - 1, y + h - 3, x + w - 1, y);// right
3014: }
3015: break;
3016: case TOP:
3017: default:
3018: if (getColorTheme() == JideTabbedPane.COLOR_THEME_WINXP) {
3019: g.setColor(_selectColor1);
3020: g.drawLine(x + 3, y, x + w - 3, y);
3021: g.drawLine(x + 2, y + 1, x + 2, y + 1);
3022: g.drawLine(x + 1, y + 2, x + 1, y + 2);
3023: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
3024: g.drawLine(x + w - 1, y + 2, x + w - 1, y + 2);
3025:
3026: g.setColor(_selectColor2);
3027: g.drawLine(x + 3, y + 1, x + w - 3, y + 1);
3028: g.drawLine(x + 2, y + 2, x + w - 2, y + 2);
3029:
3030: g.setColor(_selectColor3);
3031: g.drawLine(x + 1, y + 3, x + 1, y + h - 1); // left
3032: g.drawLine(x + w - 1, y + 3, x + w - 1, y + h - 1);// right
3033: } else {
3034: if (tabIndex > _tabPane.getSelectedIndex()) {
3035: x = x - 1;
3036: }
3037: g.setColor(_selectColor1);
3038: g.drawLine(x + 2, y + 1, x + 2, y + 1); // left arc
3039: g.drawLine(x + 1, y + 2, x + 1, y + h - 1); // left
3040: g.drawLine(x + 3, y, x + w - 2, y); // top
3041:
3042: g.setColor(_selectColor2);
3043: g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);// right
3044:
3045: g.setColor(_selectColor3);
3046: g.drawLine(x + w - 1, y + 1, x + w - 1, y + 1);// right arc
3047: g.drawLine(x + w, y + 2, x + w, y + h - 1);// right
3048: }
3049: }
3050:
3051: }
3052: }
3053:
3054: protected void paintVsnetTabBorder(Graphics g, int tabPlacement,
3055: int tabIndex, int x, int y, int w, int h, boolean isSelected) {
3056: switch (tabPlacement) {
3057: case LEFT:
3058: if (isSelected) {
3059: g.setColor(_selectColor1);
3060: g.drawLine(x, y, x + w - 1, y);// top
3061: g.drawLine(x, y, x, y + h - 2);// left
3062:
3063: g.setColor(_selectColor2);
3064: g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);// bottom
3065: } else {
3066: g.setColor(_unselectColor1);
3067: if (tabIndex > _tabPane.getSelectedIndex()) {
3068: g.drawLine(x + 2, y + h - 2, x + w - 2, y + h - 2);// bottom
3069: } else if (tabIndex < _tabPane.getSelectedIndex()
3070: && tabIndex != 0) {
3071: g.drawLine(x + 2, y, x + w - 2, y);// top
3072: }
3073: }
3074: break;
3075: case RIGHT:
3076: if (isSelected) {
3077: g.setColor(_selectColor1);
3078: g.drawLine(x, y, x + w - 1, y);// top
3079:
3080: g.setColor(_selectColor2);
3081: g.drawLine(x + w - 1, y, x + w - 1, y + h - 2);// left
3082: g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);// bottom
3083: } else {
3084: g.setColor(_unselectColor1);
3085: if (tabIndex > _tabPane.getSelectedIndex()) {
3086: g.drawLine(x + 1, y + h - 2, x + w - 3, y + h - 2);// bottom
3087: } else if (tabIndex < _tabPane.getSelectedIndex()
3088: && tabIndex != 0) {
3089: g.drawLine(x + 1, y, x + w - 3, y);// top
3090: }
3091: }
3092: break;
3093: case BOTTOM:
3094: if (isSelected) {
3095: g.setColor(_selectColor1);
3096: g.drawLine(x, y, x, y + h - 1); // left
3097:
3098: g.setColor(_selectColor2);
3099: g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); // bottom
3100: g.drawLine(x + w - 1, y, x + w - 1, y + h - 2); // right
3101: } else {
3102: g.setColor(_unselectColor1);
3103: if (tabIndex > _tabPane.getSelectedIndex()) {
3104: g.drawLine(x + w - 2, y + 2, x + w - 2, y + h - 2); // right
3105: } else if (tabIndex < _tabPane.getSelectedIndex()
3106: && tabIndex != 0) {
3107: g.drawLine(x, y + 2, x, y + h - 2); // right
3108: }
3109: }
3110: break;
3111: case TOP:
3112: default:
3113: if (isSelected) {
3114: g.setColor(_selectColor1);
3115: g.drawLine(x, y + 1, x, y + h - 1); // left
3116: g.drawLine(x, y, x + w - 1, y); // top
3117:
3118: g.setColor(_selectColor2);
3119: g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); // right
3120: } else {
3121: g.setColor(_unselectColor1);
3122: if (tabIndex > _tabPane.getSelectedIndex()) {
3123: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 2); // right
3124: } else if (tabIndex < _tabPane.getSelectedIndex()
3125: && tabIndex != 0) {
3126: g.drawLine(x + 1, y + 2, x + 1, y + h - 2); // right
3127: }
3128: }
3129: }
3130:
3131: }
3132:
3133: protected void paintRoundedVsnetTabBorder(Graphics g,
3134: int tabPlacement, int tabIndex, int x, int y, int w, int h,
3135: boolean isSelected) {
3136: switch (tabPlacement) {
3137: case LEFT:
3138: if (isSelected) {
3139: g.setColor(_selectColor1);
3140: g.drawLine(x + 2, y, x + w - 1, y);// top
3141: g.drawLine(x + 1, y + 1, x + 1, y + 1);// top-left
3142: g.drawLine(x, y + 2, x, y + h - 3);// left
3143: g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);// bottom-left
3144: g.drawLine(x + 2, y + h - 1, x + w - 1, y + h - 1);// bottom
3145: } else {
3146: g.setColor(_unselectColor1);
3147: if (tabIndex > _tabPane.getSelectedIndex()) {
3148: g.drawLine(x + 2, y + h - 2, x + w - 2, y + h - 2);// bottom
3149: } else if (tabIndex < _tabPane.getSelectedIndex()
3150: && tabIndex != 0) {
3151: g.drawLine(x + 2, y + 1, x + w - 2, y + 1);// top
3152: }
3153: }
3154: break;
3155: case RIGHT:
3156: if (isSelected) {
3157: g.setColor(_selectColor1);
3158: g.drawLine(x, y, x + w - 3, y);// top
3159: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);// top-left
3160: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 3);// left
3161: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h - 2);// bottom-left
3162: g.drawLine(x, y + h - 1, x + w - 3, y + h - 1);// bottom
3163: } else {
3164: g.setColor(_unselectColor1);
3165: if (tabIndex > _tabPane.getSelectedIndex()) {
3166: g.drawLine(x + 1, y + h - 2, x + w - 3, y + h - 2);// bottom
3167: } else if (tabIndex < _tabPane.getSelectedIndex()
3168: && tabIndex != 0) {
3169: g.drawLine(x + 1, y + 1, x + w - 3, y + 1);// top
3170: }
3171: }
3172: break;
3173: case BOTTOM:
3174: if (isSelected) {
3175: g.setColor(_selectColor1);
3176: g.drawLine(x, y, x, y + h - 3); // left
3177: g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2); // bottom-left
3178: g.drawLine(x + 2, y + h - 1, x + w - 3, y + h - 1); // bottom
3179: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y + h - 2); // bottom-right
3180: g.drawLine(x + w - 1, y, x + w - 1, y + h - 3); // right
3181: } else {
3182: g.setColor(_unselectColor1);
3183: if (tabIndex > _tabPane.getSelectedIndex()) {
3184: g.drawLine(x + w - 2, y + 1, x + w - 2, y + h - 2); // right
3185: } else if (tabIndex < _tabPane.getSelectedIndex()
3186: && tabIndex != 0) {
3187: g.drawLine(x + 1, y + 1, x + 1, y + h - 2); // right
3188: }
3189: }
3190: break;
3191: case TOP:
3192: default:
3193: if (isSelected) {
3194: g.setColor(_selectColor1);
3195: g.drawLine(x, y + 2, x, y + h - 1); // left
3196: g.drawLine(x, y + 2, x + 2, y); // top-left
3197: g.drawLine(x + 2, y, x + w - 3, y); // top
3198: g.drawLine(x + w - 3, y, x + w - 1, y + 2); // top-left
3199: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 1); // right
3200: } else {
3201: g.setColor(_unselectColor1);
3202: if (tabIndex > _tabPane.getSelectedIndex()) {
3203: g.drawLine(x + w - 2, y + 2, x + w - 2, y + h - 2); // right
3204: } else if (tabIndex < _tabPane.getSelectedIndex()
3205: && tabIndex != 0) {
3206: g.drawLine(x + 1, y + 2, x + 1, y + h - 2); // right
3207: }
3208: }
3209: }
3210:
3211: }
3212:
3213: protected void paintFlatTabBorder(Graphics g, int tabPlacement,
3214: int tabIndex, int x, int y, int w, int h, boolean isSelected) {
3215: switch (tabPlacement) {
3216: case LEFT:
3217: if (isSelected) {
3218: g.setColor(_selectColor1);
3219: g.drawRect(x, y, w, h);
3220: } else {
3221: g.setColor(_unselectColor1);
3222: if (tabIndex > _tabPane.getSelectedIndex()) {
3223: if (tabIndex == _tabPane.getTabCount() - 1) {
3224: g.drawRect(x, y, w, h - 1);
3225: } else {
3226: g.drawRect(x, y, w, h);
3227: }
3228: } else if (tabIndex < _tabPane.getSelectedIndex()) {
3229: g.drawRect(x, y, w, h);
3230: }
3231: }
3232: break;
3233: case RIGHT:
3234: if (isSelected) {
3235: g.setColor(_selectColor1);
3236: g.drawRect(x - 1, y, w, h);
3237: } else {
3238: g.setColor(_unselectColor1);
3239: if (tabIndex > _tabPane.getSelectedIndex()) {
3240: if (tabIndex == _tabPane.getTabCount() - 1) {
3241: g.drawRect(x - 1, y, w, h - 1);
3242: } else {
3243: g.drawRect(x - 1, y, w, h);
3244: }
3245: } else if (tabIndex < _tabPane.getSelectedIndex()) {
3246: g.drawRect(x - 1, y, w, h);
3247: }
3248: }
3249: break;
3250: case BOTTOM:
3251: if (isSelected) {
3252: g.setColor(_selectColor1);
3253: g.drawRect(x, y - 1, w, h);
3254: } else {
3255: g.setColor(_unselectColor1);
3256: if (tabIndex > _tabPane.getSelectedIndex()) {
3257: if (tabIndex == _tabPane.getTabCount() - 1) {
3258: g.drawRect(x, y - 1, w - 1, h);
3259: } else {
3260: g.drawRect(x, y - 1, w, h);
3261: }
3262: } else if (tabIndex < _tabPane.getSelectedIndex()) {
3263: g.drawRect(x, y - 1, w, h);
3264: }
3265: }
3266: break;
3267: case TOP:
3268: default:
3269: if (isSelected) {
3270: g.setColor(_selectColor1);
3271: g.drawRect(x, y, w, h);
3272: } else {
3273: g.setColor(_unselectColor1);
3274: if (tabIndex > _tabPane.getSelectedIndex()) {
3275: if (tabIndex == _tabPane.getTabCount() - 1) {
3276: g.drawRect(x, y, w - 1, h);
3277: } else {
3278: g.drawRect(x, y, w, h);
3279: }
3280: } else if (tabIndex < _tabPane.getSelectedIndex()) {
3281: g.drawRect(x, y, w, h);
3282: }
3283: }
3284: }
3285: }
3286:
3287: protected void paintRoundedFlatTabBorder(Graphics g,
3288: int tabPlacement, int tabIndex, int x, int y, int w, int h,
3289: boolean isSelected) {
3290: switch (tabPlacement) {
3291: case LEFT:
3292: if (isSelected) {
3293: g.setColor(_selectColor1);
3294: g.drawLine(x + 2, y, x + w - 1, y);
3295: g.drawLine(x + 2, y + h, x + w - 1, y + h);
3296: g.drawLine(x, y + 2, x, y + h - 2);
3297:
3298: g.setColor(_selectColor2);
3299: g.drawLine(x + 1, y + 1, x + 1, y + 1);
3300: // g.drawLine(x, y + 1, x, y + 1);
3301: g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);
3302: // g.drawLine(x + 1, y + h, x + 1, y + h);
3303: } else {
3304: if (tabIndex > _tabPane.getSelectedIndex()) {
3305: g.setColor(_unselectColor1);
3306: g.drawLine(x + 2, y, x + w - 1, y);
3307:
3308: if (tabIndex == _tabPane.getTabCount() - 1) {
3309: g.drawLine(x + 2, y + h - 1, x + w - 1, y + h
3310: - 1);
3311: g.drawLine(x, y + 2, x, y + h - 3);
3312: } else {
3313: g.drawLine(x + 2, y + h, x + w - 1, y + h);
3314: g.drawLine(x, y + 2, x, y + h - 2);
3315: }
3316:
3317: g.setColor(_unselectColor2);
3318: g.drawLine(x + 1, y + 1, x + 1, y + 1);
3319: // g.drawLine(x, y + 1, x, y + 1);
3320:
3321: if (tabIndex == _tabPane.getTabCount() - 1) {
3322: g.drawLine(x, y + h - 2, x, y + h - 2);
3323: g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);
3324: } else {
3325: g.drawLine(x, y + h - 1, x, y + h - 1);
3326: g.drawLine(x + 1, y + h, x + 1, y + h);
3327: }
3328: } else if (tabIndex < _tabPane.getSelectedIndex()) {
3329: g.setColor(_unselectColor1);
3330: g.drawLine(x + 2, y, x + w - 1, y);
3331: g.drawLine(x + 2, y + h, x + w - 1, y + h);
3332: g.drawLine(x, y + 2, x, y + h - 2);
3333:
3334: g.setColor(_unselectColor2);
3335: g.drawLine(x + 1, y + 1, x + 1, y + 1);
3336: // g.drawLine(x, y + 1, x, y + 1);
3337: g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);
3338: // g.drawLine(x + 1, y + h, x + 1, y + h);
3339: }
3340: }
3341: break;
3342: case RIGHT:
3343: if (isSelected) {
3344: g.setColor(_selectColor1);
3345: g.drawLine(x, y, x + w - 3, y);
3346: g.drawLine(x, y + h, x + w - 3, y + h);
3347: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 2);
3348:
3349: g.setColor(_selectColor2);
3350: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
3351: // g.drawLine(x + w - 1, y + 1, x + w - 1, y + 1);
3352: // g.drawLine(x + w - 1, y + h - 1, x + w - 1, y + h - 1);
3353: g.drawLine(x + w - 2, y + h - 1, x + w - 2, y + h - 1);
3354: } else {
3355: if (tabIndex > _tabPane.getSelectedIndex()) {
3356: g.setColor(_unselectColor1);
3357: g.drawLine(x, y, x + w - 3, y);
3358:
3359: if (tabIndex == _tabPane.getTabCount() - 1) {
3360: g.drawLine(x, y + h - 1, x + w - 3, y + h - 1);
3361: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h
3362: - 3);
3363: } else {
3364: g.drawLine(x, y + h, x + w - 3, y + h);
3365: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h
3366: - 2);
3367: }
3368:
3369: g.setColor(_unselectColor2);
3370: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
3371: // g.drawLine(x + w - 1, y + 1, x + w - 1, y + 1);
3372:
3373: if (tabIndex == _tabPane.getTabCount() - 1) {
3374: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y
3375: + h - 2);
3376: // g.drawLine(x + w - 2, y + h - 1, x + w - 2, y + h - 1);
3377: } else {
3378: // g.drawLine(x + w - 1, y + h - 1, x + w - 1, y + h - 1);
3379: g.drawLine(x + w - 2, y + h - 1, x + w - 2, y
3380: + h - 1);
3381: }
3382: } else if (tabIndex < _tabPane.getSelectedIndex()) {
3383: g.setColor(_unselectColor1);
3384: g.drawLine(x, y, x + w - 3, y);
3385: g.drawLine(x, y + h, x + w - 3, y + h);
3386: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h - 2);
3387:
3388: g.setColor(_unselectColor2);
3389: g.drawLine(x + w - 2, y + 1, x + w - 2, y + 1);
3390: // g.drawLine(x + w - 1, y + 1, x + w - 1, y + 1);
3391: g.drawLine(x + w - 2, y + h - 1, x + w - 2, y + h
3392: - 1);
3393: // g.drawLine(x + w - 2, y + h, x + w - 2, y + h);
3394: }
3395: }
3396: break;
3397: case BOTTOM:
3398: if (isSelected) {
3399: g.setColor(_selectColor1);
3400: g.drawLine(x, y, x, y + h - 3);
3401: g.drawLine(x + 2, y + h - 1, x + w - 2, y + h - 1);
3402: g.drawLine(x + w, y, x + w, y + h - 3);
3403:
3404: g.setColor(_selectColor2);
3405: g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
3406: // g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);
3407: // g.drawLine(x + w - 1, y + h - 1, x + w - 1, y + h - 1);
3408: g.drawLine(x + w - 1, y + h - 2, x + w - 1, y + h - 2);
3409: } else {
3410: if (tabIndex > _tabPane.getSelectedIndex()) {
3411: g.setColor(_unselectColor1);
3412: g.drawLine(x, y, x, y + h - 3);
3413:
3414: if (tabIndex == _tabPane.getTabCount() - 1) {
3415: g.drawLine(x + 2, y + h - 1, x + w - 3, y + h
3416: - 1);
3417: g.drawLine(x + w - 1, y, x + w - 1, y + h - 3);
3418: } else {
3419: g.drawLine(x + 2, y + h - 1, x + w - 2, y + h
3420: - 1);
3421: g.drawLine(x + w, y, x + w, y + h - 3);
3422: }
3423:
3424: g.setColor(_unselectColor2);
3425: g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
3426: // g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);
3427:
3428: if (tabIndex == _tabPane.getTabCount() - 1) {
3429: // g.drawLine(x + w - 2, y + h - 1, x + w - 2, y + h - 1);
3430: g.drawLine(x + w - 2, y + h - 2, x + w - 2, y
3431: + h - 2);
3432: } else {
3433: // g.drawLine(x + w - 1, y + h - 1, x + w - 1, y + h - 1);
3434: g.drawLine(x + w - 1, y + h - 2, x + w - 1, y
3435: + h - 2);
3436: }
3437: } else if (tabIndex < _tabPane.getSelectedIndex()) {
3438: g.setColor(_unselectColor1);
3439: g.drawLine(x, y, x, y + h - 3);
3440: g.drawLine(x + 2, y + h - 1, x + w - 2, y + h - 1);
3441: g.drawLine(x + w, y, x + w, y + h - 3);
3442:
3443: g.setColor(_unselectColor2);
3444: g.drawLine(x + 1, y + h - 2, x + 1, y + h - 2);
3445: // g.drawLine(x + 1, y + h - 1, x + 1, y + h - 1);
3446: // g.drawLine(x + w - 1, y + h - 1, x + w - 1, y + h - 1);
3447: g.drawLine(x + w - 1, y + h - 2, x + w - 1, y + h
3448: - 2);
3449: }
3450: }
3451: break;
3452: case TOP:
3453: default:
3454: if (isSelected) {
3455: g.setColor(_selectColor1);
3456: g.drawLine(x, y + h - 1, x, y + 2);
3457: g.drawLine(x + 2, y, x + w - 2, y);
3458: g.drawLine(x + w, y + 2, x + w, y + h - 1);
3459:
3460: g.setColor(_selectColor2);
3461: g.drawLine(x, y + 2, x + 2, y); // top-left
3462: g.drawLine(x + w - 2, y, x + w, y + 2);
3463: // g.drawLine(x + w, y + 1, x + w, y + 1);
3464: } else {
3465: if (tabIndex > _tabPane.getSelectedIndex()) {
3466: g.setColor(_unselectColor1);
3467: g.drawLine(x, y + h - 1, x, y + 2);
3468:
3469: if (tabIndex == _tabPane.getTabCount() - 1) {
3470: g.drawLine(x + 2, y, x + w - 3, y);
3471: g.drawLine(x + w - 1, y + 2, x + w - 1, y + h
3472: - 1);
3473: } else {
3474: g.drawLine(x + 2, y, x + w - 2, y);
3475: g.drawLine(x + w, y + 2, x + w, y + h - 1);
3476: }
3477:
3478: g.setColor(_unselectColor2);
3479: g.drawLine(x, y + 2, x + 2, y); // top-left
3480:
3481: if (tabIndex == _tabPane.getTabCount() - 1) {
3482: g.drawLine(x + w - 3, y, x + w - 1, y + 2);
3483: } else {
3484: g.drawLine(x + w - 2, y, x + w, y + 2);
3485: }
3486: } else if (tabIndex < _tabPane.getSelectedIndex()) {
3487: g.setColor(_unselectColor1);
3488: g.drawLine(x, y + h - 1, x, y + 2);
3489: g.drawLine(x + 2, y, x + w - 2, y);
3490: g.drawLine(x + w, y + 2, x + w, y + h - 1);
3491:
3492: g.setColor(_unselectColor2);
3493: g.drawLine(x, y + 2, x + 2, y);
3494: g.drawLine(x + w - 2, y, x + w, y + 2);
3495: }
3496: }
3497: }
3498: }
3499:
3500: protected void paintBoxTabBorder(Graphics g, int tabPlacement,
3501: int tabIndex, int x, int y, int w, int h, boolean isSelected) {
3502: if (isSelected) {
3503: g.setColor(_selectColor1);
3504: g.drawLine(x, y, x + w - 2, y);// top
3505: g.drawLine(x, y, x, y + h - 2);// left
3506:
3507: g.setColor(_selectColor2);
3508: g.drawLine(x + w - 1, y, x + w - 1, y + h - 1);// right
3509: g.drawLine(x, y + h - 1, x + w - 1, y + h - 1);// bottom
3510: } else {
3511: if (tabIndex != _tabPane.getSelectedIndex() - 1) {
3512: switch (tabPlacement) {
3513: case LEFT:
3514: case RIGHT:
3515: g.setColor(_unselectColor1);
3516: g.drawLine(x + 2, y + h, x + w - 2, y + h);// bottom
3517:
3518: g.setColor(_unselectColor2);
3519: g.drawLine(x + 2, y + h + 1, x + w - 2, y + h + 1);// bottom
3520: break;
3521: case BOTTOM:
3522: case TOP:
3523: default:
3524: g.setColor(_unselectColor1);
3525: g.drawLine(x + w, y + 2, x + w, y + h - 2);// right
3526:
3527: g.setColor(_unselectColor2);
3528: g.drawLine(x + w + 1, y + 2, x + w + 1, y + h - 2);// right
3529: }
3530: }
3531: }
3532: }
3533:
3534: protected void paintTabBackground(Graphics g, int tabPlacement,
3535: int tabIndex, int x, int y, int w, int h, boolean isSelected) {
3536: if (!PAINT_TAB_BACKGROUND) {
3537: return;
3538: }
3539:
3540: switch (getTabShape()) {
3541: case JideTabbedPane.SHAPE_BOX:
3542: paintButtonTabBackground(g, tabPlacement, tabIndex, x, y,
3543: w, h, isSelected);
3544: break;
3545: case JideTabbedPane.SHAPE_EXCEL:
3546: paintExcelTabBackground(g, tabPlacement, tabIndex, x, y, w,
3547: h, isSelected);
3548: break;
3549: case JideTabbedPane.SHAPE_WINDOWS:
3550: paintDefaultTabBackground(g, tabPlacement, tabIndex, x, y,
3551: w, h, isSelected);
3552: break;
3553: case JideTabbedPane.SHAPE_WINDOWS_SELECTED:
3554: if (isSelected) {
3555: paintDefaultTabBackground(g, tabPlacement, tabIndex, x,
3556: y, w, h, isSelected);
3557: }
3558: break;
3559: case JideTabbedPane.SHAPE_VSNET:
3560: case JideTabbedPane.SHAPE_ROUNDED_VSNET:
3561: paintVsnetTabBackground(g, tabPlacement, tabIndex, x, y, w,
3562: h, isSelected);
3563: break;
3564: case JideTabbedPane.SHAPE_FLAT:
3565: case JideTabbedPane.SHAPE_ROUNDED_FLAT:
3566: paintFlatTabBackground(g, tabPlacement, tabIndex, x, y, w,
3567: h, isSelected);
3568: break;
3569: case JideTabbedPane.SHAPE_OFFICE2003:
3570: default:
3571: paintOffice2003TabBackground(g, tabPlacement, tabIndex, x,
3572: y, w, h, isSelected);
3573: }
3574:
3575: }
3576:
3577: protected void paintOffice2003TabBackground(Graphics g,
3578: int tabPlacement, int tabIndex, int x, int y, int w, int h,
3579: boolean isSelected) {
3580:
3581: switch (tabPlacement) {
3582: case LEFT:
3583: if (!isSelected) {// the tab is not selected
3584: if (tabIndex == 0) {
3585: int xp[] = { x + w, x + 2, x, x, x + 3, x + w };
3586: int yp[] = { y - w + 2 + 2, y + 2, y + 5,
3587: y + h - 5, y + h - 2, y + h - 2 };
3588: int np = yp.length;
3589: tabRegion = new Polygon(xp, yp, np);
3590: } else {// tabIndex != 0
3591: int xp[] = { x + w, x + 4, x + 2, x, x, x + 3,
3592: x + w };
3593: int yp[] = { y, y, y + 2, y + 5, y + h - 5,
3594: y + h - 2, y + h - 2 };
3595: int np = yp.length;
3596: tabRegion = new Polygon(xp, yp, np);
3597: }
3598: } else {
3599:
3600: int xp[] = { x + w, x + 2, x, x, x + 3, x + w };
3601: int yp[] = { y - w + 2 + 2, y + 2, y + 5, y + h - 5,
3602: y + h - 2, y + h - 2 };
3603: int np = yp.length;
3604: tabRegion = new Polygon(xp, yp, np);
3605:
3606: }
3607: break;
3608: case RIGHT:
3609: if (!isSelected) {// the tab is not selected
3610: if (tabIndex == 0) {
3611: int xp[] = { x, x + w - 3, x + w - 1, x + w - 1,
3612: x + w - 3, x };
3613: int yp[] = { y - w + 2 + 2, y + 2, y + 5,
3614: y + h - 5, y + h - 2, y + h - 2 };
3615: int np = yp.length;
3616: tabRegion = new Polygon(xp, yp, np);
3617: } else {// tabIndex != 0
3618: int xp[] = { x, x + w - 4, x + w - 3, x + w - 1,
3619: x + w - 1, x + w - 3, x };
3620: int yp[] = { y, y, y + 2, y + 5, y + h - 5,
3621: y + h - 2, y + h - 2 };
3622: int np = yp.length;
3623: tabRegion = new Polygon(xp, yp, np);
3624: }
3625: } else {
3626: int xp[] = { x, x + w - 3, x + w - 1, x + w - 1,
3627: x + w - 3, x };
3628: int yp[] = { y - w + 2 + 2, y + 2, y + 5, y + h - 5,
3629: y + h - 2, y + h - 2 };
3630: int np = yp.length;
3631: tabRegion = new Polygon(xp, yp, np);
3632: }
3633: break;
3634: case BOTTOM:
3635: if (!isSelected) {// the tab is not selected
3636: if (tabIndex == 0) {
3637: int xp[] = { x - h + 5, x, x + 4, x + w - 3,
3638: x + w - 1, x + w - 1 };
3639: int yp[] = { y, y + h - 5, y + h - 1, y + h - 1,
3640: y + h - 5, y };
3641: int np = yp.length;
3642: tabRegion = new Polygon(xp, yp, np);
3643: } else {// tabIndex != 0
3644: int xp[] = { x, x, x + 4, x + w - 3, x + w - 1,
3645: x + w - 1 };
3646: int yp[] = { y, y + h - 5, y + h - 1, y + h - 1,
3647: y + h - 5, y };
3648: int np = yp.length;
3649: tabRegion = new Polygon(xp, yp, np);
3650: }
3651:
3652: } else {
3653: int xp[] = { x - h + 5, x, x + 4, x + w - 3, x + w - 1,
3654: x + w - 1 };
3655: int yp[] = { y, y + h - 5, y + h - 1, y + h - 1,
3656: y + h - 5, y };
3657: int np = yp.length;
3658: tabRegion = new Polygon(xp, yp, np);
3659: }
3660: break;
3661: case TOP:
3662: default:
3663: if (!isSelected) {// the tab is not selected
3664: if (tabIndex == 0) {
3665: int xp[] = { x - h + 5, x, x + 4, x + w - 3,
3666: x + w - 1, x + w - 1 };
3667: int yp[] = { y + h, y + 3, y + 1, y + 1, y + 3,
3668: y + h };
3669: int np = yp.length;
3670: tabRegion = new Polygon(xp, yp, np);
3671: } else {// tabIndex != 0
3672: int xp[] = { x, x, x + 4, x + w - 3, x + w - 1,
3673: x + w - 1 };
3674: int yp[] = { y + h, y + 3, y + 1, y + 1, y + 3,
3675: y + h };
3676: int np = yp.length;
3677: tabRegion = new Polygon(xp, yp, np);
3678: }
3679: } else {
3680: int xp[] = { x - h + 5, x, x + 4, x + w - 3, x + w - 1,
3681: x + w - 1 };
3682: int yp[] = { y + h, y + 3, y + 1, y + 1, y + 3, y + h };
3683: int np = yp.length;
3684: tabRegion = new Polygon(xp, yp, np);
3685:
3686: }
3687: }
3688: }
3689:
3690: protected void paintExcelTabBackground(Graphics g,
3691: int tabPlacement, int tabIndex, int x, int y, int w, int h,
3692: boolean isSelected) {
3693: switch (tabPlacement) {
3694: case LEFT:
3695: if (!isSelected) {
3696: if (tabIndex == 0) {
3697: int xp[] = { x + w, x, x, x + w };
3698: int yp[] = { y - 5, y + 5, y + h - 5, y + h + 6 };
3699: int np = yp.length;
3700: tabRegion = new Polygon(xp, yp, np);
3701: } else {
3702: int xp[] = { x + w, x + 9, x, x, x + w };
3703: int yp[] = { y + 8, y + 2, y + 6, y + h - 5,
3704: y + h + 6 };
3705: int np = yp.length;
3706: tabRegion = new Polygon(xp, yp, np);
3707: }
3708: } else {
3709: int xp[] = { x + w, x, x, x + w };
3710: int yp[] = { y - 5, y + 5, y + h - 5, y + h + 6 };
3711: int np = yp.length;
3712: tabRegion = new Polygon(xp, yp, np);
3713: }
3714: break;
3715: case RIGHT:
3716: if (!isSelected) {
3717: if (tabIndex == 0) {
3718: int xp[] = { x, x + w - 1, x + w - 1, x };
3719: int yp[] = { y - 5, y + 5, y + h - 5, y + h + 6 };
3720: int np = yp.length;
3721: tabRegion = new Polygon(xp, yp, np);
3722: } else {
3723: int xp[] = { x, x + w - 10, x + w - 1, x + w - 1, x };
3724: int yp[] = { y + 8, y + 2, y + 6, y + h - 5,
3725: y + h + 6 };
3726: int np = yp.length;
3727: tabRegion = new Polygon(xp, yp, np);
3728: }
3729: } else {
3730: int xp[] = { x, x + w - 1, x + w - 1, x };
3731: int yp[] = { y - 5, y + 5, y + h - 4, y + h + 6 };
3732: int np = yp.length;
3733: tabRegion = new Polygon(xp, yp, np);
3734: }
3735: break;
3736: case BOTTOM:
3737: if (!isSelected) {
3738: if (tabIndex == 0) {
3739: int xp[] = { x - 5, x + 5, x + w - 5, x + w + 5 };
3740: int yp[] = { y, y + h - 1, y + h - 1, y };
3741: int np = yp.length;
3742: tabRegion = new Polygon(xp, yp, np);
3743: } else {
3744: int xp[] = { x + 7, x + 1, x + 5, x + w - 5,
3745: x + w + 5 };
3746: int yp[] = { y, y + h - 10, y + h - 1, y + h - 1, y };
3747: int np = yp.length;
3748: tabRegion = new Polygon(xp, yp, np);
3749: }
3750: } else {
3751: int xp[] = { x - 5, x + 5, x + w - 5, x + w + 5 };
3752: int yp[] = { y, y + h - 1, y + h - 1, y };
3753: int np = yp.length;
3754: tabRegion = new Polygon(xp, yp, np);
3755: }
3756: break;
3757: case TOP:
3758: default:
3759: if (!isSelected) {
3760: if (tabIndex == 0) {
3761: int xp[] = { x - 6, x + 5, x + w - 5, x + w + 5 };
3762: int yp[] = { y + h, y, y, y + h };
3763: int np = yp.length;
3764: tabRegion = new Polygon(xp, yp, np);
3765: } else {
3766: int xp[] = { x + 7, x + 1, x + 6, x + w - 5,
3767: x + w + 5 };
3768: int yp[] = { y + h, y + 9, y, y, y + h };
3769: int np = yp.length;
3770: tabRegion = new Polygon(xp, yp, np);
3771: }
3772: } else {
3773: int xp[] = { x - 6, x + 5, x + w - 5, x + w + 5 };
3774: int yp[] = { y + h, y, y, y + h };
3775: int np = yp.length;
3776: tabRegion = new Polygon(xp, yp, np);
3777: }
3778: }
3779: }
3780:
3781: protected void paintDefaultTabBackground(Graphics g,
3782: int tabPlacement, int tabIndex, int x, int y, int w, int h,
3783: boolean isSelected) {
3784: switch (tabPlacement) {
3785: case LEFT:
3786: if (isSelected) {
3787: x = x + 1;
3788: int xp[] = { x + w, x, x - 2, x - 2, x + w };
3789: int yp[] = { y - 1, y - 1, y + 1, y + h + 2, y + h + 2 };
3790: int np = yp.length;
3791: tabRegion = new Polygon(xp, yp, np);
3792: } else {
3793: if (tabIndex < _tabPane.getSelectedIndex()) {
3794: y = y + 1;
3795: int xp[] = { x + w, x + 2, x, x, x + w };
3796: int yp[] = { y + 1, y + 1, y + 3, y + h - 1,
3797: y + h - 1 };
3798: int np = yp.length;
3799: tabRegion = new Polygon(xp, yp, np);
3800: } else {
3801: int xp[] = { x + w, x + 2, x, x, x + w };
3802: int yp[] = { y + 1, y + 1, y + 3, y + h - 2,
3803: y + h - 2 };
3804: int np = yp.length;
3805: tabRegion = new Polygon(xp, yp, np);
3806: }
3807: }
3808: break;
3809: case RIGHT:
3810: if (isSelected) {
3811:
3812: int xp[] = { x, x + w - 1, x + w, x + w, x };
3813: int yp[] = { y - 1, y - 1, y + 1, y + h + 2, y + h + 2 };
3814: int np = yp.length;
3815: tabRegion = new Polygon(xp, yp, np);
3816: } else {
3817: if (tabIndex < _tabPane.getSelectedIndex()) {
3818: y = y + 1;
3819: int xp[] = { x, x + w - 3, x + w - 1, x + w - 1, x };
3820: int yp[] = { y + 1, y + 1, y + 3, y + h - 1,
3821: y + h - 1 };
3822: int np = yp.length;
3823: tabRegion = new Polygon(xp, yp, np);
3824: } else {
3825: int xp[] = { x, x + w - 2, x + w - 1, x + w - 1, x };
3826: int yp[] = { y + 1, y + 1, y + 3, y + h - 2,
3827: y + h - 2 };
3828: int np = yp.length;
3829: tabRegion = new Polygon(xp, yp, np);
3830: }
3831: }
3832: break;
3833: case BOTTOM:
3834: if (isSelected) {
3835: int xp[] = { x, x, x + 2, x + w + 2, x + w + 2 };
3836: int yp[] = { y + h, y, y - 2, y - 2, y + h };
3837: int np = yp.length;
3838: tabRegion = new Polygon(xp, yp, np);
3839: } else {
3840: int xp[] = { x + 1, x + 1, x + 1, x + w - 1, x + w - 1 };
3841: int yp[] = { y + h - 1, y + 2, y, y, y + h - 1 };
3842: int np = yp.length;
3843: tabRegion = new Polygon(xp, yp, np);
3844: }
3845: break;
3846: case TOP:
3847: default:
3848: if (isSelected) {
3849: int xp[] = { x, x, x + 2, x + w + 2, x + w + 2 };
3850: int yp[] = { y + h + 1, y, y - 2, y - 2, y + h + 1 };
3851: int np = yp.length;
3852: tabRegion = new Polygon(xp, yp, np);
3853: } else {
3854: int xp[] = { x + 1, x + 1, x + 3, x + w - 1, x + w - 1 };
3855: int yp[] = { y + h, y + 2, y, y, y + h };
3856: int np = yp.length;
3857: tabRegion = new Polygon(xp, yp, np);
3858: }
3859: }
3860: }
3861:
3862: protected void paintTabBackgroundMouseOver(Graphics g,
3863: int tabPlacement, int tabIndex, int x, int y, int w, int h,
3864: boolean isSelected, Color backgroundUnselectedColorStart,
3865: Color backgroundUnselectedColorEnd) {
3866: Graphics2D g2d = (Graphics2D) g;
3867:
3868: Polygon polygon = null;
3869:
3870: switch (tabPlacement) {
3871: case LEFT:
3872: if (tabIndex < _tabPane.getSelectedIndex()) {
3873:
3874: int xp[] = { x + w, x + 2, x, x, x + 2, x + w };
3875: int yp[] = { y + 2, y + 2, y + 4, y + h - 1, y + h,
3876: y + h };
3877: int np = yp.length;
3878: polygon = new Polygon(xp, yp, np);
3879:
3880: } else {// tabIndex > _tabPane.getSelectedIndex()
3881:
3882: int xp[] = { x + w, x + 2, x, x, x + 2, x + w };
3883: int yp[] = { y + 1, y + 1, y + 3, y + h - 3, y + h - 2,
3884: y + h - 2 };
3885: int np = yp.length;
3886: polygon = new Polygon(xp, yp, np);
3887:
3888: }
3889: JideSwingUtilities.fillGradient(g2d, polygon,
3890: backgroundUnselectedColorStart,
3891: backgroundUnselectedColorEnd, false);
3892: break;
3893: case RIGHT:
3894: if (tabIndex < _tabPane.getSelectedIndex()) {
3895: int xp[] = { x, x + w - 3, x + w - 1, x + w - 1,
3896: x + w - 3, x };
3897: int yp[] = { y + 2, y + 2, y + 4, y + h - 1, y + h,
3898: y + h };
3899: int np = yp.length;
3900: polygon = new Polygon(xp, yp, np);
3901: } else {
3902: int xp[] = { x, x + w - 2, x + w - 1, x + w - 1,
3903: x + w - 3, x };
3904: int yp[] = { y + 1, y + 1, y + 3, y + h - 3, y + h - 2,
3905: y + h - 2 };
3906: int np = yp.length;
3907: polygon = new Polygon(xp, yp, np);
3908: }
3909: JideSwingUtilities.fillGradient(g2d, polygon,
3910: backgroundUnselectedColorEnd,
3911: backgroundUnselectedColorStart, false);
3912: break;
3913: case BOTTOM:
3914: int xp[] = { x + 1, x + 1, x + 1, x + w - 1, x + w - 1 };
3915: int yp[] = { y + h - 2, y + 2, y, y, y + h - 2 };
3916: int np = yp.length;
3917: polygon = new Polygon(xp, yp, np);
3918: JideSwingUtilities.fillGradient(g2d, polygon,
3919: backgroundUnselectedColorEnd,
3920: backgroundUnselectedColorStart, true);
3921: break;
3922: case TOP:
3923: default:
3924: int xp1[] = { x + 1, x + 1, x + 3, x + w - 1, x + w - 1 };
3925: int yp1[] = { y + h, y + 2, y, y, y + h };
3926: int np1 = yp1.length;
3927: polygon = new Polygon(xp1, yp1, np1);
3928: JideSwingUtilities.fillGradient(g2d, polygon,
3929: backgroundUnselectedColorStart,
3930: backgroundUnselectedColorEnd, true);
3931: }
3932: }
3933:
3934: protected void paintVsnetTabBackground(Graphics g,
3935: int tabPlacement, int tabIndex, int x, int y, int w, int h,
3936: boolean isSelected) {
3937: int xp[];
3938: int yp[];
3939: switch (tabPlacement) {
3940: case LEFT:
3941: xp = new int[] { x + 1, x + 1, x + w, x + w };
3942: yp = new int[] { y + h - 1, y + 1, y + 1, y + h - 1 };
3943: break;
3944: case RIGHT:
3945: xp = new int[] { x, x, x + w - 1, x + w - 1 };
3946: yp = new int[] { y + h - 1, y + 1, y + 1, y + h - 1 };
3947: break;
3948: case BOTTOM:
3949: xp = new int[] { x + 1, x + 1, x + w - 1, x + w - 1 };
3950: yp = new int[] { y + h - 1, y, y, y + h - 1 };
3951: break;
3952: case TOP:
3953: default:
3954: xp = new int[] { x + 1, x + 1, x + w - 1, x + w - 1 };
3955: yp = new int[] { y + h, y + 1, y + 1, y + h };
3956: break;
3957: }
3958: int np = yp.length;
3959: tabRegion = new Polygon(xp, yp, np);
3960: }
3961:
3962: protected void paintFlatTabBackground(Graphics g, int tabPlacement,
3963: int tabIndex, int x, int y, int w, int h, boolean isSelected) {
3964: switch (tabPlacement) {
3965: case LEFT:
3966: int xp1[] = { x + 1, x + 1, x + w, x + w };
3967: int yp1[] = { y + h, y + 1, y + 1, y + h };
3968: int np1 = yp1.length;
3969: tabRegion = new Polygon(xp1, yp1, np1);
3970: break;
3971: case RIGHT:
3972: int xp2[] = { x, x, x + w - 1, x + w - 1 };
3973: int yp2[] = { y + h, y + 1, y + 1, y + h };
3974: int np2 = yp2.length;
3975: tabRegion = new Polygon(xp2, yp2, np2);
3976: break;
3977: case BOTTOM:
3978: int xp3[] = { x + 1, x + 1, x + w, x + w };
3979: int yp3[] = { y + h - 1, y, y, y + h - 1 };
3980: int np3 = yp3.length;
3981: tabRegion = new Polygon(xp3, yp3, np3);
3982: break;
3983: case TOP:
3984: default:
3985: int xp4[] = { x, x + 1, x + w, x + w };
3986: int yp4[] = { y + h, y + 1, y + 1, y + h };
3987: int np4 = yp4.length;
3988: tabRegion = new Polygon(xp4, yp4, np4);
3989: }
3990: }
3991:
3992: protected void paintButtonTabBackground(Graphics g,
3993: int tabPlacement, int tabIndex, int x, int y, int w, int h,
3994: boolean isSelected) {
3995: int xp[] = { x, x, x + w, x + w };
3996: int yp[] = { y + h, y, y, y + h };
3997: int np = yp.length;
3998: tabRegion = new Polygon(xp, yp, np);
3999: }
4000:
4001: protected void paintContentBorder(Graphics g, int tabPlacement,
4002: int selectedIndex) {
4003: int width = _tabPane.getWidth();
4004: int height = _tabPane.getHeight();
4005: Insets insets = _tabPane.getInsets();
4006:
4007: int x = insets.left;
4008: int y = insets.top;
4009: int w = width - insets.right - insets.left;
4010: int h = height - insets.top - insets.bottom;
4011:
4012: int temp = -1;
4013: switch (tabPlacement) {
4014: case LEFT:
4015: x += calculateTabAreaWidth(tabPlacement, _runCount,
4016: _maxTabWidth);
4017: if (isTabLeadingComponentVisible()) {
4018: if (_tabLeadingComponent.getSize().width > calculateTabAreaWidth(
4019: tabPlacement, _runCount, _maxTabWidth)) {
4020: x = insets.left
4021: + _tabLeadingComponent.getSize().width;
4022: temp = _tabLeadingComponent.getSize().width;
4023: }
4024: }
4025: if (isTabTrailingComponentVisible()) {
4026: if (_maxTabWidth < _tabTrailingComponent.getSize().width
4027: && temp < _tabTrailingComponent.getSize().width) {
4028: x = insets.left
4029: + _tabTrailingComponent.getSize().width;
4030: }
4031: }
4032: w -= (x - insets.left);
4033: break;
4034: case RIGHT:
4035: w -= calculateTabAreaWidth(tabPlacement, _runCount,
4036: _maxTabWidth);
4037: break;
4038: case BOTTOM:
4039: h -= calculateTabAreaHeight(tabPlacement, _runCount,
4040: _maxTabHeight);
4041: break;
4042: case TOP:
4043: default:
4044: y += calculateTabAreaHeight(tabPlacement, _runCount,
4045: _maxTabHeight);
4046: if (isTabLeadingComponentVisible()) {
4047: if (_tabLeadingComponent.getSize().height > calculateTabAreaHeight(
4048: tabPlacement, _runCount, _maxTabHeight)) {
4049: y = insets.top
4050: + _tabLeadingComponent.getSize().height;
4051: temp = _tabLeadingComponent.getSize().height;
4052: }
4053: }
4054: if (isTabTrailingComponentVisible()) {
4055: if (_maxTabHeight < _tabTrailingComponent.getSize().height
4056: && temp < _tabTrailingComponent.getSize().height) {
4057: y = insets.top
4058: + _tabTrailingComponent.getSize().height;
4059: }
4060: }
4061: h -= (y - insets.top);
4062: }
4063:
4064: if (getTabShape() != JideTabbedPane.SHAPE_BOX) {
4065:
4066: // Fill region behind content area
4067: paintContentBorder(g, x, y, w, h);
4068:
4069: switch (tabPlacement) {
4070: case LEFT:
4071: paintContentBorderLeftEdge(g, tabPlacement,
4072: selectedIndex, x, y, w, h);
4073: break;
4074: case RIGHT:
4075: paintContentBorderRightEdge(g, tabPlacement,
4076: selectedIndex, x, y, w, h);
4077: break;
4078: case BOTTOM:
4079: paintContentBorderBottomEdge(g, tabPlacement,
4080: selectedIndex, x, y, w, h);
4081: break;
4082: case TOP:
4083: default:
4084: paintContentBorderTopEdge(g, tabPlacement,
4085: selectedIndex, x, y, w, h);
4086: break;
4087:
4088: }
4089: }
4090:
4091: }
4092:
4093: protected void paintContentBorderLeftEdge(Graphics g,
4094: int tabPlacement, int selectedIndex, int x, int y, int w,
4095: int h) {
4096:
4097: }
4098:
4099: protected void paintContentBorderRightEdge(Graphics g,
4100: int tabPlacement, int selectedIndex, int x, int y, int w,
4101: int h) {
4102:
4103: }
4104:
4105: protected void paintContentBorder(Graphics g, int x, int y, int w,
4106: int h) {
4107: if (!PAINT_CONTENT_BORDER) {
4108: return;
4109: }
4110:
4111: if (_tabPane.isOpaque()) {
4112: g.setColor(_tabBackground);
4113: g.fillRect(x, y, w, h);
4114: }
4115: }
4116:
4117: protected Color getBorderEdgeColor() {
4118: if ("true".equals(SecurityUtils.getProperty("shadingtheme",
4119: "false"))) {
4120: return _shadow;
4121: } else {
4122: return _lightHighlight;
4123: }
4124: }
4125:
4126: protected void paintContentBorderTopEdge(Graphics g,
4127: int tabPlacement, int selectedIndex, int x, int y, int w,
4128: int h) {
4129:
4130: if (!PAINT_CONTENT_BORDER_EDGE) {
4131: return;
4132: }
4133:
4134: if (selectedIndex < 0) {
4135: return;
4136: }
4137:
4138: Rectangle selRect = getTabBounds(selectedIndex, _calcRect);
4139:
4140: g.setColor(getBorderEdgeColor());
4141:
4142: // Draw unbroken line if tabs are not on TOP, OR
4143: // selected tab is not in run adjacent to content, OR
4144: // selected tab is not visible (SCROLL_TAB_LAYOUT)
4145: //
4146: if (tabPlacement != TOP || selectedIndex < 0 ||
4147: /*(selRect.y + selRect.height + 1 < y) ||*/
4148: (selRect.x < x || selRect.x > x + w)) {
4149: g.drawLine(x, y, x + w - 1, y);
4150: } else {
4151: // Break line to show visual connection to selected tab
4152: g.drawLine(x, y, selRect.x, y);
4153: if (!getBorderEdgeColor().equals(_lightHighlight)) {
4154: if (selRect.x + selRect.width < x + w - 2) {
4155: g.drawLine(selRect.x + selRect.width - 1, y,
4156: selRect.x + selRect.width - 1, y);
4157: g.drawLine(selRect.x + selRect.width, y, x + w - 1,
4158: y);
4159: } else {
4160: g.drawLine(x + w - 2, y, x + w - 1, y);
4161: }
4162: } else {
4163: if (selRect.x + selRect.width < x + w - 2) {
4164: g.setColor(_darkShadow);
4165: g.drawLine(selRect.x + selRect.width - 1, y,
4166: selRect.x + selRect.width - 1, y);
4167: g.setColor(_lightHighlight);
4168: g.drawLine(selRect.x + selRect.width, y, x + w - 1,
4169: y);
4170: } else {
4171: g.setColor(_selectedColor == null ? _tabPane
4172: .getBackground() : _selectedColor);
4173: g.drawLine(x + w - 2, y, x + w - 1, y);
4174: }
4175: }
4176: }
4177: }
4178:
4179: protected void paintContentBorderBottomEdge(Graphics g,
4180: int tabPlacement, int selectedIndex, int x, int y, int w,
4181: int h) {
4182: if (!PAINT_CONTENT_BORDER_EDGE) {
4183: return;
4184: }
4185:
4186: if (selectedIndex < 0) {
4187: return;
4188: }
4189:
4190: Rectangle selRect = getTabBounds(selectedIndex, _calcRect);
4191:
4192: // Draw unbroken line if tabs are not on BOTTOM, OR
4193: // selected tab is not in run adjacent to content, OR
4194: // selected tab is not visible (SCROLL_TAB_LAYOUT)
4195: //
4196: if (tabPlacement != BOTTOM || selectedIndex < 0 ||
4197: /*(selRect.y - 1 > h) ||*/
4198: (selRect.x < x || selRect.x > x + w)) {
4199: g.setColor(getBorderEdgeColor());
4200: g.drawLine(x, y + h - 1, x + w - 2, y + h - 1);
4201: } else {
4202: if (!getBorderEdgeColor().equals(_lightHighlight)) {
4203: g.setColor(getBorderEdgeColor());
4204: g.drawLine(x, y + h - 1, selRect.x - 1, y + h - 1);
4205: g.drawLine(selRect.x, y + h - 1, selRect.x, y + h - 1);
4206: if (selRect.x + selRect.width < x + w - 2) {
4207: g.drawLine(selRect.x + selRect.width - 1,
4208: y + h - 1, x + w - 2, y + h - 1); // dark line to the end
4209: }
4210: } else {
4211: // Break line to show visual connection to selected tab
4212: g.setColor(_darkShadow); // dark line at the beginning
4213: g.drawLine(x, y + h - 1, selRect.x - 1, y + h - 1);
4214: g.setColor(_lightHighlight); // light line to meet with tab
4215: // border
4216: g.drawLine(selRect.x, y + h - 1, selRect.x, y + h - 1);
4217: if (selRect.x + selRect.width < x + w - 2) {
4218: g.setColor(_darkShadow);
4219: g.drawLine(selRect.x + selRect.width - 1,
4220: y + h - 1, x + w - 2, y + h - 1); // dark line to the end
4221: }
4222: }
4223: }
4224:
4225: }
4226:
4227: protected void ensureCurrentLayout() {
4228: // this line cause layout when repaint. It looks like tabbed pane is always not valid.
4229:
4230: /* If tabPane doesn't have a peer yet, the validate() call will
4231: * silently fail. We handle that by forcing a layout if tabPane
4232: * is still invalid. See bug 4237677.
4233: */
4234: if (!_tabPane.isValid()) {
4235: TabbedPaneLayout layout = (TabbedPaneLayout) _tabPane
4236: .getLayout();
4237: layout.calculateLayoutInfo();
4238: }
4239:
4240: if (scrollableTabLayoutEnabled() && isShowCloseButton()
4241: && isShowCloseButtonOnTab()) {
4242: for (int i = 0; i < _closeButtons.length; i++) {
4243: if (_tabPane.isShowCloseButtonOnSelectedTab()) {
4244: if (i != _tabPane.getSelectedIndex()) {
4245: _closeButtons[i].setBounds(0, 0, 0, 0);
4246: continue;
4247: }
4248: } else {
4249: if (i >= _rects.length) {
4250: _closeButtons[i].setBounds(0, 0, 0, 0);
4251: continue;
4252: }
4253: }
4254:
4255: if (!_tabPane.isTabClosableAt(i)) {
4256: _closeButtons[i].setBounds(0, 0, 0, 0);
4257: continue;
4258: }
4259: Dimension size = _closeButtons[i].getPreferredSize();
4260:
4261: Rectangle bounds = null;
4262: if (_closeButtonAlignment == SwingConstants.TRAILING) {
4263: if (_tabPane.getTabPlacement() == JideTabbedPane.TOP
4264: || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM) {
4265: bounds = new Rectangle(
4266: _rects[i].x + _rects[i].width
4267: - size.width - 6,
4268: _rects[i].y
4269: + (_rects[i].height - size.height)
4270: / 2, size.width, size.height);
4271: bounds.x -= getTabGap();
4272: } else /*if (_tabPane.getTabPlacement() == JideTabbedPane.LEFT || _tabPane.getTabPlacement() == JideTabbedPane.RIGHT)*/{
4273: bounds = new Rectangle(_rects[i].x
4274: + (_rects[i].width - size.width) / 2,
4275: _rects[i].y + _rects[i].height
4276: - size.height - 6, size.width,
4277: size.height);
4278: bounds.y -= getTabGap();
4279: }
4280: } else {
4281: if (_tabPane.getTabPlacement() == JideTabbedPane.TOP
4282: || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM) {
4283: bounds = new Rectangle(
4284: _rects[i].x + 4,
4285: _rects[i].y
4286: + (_rects[i].height - size.height)
4287: / 2, size.width, size.height);
4288: } else if (_tabPane.getTabPlacement() == JideTabbedPane.LEFT) {
4289: bounds = new Rectangle(_rects[i].x
4290: + (_rects[i].width - size.width) / 2,
4291: _rects[i].y + 4, size.width,
4292: size.height);
4293: } else /*if (_tabPane.getTabPlacement() == JideTabbedPane.RIGHT)*/{
4294: bounds = new Rectangle(_rects[i].x
4295: + (_rects[i].width - size.width) / 2
4296: - 2, _rects[i].y + 4, size.width,
4297: size.height);
4298: }
4299: }
4300: _closeButtons[i].setIndex(i);
4301: if (!bounds.equals(_closeButtons[i].getBounds())) {
4302: _closeButtons[i].setBounds(bounds);
4303: }
4304: if (_tabPane.getSelectedIndex() == i) {
4305: _closeButtons[i]
4306: .setBackground(_selectedColor == null ? _tabPane
4307: .getBackgroundAt(i)
4308: : _selectedColor);
4309: } else {
4310: _closeButtons[i].setBackground(_tabPane
4311: .getBackgroundAt(i));
4312: }
4313: }
4314: }
4315:
4316: }
4317:
4318: // TabbedPaneUI methods
4319:
4320: /**
4321: * Returns the bounds of the specified tab index. The bounds are
4322: * with respect to the JTabbedPane's coordinate space.
4323: */
4324: @Override
4325: public Rectangle getTabBounds(JTabbedPane pane, int i) {
4326: ensureCurrentLayout();
4327: Rectangle tabRect = new Rectangle();
4328: return getTabBounds(i, tabRect);
4329: }
4330:
4331: @Override
4332: public int getTabRunCount(JTabbedPane pane) {
4333: ensureCurrentLayout();
4334: return _runCount;
4335: }
4336:
4337: /**
4338: * Returns the tab index which intersects the specified point
4339: * in the JTabbedPane's coordinate space.
4340: */
4341: @Override
4342: public int tabForCoordinate(JTabbedPane pane, int x, int y) {
4343: ensureCurrentLayout();
4344: Point p = new Point(x, y);
4345:
4346: if (scrollableTabLayoutEnabled()) {
4347: translatePointToTabPanel(x, y, p);
4348: }
4349: int tabCount = _tabPane.getTabCount();
4350: for (int i = 0; i < tabCount; i++) {
4351: if (_rects[i].contains(p.x, p.y)) {
4352: return i;
4353: }
4354: }
4355: return -1;
4356: }
4357:
4358: /**
4359: * Returns the bounds of the specified tab in the coordinate space
4360: * of the JTabbedPane component. This is required because the tab rects
4361: * are by default defined in the coordinate space of the component where
4362: * they are rendered, which could be the JTabbedPane
4363: * (for WRAP_TAB_LAYOUT) or a ScrollableTabPanel (SCROLL_TAB_LAYOUT).
4364: * This method should be used whenever the tab rectangle must be relative
4365: * to the JTabbedPane itself and the result should be placed in a
4366: * designated Rectangle object (rather than instantiating and returning
4367: * a new Rectangle each time). The tab index parameter must be a valid
4368: * tabbed pane tab index (0 to tab count - 1, inclusive). The destination
4369: * rectangle parameter must be a valid <code>Rectangle</code> instance.
4370: * The handling of invalid parameters is unspecified.
4371: *
4372: * @param tabIndex the index of the tab
4373: * @param dest the rectangle where the result should be placed
4374: * @return the resulting rectangle
4375: */
4376: protected Rectangle getTabBounds(int tabIndex, Rectangle dest) {
4377: if (_rects.length == 0) {
4378: return null;
4379: }
4380: // to make the index is in bound.
4381: if (tabIndex > _rects.length - 1) {
4382: tabIndex = _rects.length - 1;
4383: }
4384: if (tabIndex < 0) {
4385: tabIndex = 0;
4386: }
4387:
4388: dest.width = _rects[tabIndex].width;
4389: dest.height = _rects[tabIndex].height;
4390:
4391: if (scrollableTabLayoutEnabled()) { // SCROLL_TAB_LAYOUT
4392: // Need to translate coordinates based on viewport location &
4393: // view position
4394: Point vpp = _tabScroller.viewport.getLocation();
4395: Point viewp = _tabScroller.viewport.getViewPosition();
4396: dest.x = _rects[tabIndex].x + vpp.x - viewp.x;
4397: dest.y = _rects[tabIndex].y + vpp.y - viewp.y;
4398:
4399: } else { // WRAP_TAB_LAYOUT
4400: dest.x = _rects[tabIndex].x;
4401: dest.y = _rects[tabIndex].y;
4402: }
4403: return dest;
4404: }
4405:
4406: /**
4407: * Returns the tab index which intersects the specified point
4408: * in the coordinate space of the component where the
4409: * tabs are actually rendered, which could be the JTabbedPane
4410: * (for WRAP_TAB_LAYOUT) or a ScrollableTabPanel (SCROLL_TAB_LAYOUT).
4411: */
4412: public int getTabAtLocation(int x, int y) {
4413: ensureCurrentLayout();
4414:
4415: int tabCount = _tabPane.getTabCount();
4416: for (int i = 0; i < tabCount; i++) {
4417: if (_rects[i].contains(x, y)) {
4418: return i;
4419: }
4420: }
4421: return -1;
4422: }
4423:
4424: /**
4425: * Returns the index of the tab closest to the passed in location, note
4426: * that the returned tab may not contain the location x,y.
4427: */
4428: private int getClosestTab(int x, int y) {
4429: int min = 0;
4430: int tabCount = Math.min(_rects.length, _tabPane.getTabCount());
4431: int max = tabCount;
4432: int tabPlacement = _tabPane.getTabPlacement();
4433: boolean useX = (tabPlacement == TOP || tabPlacement == BOTTOM);
4434: int want = (useX) ? x : y;
4435:
4436: while (min != max) {
4437: int current = (max + min) >> 1;
4438: int minLoc;
4439: int maxLoc;
4440:
4441: if (useX) {
4442: minLoc = _rects[current].x;
4443: maxLoc = minLoc + _rects[current].width;
4444: } else {
4445: minLoc = _rects[current].y;
4446: maxLoc = minLoc + _rects[current].height;
4447: }
4448: if (want < minLoc) {
4449: max = current;
4450: if (min == max) {
4451: return Math.max(0, current - 1);
4452: }
4453: } else if (want >= maxLoc) {
4454: min = current;
4455: if (max - min <= 1) {
4456: return Math.max(current + 1, tabCount - 1);
4457: }
4458: } else {
4459: return current;
4460: }
4461: }
4462: return min;
4463: }
4464:
4465: /**
4466: * Returns a point which is translated from the specified point in the
4467: * JTabbedPane's coordinate space to the coordinate space of the
4468: * ScrollableTabPanel. This is used for SCROLL_TAB_LAYOUT ONLY.
4469: */
4470: private Point translatePointToTabPanel(int srcx, int srcy,
4471: Point dest) {
4472: Point vpp = _tabScroller.viewport.getLocation();
4473: Point viewp = _tabScroller.viewport.getViewPosition();
4474: dest.x = srcx - vpp.x + viewp.x;
4475: dest.y = srcy - vpp.y + viewp.y;
4476: return dest;
4477: }
4478:
4479: // VsnetJideTabbedPaneUI methods
4480:
4481: protected Component getVisibleComponent() {
4482: return visibleComponent;
4483: }
4484:
4485: protected void setVisibleComponent(Component component) {
4486: if (visibleComponent != null && visibleComponent != component
4487: && visibleComponent.getParent() == _tabPane) {
4488: visibleComponent.setVisible(false);
4489: }
4490: if (component != null && !component.isVisible()) {
4491: component.setVisible(true);
4492: }
4493: visibleComponent = component;
4494: }
4495:
4496: protected void assureRectsCreated(int tabCount) {
4497: int rectArrayLen = _rects.length;
4498: if (tabCount != rectArrayLen) {
4499: Rectangle[] tempRectArray = new Rectangle[tabCount];
4500: System.arraycopy(_rects, 0, tempRectArray, 0, Math.min(
4501: rectArrayLen, tabCount));
4502: _rects = tempRectArray;
4503: for (int rectIndex = rectArrayLen; rectIndex < tabCount; rectIndex++) {
4504: _rects[rectIndex] = new Rectangle();
4505: }
4506: }
4507:
4508: }
4509:
4510: protected void expandTabRunsArray() {
4511: int rectLen = _tabRuns.length;
4512: int[] newArray = new int[rectLen + 10];
4513: System.arraycopy(_tabRuns, 0, newArray, 0, _runCount);
4514: _tabRuns = newArray;
4515: }
4516:
4517: protected int getRunForTab(int tabCount, int tabIndex) {
4518: for (int i = 0; i < _runCount; i++) {
4519: int first = _tabRuns[i];
4520: int last = lastTabInRun(tabCount, i);
4521: if (tabIndex >= first && tabIndex <= last) {
4522: return i;
4523: }
4524: }
4525: return 0;
4526: }
4527:
4528: protected int lastTabInRun(int tabCount, int run) {
4529: if (_runCount == 1) {
4530: return tabCount - 1;
4531: }
4532: int nextRun = (run == _runCount - 1 ? 0 : run + 1);
4533: if (_tabRuns[nextRun] == 0) {
4534: return tabCount - 1;
4535: }
4536: return _tabRuns[nextRun] - 1;
4537: }
4538:
4539: protected int getTabRunOverlay(int tabPlacement) {
4540: return _tabRunOverlay;
4541: }
4542:
4543: protected int getTabRunIndent(int tabPlacement, int run) {
4544: return 0;
4545: }
4546:
4547: protected boolean shouldPadTabRun(int tabPlacement, int run) {
4548: return _runCount > 1;
4549: }
4550:
4551: protected boolean shouldRotateTabRuns(int tabPlacement) {
4552: return true;
4553: }
4554:
4555: protected Icon getIconForTab(int tabIndex) {
4556: if (_tabPane.isUseDefaultShowIconsOnTab()) {
4557: if (_showIconOnTab) {
4558: return (!_tabPane.isEnabled() || !_tabPane
4559: .isEnabledAt(tabIndex)) ? _tabPane
4560: .getDisabledIconAt(tabIndex) : _tabPane
4561: .getIconAt(tabIndex);
4562: } else {
4563: return null;
4564: }
4565: } else if (_tabPane.isShowIconsOnTab()) {
4566: return (!_tabPane.isEnabled() || !_tabPane
4567: .isEnabledAt(tabIndex)) ? _tabPane
4568: .getDisabledIconAt(tabIndex) : _tabPane
4569: .getIconAt(tabIndex);
4570: } else {
4571: return null;
4572: }
4573: }
4574:
4575: /**
4576: * Returns the text View object required to render stylized text (HTML) for
4577: * the specified tab or null if no specialized text rendering is needed
4578: * for this tab. This is provided to support html rendering inside tabs.
4579: *
4580: * @param tabIndex the index of the tab
4581: * @return the text view to render the tab's text or null if no
4582: * specialized rendering is required
4583: */
4584: protected View getTextViewForTab(int tabIndex) {
4585: if (htmlViews != null && tabIndex < htmlViews.size()) {
4586: return (View) htmlViews.elementAt(tabIndex);
4587: }
4588: return null;
4589: }
4590:
4591: protected int calculateTabHeight(int tabPlacement, int tabIndex,
4592: FontMetrics metrics) {
4593: int height = 0;
4594: if (tabPlacement == JideTabbedPane.TOP
4595: || tabPlacement == JideTabbedPane.BOTTOM) {
4596: View v = getTextViewForTab(tabIndex);
4597: if (v != null) {
4598: // html
4599: height += (int) v.getPreferredSpan(View.Y_AXIS);
4600: } else {
4601: // plain text
4602: height += metrics.getHeight();
4603: }
4604: Icon icon = getIconForTab(tabIndex);
4605: Insets tabInsets = getTabInsets(tabPlacement, tabIndex);
4606:
4607: if (icon != null) {
4608: height = Math.max(height, icon.getIconHeight());
4609: }
4610: height += tabInsets.top + tabInsets.bottom + 2;
4611: } else {
4612: Icon icon = getIconForTab(tabIndex);
4613: Insets tabInsets = getTabInsets(tabPlacement, tabIndex);
4614: height = tabInsets.top + tabInsets.bottom + 3;
4615:
4616: if (icon != null) {
4617: height += icon.getIconHeight() + _textIconGap;
4618: }
4619: View v = getTextViewForTab(tabIndex);
4620: if (v != null) {
4621: // html
4622: height += (int) v.getPreferredSpan(View.X_AXIS);
4623: } else {
4624: // plain text
4625: String title = _tabPane.getDisplayTitleAt(tabIndex);
4626: height += SwingUtilities.computeStringWidth(metrics,
4627: title);
4628: }
4629:
4630: // for gripper
4631: if (_tabPane.isShowGripper()) {
4632: height += _gripperHeight;
4633: }
4634:
4635: if (scrollableTabLayoutEnabled() && isShowCloseButton()
4636: && isShowCloseButtonOnTab()
4637: && _tabPane.isTabClosableAt(tabIndex)) {
4638: if (_tabPane.isShowCloseButtonOnSelectedTab()) {
4639: if (_tabPane.getSelectedIndex() == tabIndex) {
4640: height += _closeButtons[tabIndex]
4641: .getPreferredSize().height + 2;
4642: }
4643: } else {
4644: height += _closeButtons[tabIndex]
4645: .getPreferredSize().height + 2;
4646: }
4647: }
4648:
4649: // height += _tabRectPadding;
4650: }
4651: return height;
4652: }
4653:
4654: protected int calculateMaxTabHeight(int tabPlacement) {
4655: int tabCount = _tabPane.getTabCount();
4656: int result = 0;
4657: for (int i = 0; i < tabCount; i++) {
4658: FontMetrics metrics = getFontMetrics(i);
4659: result = Math.max(calculateTabHeight(tabPlacement, i,
4660: metrics), result);
4661: }
4662: return result;
4663: }
4664:
4665: protected int calculateTabWidth(int tabPlacement, int tabIndex,
4666: FontMetrics metrics) {
4667: int width = 0;
4668: if (tabPlacement == JideTabbedPane.TOP
4669: || tabPlacement == JideTabbedPane.BOTTOM) {
4670: Icon icon = getIconForTab(tabIndex);
4671: Insets tabInsets = getTabInsets(tabPlacement, tabIndex);
4672: width = tabInsets.left + tabInsets.right + 3 + getTabGap();
4673:
4674: if (icon != null) {
4675: width += icon.getIconWidth() + _textIconGap;
4676: }
4677: View v = getTextViewForTab(tabIndex);
4678: if (v != null) {
4679: // html
4680: width += (int) v.getPreferredSpan(View.X_AXIS);
4681: } else {
4682: // plain text
4683: String title = _tabPane.getDisplayTitleAt(tabIndex);
4684: width += SwingUtilities.computeStringWidth(metrics,
4685: title);
4686: }
4687:
4688: // for gripper
4689: if (_tabPane.isShowGripper()) {
4690: width += _gripperWidth;
4691: }
4692:
4693: if (scrollableTabLayoutEnabled() && isShowCloseButton()
4694: && isShowCloseButtonOnTab()
4695: && _tabPane.isTabClosableAt(tabIndex)) {
4696: if (_tabPane.isShowCloseButtonOnSelectedTab()) {
4697: if (_tabPane.getSelectedIndex() == tabIndex) {
4698: width += _closeButtons[tabIndex]
4699: .getPreferredSize().width + 2;
4700: }
4701: } else {
4702: width += _closeButtons[tabIndex].getPreferredSize().width + 2;
4703: }
4704: }
4705:
4706: // width += _tabRectPadding;
4707: } else {
4708: View v = getTextViewForTab(tabIndex);
4709: if (v != null) {
4710: // html
4711: width += (int) v.getPreferredSpan(View.Y_AXIS);
4712: } else {
4713: // plain text
4714: width += metrics.getHeight();
4715: }
4716: Icon icon = getIconForTab(tabIndex);
4717: Insets tabInsets = getTabInsets(tabPlacement, tabIndex);
4718:
4719: if (icon != null) {
4720: width = Math.max(width, icon.getIconWidth());
4721: }
4722: width += tabInsets.left + tabInsets.right + 2;
4723: }
4724: return width;
4725: }
4726:
4727: protected int calculateMaxTabWidth(int tabPlacement) {
4728: int tabCount = _tabPane.getTabCount();
4729: int result = 0;
4730: for (int i = 0; i < tabCount; i++) {
4731: FontMetrics metrics = getFontMetrics(i);
4732: result = Math.max(calculateTabWidth(tabPlacement, i,
4733: metrics), result);
4734: }
4735: return result;
4736: }
4737:
4738: protected int calculateTabAreaHeight(int tabPlacement,
4739: int horizRunCount, int maxTabHeight) {
4740: if (!_tabPane.isTabShown()) {
4741: return 0;
4742: }
4743: Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
4744: int tabRunOverlay = getTabRunOverlay(tabPlacement);
4745: return (horizRunCount > 0 ? horizRunCount
4746: * (maxTabHeight - tabRunOverlay) + tabRunOverlay
4747: + tabAreaInsets.top + tabAreaInsets.bottom : 0);
4748: }
4749:
4750: protected int calculateTabAreaWidth(int tabPlacement,
4751: int vertRunCount, int maxTabWidth) {
4752: if (!_tabPane.isTabShown()) {
4753: return 0;
4754: }
4755: Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
4756: int tabRunOverlay = getTabRunOverlay(tabPlacement);
4757: return (vertRunCount > 0 ? vertRunCount
4758: * (maxTabWidth - tabRunOverlay) + tabRunOverlay
4759: + tabAreaInsets.left + tabAreaInsets.right : 0);
4760: }
4761:
4762: protected Insets getTabInsets(int tabPlacement, int tabIndex) {
4763: rotateInsets(_tabInsets, _currentTabInsets, tabPlacement);
4764: return _currentTabInsets;
4765: }
4766:
4767: protected Insets getSelectedTabPadInsets(int tabPlacement) {
4768: rotateInsets(_selectedTabPadInsets, _currentPadInsets,
4769: tabPlacement);
4770: return _currentPadInsets;
4771: }
4772:
4773: protected Insets getTabAreaInsets(int tabPlacement) {
4774: rotateInsets(_tabAreaInsets, _currentTabAreaInsets,
4775: tabPlacement);
4776: return _currentTabAreaInsets;
4777: }
4778:
4779: protected Insets getContentBorderInsets(int tabPlacement) {
4780: rotateInsets(_tabPane.getContentBorderInsets(),
4781: _currentContentBorderInsets, tabPlacement);
4782: if (_ignoreContentBorderInsetsIfNoTabs
4783: && !_tabPane.isTabShown())
4784: return new Insets(0, 0, 0, 0);
4785: else
4786: return _currentContentBorderInsets;
4787:
4788: }
4789:
4790: protected FontMetrics getFontMetrics(int tab) {
4791: Font font = null;
4792: int selectedIndex = _tabPane.getSelectedIndex();
4793: if (selectedIndex == tab
4794: && _tabPane.getSelectedTabFont() != null) {
4795: font = _tabPane.getSelectedTabFont();
4796: } else {
4797: font = _tabPane.getFont();
4798: }
4799:
4800: if (selectedIndex == tab && _tabPane.isBoldActiveTab()
4801: && font.getStyle() != Font.BOLD) {
4802: font = font.deriveFont(Font.BOLD);
4803: }
4804: return _tabPane.getFontMetrics(font);
4805: }
4806:
4807: // Tab Navigation methods
4808:
4809: protected void navigateSelectedTab(int direction) {
4810: int tabPlacement = _tabPane.getTabPlacement();
4811: int current = _tabPane.getSelectedIndex();
4812: int tabCount = _tabPane.getTabCount();
4813:
4814: boolean leftToRight = _tabPane.getComponentOrientation()
4815: .isLeftToRight();
4816:
4817: // If we have no tabs then don't navigate.
4818: if (tabCount <= 0) {
4819: return;
4820: }
4821:
4822: int offset;
4823: switch (tabPlacement) {
4824: case NEXT:
4825: selectNextTab(current);
4826: break;
4827: case PREVIOUS:
4828: selectPreviousTab(current);
4829: break;
4830: case LEFT:
4831: case RIGHT:
4832: switch (direction) {
4833: case NORTH:
4834: selectPreviousTabInRun(current);
4835: break;
4836: case SOUTH:
4837: selectNextTabInRun(current);
4838: break;
4839: case WEST:
4840: offset = getTabRunOffset(tabPlacement, tabCount,
4841: current, false);
4842: selectAdjacentRunTab(tabPlacement, current, offset);
4843: break;
4844: case EAST:
4845: offset = getTabRunOffset(tabPlacement, tabCount,
4846: current, true);
4847: selectAdjacentRunTab(tabPlacement, current, offset);
4848: break;
4849: default:
4850: }
4851: break;
4852: case BOTTOM:
4853: case TOP:
4854: default:
4855: switch (direction) {
4856: case NORTH:
4857: offset = getTabRunOffset(tabPlacement, tabCount,
4858: current, false);
4859: selectAdjacentRunTab(tabPlacement, current, offset);
4860: break;
4861: case SOUTH:
4862: offset = getTabRunOffset(tabPlacement, tabCount,
4863: current, true);
4864: selectAdjacentRunTab(tabPlacement, current, offset);
4865: break;
4866: case EAST:
4867: if (leftToRight) {
4868: selectNextTabInRun(current);
4869: } else {
4870: selectPreviousTabInRun(current);
4871: }
4872: break;
4873: case WEST:
4874: if (leftToRight) {
4875: selectPreviousTabInRun(current);
4876: } else {
4877: selectNextTabInRun(current);
4878: }
4879: break;
4880: default:
4881: }
4882: }
4883: }
4884:
4885: protected void selectNextTabInRun(int current) {
4886: int tabCount = _tabPane.getTabCount();
4887: int tabIndex = getNextTabIndexInRun(tabCount, current);
4888:
4889: while (tabIndex != current && !_tabPane.isEnabledAt(tabIndex)) {
4890: tabIndex = getNextTabIndexInRun(tabCount, tabIndex);
4891: }
4892: _tabPane.setSelectedIndex(tabIndex);
4893: }
4894:
4895: protected void selectPreviousTabInRun(int current) {
4896: int tabCount = _tabPane.getTabCount();
4897: int tabIndex = getPreviousTabIndexInRun(tabCount, current);
4898:
4899: while (tabIndex != current && !_tabPane.isEnabledAt(tabIndex)) {
4900: tabIndex = getPreviousTabIndexInRun(tabCount, tabIndex);
4901: }
4902: _tabPane.setSelectedIndex(tabIndex);
4903: }
4904:
4905: protected void selectNextTab(int current) {
4906: int tabIndex = getNextTabIndex(current);
4907:
4908: while (tabIndex != current && !_tabPane.isEnabledAt(tabIndex)) {
4909: tabIndex = getNextTabIndex(tabIndex);
4910: }
4911: _tabPane.setSelectedIndex(tabIndex);
4912: }
4913:
4914: protected void selectPreviousTab(int current) {
4915: int tabIndex = getPreviousTabIndex(current);
4916:
4917: while (tabIndex != current && !_tabPane.isEnabledAt(tabIndex)) {
4918: tabIndex = getPreviousTabIndex(tabIndex);
4919: }
4920: _tabPane.setSelectedIndex(tabIndex);
4921: }
4922:
4923: protected void selectAdjacentRunTab(int tabPlacement, int tabIndex,
4924: int offset) {
4925: if (_runCount < 2) {
4926: return;
4927: }
4928: int newIndex;
4929: Rectangle r = _rects[tabIndex];
4930: switch (tabPlacement) {
4931: case LEFT:
4932: case RIGHT:
4933: newIndex = getTabAtLocation(r.x + (r.width >> 1) + offset,
4934: r.y + (r.height >> 1));
4935: break;
4936: case BOTTOM:
4937: case TOP:
4938: default:
4939: newIndex = getTabAtLocation(r.x + (r.width >> 1), r.y
4940: + (r.height >> 1) + offset);
4941: }
4942: if (newIndex != -1) {
4943: while (!_tabPane.isEnabledAt(newIndex)
4944: && newIndex != tabIndex) {
4945: newIndex = getNextTabIndex(newIndex);
4946: }
4947: _tabPane.setSelectedIndex(newIndex);
4948: }
4949: }
4950:
4951: protected int getTabRunOffset(int tabPlacement, int tabCount,
4952: int tabIndex, boolean forward) {
4953: int run = getRunForTab(tabCount, tabIndex);
4954: int offset;
4955: switch (tabPlacement) {
4956: case LEFT: {
4957: if (run == 0) {
4958: offset = (forward ? -(calculateTabAreaWidth(
4959: tabPlacement, _runCount, _maxTabWidth) - _maxTabWidth)
4960: : -_maxTabWidth);
4961:
4962: } else if (run == _runCount - 1) {
4963: offset = (forward ? _maxTabWidth
4964: : calculateTabAreaWidth(tabPlacement,
4965: _runCount, _maxTabWidth)
4966: - _maxTabWidth);
4967: } else {
4968: offset = (forward ? _maxTabWidth : -_maxTabWidth);
4969: }
4970: break;
4971: }
4972: case RIGHT: {
4973: if (run == 0) {
4974: offset = (forward ? _maxTabWidth
4975: : calculateTabAreaWidth(tabPlacement,
4976: _runCount, _maxTabWidth)
4977: - _maxTabWidth);
4978: } else if (run == _runCount - 1) {
4979: offset = (forward ? -(calculateTabAreaWidth(
4980: tabPlacement, _runCount, _maxTabWidth) - _maxTabWidth)
4981: : -_maxTabWidth);
4982: } else {
4983: offset = (forward ? _maxTabWidth : -_maxTabWidth);
4984: }
4985: break;
4986: }
4987: case BOTTOM: {
4988: if (run == 0) {
4989: offset = (forward ? _maxTabHeight
4990: : calculateTabAreaHeight(tabPlacement,
4991: _runCount, _maxTabHeight)
4992: - _maxTabHeight);
4993: } else if (run == _runCount - 1) {
4994: offset = (forward ? -(calculateTabAreaHeight(
4995: tabPlacement, _runCount, _maxTabHeight) - _maxTabHeight)
4996: : -_maxTabHeight);
4997: } else {
4998: offset = (forward ? _maxTabHeight : -_maxTabHeight);
4999: }
5000: break;
5001: }
5002: case TOP:
5003: default: {
5004: if (run == 0) {
5005: offset = (forward ? -(calculateTabAreaHeight(
5006: tabPlacement, _runCount, _maxTabHeight) - _maxTabHeight)
5007: : -_maxTabHeight);
5008: } else if (run == _runCount - 1) {
5009: offset = (forward ? _maxTabHeight
5010: : calculateTabAreaHeight(tabPlacement,
5011: _runCount, _maxTabHeight)
5012: - _maxTabHeight);
5013: } else {
5014: offset = (forward ? _maxTabHeight : -_maxTabHeight);
5015: }
5016: }
5017: }
5018: return offset;
5019: }
5020:
5021: protected int getPreviousTabIndex(int base) {
5022: int tabIndex = (base - 1 >= 0 ? base - 1 : _tabPane
5023: .getTabCount() - 1);
5024: return (tabIndex >= 0 ? tabIndex : 0);
5025: }
5026:
5027: protected int getNextTabIndex(int base) {
5028: return (base + 1) % _tabPane.getTabCount();
5029: }
5030:
5031: protected int getNextTabIndexInRun(int tabCount, int base) {
5032: if (_runCount < 2) {
5033: return getNextTabIndex(base);
5034: }
5035: int currentRun = getRunForTab(tabCount, base);
5036: int next = getNextTabIndex(base);
5037: if (next == _tabRuns[getNextTabRun(currentRun)]) {
5038: return _tabRuns[currentRun];
5039: }
5040: return next;
5041: }
5042:
5043: protected int getPreviousTabIndexInRun(int tabCount, int base) {
5044: if (_runCount < 2) {
5045: return getPreviousTabIndex(base);
5046: }
5047: int currentRun = getRunForTab(tabCount, base);
5048: if (base == _tabRuns[currentRun]) {
5049: int previous = _tabRuns[getNextTabRun(currentRun)] - 1;
5050: return (previous != -1 ? previous : tabCount - 1);
5051: }
5052: return getPreviousTabIndex(base);
5053: }
5054:
5055: protected int getPreviousTabRun(int baseRun) {
5056: int runIndex = (baseRun - 1 >= 0 ? baseRun - 1 : _runCount - 1);
5057: return (runIndex >= 0 ? runIndex : 0);
5058: }
5059:
5060: protected int getNextTabRun(int baseRun) {
5061: return (baseRun + 1) % _runCount;
5062: }
5063:
5064: public static void rotateInsets(Insets topInsets,
5065: Insets targetInsets, int targetPlacement) {
5066: switch (targetPlacement) {
5067: case LEFT:
5068: targetInsets.top = topInsets.left;
5069: targetInsets.left = topInsets.top;
5070: targetInsets.bottom = topInsets.right;
5071: targetInsets.right = topInsets.bottom;
5072: break;
5073: case BOTTOM:
5074: targetInsets.top = topInsets.bottom;
5075: targetInsets.left = topInsets.left;
5076: targetInsets.bottom = topInsets.top;
5077: targetInsets.right = topInsets.right;
5078: break;
5079: case RIGHT:
5080: targetInsets.top = topInsets.left;
5081: targetInsets.left = topInsets.bottom;
5082: targetInsets.bottom = topInsets.right;
5083: targetInsets.right = topInsets.top;
5084: break;
5085: case TOP:
5086: default:
5087: targetInsets.top = topInsets.top;
5088: targetInsets.left = topInsets.left;
5089: targetInsets.bottom = topInsets.bottom;
5090: targetInsets.right = topInsets.right;
5091: }
5092: }
5093:
5094: protected boolean requestFocusForVisibleComponent() {
5095: Component visibleComponent = getVisibleComponent();
5096: Component lastFocused = _tabPane
5097: .getLastFocusedComponent(visibleComponent);
5098: if (lastFocused != null && lastFocused.requestFocusInWindow()) {
5099: return true;
5100: } else if (visibleComponent != null
5101: && visibleComponent.isFocusTraversable()) {
5102: JideSwingUtilities.compositeRequestFocus(visibleComponent);
5103: return true;
5104: } else if (visibleComponent instanceof JComponent) {
5105: if (((JComponent) visibleComponent).requestDefaultFocus()) {
5106: return true;
5107: }
5108: }
5109: return false;
5110: }
5111:
5112: private static class RightAction extends AbstractAction {
5113: public void actionPerformed(ActionEvent e) {
5114: JTabbedPane pane = (JTabbedPane) e.getSource();
5115: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5116: .getUI();
5117: ui.navigateSelectedTab(EAST);
5118: }
5119: }
5120:
5121: private static class LeftAction extends AbstractAction {
5122: public void actionPerformed(ActionEvent e) {
5123: JTabbedPane pane = (JTabbedPane) e.getSource();
5124: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5125: .getUI();
5126: ui.navigateSelectedTab(WEST);
5127: }
5128: }
5129:
5130: private static class UpAction extends AbstractAction {
5131: public void actionPerformed(ActionEvent e) {
5132: JTabbedPane pane = (JTabbedPane) e.getSource();
5133: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5134: .getUI();
5135: ui.navigateSelectedTab(NORTH);
5136: }
5137: }
5138:
5139: private static class DownAction extends AbstractAction {
5140: public void actionPerformed(ActionEvent e) {
5141: JTabbedPane pane = (JTabbedPane) e.getSource();
5142: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5143: .getUI();
5144: ui.navigateSelectedTab(SOUTH);
5145: }
5146: }
5147:
5148: private static class NextAction extends AbstractAction {
5149: public void actionPerformed(ActionEvent e) {
5150: JTabbedPane pane = (JTabbedPane) e.getSource();
5151: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5152: .getUI();
5153: ui.navigateSelectedTab(NEXT);
5154: }
5155: }
5156:
5157: private static class PreviousAction extends AbstractAction {
5158: public void actionPerformed(ActionEvent e) {
5159: JTabbedPane pane = (JTabbedPane) e.getSource();
5160: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5161: .getUI();
5162: ui.navigateSelectedTab(PREVIOUS);
5163: }
5164: }
5165:
5166: private static class PageUpAction extends AbstractAction {
5167: public void actionPerformed(ActionEvent e) {
5168: JTabbedPane pane = (JTabbedPane) e.getSource();
5169: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5170: .getUI();
5171: int tabPlacement = pane.getTabPlacement();
5172: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
5173: ui.navigateSelectedTab(WEST);
5174: } else {
5175: ui.navigateSelectedTab(NORTH);
5176: }
5177: }
5178: }
5179:
5180: private static class PageDownAction extends AbstractAction {
5181: public void actionPerformed(ActionEvent e) {
5182: JTabbedPane pane = (JTabbedPane) e.getSource();
5183: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5184: .getUI();
5185: int tabPlacement = pane.getTabPlacement();
5186: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
5187: ui.navigateSelectedTab(EAST);
5188: } else {
5189: ui.navigateSelectedTab(SOUTH);
5190: }
5191: }
5192: }
5193:
5194: private static class RequestFocusAction extends AbstractAction {
5195: public void actionPerformed(ActionEvent e) {
5196: JTabbedPane pane = (JTabbedPane) e.getSource();
5197: if (!pane.requestFocusInWindow()) {
5198: pane.requestFocus();
5199: }
5200: }
5201: }
5202:
5203: private static class RequestFocusForVisibleAction extends
5204: AbstractAction {
5205: public void actionPerformed(ActionEvent e) {
5206: JTabbedPane pane = (JTabbedPane) e.getSource();
5207: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5208: .getUI();
5209: ui.requestFocusForVisibleComponent();
5210: }
5211: }
5212:
5213: /**
5214: * Selects a tab in the JTabbedPane based on the String of the
5215: * action command. The tab selected is based on the first tab that
5216: * has a mnemonic matching the first character of the action command.
5217: */
5218: private static class SetSelectedIndexAction extends AbstractAction {
5219: public void actionPerformed(ActionEvent e) {
5220: JTabbedPane pane = (JTabbedPane) e.getSource();
5221:
5222: if (pane != null
5223: && (pane.getUI() instanceof BasicJideTabbedPaneUI)) {
5224: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5225: .getUI();
5226: String command = e.getActionCommand();
5227:
5228: if (command != null && command.length() > 0) {
5229: int mnemonic = (int) e.getActionCommand().charAt(0);
5230: if (mnemonic >= 'a' && mnemonic <= 'z') {
5231: mnemonic -= ('a' - 'A');
5232: }
5233: Integer index = (Integer) ui._mnemonicToIndexMap
5234: .get(new Integer(mnemonic));
5235: if (index != null && pane.isEnabledAt(index)) {
5236: pane.setSelectedIndex(index);
5237: }
5238: }
5239: }
5240: }
5241: }
5242:
5243: protected TabCloseButton createNoFocusButton(int type) {
5244: return new TabCloseButton(type);
5245: }
5246:
5247: private static class ScrollTabsForwardAction extends AbstractAction {
5248: public ScrollTabsForwardAction() {
5249: super ();
5250: putValue(Action.SHORT_DESCRIPTION, Resource
5251: .getResourceBundle(Locale.getDefault()).getString(
5252: "JideTabbedPane.scrollForward"));
5253: }
5254:
5255: public void actionPerformed(ActionEvent e) {
5256: JTabbedPane pane = null;
5257: Object src = e.getSource();
5258: if (src instanceof JTabbedPane) {
5259: pane = (JTabbedPane) src;
5260: } else if (src instanceof TabCloseButton) {
5261: pane = (JTabbedPane) SwingUtilities.getAncestorOfClass(
5262: JTabbedPane.class, (TabCloseButton) src);
5263: }
5264:
5265: if (pane != null) {
5266: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5267: .getUI();
5268:
5269: if (ui.scrollableTabLayoutEnabled()) {
5270: ui._tabScroller.scrollForward(pane
5271: .getTabPlacement());
5272: }
5273: }
5274: }
5275: }
5276:
5277: private static class ScrollTabsBackwardAction extends
5278: AbstractAction {
5279: public ScrollTabsBackwardAction() {
5280: super ();
5281: putValue(Action.SHORT_DESCRIPTION, Resource
5282: .getResourceBundle(Locale.getDefault()).getString(
5283: "JideTabbedPane.scrollBackward"));
5284: }
5285:
5286: public void actionPerformed(ActionEvent e) {
5287: JTabbedPane pane = null;
5288: Object src = e.getSource();
5289: if (src instanceof JTabbedPane) {
5290: pane = (JTabbedPane) src;
5291: } else if (src instanceof TabCloseButton) {
5292: pane = (JTabbedPane) SwingUtilities.getAncestorOfClass(
5293: JTabbedPane.class, (TabCloseButton) src);
5294: }
5295:
5296: if (pane != null) {
5297: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5298: .getUI();
5299:
5300: if (ui.scrollableTabLayoutEnabled()) {
5301: ui._tabScroller.scrollBackward(pane
5302: .getTabPlacement());
5303: }
5304: }
5305: }
5306: }
5307:
5308: private static class ScrollTabsListAction extends AbstractAction {
5309:
5310: public ScrollTabsListAction() {
5311: super ();
5312: putValue(Action.SHORT_DESCRIPTION, Resource
5313: .getResourceBundle(Locale.getDefault()).getString(
5314: "JideTabbedPane.showList"));
5315: }
5316:
5317: public void actionPerformed(ActionEvent e) {
5318: JTabbedPane pane = null;
5319: Object src = e.getSource();
5320: if (src instanceof JTabbedPane) {
5321: pane = (JTabbedPane) src;
5322: } else if (src instanceof TabCloseButton) {
5323: pane = (JTabbedPane) SwingUtilities.getAncestorOfClass(
5324: JTabbedPane.class, (TabCloseButton) src);
5325: }
5326:
5327: if (pane != null) {
5328: BasicJideTabbedPaneUI ui = (BasicJideTabbedPaneUI) pane
5329: .getUI();
5330:
5331: if (ui.scrollableTabLayoutEnabled()) {
5332: if (ui._tabScroller._popup != null
5333: && ui._tabScroller._popup.isPopupVisible()) {
5334: ui._tabScroller._popup.hidePopupImmediately();
5335: ui._tabScroller._popup = null;
5336: } else {
5337: ui._tabScroller.createPopup(pane
5338: .getTabPlacement());
5339: }
5340: }
5341: }
5342: }
5343: }
5344:
5345: private static class CloseTabAction extends AbstractAction {
5346: public CloseTabAction() {
5347: super ();
5348: putValue(Action.SHORT_DESCRIPTION, Resource
5349: .getResourceBundle(Locale.getDefault()).getString(
5350: "JideTabbedPane.close"));
5351: }
5352:
5353: public void actionPerformed(ActionEvent e) {
5354: JideTabbedPane pane = null;
5355: Object src = e.getSource();
5356: boolean closeSelected = false;
5357: if (src instanceof JideTabbedPane) {
5358: pane = (JideTabbedPane) src;
5359: } else if (src instanceof TabCloseButton
5360: && ((TabCloseButton) src).getParent() instanceof JideTabbedPane) {
5361: pane = (JideTabbedPane) ((TabCloseButton) src)
5362: .getParent();
5363: closeSelected = true;
5364: } else if (src instanceof TabCloseButton
5365: && ((TabCloseButton) src).getParent() instanceof ScrollableTabPanel) {
5366: pane = (JideTabbedPane) SwingUtilities
5367: .getAncestorOfClass(JideTabbedPane.class,
5368: (TabCloseButton) src);
5369: closeSelected = false;
5370: } else {
5371: return; // shouldn't happen
5372: }
5373:
5374: if (pane.isTabEditing()) {
5375: pane.stopTabEditing();
5376: }
5377:
5378: if (pane.getCloseAction() != null) {
5379: if (closeSelected) {
5380: pane.getCloseAction().actionPerformed(e);
5381: } else {
5382: int i = ((TabCloseButton) src).getIndex();
5383: if (i != -1) {
5384: pane.setSelectedIndex(i);
5385: pane.getCloseAction().actionPerformed(e);
5386: }
5387: }
5388: } else {
5389: if (closeSelected) {
5390: if (pane.getSelectedIndex() >= 0)
5391: pane.removeTabAt(pane.getSelectedIndex());
5392: if (pane.getTabCount() == 0) {
5393: pane.updateUI();
5394: }
5395: } else {
5396: int i = ((TabCloseButton) src).getIndex();
5397: if (i != -1) {
5398:
5399: int tabIndex = pane.getSelectedIndex();
5400:
5401: pane.removeTabAt(i);
5402:
5403: if (i < tabIndex) {
5404: pane.setSelectedIndex(tabIndex - 1);
5405: }
5406:
5407: if (pane.getTabCount() == 0) {
5408: pane.updateUI();
5409: }
5410: }
5411: }
5412: }
5413: }
5414: }
5415:
5416: /**
5417: * This inner class is marked "public" due to a compiler bug. This
5418: * class should be treated as a "protected" inner class.
5419: * Instantiate it only within subclasses of VsnetJideTabbedPaneUI.
5420: */
5421: public class TabbedPaneLayout implements LayoutManager {
5422: public void addLayoutComponent(String name, Component comp) {
5423: }
5424:
5425: public void removeLayoutComponent(Component comp) {
5426: }
5427:
5428: public Dimension preferredLayoutSize(Container parent) {
5429: Dimension dimension = calculateSize(false);
5430: return dimension;
5431: }
5432:
5433: public Dimension minimumLayoutSize(Container parent) {
5434: return calculateSize(true);
5435: }
5436:
5437: protected Dimension calculateSize(boolean minimum) {
5438: int tabPlacement = _tabPane.getTabPlacement();
5439: Insets insets = _tabPane.getInsets();
5440: Insets contentInsets = getContentBorderInsets(tabPlacement);
5441: Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
5442:
5443: Dimension zeroSize = new Dimension(0, 0);
5444: int height = contentInsets.top + contentInsets.bottom;
5445: int width = contentInsets.left + contentInsets.right;
5446: int cWidth = 0;
5447: int cHeight = 0;
5448:
5449: synchronized (this ) {
5450: ensureCloseButtonCreated();
5451: calculateLayoutInfo();
5452:
5453: // Determine minimum size required to display largest
5454: // child in each dimension
5455: //
5456:
5457: if (_tabPane.isShowTabContent()) {
5458: for (int i = 0; i < _tabPane.getTabCount(); i++) {
5459: Component component = _tabPane
5460: .getComponentAt(i);
5461: if (component != null) {
5462: Dimension size = zeroSize;
5463: size = minimum ? component.getMinimumSize()
5464: : component.getPreferredSize();
5465:
5466: if (size != null) {
5467: cHeight = Math
5468: .max(size.height, cHeight);
5469: cWidth = Math.max(size.width, cWidth);
5470: }
5471: }
5472: }
5473: // Add content border insets to minimum size
5474: width += cWidth;
5475: height += cHeight;
5476: }
5477:
5478: int tabExtent = 0;
5479:
5480: // Calculate how much space the tabs will need, based on the
5481: // minimum size required to display largest child + content border
5482: //
5483: switch (tabPlacement) {
5484: case LEFT:
5485: case RIGHT:
5486: height = Math.max(height, (minimum ? 0
5487: : calculateMaxTabHeight(tabPlacement))
5488: + tabAreaInsets.top + tabAreaInsets.bottom);
5489: tabExtent = calculateTabAreaHeight(tabPlacement,
5490: _runCount, _maxTabHeight);
5491:
5492: if (isTabLeadingComponentVisible()) {
5493: tabExtent = Math.max(_tabLeadingComponent
5494: .getSize().width, tabExtent);
5495: }
5496: if (isTabTrailingComponentVisible()) {
5497: tabExtent = Math.max(_tabTrailingComponent
5498: .getSize().width, tabExtent);
5499: }
5500:
5501: width += tabExtent;
5502: break;
5503: case TOP:
5504: case BOTTOM:
5505: default:
5506: if (_tabPane.getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIT) {
5507: width = Math.max(width,
5508: (_tabPane.getTabCount() << 2)
5509: + tabAreaInsets.left
5510: + tabAreaInsets.right);
5511: } else {
5512: width = Math.max(width, (minimum ? 0
5513: : calculateMaxTabWidth(tabPlacement))
5514: + tabAreaInsets.left
5515: + tabAreaInsets.right);
5516: }
5517:
5518: if (_tabPane.isTabShown()) {
5519: tabExtent = calculateTabAreaHeight(
5520: tabPlacement, _runCount, _maxTabHeight);
5521:
5522: if (isTabLeadingComponentVisible()) {
5523: tabExtent = Math.max(_tabLeadingComponent
5524: .getSize().height, tabExtent);
5525: }
5526: if (isTabTrailingComponentVisible()) {
5527: tabExtent = Math.max(_tabTrailingComponent
5528: .getSize().height, tabExtent);
5529: }
5530:
5531: height += tabExtent;
5532: }
5533: }
5534: }
5535: return new Dimension(width + insets.left + insets.right,
5536: height + insets.bottom + insets.top);
5537:
5538: }
5539:
5540: protected int preferredTabAreaHeight(int tabPlacement, int width) {
5541: int tabCount = _tabPane.getTabCount();
5542: int total = 0;
5543: if (tabCount > 0) {
5544: int rows = 1;
5545: int x = 0;
5546:
5547: int maxTabHeight = calculateMaxTabHeight(tabPlacement);
5548:
5549: for (int i = 0; i < tabCount; i++) {
5550: FontMetrics metrics = getFontMetrics(i);
5551: int tabWidth = calculateTabWidth(tabPlacement, i,
5552: metrics);
5553:
5554: if (x != 0 && x + tabWidth > width) {
5555: rows++;
5556: x = 0;
5557: }
5558: x += tabWidth;
5559: }
5560: total = calculateTabAreaHeight(tabPlacement, rows,
5561: maxTabHeight);
5562: }
5563: return total;
5564: }
5565:
5566: protected int preferredTabAreaWidth(int tabPlacement, int height) {
5567: int tabCount = _tabPane.getTabCount();
5568: int total = 0;
5569: if (tabCount > 0) {
5570: int columns = 1;
5571: int y = 0;
5572:
5573: _maxTabWidth = calculateMaxTabWidth(tabPlacement);
5574:
5575: for (int i = 0; i < tabCount; i++) {
5576: FontMetrics metrics = getFontMetrics(i);
5577: int tabHeight = calculateTabHeight(tabPlacement, i,
5578: metrics);
5579: if (y != 0 && y + tabHeight > height) {
5580: columns++;
5581: y = 0;
5582: }
5583: y += tabHeight;
5584: }
5585: total = calculateTabAreaWidth(tabPlacement, columns,
5586: _maxTabWidth);
5587: }
5588: return total;
5589: }
5590:
5591: public void layoutContainer(Container parent) {
5592: int tabPlacement = _tabPane.getTabPlacement();
5593: Insets insets = _tabPane.getInsets();
5594: int selectedIndex = _tabPane.getSelectedIndex();
5595: Component visibleComponent = getVisibleComponent();
5596:
5597: synchronized (this ) {
5598: ensureCloseButtonCreated();
5599: calculateLayoutInfo();
5600:
5601: if (selectedIndex < 0) {
5602: if (visibleComponent != null) {
5603: // The last tab was removed, so remove the component
5604: setVisibleComponent(null);
5605: }
5606: } else {
5607: int cx, cy, cw, ch;
5608: int totalTabWidth = 0;
5609: int totalTabHeight = 0;
5610: Insets contentInsets = getContentBorderInsets(tabPlacement);
5611:
5612: Component selectedComponent = _tabPane
5613: .getComponentAt(selectedIndex);
5614: boolean shouldChangeFocus = false;
5615:
5616: // In order to allow programs to use a single component
5617: // as the display for multiple tabs, we will not change
5618: // the visible compnent if the currently selected tab
5619: // has a null component. This is a bit dicey, as we don't
5620: // explicitly state we support this in the spec, but since
5621: // programs are now depending on this, we're making it work.
5622: //
5623: if (selectedComponent != null) {
5624: if (selectedComponent != visibleComponent
5625: && visibleComponent != null) {
5626: if (JideSwingUtilities
5627: .isAncestorOfFocusOwner(visibleComponent)
5628: && _tabPane.isAutoRequestFocus()) {
5629: shouldChangeFocus = true;
5630: }
5631: }
5632: setVisibleComponent(selectedComponent);
5633: }
5634:
5635: Rectangle bounds = _tabPane.getBounds();
5636: int numChildren = _tabPane.getComponentCount();
5637:
5638: if (numChildren > 0) {
5639: switch (tabPlacement) {
5640: case LEFT:
5641: totalTabWidth = calculateTabAreaWidth(
5642: tabPlacement, _runCount,
5643: _maxTabWidth);
5644: cx = insets.left + totalTabWidth
5645: + contentInsets.left;
5646: cy = insets.top + contentInsets.top;
5647: break;
5648: case RIGHT:
5649: totalTabWidth = calculateTabAreaWidth(
5650: tabPlacement, _runCount,
5651: _maxTabWidth);
5652: cx = insets.left + contentInsets.left;
5653: cy = insets.top + contentInsets.top;
5654: break;
5655: case BOTTOM:
5656: totalTabHeight = calculateTabAreaHeight(
5657: tabPlacement, _runCount,
5658: _maxTabHeight);
5659: cx = insets.left + contentInsets.left;
5660: cy = insets.top + contentInsets.top;
5661: break;
5662: case TOP:
5663: default:
5664: totalTabHeight = calculateTabAreaHeight(
5665: tabPlacement, _runCount,
5666: _maxTabHeight);
5667: cx = insets.left + contentInsets.left;
5668: cy = insets.top + totalTabHeight
5669: + contentInsets.top;
5670: }
5671:
5672: cw = bounds.width - totalTabWidth - insets.left
5673: - insets.right - contentInsets.left
5674: - contentInsets.right;
5675: ch = bounds.height - totalTabHeight
5676: - insets.top - insets.bottom
5677: - contentInsets.top
5678: - contentInsets.bottom;
5679:
5680: for (int i = 0; i < numChildren; i++) {
5681: Component child = _tabPane.getComponent(i);
5682: child.setBounds(cx, cy, cw, ch);
5683: }
5684: }
5685:
5686: if (shouldChangeFocus) {
5687: if (!requestFocusForVisibleComponent()) {
5688: if (!_tabPane.requestFocusInWindow()) {
5689: _tabPane.requestFocus();
5690: }
5691: }
5692: }
5693: }
5694: }
5695: }
5696:
5697: public void calculateLayoutInfo() {
5698: int tabCount = _tabPane.getTabCount();
5699: assureRectsCreated(tabCount);
5700: calculateTabRects(_tabPane.getTabPlacement(), tabCount);
5701: }
5702:
5703: protected void calculateTabRects(int tabPlacement, int tabCount) {
5704: Dimension size = _tabPane.getSize();
5705: Insets insets = _tabPane.getInsets();
5706: Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
5707: int selectedIndex = _tabPane.getSelectedIndex();
5708: int tabRunOverlay;
5709: int i, j;
5710: int x, y;
5711: int returnAt;
5712: boolean verticalTabRuns = (tabPlacement == LEFT || tabPlacement == RIGHT);
5713: boolean leftToRight = _tabPane.getComponentOrientation()
5714: .isLeftToRight();
5715:
5716: //
5717: // Calculate bounds within which a tab run must fit
5718: //
5719: switch (tabPlacement) {
5720: case LEFT:
5721: _maxTabWidth = calculateMaxTabWidth(tabPlacement);
5722: x = insets.left + tabAreaInsets.left;
5723: y = insets.top + tabAreaInsets.top;
5724: returnAt = size.height
5725: - (insets.bottom + tabAreaInsets.bottom);
5726: break;
5727: case RIGHT:
5728: _maxTabWidth = calculateMaxTabWidth(tabPlacement);
5729: x = size.width - insets.right - tabAreaInsets.right
5730: - _maxTabWidth;
5731: y = insets.top + tabAreaInsets.top;
5732: returnAt = size.height
5733: - (insets.bottom + tabAreaInsets.bottom);
5734: break;
5735: case BOTTOM:
5736: _maxTabHeight = calculateMaxTabHeight(tabPlacement);
5737: x = insets.left + tabAreaInsets.left;
5738: y = size.height - insets.bottom - tabAreaInsets.bottom
5739: - _maxTabHeight;
5740: returnAt = size.width
5741: - (insets.right + tabAreaInsets.right);
5742: break;
5743: case TOP:
5744: default:
5745: _maxTabHeight = calculateMaxTabHeight(tabPlacement);
5746: x = insets.left + tabAreaInsets.left;
5747: y = insets.top + tabAreaInsets.top;
5748: returnAt = size.width
5749: - (insets.right + tabAreaInsets.right);
5750: break;
5751: }
5752:
5753: tabRunOverlay = getTabRunOverlay(tabPlacement);
5754:
5755: _runCount = 0;
5756: _selectedRun = -1;
5757:
5758: if (tabCount == 0) {
5759: return;
5760: }
5761:
5762: // Run through tabs and partition them into runs
5763: Rectangle rect;
5764: for (i = 0; i < tabCount; i++) {
5765: FontMetrics metrics = getFontMetrics(i);
5766: rect = _rects[i];
5767:
5768: if (!verticalTabRuns) {
5769: // Tabs on TOP or BOTTOM....
5770: if (i > 0) {
5771: rect.x = _rects[i - 1].x + _rects[i - 1].width;
5772: } else {
5773: _tabRuns[0] = 0;
5774: _runCount = 1;
5775: _maxTabWidth = 0;
5776: rect.x = x;
5777: }
5778: rect.width = calculateTabWidth(tabPlacement, i,
5779: metrics);
5780: _maxTabWidth = Math.max(_maxTabWidth, rect.width);
5781:
5782: // Never move a TAB down a run if it is in the first column.
5783: // Even if there isn't enough room, moving it to a fresh
5784: // line won't help.
5785: if (rect.x != 2 + insets.left
5786: && rect.x + rect.width > returnAt) {
5787: if (_runCount > _tabRuns.length - 1) {
5788: expandTabRunsArray();
5789: }
5790: _tabRuns[_runCount] = i;
5791: _runCount++;
5792: rect.x = x;
5793: }
5794: // Initialize y position in case there's just one run
5795: rect.y = y;
5796: rect.height = _maxTabHeight/* - 2 */;
5797:
5798: } else {
5799: // Tabs on LEFT or RIGHT...
5800: if (i > 0) {
5801: rect.y = _rects[i - 1].y + _rects[i - 1].height;
5802: } else {
5803: _tabRuns[0] = 0;
5804: _runCount = 1;
5805: _maxTabHeight = 0;
5806: rect.y = y;
5807: }
5808: rect.height = calculateTabHeight(tabPlacement, i,
5809: metrics);
5810: _maxTabHeight = Math
5811: .max(_maxTabHeight, rect.height);
5812:
5813: // Never move a TAB over a run if it is in the first run.
5814: // Even if there isn't enough room, moving it to a fresh
5815: // column won't help.
5816: if (rect.y != 2 + insets.top
5817: && rect.y + rect.height > returnAt) {
5818: if (_runCount > _tabRuns.length - 1) {
5819: expandTabRunsArray();
5820: }
5821: _tabRuns[_runCount] = i;
5822: _runCount++;
5823: rect.y = y;
5824: }
5825: // Initialize x position in case there's just one column
5826: rect.x = x;
5827: rect.width = _maxTabWidth/* - 2 */;
5828:
5829: }
5830: if (i == selectedIndex) {
5831: _selectedRun = _runCount - 1;
5832: }
5833: }
5834:
5835: if (_runCount > 1) {
5836: // Re-distribute tabs in case last run has leftover space
5837: normalizeTabRuns(tabPlacement, tabCount,
5838: verticalTabRuns ? y : x, returnAt);
5839:
5840: _selectedRun = getRunForTab(tabCount, selectedIndex);
5841:
5842: // Rotate run array so that selected run is first
5843: if (shouldRotateTabRuns(tabPlacement)) {
5844: rotateTabRuns(tabPlacement, _selectedRun);
5845: }
5846: }
5847:
5848: // Step through runs from back to front to calculate
5849: // tab y locations and to pad runs appropriately
5850: for (i = _runCount - 1; i >= 0; i--) {
5851: int start = _tabRuns[i];
5852: int next = _tabRuns[i == (_runCount - 1) ? 0 : i + 1];
5853: int end = (next != 0 ? next - 1 : tabCount - 1);
5854: if (!verticalTabRuns) {
5855: for (j = start; j <= end; j++) {
5856: rect = _rects[j];
5857: rect.y = y;
5858: rect.x += getTabRunIndent(tabPlacement, i);
5859: }
5860: if (shouldPadTabRun(tabPlacement, i)) {
5861: padTabRun(tabPlacement, start, end, returnAt);
5862: }
5863: if (tabPlacement == BOTTOM) {
5864: y -= (_maxTabHeight - tabRunOverlay);
5865: } else {
5866: y += (_maxTabHeight - tabRunOverlay);
5867: }
5868: } else {
5869: for (j = start; j <= end; j++) {
5870: rect = _rects[j];
5871: rect.x = x;
5872: rect.y += getTabRunIndent(tabPlacement, i);
5873: }
5874: if (shouldPadTabRun(tabPlacement, i)) {
5875: padTabRun(tabPlacement, start, end, returnAt);
5876: }
5877: if (tabPlacement == RIGHT) {
5878: x -= (_maxTabWidth - tabRunOverlay);
5879: } else {
5880: x += (_maxTabWidth - tabRunOverlay);
5881: }
5882: }
5883: }
5884:
5885: // Pad the selected tab so that it appears raised in front
5886: padSelectedTab(tabPlacement, selectedIndex);
5887:
5888: // if right to left and tab placement on the top or
5889: // the bottom, flip x positions and adjust by widths
5890: if (!leftToRight && !verticalTabRuns) {
5891: int rightMargin = size.width
5892: - (insets.right + tabAreaInsets.right);
5893: for (i = 0; i < tabCount; i++) {
5894: _rects[i].x = rightMargin - _rects[i].x
5895: - _rects[i].width;
5896: }
5897: }
5898: }
5899:
5900: /*
5901: * Rotates the run-index array so that the selected run is run[0]
5902: */
5903: protected void rotateTabRuns(int tabPlacement, int selectedRun) {
5904: for (int i = 0; i < selectedRun; i++) {
5905: int save = _tabRuns[0];
5906: for (int j = 1; j < _runCount; j++) {
5907: _tabRuns[j - 1] = _tabRuns[j];
5908: }
5909: _tabRuns[_runCount - 1] = save;
5910: }
5911: }
5912:
5913: protected void normalizeTabRuns(int tabPlacement, int tabCount,
5914: int start, int max) {
5915: boolean verticalTabRuns = (tabPlacement == LEFT || tabPlacement == RIGHT);
5916: int run = _runCount - 1;
5917: boolean keepAdjusting = true;
5918: double weight = 1.25;
5919:
5920: // At this point the tab runs are packed to fit as many
5921: // tabs as possible, which can leave the last run with a lot
5922: // of extra space (resulting in very fat tabs on the last run).
5923: // So we'll attempt to distribute this extra space more evenly
5924: // across the runs in order to make the runs look more consistent.
5925: //
5926: // Starting with the last run, determine whether the last tab in
5927: // the previous run would fit (generously) in this run; if so,
5928: // move tab to current run and shift tabs accordingly. Cycle
5929: // through remaining runs using the same algorithm.
5930: //
5931: while (keepAdjusting) {
5932: int last = lastTabInRun(tabCount, run);
5933: int prevLast = lastTabInRun(tabCount, run - 1);
5934: int end;
5935: int prevLastLen;
5936:
5937: if (!verticalTabRuns) {
5938: end = _rects[last].x + _rects[last].width;
5939: prevLastLen = (int) (_maxTabWidth * weight);
5940: } else {
5941: end = _rects[last].y + _rects[last].height;
5942: prevLastLen = (int) (_maxTabHeight * weight * 2);
5943: }
5944:
5945: // Check if the run has enough extra space to fit the last tab
5946: // from the previous row...
5947: if (max - end > prevLastLen) {
5948:
5949: // Insert tab from previous row and shift rest over
5950: _tabRuns[run] = prevLast;
5951: if (!verticalTabRuns) {
5952: _rects[prevLast].x = start;
5953: } else {
5954: _rects[prevLast].y = start;
5955: }
5956: for (int i = prevLast + 1; i <= last; i++) {
5957: if (!verticalTabRuns) {
5958: _rects[i].x = _rects[i - 1].x
5959: + _rects[i - 1].width;
5960: } else {
5961: _rects[i].y = _rects[i - 1].y
5962: + _rects[i - 1].height;
5963: }
5964: }
5965:
5966: } else if (run == _runCount - 1) {
5967: // no more room left in last run, so we're done!
5968: keepAdjusting = false;
5969: }
5970: if (run - 1 > 0) {
5971: // check previous run next...
5972: run -= 1;
5973: } else {
5974: // check last run again...but require a higher ratio
5975: // of extraspace-to-tabsize because we don't want to
5976: // end up with too many tabs on the last run!
5977: run = _runCount - 1;
5978: weight += .25;
5979: }
5980: }
5981: }
5982:
5983: protected void padTabRun(int tabPlacement, int start, int end,
5984: int max) {
5985: Rectangle lastRect = _rects[end];
5986: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
5987: int runWidth = (lastRect.x + lastRect.width)
5988: - _rects[start].x;
5989: int deltaWidth = max - (lastRect.x + lastRect.width);
5990: float factor = (float) deltaWidth / (float) runWidth;
5991:
5992: for (int j = start; j <= end; j++) {
5993: Rectangle pastRect = _rects[j];
5994: if (j > start) {
5995: pastRect.x = _rects[j - 1].x
5996: + _rects[j - 1].width;
5997: }
5998: pastRect.width += Math.round((float) pastRect.width
5999: * factor);
6000: }
6001: lastRect.width = max - lastRect.x;
6002: } else {
6003: int runHeight = (lastRect.y + lastRect.height)
6004: - _rects[start].y;
6005: int deltaHeight = max - (lastRect.y + lastRect.height);
6006: float factor = (float) deltaHeight / (float) runHeight;
6007:
6008: for (int j = start; j <= end; j++) {
6009: Rectangle pastRect = _rects[j];
6010: if (j > start) {
6011: pastRect.y = _rects[j - 1].y
6012: + _rects[j - 1].height;
6013: }
6014: pastRect.height += Math
6015: .round((float) pastRect.height * factor);
6016: }
6017: lastRect.height = max - lastRect.y;
6018: }
6019: }
6020:
6021: protected void padSelectedTab(int tabPlacement,
6022: int selectedIndex) {
6023:
6024: if (selectedIndex >= 0) {
6025: Rectangle selRect = _rects[selectedIndex];
6026: Insets padInsets = getSelectedTabPadInsets(tabPlacement);
6027: selRect.x -= padInsets.left;
6028: selRect.width += (padInsets.left + padInsets.right);
6029: selRect.y -= padInsets.top;
6030: selRect.height += (padInsets.top + padInsets.bottom);
6031: }
6032: }
6033: }
6034:
6035: protected TabSpaceAllocator tryTabSpacer = new TabSpaceAllocator();
6036:
6037: protected class TabbedPaneScrollLayout extends TabbedPaneLayout {
6038:
6039: @Override
6040: protected int preferredTabAreaHeight(int tabPlacement, int width) {
6041: return calculateMaxTabHeight(tabPlacement);
6042: }
6043:
6044: @Override
6045: protected int preferredTabAreaWidth(int tabPlacement, int height) {
6046: return calculateMaxTabWidth(tabPlacement);
6047: }
6048:
6049: @Override
6050: public void layoutContainer(Container parent) {
6051: int tabPlacement = _tabPane.getTabPlacement();
6052: int tabCount = _tabPane.getTabCount();
6053: Insets insets = _tabPane.getInsets();
6054: int selectedIndex = _tabPane.getSelectedIndex();
6055: Component visibleComponent = getVisibleComponent();
6056:
6057: calculateLayoutInfo();
6058:
6059: if (selectedIndex < 0) {
6060: if (visibleComponent != null) {
6061: // The last tab was removed, so remove the component
6062: setVisibleComponent(null);
6063: }
6064:
6065: } else {
6066: Component selectedComponent = selectedIndex >= _tabPane
6067: .getTabCount() ? null : _tabPane
6068: .getComponentAt(selectedIndex); // check for range because of a change in JDK1.6-rc-b89
6069: boolean shouldChangeFocus = false;
6070:
6071: // In order to allow programs to use a single component
6072: // as the display for multiple tabs, we will not change
6073: // the visible compnent if the currently selected tab
6074: // has a null component. This is a bit dicey, as we don't
6075: // explicitly state we support this in the spec, but since
6076: // programs are now depending on this, we're making it work.
6077: //
6078: if (selectedComponent != null) {
6079: if (selectedComponent != visibleComponent
6080: && visibleComponent != null) {
6081: if (JideSwingUtilities
6082: .isAncestorOfFocusOwner(visibleComponent)
6083: && _tabPane.isAutoRequestFocus()) {
6084: shouldChangeFocus = true;
6085: }
6086: }
6087: setVisibleComponent(selectedComponent);
6088: }
6089: int tx, ty, tw, th; // tab area bounds
6090: int cx, cy, cw, ch; // content area bounds
6091: Insets contentInsets = getContentBorderInsets(tabPlacement);
6092: Rectangle bounds = _tabPane.getBounds();
6093: int numChildren = _tabPane.getComponentCount();
6094:
6095: Dimension lsize = new Dimension(0, 0);
6096: Dimension tsize = new Dimension(0, 0);
6097:
6098: if (isTabLeadingComponentVisible()) {
6099: lsize = _tabLeadingComponent.getSize();
6100: }
6101: if (isTabTrailingComponentVisible()) {
6102: tsize = _tabTrailingComponent.getSize();
6103:
6104: }
6105:
6106: if (numChildren > 0) {
6107: switch (tabPlacement) {
6108: case LEFT:
6109: // calculate tab area bounds
6110: tw = calculateTabAreaHeight(TOP, _runCount,
6111: _maxTabWidth);
6112: th = bounds.height - insets.top - insets.bottom;
6113: tx = insets.left;
6114: ty = insets.top;
6115:
6116: if (isTabLeadingComponentVisible()) {
6117: ty += lsize.height;
6118: th -= lsize.height;
6119:
6120: if (lsize.width > tw) {
6121: tw = lsize.width;
6122: }
6123: }
6124: if (isTabTrailingComponentVisible()) {
6125: th -= tsize.height;
6126:
6127: if (tsize.width > tw) {
6128: tw = tsize.width;
6129: }
6130: }
6131:
6132: // calculate content area bounds
6133: cx = tx + tw + contentInsets.left;
6134: cy = insets.top + contentInsets.top;
6135: cw = bounds.width - insets.left - insets.right
6136: - tw - contentInsets.left
6137: - contentInsets.right;
6138: ch = bounds.height - insets.top - insets.bottom
6139: - contentInsets.top
6140: - contentInsets.bottom;
6141: break;
6142: case RIGHT:
6143: // calculate tab area bounds
6144: tw = calculateTabAreaHeight(TOP, _runCount,
6145: _maxTabWidth);
6146: th = bounds.height - insets.top - insets.bottom;
6147: tx = bounds.width - insets.right - tw;
6148: ty = insets.top;
6149:
6150: if (isTabLeadingComponentVisible()) {
6151: ty += lsize.height;
6152: th -= lsize.height;
6153:
6154: if (lsize.width > tw) {
6155: tw = lsize.width;
6156: tx = bounds.width - insets.right - tw;
6157: }
6158: }
6159: if (isTabTrailingComponentVisible()) {
6160: th -= tsize.height;
6161:
6162: if (tsize.width > tw) {
6163: tw = tsize.width;
6164: tx = bounds.width - insets.right - tw;
6165: }
6166: }
6167:
6168: // calculate content area bounds
6169: cx = insets.left + contentInsets.left;
6170: cy = insets.top + contentInsets.top;
6171: cw = bounds.width - insets.left - insets.right
6172: - tw - contentInsets.left
6173: - contentInsets.right;
6174: ch = bounds.height - insets.top - insets.bottom
6175: - contentInsets.top
6176: - contentInsets.bottom;
6177: break;
6178: case BOTTOM:
6179: // calculate tab area bounds
6180: tw = bounds.width - insets.left - insets.right;
6181: th = calculateTabAreaHeight(tabPlacement,
6182: _runCount, _maxTabHeight);
6183: tx = insets.left;
6184: ty = bounds.height - insets.bottom - th;
6185:
6186: if (isTabLeadingComponentVisible()) {
6187: tx += lsize.width;
6188: tw -= lsize.width;
6189:
6190: if (lsize.height > th) {
6191: th = lsize.height;
6192: ty = bounds.height - insets.bottom - th;
6193: }
6194: }
6195: if (isTabTrailingComponentVisible()) {
6196: tw -= tsize.width;
6197:
6198: if (tsize.height > th) {
6199: th = tsize.height;
6200: ty = bounds.height - insets.bottom - th;
6201: }
6202: }
6203:
6204: // calculate content area bounds
6205: cx = insets.left + contentInsets.left;
6206: cy = insets.top + contentInsets.top;
6207: cw = bounds.width - insets.left - insets.right
6208: - contentInsets.left
6209: - contentInsets.right;
6210: ch = bounds.height - insets.top - insets.bottom
6211: - th - contentInsets.top
6212: - contentInsets.bottom;
6213: break;
6214: case TOP:
6215: default:
6216: // calculate tab area bounds
6217: tw = bounds.width - insets.left - insets.right;
6218: th = calculateTabAreaHeight(tabPlacement,
6219: _runCount, _maxTabHeight);
6220: tx = insets.left;
6221: ty = insets.top;
6222:
6223: if (isTabLeadingComponentVisible()) {
6224: tx += lsize.width;
6225: tw -= lsize.width;
6226:
6227: if (lsize.height > th) {
6228: th = lsize.height;
6229: }
6230: }
6231: if (isTabTrailingComponentVisible()) {
6232: tw -= tsize.width;
6233:
6234: if (tsize.height > th) {
6235: th = tsize.height;
6236: }
6237: }
6238:
6239: // calculate content area bounds
6240: cx = insets.left + contentInsets.left;
6241: cy = insets.top + th + contentInsets.top;
6242: cw = bounds.width - insets.left - insets.right
6243: - contentInsets.left
6244: - contentInsets.right;
6245: ch = bounds.height - insets.top - insets.bottom
6246: - th - contentInsets.top
6247: - contentInsets.bottom;
6248: }
6249:
6250: // if (tabPlacement == JideTabbedPane.TOP || tabPlacement == JideTabbedPane.BOTTOM) {
6251: // if (getTabResizeMode() != JideTabbedPane.RESIZE_MODE_FIT) {
6252: // int numberOfButtons = isShrinkTabs() ? 1 : 4;
6253: // if (tw < _rects[0].width + numberOfButtons * _buttonSize) {
6254: // return;
6255: // }
6256: // }
6257: // }
6258: // else {
6259: // if (getTabResizeMode() != JideTabbedPane.RESIZE_MODE_FIT) {
6260: // int numberOfButtons = isShrinkTabs() ? 1 : 4;
6261: // if (th < _rects[0].height + numberOfButtons * _buttonSize) {
6262: // return;
6263: // }
6264: // }
6265: // }
6266:
6267: for (int i = 0; i < numChildren; i++) {
6268: Component child = _tabPane.getComponent(i);
6269:
6270: if (child instanceof ScrollableTabViewport) {
6271: JViewport viewport = (JViewport) child;
6272: // Rectangle viewRect = viewport.getViewRect();
6273: int vw = tw;
6274: int vh = th;
6275: int numberOfButtons;
6276: switch (tabPlacement) {
6277: case LEFT:
6278: case RIGHT:
6279: int totalTabHeight = _rects[tabCount - 1].y
6280: + _rects[tabCount - 1].height;
6281: if (totalTabHeight > th
6282: || isShowTabButtons()) {
6283: numberOfButtons = isShrinkTabs() ? 1
6284: : 4;
6285: if (!isShowCloseButton()) {
6286: numberOfButtons--;
6287: }
6288: // Allow space for scrollbuttons
6289: vh = Math.max(th - _buttonSize
6290: * numberOfButtons,
6291: _buttonSize
6292: * numberOfButtons);
6293: // if (totalTabHeight - viewRect.y <= vh) {
6294: // // Scrolled to the end, so ensure the
6295: // // viewport size is
6296: // // such that the scroll offset aligns
6297: // // with a tab
6298: // vh = totalTabHeight - viewRect.y;
6299: // }
6300: } else {
6301: numberOfButtons = 1;
6302: if (!isShowCloseButton()) {
6303: numberOfButtons--;
6304: }
6305: // Allow space for scrollbuttons
6306: vh = Math.max(th - _buttonSize
6307: * numberOfButtons,
6308: _buttonSize
6309: * numberOfButtons);
6310: }
6311:
6312: if (vh + getLayoutSize() < th
6313: - _buttonSize * numberOfButtons) {
6314: vh += getLayoutSize();
6315: }
6316: break;
6317: case BOTTOM:
6318: case TOP:
6319: default:
6320: int totalTabWidth = _rects[tabCount - 1].x
6321: + _rects[tabCount - 1].width;
6322: if (isShowTabButtons()
6323: || totalTabWidth > tw) {
6324: // Need to allow space for scrollbuttons
6325: numberOfButtons = isShrinkTabs() ? 1
6326: : 4;
6327: if (!isShowCloseButton()) {
6328: numberOfButtons--;
6329: }
6330: vw = Math.max(tw - _buttonSize
6331: * numberOfButtons,
6332: _buttonSize
6333: * numberOfButtons);
6334:
6335: // if (totalTabWidth - viewRect.x <= vw) {
6336: // // Scrolled to the end, so ensure the
6337: // // viewport size is
6338: // // such that the scroll offset aligns
6339: // // with a tab
6340: // vw = totalTabWidth - viewRect.x;
6341: // }
6342: } else {
6343: numberOfButtons = 1;
6344: if (!isShowCloseButton()) {
6345: numberOfButtons--;
6346: }
6347: // Allow space for scrollbuttons
6348: vw = Math.max(tw - _buttonSize
6349: * numberOfButtons,
6350: _buttonSize
6351: * numberOfButtons);
6352: }
6353: if (vw + getLayoutSize() < tw
6354: - _buttonSize * numberOfButtons) {
6355: vw += getLayoutSize();
6356: }
6357: break;
6358: }
6359: child.setBounds(tx, ty, vw, vh);
6360:
6361: } else if (child instanceof TabCloseButton) {
6362: TabCloseButton scrollbutton = (TabCloseButton) child;
6363: if (_tabPane.isTabShown()
6364: && (scrollbutton.getType() != TabCloseButton.CLOSE_BUTTON || !isShowCloseButtonOnTab())) {
6365: Dimension bsize = scrollbutton
6366: .getPreferredSize();
6367: int bx = 0;
6368: int by = 0;
6369: int bw = bsize.width;
6370: int bh = bsize.height;
6371: boolean visible = false;
6372:
6373: switch (tabPlacement) {
6374: case LEFT:
6375: case RIGHT:
6376: int totalTabHeight = _rects[tabCount - 1].y
6377: + _rects[tabCount - 1].height;
6378: if (_tabPane.isTabShown()
6379: && (isShowTabButtons() || totalTabHeight > th)) {
6380: int dir = scrollbutton
6381: .getType();//NoFocusButton.EAST_BUTTON : NoFocusButton.WEST_BUTTON;
6382: scrollbutton.setType(dir);
6383: switch (dir) {
6384: case TabCloseButton.CLOSE_BUTTON:
6385: if (isShowCloseButton()) {
6386: visible = true;
6387: by = bounds.height
6388: - insets.top
6389: - bsize.height
6390: - 5;
6391: } else {
6392: visible = false;
6393: by = 0;
6394: }
6395: break;
6396: case TabCloseButton.LIST_BUTTON:
6397: visible = true;
6398: by = bounds.height
6399: - insets.top
6400: - (2 - (!isShowCloseButton()
6401: || isShowCloseButtonOnTab() ? 1
6402: : 0))
6403: * bsize.height - 5;
6404: break;
6405: case TabCloseButton.EAST_BUTTON:
6406: visible = !isShrinkTabs();
6407: by = bounds.height
6408: - insets.top
6409: - (3 - (!isShowCloseButton()
6410: || isShowCloseButtonOnTab() ? 1
6411: : 0))
6412: * bsize.height - 5;
6413: break;
6414: case TabCloseButton.WEST_BUTTON:
6415: visible = !isShrinkTabs();
6416: by = bounds.height
6417: - insets.top
6418: - (4 - (!isShowCloseButton()
6419: || isShowCloseButtonOnTab() ? 1
6420: : 0))
6421: * bsize.height - 5;
6422: break;
6423: }
6424: bx = tx + 2;
6425:
6426: } else {
6427: int dir = scrollbutton
6428: .getType();
6429: scrollbutton.setType(dir);
6430: if (dir == TabCloseButton.CLOSE_BUTTON) {
6431: if (isShowCloseButton()) {
6432: visible = true;
6433: by = bounds.height
6434: - insets.top
6435: - bsize.height
6436: - 5;
6437: } else {
6438: visible = false;
6439: by = 0;
6440: }
6441: bx = tx + 2;
6442: }
6443: }
6444: if (isTabTrailingComponentVisible()) {
6445: by = by - tsize.height;
6446: }
6447: int temp = -1;
6448: if (isTabLeadingComponentVisible()) {
6449: if (_tabLeadingComponent
6450: .getSize().width >= _rects[0].width) {
6451: if (tabPlacement == LEFT) {
6452: bx += _tabLeadingComponent
6453: .getSize().width
6454: - _rects[0].width;
6455: temp = _tabLeadingComponent
6456: .getSize().width;
6457: }
6458: }
6459: }
6460: if (isTabTrailingComponentVisible()) {
6461: if (_tabTrailingComponent
6462: .getSize().width >= _rects[0].width
6463: && temp < _tabTrailingComponent
6464: .getSize().width) {
6465: if (tabPlacement == LEFT) {
6466: bx += _tabTrailingComponent
6467: .getSize().width
6468: - _rects[0].width;
6469: }
6470: }
6471: }
6472: break;
6473: case TOP:
6474: case BOTTOM:
6475: default:
6476: int totalTabWidth = _rects[tabCount - 1].x
6477: + _rects[tabCount - 1].width;
6478: if (_tabPane.isTabShown()
6479: && (isShowTabButtons() || totalTabWidth > tw)) {
6480: int dir = scrollbutton
6481: .getType();// NoFocusButton.EAST_BUTTON
6482: // NoFocusButton.WEST_BUTTON;
6483: scrollbutton.setType(dir);
6484: switch (dir) {
6485: case TabCloseButton.CLOSE_BUTTON:
6486: if (isShowCloseButton()) {
6487: visible = true;
6488: bx = bounds.width
6489: - insets.left
6490: - bsize.width
6491: - 5;
6492: } else {
6493: visible = false;
6494: bx = 0;
6495: }
6496: break;
6497: case TabCloseButton.LIST_BUTTON:
6498: visible = true;
6499: bx = bounds.width
6500: - insets.left
6501: - (2 - (!isShowCloseButton()
6502: || isShowCloseButtonOnTab() ? 1
6503: : 0))
6504: * bsize.width - 5;
6505: break;
6506: case TabCloseButton.EAST_BUTTON:
6507: visible = !isShrinkTabs();
6508: bx = bounds.width
6509: - insets.left
6510: - (3 - (!isShowCloseButton()
6511: || isShowCloseButtonOnTab() ? 1
6512: : 0))
6513: * bsize.width - 5;
6514: break;
6515: case TabCloseButton.WEST_BUTTON:
6516: visible = !isShrinkTabs();
6517: bx = bounds.width
6518: - insets.left
6519: - (4 - (!isShowCloseButton()
6520: || isShowCloseButtonOnTab() ? 1
6521: : 0))
6522: * bsize.width - 5;
6523: break;
6524: }
6525: by = ((th - bsize.height) >> 1)
6526: + ty;
6527:
6528: } else {
6529: int dir = scrollbutton
6530: .getType();
6531: scrollbutton.setType(dir);
6532: if (dir == TabCloseButton.CLOSE_BUTTON) {
6533: if (isShowCloseButton()) {
6534: visible = true;
6535: bx = bounds.width
6536: - insets.left
6537: - bsize.width
6538: - 5;
6539: } else {
6540: visible = false;
6541: bx = 0;
6542: }
6543: by = ((th - bsize.height) >> 1)
6544: + ty;
6545: }
6546: }
6547: if (isTabTrailingComponentVisible()) {
6548: bx -= tsize.width;
6549: }
6550: temp = -1;
6551: if (isTabLeadingComponentVisible()) {
6552: if (_tabLeadingComponent
6553: .getSize().height >= _rects[0].height) {
6554: if (tabPlacement == TOP) {
6555: by = ty
6556: + 2
6557: + _tabLeadingComponent
6558: .getSize().height
6559: - _rects[0].height;
6560: temp = _tabLeadingComponent
6561: .getSize().height;
6562: } else {
6563: by = ty + 2;
6564: }
6565: }
6566: }
6567: if (isTabTrailingComponentVisible()) {
6568: if (_tabTrailingComponent
6569: .getSize().height >= _rects[0].height
6570: && temp < _tabTrailingComponent
6571: .getSize().height) {
6572: if (tabPlacement == TOP) {
6573: by = ty
6574: + 2
6575: + _tabTrailingComponent
6576: .getSize().height
6577: - _rects[0].height;
6578: } else {
6579: by = ty + 2;
6580: }
6581: }
6582: }
6583:
6584: }
6585:
6586: child.setVisible(visible);
6587: if (visible) {
6588: child.setBounds(bx, by, bw, bh);
6589: }
6590: } else {
6591: scrollbutton.setBounds(0, 0, 0, 0);
6592: }
6593: } else if (child != _tabPane
6594: .getTabLeadingComponent()
6595: && child != _tabPane
6596: .getTabTrailingComponent()) {
6597: if (_tabPane.isShowTabContent()) {
6598: // All content children...
6599: child.setBounds(cx, cy, cw, ch);
6600: } else {
6601: child.setBounds(0, 0, 0, 0);
6602: }
6603: }
6604: }
6605:
6606: if (isTabLeadingComponentVisible()) {
6607: switch (_tabPane.getTabPlacement()) {
6608: case LEFT:
6609: _tabLeadingComponent.setBounds(tx + tw
6610: - lsize.width, ty - lsize.height,
6611: lsize.width, lsize.height);
6612: break;
6613: case RIGHT:
6614: _tabLeadingComponent.setBounds(tx, ty
6615: - lsize.height, lsize.width,
6616: lsize.height);
6617: break;
6618: case BOTTOM:
6619: _tabLeadingComponent.setBounds(tx
6620: - lsize.width, ty, lsize.width,
6621: lsize.height);
6622: break;
6623: case TOP:
6624: default:
6625: _tabLeadingComponent.setBounds(tx
6626: - lsize.width, ty + th
6627: - lsize.height, lsize.width,
6628: lsize.height);
6629: break;
6630: }
6631:
6632: }
6633:
6634: if (isTabTrailingComponentVisible()) {
6635: switch (_tabPane.getTabPlacement()) {
6636: case LEFT:
6637: _tabTrailingComponent.setBounds(tx + tw
6638: - tsize.width, ty + th,
6639: tsize.width, tsize.height);
6640: break;
6641: case RIGHT:
6642: _tabTrailingComponent.setBounds(tx,
6643: ty + th, tsize.width, tsize.height);
6644: break;
6645: case BOTTOM:
6646: _tabTrailingComponent.setBounds(tx + tw,
6647: ty, tsize.width, tsize.height);
6648: break;
6649: case TOP:
6650: default:
6651: _tabTrailingComponent.setBounds(tx + tw, ty
6652: + th - tsize.height, tsize.width,
6653: tsize.height);
6654: break;
6655: }
6656:
6657: }
6658:
6659: if (shouldChangeFocus) {
6660: if (!requestFocusForVisibleComponent()) {
6661: if (!_tabPane.requestFocusInWindow()) {
6662: _tabPane.requestFocus();
6663: }
6664: }
6665: }
6666: }
6667: }
6668: }
6669:
6670: @Override
6671: protected void calculateTabRects(int tabPlacement, int tabCount) {
6672: Dimension size = _tabPane.getSize();
6673: Insets insets = _tabPane.getInsets();
6674: Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
6675: boolean verticalTabRuns = (tabPlacement == LEFT || tabPlacement == RIGHT);
6676: boolean leftToRight = _tabPane.getComponentOrientation()
6677: .isLeftToRight();
6678: int x = tabAreaInsets.left;
6679: int y = tabAreaInsets.top;
6680: int totalWidth = 0;
6681: int totalHeight = 0;
6682:
6683: //
6684: // Calculate bounds within which a tab run must fit
6685: //
6686: switch (tabPlacement) {
6687: case LEFT:
6688: case RIGHT:
6689: _maxTabWidth = calculateMaxTabWidth(tabPlacement);
6690: if (isTabLeadingComponentVisible()) {
6691: if (tabPlacement == RIGHT) {
6692: if (_maxTabWidth < _tabLeadingComponent
6693: .getSize().width) {
6694: _maxTabWidth = _tabLeadingComponent
6695: .getSize().width;
6696: }
6697: }
6698: }
6699: if (isTabTrailingComponentVisible()) {
6700: if (tabPlacement == RIGHT) {
6701: if (_maxTabWidth < _tabTrailingComponent
6702: .getSize().width) {
6703: _maxTabWidth = _tabTrailingComponent
6704: .getSize().width;
6705: }
6706: }
6707: }
6708: break;
6709: case BOTTOM:
6710: case TOP:
6711: default:
6712: _maxTabHeight = calculateMaxTabHeight(tabPlacement);
6713: if (isTabLeadingComponentVisible()) {
6714: if (tabPlacement == BOTTOM) {
6715: if (_maxTabHeight < _tabLeadingComponent
6716: .getSize().height) {
6717: _maxTabHeight = _tabLeadingComponent
6718: .getSize().height;
6719: }
6720: }
6721: }
6722: if (isTabTrailingComponentVisible()) {
6723: if (tabPlacement == BOTTOM) {
6724: if (_maxTabHeight < _tabTrailingComponent
6725: .getSize().height) {
6726: _maxTabHeight = _tabTrailingComponent
6727: .getSize().height;
6728: }
6729: }
6730: }
6731: }
6732:
6733: _runCount = 0;
6734: _selectedRun = -1;
6735:
6736: if (tabCount == 0) {
6737: return;
6738: }
6739:
6740: _selectedRun = 0;
6741: _runCount = 1;
6742:
6743: // Run through tabs and lay them out in a single run
6744: Rectangle rect;
6745: for (int i = 0; i < tabCount; i++) {
6746: FontMetrics metrics = getFontMetrics(i);
6747: rect = _rects[i];
6748:
6749: if (!verticalTabRuns) {
6750: // Tabs on TOP or BOTTOM....
6751: if (i > 0) {
6752: rect.x = _rects[i - 1].x + _rects[i - 1].width;
6753: } else {
6754: _tabRuns[0] = 0;
6755: _maxTabWidth = 0;
6756: totalHeight += _maxTabHeight;
6757: if (getTabShape() != JideTabbedPane.SHAPE_BOX) {
6758: rect.x = x + getLeftMargin();// give the first tab arrow angle extra space
6759: } else {
6760: rect.x = x;
6761: }
6762: }
6763: rect.width = calculateTabWidth(tabPlacement, i,
6764: metrics)
6765: + _rectSizeExtend;
6766: totalWidth = rect.x + rect.width;
6767: _maxTabWidth = Math.max(_maxTabWidth, rect.width);
6768:
6769: rect.y = y;
6770:
6771: int temp = -1;
6772: if (isTabLeadingComponentVisible()) {
6773: if (tabPlacement == TOP) {
6774: if (_maxTabHeight < _tabLeadingComponent
6775: .getSize().height) {
6776: rect.y = y
6777: + _tabLeadingComponent
6778: .getSize().height
6779: - _maxTabHeight - 2;
6780: temp = _tabLeadingComponent.getSize().height;
6781:
6782: if (_rectSizeExtend > 0) {
6783: rect.y = rect.y + 2;
6784: }
6785: }
6786:
6787: }
6788: }
6789: if (isTabTrailingComponentVisible()) {
6790: if (tabPlacement == TOP) {
6791: if (_maxTabHeight < _tabTrailingComponent
6792: .getSize().height
6793: && temp < _tabTrailingComponent
6794: .getSize().height) {
6795: rect.y = y
6796: + _tabTrailingComponent
6797: .getSize().height
6798: - _maxTabHeight - 2;
6799:
6800: if (_rectSizeExtend > 0) {
6801: rect.y = rect.y + 2;
6802: }
6803: }
6804:
6805: }
6806: }
6807: rect.height = calculateMaxTabHeight(tabPlacement);///* - 2 */;
6808: } else {
6809: // Tabs on LEFT or RIGHT...
6810: if (i > 0) {
6811: rect.y = _rects[i - 1].y + _rects[i - 1].height;
6812: } else {
6813: _tabRuns[0] = 0;
6814: _maxTabHeight = 0;
6815: totalWidth = _maxTabWidth;
6816: if (getTabShape() != JideTabbedPane.SHAPE_BOX) {
6817: rect.y = y + getLeftMargin();// give the first tab arrow angle extra space
6818: } else {
6819: rect.y = y;
6820: }
6821: }
6822: rect.height = calculateTabHeight(tabPlacement, i,
6823: metrics)
6824: + _rectSizeExtend;
6825: totalHeight = rect.y + rect.height;
6826: _maxTabHeight = Math
6827: .max(_maxTabHeight, rect.height);
6828:
6829: rect.x = x;
6830: int temp = -1;
6831: if (isTabLeadingComponentVisible()) {
6832: if (tabPlacement == LEFT) {
6833: if (_maxTabWidth < _tabLeadingComponent
6834: .getSize().width) {
6835: rect.x = x
6836: + _tabLeadingComponent
6837: .getSize().width
6838: - _maxTabWidth - 2;
6839: temp = _tabLeadingComponent.getSize().width;
6840:
6841: if (_rectSizeExtend > 0) {
6842: rect.x = rect.x + 2;
6843: }
6844: }
6845:
6846: }
6847: }
6848: if (isTabTrailingComponentVisible()) {
6849: if (tabPlacement == LEFT) {
6850: if (_maxTabWidth < _tabTrailingComponent
6851: .getSize().width
6852: && temp < _tabTrailingComponent
6853: .getSize().width) {
6854: rect.x = x
6855: + _tabTrailingComponent
6856: .getSize().width
6857: - _maxTabWidth - 2;
6858:
6859: if (_rectSizeExtend > 0) {
6860: rect.x = rect.x + 2;
6861: }
6862: }
6863:
6864: }
6865: }
6866: rect.width = calculateMaxTabWidth(tabPlacement)/* - 2 */;
6867:
6868: }
6869: }
6870:
6871: // if right to left and tab placement on the top or
6872: // the bottom, flip x positions and adjust by widths
6873: if (!leftToRight && !verticalTabRuns) {
6874: int rightMargin = size.width
6875: - (insets.right + tabAreaInsets.right);
6876: for (int i = 0; i < tabCount; i++) {
6877: _rects[i].x = rightMargin - _rects[i].x
6878: - _rects[i].width;
6879: }
6880: }
6881:
6882: ensureCurrentRects(getLeftMargin(), tabCount);
6883:
6884: }
6885: }
6886:
6887: protected void ensureCurrentRects(int style, int tabCount) {
6888: Dimension size = _tabPane.getSize();
6889: Insets insets = _tabPane.getInsets();
6890: int totalWidth = 0;
6891: int totalHeight = 0;
6892: boolean verticalTabRuns = (_tabPane.getTabPlacement() == LEFT || _tabPane
6893: .getTabPlacement() == RIGHT);
6894:
6895: if (tabCount == 0) {
6896: return;
6897: }
6898:
6899: Rectangle r = _rects[tabCount - 1];
6900:
6901: Dimension lsize = new Dimension(0, 0);
6902: Dimension tsize = new Dimension(0, 0);
6903:
6904: if (isTabLeadingComponentVisible()) {
6905: lsize = _tabLeadingComponent.getSize();
6906: }
6907: if (isTabTrailingComponentVisible()) {
6908: tsize = _tabTrailingComponent.getSize();
6909: }
6910:
6911: if (verticalTabRuns) {
6912: totalHeight = r.y + r.height;
6913:
6914: if (_tabLeadingComponent != null) {
6915: totalHeight -= lsize.height;
6916: }
6917:
6918: } else {
6919: totalWidth = r.x + r.width;
6920:
6921: if (_tabLeadingComponent != null) {
6922: totalWidth -= lsize.width;
6923: }
6924:
6925: }
6926:
6927: if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIT) {// LayOut Style is Size to Fix
6928: if (verticalTabRuns) {
6929: int availHeight;
6930: if (getTabShape() != JideTabbedPane.SHAPE_BOX) {
6931: availHeight = (int) size.getHeight()
6932: - _fitStyleBoundSize - insets.top
6933: - insets.bottom - style
6934: - getTabRightPadding();// give the first tab extra space
6935: } else {
6936: availHeight = (int) size.getHeight()
6937: - _fitStyleBoundSize - insets.top
6938: - insets.bottom;
6939: }
6940:
6941: if (_tabPane.isShowCloseButton()) {
6942: availHeight -= _buttonSize;
6943: }
6944:
6945: if (isTabLeadingComponentVisible()) {
6946: availHeight = availHeight - lsize.height;
6947: }
6948: if (isTabTrailingComponentVisible()) {
6949: availHeight = availHeight - tsize.height;
6950: }
6951:
6952: if (isShowTabButtons()) {
6953: int numberOfButtons = isShrinkTabs() ? 1 : 4;
6954: availHeight -= _buttonSize * numberOfButtons;
6955: }
6956: if (totalHeight > availHeight) { // shrink is necessary
6957: // calculate each tab width
6958: int tabHeight = availHeight / tabCount;
6959:
6960: totalHeight = _fitStyleFirstTabMargin; // start
6961:
6962: for (int k = 0; k < tabCount; k++) {
6963: _rects[k].height = tabHeight;
6964: Rectangle tabRect = _rects[k];
6965: if (getTabShape() != JideTabbedPane.SHAPE_BOX) {
6966: tabRect.y = totalHeight + style;// give the first tab extra space
6967: } else {
6968: tabRect.y = totalHeight;
6969: }
6970: totalHeight += tabRect.height;
6971: }
6972: }
6973:
6974: } else {
6975: int availWidth;
6976: if (getTabShape() != JideTabbedPane.SHAPE_BOX) {
6977: availWidth = (int) size.getWidth()
6978: - _fitStyleBoundSize - insets.left
6979: - insets.right - style
6980: - getTabRightPadding();
6981: } else {
6982: availWidth = (int) size.getWidth()
6983: - _fitStyleBoundSize - insets.left
6984: - insets.right;
6985: }
6986:
6987: if (_tabPane.isShowCloseButton()) {
6988: availWidth -= _buttonSize;
6989: }
6990:
6991: if (isTabLeadingComponentVisible()) {
6992: availWidth -= lsize.width;
6993: }
6994: if (isTabTrailingComponentVisible()) {
6995: availWidth -= tsize.width;
6996: }
6997:
6998: if (isShowTabButtons()) {
6999: int numberOfButtons = isShrinkTabs() ? 1 : 4;
7000: availWidth -= _buttonSize * numberOfButtons;
7001: }
7002: if (totalWidth > availWidth) { // shrink is necessary
7003: // calculate each tab width
7004: int tabWidth = availWidth / tabCount;
7005: int gripperWidth = _tabPane.isShowGripper() ? _gripperWidth
7006: : 0;
7007: if (tabWidth < _textIconGap + _fitStyleTextMinWidth
7008: + _fitStyleIconMinWidth + gripperWidth
7009: && tabWidth > _fitStyleIconMinWidth
7010: + gripperWidth) // cannot
7011: // hold any text but can hold an icon
7012: tabWidth = _fitStyleIconMinWidth + gripperWidth;
7013:
7014: if (tabWidth < _fitStyleIconMinWidth + gripperWidth
7015: && tabWidth > _fitStyleFirstTabMargin
7016: + gripperWidth) // cannot
7017: // hold any icon but gripper
7018: tabWidth = _fitStyleFirstTabMargin
7019: + gripperWidth;
7020:
7021: tryTabSpacer.reArrange(_rects, insets, availWidth);
7022: }
7023: totalWidth = _fitStyleFirstTabMargin; // start
7024:
7025: for (int k = 0; k < tabCount; k++) {
7026: Rectangle tabRect = _rects[k];
7027: if (getTabShape() != JideTabbedPane.SHAPE_BOX) {
7028: tabRect.x = totalWidth + style;// give the first tab extra space when the style is not box style
7029: } else {
7030: tabRect.x = totalWidth;
7031: }
7032: totalWidth += tabRect.width;
7033: }
7034: }
7035: }
7036:
7037: if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIXED) {// LayOut Style is Fix
7038: if (verticalTabRuns) {
7039: for (int k = 0; k < tabCount; k++) {
7040: _rects[k].height = _fixedStyleRectSize;// + _rectSizeExtend * 2;
7041:
7042: if (isShowCloseButton()
7043: && _tabPane.isShowCloseButtonOnTab()) {
7044: _rects[k].height += _closeButtons[k]
7045: .getPreferredSize().height;
7046: }
7047:
7048: if (k != 0) {
7049: _rects[k].y = _rects[k - 1].y
7050: + _rects[k - 1].height;
7051: }
7052:
7053: totalHeight = _rects[k].y + _rects[k].height;
7054: }
7055:
7056: } else {
7057: for (int k = 0; k < tabCount; k++) {
7058: _rects[k].width = _fixedStyleRectSize;// + _rectSizeExtend * 2;
7059:
7060: if (isShowCloseButton()
7061: && _tabPane.isShowCloseButtonOnTab()) {
7062: _rects[k].width += _closeButtons[k]
7063: .getPreferredSize().width;
7064: }
7065:
7066: if (k != 0) {
7067: _rects[k].x = _rects[k - 1].x
7068: + _rects[k - 1].width;
7069: }
7070:
7071: totalWidth = _rects[k].x + _rects[k].width;
7072:
7073: }
7074: }
7075: }
7076:
7077: if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_COMPRESSED) {// LayOut Style is Compressed
7078: if (verticalTabRuns) {
7079: for (int k = 0; k < tabCount; k++) {
7080: if (k != _tabPane.getSelectedIndex()) {
7081: if (!_tabPane.isShowIconsOnTab()
7082: && !_tabPane
7083: .isUseDefaultShowIconsOnTab()) {
7084: _rects[k].height = _compressedStyleNoIconRectSize;
7085: } else {
7086: Icon icon = getIconForTab(k);
7087: _rects[k].height = icon.getIconHeight()
7088: + _compressedStyleIconMargin;
7089: }
7090:
7091: if (isShowCloseButton()
7092: && isShowCloseButtonOnTab()
7093: && !_tabPane
7094: .isShowCloseButtonOnSelectedTab()) {
7095: _rects[k].height = _rects[k].height
7096: + _closeButtons[k]
7097: .getPreferredSize().height
7098: + _compressedStyleCloseButtonMarginVertical;
7099: }
7100: }
7101:
7102: if (k != 0) {
7103: _rects[k].y = _rects[k - 1].y
7104: + _rects[k - 1].height;
7105: }
7106:
7107: totalHeight = _rects[k].y + _rects[k].height;
7108:
7109: }
7110:
7111: } else {
7112: for (int k = 0; k < tabCount; k++) {
7113: if (k != _tabPane.getSelectedIndex()) {
7114: if (!_tabPane.isShowIconsOnTab()
7115: && !_tabPane
7116: .isUseDefaultShowIconsOnTab()) {
7117: _rects[k].width = _compressedStyleNoIconRectSize;
7118: } else {
7119: Icon icon = getIconForTab(k);
7120: _rects[k].width = icon.getIconWidth()
7121: + _compressedStyleIconMargin;
7122: }
7123:
7124: if (isShowCloseButton()
7125: && isShowCloseButtonOnTab()
7126: && !_tabPane
7127: .isShowCloseButtonOnSelectedTab()) {
7128: _rects[k].width = _rects[k].width
7129: + _closeButtons[k]
7130: .getPreferredSize().width
7131: + _compressedStyleCloseButtonMarginHorizon;
7132: }
7133:
7134: }
7135:
7136: if (k != 0) {
7137: _rects[k].x = _rects[k - 1].x
7138: + _rects[k - 1].width;
7139: }
7140:
7141: totalWidth = _rects[k].x + _rects[k].width;
7142:
7143: }
7144:
7145: }
7146: }
7147:
7148: if (_tabPane.getTabPlacement() == TOP
7149: || _tabPane.getTabPlacement() == BOTTOM) {
7150: totalWidth += getLayoutSize();
7151:
7152: if (isTabLeadingComponentVisible()) {
7153: totalWidth += _tabLeadingComponent.getSize().width;
7154: }
7155: } else {
7156: totalHeight += getLayoutSize();
7157:
7158: if (isTabLeadingComponentVisible()) {
7159: totalHeight += _tabLeadingComponent.getSize().height;
7160: }
7161: }
7162:
7163: _tabScroller.tabPanel.setPreferredSize(new Dimension(
7164: totalWidth, totalHeight));
7165:
7166: }
7167:
7168: protected class ActivateTabAction extends AbstractAction {
7169: int _tabIndex;
7170:
7171: public ActivateTabAction(String name, Icon icon, int tabIndex) {
7172: super (name, icon);
7173: _tabIndex = tabIndex;
7174: }
7175:
7176: public void actionPerformed(ActionEvent e) {
7177: _tabPane.setSelectedIndex(_tabIndex);
7178: }
7179: }
7180:
7181: protected ListCellRenderer getTabListCellRenderer() {
7182: return _tabPane.getTabListCellRenderer();
7183: }
7184:
7185: public class ScrollableTabSupport implements ChangeListener {
7186: public ScrollableTabViewport viewport;
7187: public ScrollableTabPanel tabPanel;
7188: public TabCloseButton scrollForwardButton;
7189: public TabCloseButton scrollBackwardButton;
7190: public TabCloseButton listButton;
7191: public TabCloseButton closeButton;
7192: public int leadingTabIndex;
7193:
7194: private Point tabViewPosition = new Point(0, 0);
7195: public JidePopup _popup;
7196:
7197: ScrollableTabSupport(int tabPlacement) {
7198: viewport = new ScrollableTabViewport();
7199: tabPanel = new ScrollableTabPanel();
7200: viewport.setView(tabPanel);
7201: viewport.addChangeListener(this );
7202:
7203: scrollForwardButton = createNoFocusButton(TabCloseButton.EAST_BUTTON);
7204: scrollForwardButton.setName("TabScrollForward");
7205: scrollBackwardButton = createNoFocusButton(TabCloseButton.WEST_BUTTON);
7206: scrollBackwardButton.setName("TabScrollBackward");
7207:
7208: scrollForwardButton.setBackground(viewport.getBackground());
7209: scrollBackwardButton
7210: .setBackground(viewport.getBackground());
7211:
7212: listButton = createNoFocusButton(TabCloseButton.LIST_BUTTON);
7213: listButton.setBackground(viewport.getBackground());
7214:
7215: closeButton = createNoFocusButton(TabCloseButton.CLOSE_BUTTON);
7216: closeButton.setBackground(viewport.getBackground());
7217: }
7218:
7219: public void createPopupMenu(int tabPlacement) {
7220: JPopupMenu popup = new JPopupMenu();
7221: int totalCount = _tabPane.getTabCount();
7222:
7223: // drop down menu items
7224: int selectedIndex = _tabPane.getSelectedIndex();
7225: for (int i = 0; i < totalCount; i++) {
7226: if (_tabPane.isEnabledAt(i)) {
7227: JMenuItem item;
7228: popup
7229: .add(item = new JCheckBoxMenuItem(
7230: new ActivateTabAction(_tabPane
7231: .getTitleAt(i),
7232: getIconForTab(i), i)));
7233: item.setToolTipText(_tabPane.getToolTipTextAt(i));
7234: item.setSelected(selectedIndex == i);
7235: item.setHorizontalTextPosition(JMenuItem.RIGHT);
7236: }
7237: }
7238:
7239: Dimension preferredSize = popup.getPreferredSize();
7240: Rectangle bounds = listButton.getBounds();
7241: switch (tabPlacement) {
7242: case TOP:
7243: popup
7244: .show(_tabPane, bounds.x + bounds.width
7245: - preferredSize.width, bounds.y
7246: + bounds.height);
7247: break;
7248: case BOTTOM:
7249: popup.show(_tabPane, bounds.x + bounds.width
7250: - preferredSize.width, bounds.y
7251: - preferredSize.height);
7252: break;
7253: case LEFT:
7254: popup.show(_tabPane, bounds.x + bounds.width, bounds.y
7255: + bounds.height - preferredSize.height);
7256: break;
7257: case RIGHT:
7258: popup
7259: .show(_tabPane, bounds.x - preferredSize.width,
7260: bounds.y + bounds.height
7261: - preferredSize.height);
7262: break;
7263: }
7264: }
7265:
7266: public void createPopup(int tabPlacement) {
7267: final JList list = new JList() {
7268: // override this method to disallow deselect by ctrl-click
7269: @Override
7270: public void removeSelectionInterval(int index0,
7271: int index1) {
7272: super .removeSelectionInterval(index0, index1);
7273: if (getSelectedIndex() == -1) {
7274: setSelectedIndex(index0);
7275: }
7276: }
7277:
7278: @Override
7279: public Dimension getPreferredScrollableViewportSize() {
7280: Dimension preferredScrollableViewportSize = super
7281: .getPreferredScrollableViewportSize();
7282: if (preferredScrollableViewportSize.width < 150) {
7283: preferredScrollableViewportSize.width = 150;
7284: }
7285: return preferredScrollableViewportSize;
7286: }
7287: };
7288: new Sticky(list);
7289: list.setBackground(new Color(255, 255, 225));
7290: JScrollPane scroller = new JScrollPane(list);
7291: scroller.setBorder(BorderFactory.createEmptyBorder());
7292: scroller.getViewport().setOpaque(false);
7293: scroller.setOpaque(false);
7294:
7295: JPanel panel = new JPanel(new BorderLayout());
7296: panel.setBackground(new Color(255, 255, 225));
7297: panel.setOpaque(true);
7298: panel.add(scroller);
7299: panel
7300: .setBorder(BorderFactory.createEmptyBorder(3, 3, 3,
7301: 3));
7302:
7303: if (_popup != null) {
7304: if (_popup.isPopupVisible()) {
7305: _popup.hidePopupImmediately();
7306: }
7307: _popup = null;
7308: }
7309: _popup = new JidePopup();
7310: _popup.setPopupBorder(BorderFactory
7311: .createLineBorder(_darkShadow));
7312: _popup.add(panel);
7313: _popup.addExcludedComponent(listButton);
7314: _popup.setDefaultFocusComponent(list);
7315:
7316: DefaultListModel listModel = new DefaultListModel();
7317:
7318: // drop down menu items
7319: int selectedIndex = _tabPane.getSelectedIndex();
7320: int totalCount = _tabPane.getTabCount();
7321: for (int i = 0; i < totalCount; i++) {
7322: listModel.addElement(_tabPane);
7323: }
7324: list.setCellRenderer(getTabListCellRenderer());
7325: list.setModel(listModel);
7326: list.setSelectedIndex(selectedIndex);
7327: list.addMouseListener(new MouseAdapter() {
7328: @Override
7329: public void mouseReleased(MouseEvent e) {
7330: int index = list.getSelectedIndex();
7331: if (index != -1 && _tabPane.isEnabledAt(index)) {
7332: _tabPane.setSelectedIndex(index);
7333: _popup.hidePopupImmediately();
7334: _popup = null;
7335: }
7336: }
7337: });
7338:
7339: list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
7340: Insets insets = panel.getInsets();
7341: int max = (PortingUtils.getLocalScreenSize(_tabPane).height
7342: - insets.top - insets.bottom)
7343: / list.getCellBounds(0, 0).height;
7344: if (listModel.getSize() > max) {
7345: list.setVisibleRowCount(max);
7346: } else {
7347: list.setVisibleRowCount(listModel.getSize());
7348: }
7349:
7350: _popup.setOwner(_tabPane);
7351: _popup.removeExcludedComponent(_tabPane);
7352:
7353: Dimension size = _popup.getPreferredSize();
7354: Rectangle bounds = listButton.getBounds();
7355: Point p = listButton.getLocationOnScreen();
7356: bounds.x = p.x;
7357: bounds.y = p.y;
7358: int x;
7359: int y;
7360: switch (tabPlacement) {
7361: case TOP:
7362: default:
7363: x = bounds.x + bounds.width - size.width;
7364: y = bounds.y + bounds.height + 2;
7365: break;
7366: case BOTTOM:
7367: x = bounds.x + bounds.width - size.width;
7368: y = bounds.y - size.height - 2;
7369: break;
7370: case LEFT:
7371: x = bounds.x + bounds.width + 2;
7372: y = bounds.y + bounds.height - size.height;
7373: break;
7374: case RIGHT:
7375: x = bounds.x - size.width - 2;
7376: y = bounds.y + bounds.height - size.height;
7377: break;
7378: }
7379:
7380: Rectangle screenBounds = PortingUtils
7381: .getScreenBounds(_tabPane);
7382: int right = x + size.width + 3;
7383: int bottom = y + size.height + 3;
7384:
7385: if (right > screenBounds.x + screenBounds.width) {
7386: x -= right - screenBounds.x - screenBounds.width; // move left so that the whole popup can fit in
7387: }
7388:
7389: if (x < screenBounds.x) {
7390: x = screenBounds.x; // move right so that the whole popup can fit in
7391: }
7392:
7393: if (bottom > screenBounds.height) {
7394: y -= bottom - screenBounds.height;
7395: }
7396:
7397: if (y < screenBounds.y) {
7398: y = screenBounds.y;
7399: }
7400:
7401: _popup.showPopup(x, y);
7402: }
7403:
7404: public void scrollForward(int tabPlacement) {
7405: Dimension viewSize = viewport.getViewSize();
7406: Rectangle viewRect = viewport.getViewRect();
7407:
7408: if (tabPlacement == TOP || tabPlacement == BOTTOM) {
7409: if (viewRect.width >= viewSize.width - viewRect.x) {
7410: return; // no room left to scroll
7411: }
7412: } else { // tabPlacement == LEFT || tabPlacement == RIGHT
7413: if (viewRect.height >= viewSize.height - viewRect.y) {
7414: return;
7415: }
7416: }
7417: setLeadingTabIndex(tabPlacement, leadingTabIndex + 1);
7418: }
7419:
7420: public void scrollBackward(int tabPlacement) {
7421: setLeadingTabIndex(tabPlacement,
7422: leadingTabIndex > 0 ? leadingTabIndex - 1 : 0);
7423: }
7424:
7425: public void setLeadingTabIndex(int tabPlacement, int index) {
7426: leadingTabIndex = index;
7427: Dimension viewSize = viewport.getViewSize();
7428: Rectangle viewRect = viewport.getViewRect();
7429:
7430: switch (tabPlacement) {
7431: case TOP:
7432: case BOTTOM:
7433: tabViewPosition.y = 0;
7434: tabViewPosition.x = leadingTabIndex == 0 ? 0
7435: : _rects[leadingTabIndex].x;
7436:
7437: if ((viewSize.width - tabViewPosition.x) < viewRect.width) {
7438: tabViewPosition.x = viewSize.width - viewRect.width;
7439: // // We've scrolled to the end, so adjust the viewport size
7440: // // to ensure the view position remains aligned on a tab boundary
7441: // Dimension extentSize = new Dimension(viewSize.width - tabViewPosition.x,
7442: // viewRect.height);
7443: // System.out.println("setExtendedSize: " + extentSize);
7444: // viewport.setExtentSize(extentSize);
7445: }
7446: break;
7447: case LEFT:
7448: case RIGHT:
7449: tabViewPosition.x = 0;
7450: tabViewPosition.y = leadingTabIndex == 0 ? 0
7451: : _rects[leadingTabIndex].y;
7452:
7453: if ((viewSize.height - tabViewPosition.y) < viewRect.height) {
7454: tabViewPosition.y = viewSize.height
7455: - viewRect.height;
7456: // // We've scrolled to the end, so adjust the viewport size
7457: // // to ensure the view position remains aligned on a tab boundary
7458: // Dimension extentSize = new Dimension(viewRect.width,
7459: // viewSize.height - tabViewPosition.y);
7460: // viewport.setExtentSize(extentSize);
7461: }
7462: break;
7463: }
7464: viewport.setViewPosition(tabViewPosition);
7465: }
7466:
7467: public void stateChanged(ChangeEvent e) {
7468: if (_tabPane == null)
7469: return;
7470:
7471: ensureCurrentLayout();
7472:
7473: JViewport viewport = (JViewport) e.getSource();
7474: int tabPlacement = _tabPane.getTabPlacement();
7475: int tabCount = _tabPane.getTabCount();
7476: Rectangle vpRect = viewport.getBounds();
7477: Dimension viewSize = viewport.getViewSize();
7478: Rectangle viewRect = viewport.getViewRect();
7479:
7480: leadingTabIndex = getClosestTab(viewRect.x, viewRect.y);
7481:
7482: // If the tab isn't right aligned, adjust it.
7483: if (leadingTabIndex < _rects.length
7484: && leadingTabIndex >= _rects.length) {
7485: switch (tabPlacement) {
7486: case TOP:
7487: case BOTTOM:
7488: if (_rects[leadingTabIndex].x < viewRect.x) {
7489: leadingTabIndex++;
7490: }
7491: break;
7492: case LEFT:
7493: case RIGHT:
7494: if (_rects[leadingTabIndex].y < viewRect.y) {
7495: leadingTabIndex++;
7496: }
7497: break;
7498: }
7499: }
7500:
7501: Insets contentInsets = getContentBorderInsets(tabPlacement);
7502: switch (tabPlacement) {
7503: case LEFT:
7504: _tabPane.repaint(vpRect.x + vpRect.width, vpRect.y,
7505: contentInsets.left, vpRect.height);
7506: scrollBackwardButton.setEnabled(viewRect.y > 0
7507: || leadingTabIndex > 0);
7508: scrollForwardButton
7509: .setEnabled(leadingTabIndex < tabCount - 1
7510: && viewSize.height - viewRect.y > viewRect.height);
7511: break;
7512: case RIGHT:
7513: _tabPane.repaint(vpRect.x - contentInsets.right,
7514: vpRect.y, contentInsets.right, vpRect.height);
7515: scrollBackwardButton.setEnabled(viewRect.y > 0
7516: || leadingTabIndex > 0);
7517: scrollForwardButton
7518: .setEnabled(leadingTabIndex < tabCount - 1
7519: && viewSize.height - viewRect.y > viewRect.height);
7520: break;
7521: case BOTTOM:
7522: _tabPane.repaint(vpRect.x, vpRect.y
7523: - contentInsets.bottom, vpRect.width,
7524: contentInsets.bottom);
7525: scrollBackwardButton.setEnabled(viewRect.x > 0
7526: || leadingTabIndex > 0);
7527: scrollForwardButton
7528: .setEnabled(leadingTabIndex < tabCount - 1
7529: && viewSize.width - viewRect.x > viewRect.width);
7530: break;
7531: case TOP:
7532: default:
7533: _tabPane.repaint(vpRect.x, vpRect.y + vpRect.height,
7534: vpRect.width, contentInsets.top);
7535: scrollBackwardButton.setEnabled(viewRect.x > 0
7536: || leadingTabIndex > 0);
7537: scrollForwardButton
7538: .setEnabled(leadingTabIndex < tabCount - 1
7539: && viewSize.width - viewRect.x > viewRect.width);
7540: }
7541:
7542: int selectedIndex = _tabPane.getSelectedIndex();
7543: if (selectedIndex >= 0
7544: && selectedIndex < _tabPane.getTabCount()) {
7545: closeButton.setEnabled(_tabPane
7546: .isTabClosableAt(selectedIndex));
7547: }
7548: }
7549:
7550: @Override
7551: public String toString() {
7552: return "viewport.viewSize=" + viewport.getViewSize() + "\n"
7553: + "viewport.viewRectangle="
7554: + viewport.getViewRect() + "\n"
7555: + "leadingTabIndex=" + leadingTabIndex + "\n"
7556: + "tabViewPosition=" + tabViewPosition;
7557: }
7558:
7559: }
7560:
7561: public class ScrollableTabViewport extends JViewport implements
7562: UIResource {
7563: public ScrollableTabViewport() {
7564: super ();
7565: setScrollMode(JViewport.SIMPLE_SCROLL_MODE);
7566: setOpaque(false);
7567: }
7568:
7569: /**
7570: * Gets the background color of this component.
7571: *
7572: * @return this component's background color; if this component does not
7573: * have a background color, the background color of its parent
7574: * is returned
7575: */
7576: @Override
7577: public Color getBackground() {
7578: return UIDefaultsLookup
7579: .getColor("JideTabbedPane.background");
7580: }
7581: }
7582:
7583: public class ScrollableTabPanel extends JPanel implements
7584: UIResource {
7585: public ScrollableTabPanel() {
7586: setLayout(null);
7587: }
7588:
7589: @Override
7590: public boolean isOpaque() {
7591: return false;
7592: }
7593:
7594: @Override
7595: public void paintComponent(Graphics g) {
7596: super .paintComponent(g);
7597:
7598: if (_tabPane.isOpaque()) {
7599: if (getTabShape() == JideTabbedPane.SHAPE_BOX) {
7600: g
7601: .setColor(UIDefaultsLookup
7602: .getColor("JideTabbedPane.selectedTabBackground"));
7603: } else {
7604: g
7605: .setColor(UIDefaultsLookup
7606: .getColor("JideTabbedPane.tabAreaBackground"));
7607: }
7608: g.fillRect(0, 0, getWidth(), getHeight());
7609: }
7610:
7611: paintTabArea(g, _tabPane.getTabPlacement(), _tabPane
7612: .getSelectedIndex());
7613: }
7614:
7615: // workaround for swing bug
7616: // http://developer.java.sun.com/developer/bugParade/bugs/4668865.html
7617: @Override
7618: public void setToolTipText(String text) {
7619: _tabPane.setToolTipText(text);
7620: }
7621:
7622: @Override
7623: public String getToolTipText() {
7624: return _tabPane.getToolTipText();
7625: }
7626:
7627: @Override
7628: public String getToolTipText(MouseEvent event) {
7629: return _tabPane.getToolTipText(SwingUtilities
7630: .convertMouseEvent(this , event, _tabPane));
7631: }
7632:
7633: @Override
7634: public Point getToolTipLocation(MouseEvent event) {
7635: return _tabPane.getToolTipLocation(SwingUtilities
7636: .convertMouseEvent(this , event, _tabPane));
7637: }
7638:
7639: @Override
7640: public JToolTip createToolTip() {
7641: return _tabPane.createToolTip();
7642: }
7643: }
7644:
7645: protected Color _closeButtonSelectedColor = new Color(255, 162, 165);
7646: protected Color _closeButtonColor = Color.BLACK;
7647: protected Color _popupColor = Color.BLACK;
7648:
7649: /**
7650: * Close button on the tab.
7651: */
7652: public class TabCloseButton extends JButton implements
7653: MouseMotionListener, MouseListener, UIResource {
7654: public static final int CLOSE_BUTTON = 0;
7655: public static final int EAST_BUTTON = 1;
7656: public static final int WEST_BUTTON = 2;
7657: public static final int NORTH_BUTTON = 3;
7658: public static final int SOUTH_BUTTON = 4;
7659: public static final int LIST_BUTTON = 5;
7660: private int _type;
7661: private int _index = -1;
7662: private boolean _mouseOver = false;
7663: private boolean _mousePressed = false;
7664:
7665: /**
7666: * Resets the UI property to a value from the current look and
7667: * feel.
7668: *
7669: * @see JComponent#updateUI
7670: */
7671: @Override
7672: public void updateUI() {
7673: super .updateUI();
7674: setMargin(new Insets(0, 0, 0, 0));
7675: setBorder(BorderFactory.createEmptyBorder());
7676: setFocusPainted(false);
7677: setFocusable(false);
7678: setRequestFocusEnabled(false);
7679: }
7680:
7681: public TabCloseButton() {
7682: this (CLOSE_BUTTON);
7683: }
7684:
7685: public TabCloseButton(int type) {
7686: addMouseMotionListener(this );
7687: addMouseListener(this );
7688: setFocusPainted(false);
7689: setFocusable(false);
7690: setType(type);
7691: }
7692:
7693: @Override
7694: public Dimension getPreferredSize() {
7695: return new Dimension(16, 16);
7696: }
7697:
7698: @Override
7699: public Dimension getMinimumSize() {
7700: return new Dimension(5, 5);
7701: }
7702:
7703: public int getIndex() {
7704: return _index;
7705: }
7706:
7707: public void setIndex(int index) {
7708: _index = index;
7709: }
7710:
7711: @Override
7712: public Dimension getMaximumSize() {
7713: return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE);
7714: }
7715:
7716: @Override
7717: protected void paintComponent(Graphics g) {
7718: if (!isEnabled()) {
7719: setMouseOver(false);
7720: setMousePressed(false);
7721: }
7722: if (isMouseOver() && isMousePressed()) {
7723: g
7724: .setColor(UIDefaultsLookup
7725: .getColor("controlDkShadow"));
7726: g.drawLine(0, 0, getWidth() - 1, 0);
7727: g.drawLine(0, getHeight() - 2, 0, 1);
7728: g.setColor(UIDefaultsLookup.getColor("control"));
7729: g.drawLine(getWidth() - 1, 1, getWidth() - 1,
7730: getHeight() - 2);
7731: g.drawLine(getWidth() - 1, getHeight() - 1, 0,
7732: getHeight() - 1);
7733: } else if (isMouseOver()) {
7734: g.setColor(UIDefaultsLookup.getColor("control"));
7735: g.drawLine(0, 0, getWidth() - 1, 0);
7736: g.drawLine(0, getHeight() - 2, 0, 1);
7737: g
7738: .setColor(UIDefaultsLookup
7739: .getColor("controlDkShadow"));
7740: g.drawLine(getWidth() - 1, 1, getWidth() - 1,
7741: getHeight() - 2);
7742: g.drawLine(getWidth() - 1, getHeight() - 1, 0,
7743: getHeight() - 1);
7744: }
7745: g.setColor(UIDefaultsLookup.getColor("controlShadow")
7746: .darker());
7747: int centerX = getWidth() >> 1;
7748: int centerY = getHeight() >> 1;
7749: switch (getType()) {
7750: case CLOSE_BUTTON:
7751: if (isEnabled()) {
7752: g.drawLine(centerX - 3, centerY - 3, centerX + 3,
7753: centerY + 3);
7754: g.drawLine(centerX - 4, centerY - 3, centerX + 2,
7755: centerY + 3);
7756: g.drawLine(centerX + 3, centerY - 3, centerX - 3,
7757: centerY + 3);
7758: g.drawLine(centerX + 2, centerY - 3, centerX - 4,
7759: centerY + 3);
7760: } else {
7761: g.drawLine(centerX - 3, centerY - 3, centerX + 3,
7762: centerY + 3);
7763: g.drawLine(centerX + 3, centerY - 3, centerX - 3,
7764: centerY + 3);
7765: }
7766: break;
7767: case EAST_BUTTON:
7768: //
7769: // |
7770: // ||
7771: // |||
7772: // ||||
7773: // ||||*
7774: // ||||
7775: // |||
7776: // ||
7777: // |
7778: //
7779: {
7780: if (_tabPane.getTabPlacement() == TOP
7781: || _tabPane.getTabPlacement() == BOTTOM) {
7782: int x = centerX + 2, y = centerY; // start point. mark as * above
7783: if (isEnabled()) {
7784: g.drawLine(x - 4, y - 4, x - 4, y + 4);
7785: g.drawLine(x - 3, y - 3, x - 3, y + 3);
7786: g.drawLine(x - 2, y - 2, x - 2, y + 2);
7787: g.drawLine(x - 1, y - 1, x - 1, y + 1);
7788: g.drawLine(x, y, x, y);
7789: } else {
7790: g.drawLine(x - 4, y - 4, x, y);
7791: g.drawLine(x - 4, y - 4, x - 4, y + 4);
7792: g.drawLine(x - 4, y + 4, x, y);
7793: }
7794:
7795: } else {
7796: int x = centerX + 3, y = centerY - 2; // start point. mark as * above
7797: if (isEnabled()) {
7798: g.drawLine(x - 8, y, x, y);
7799: g.drawLine(x - 7, y + 1, x - 1, y + 1);
7800: g.drawLine(x - 6, y + 2, x - 2, y + 2);
7801: g.drawLine(x - 5, y + 3, x - 3, y + 3);
7802: g.drawLine(x - 4, y + 4, x - 4, y + 4);
7803: } else {
7804: g.drawLine(x - 8, y, x, y);
7805: g.drawLine(x - 8, y, x - 4, y + 4);
7806: g.drawLine(x - 4, y + 4, x, y);
7807: }
7808: }
7809: }
7810: break;
7811: case WEST_BUTTON: {
7812: //
7813: // |
7814: // ||
7815: // |||
7816: // ||||
7817: // *||||
7818: // ||||
7819: // |||
7820: // ||
7821: // |
7822: //
7823: {
7824: if (_tabPane.getTabPlacement() == TOP
7825: || _tabPane.getTabPlacement() == BOTTOM) {
7826: int x = centerX - 3, y = centerY; // start point. mark as * above
7827: if (isEnabled()) {
7828: g.drawLine(x, y, x, y);
7829: g.drawLine(x + 1, y - 1, x + 1, y + 1);
7830: g.drawLine(x + 2, y - 2, x + 2, y + 2);
7831: g.drawLine(x + 3, y - 3, x + 3, y + 3);
7832: g.drawLine(x + 4, y - 4, x + 4, y + 4);
7833: } else {
7834: g.drawLine(x, y, x + 4, y - 4);
7835: g.drawLine(x, y, x + 4, y + 4);
7836: g.drawLine(x + 4, y - 4, x + 4, y + 4);
7837: }
7838: } else {
7839:
7840: int x = centerX - 5, y = centerY + 3; // start point. mark as * above
7841: if (isEnabled()) {
7842: g.drawLine(x, y, x + 8, y);
7843: g.drawLine(x + 1, y - 1, x + 7, y - 1);
7844: g.drawLine(x + 2, y - 2, x + 6, y - 2);
7845: g.drawLine(x + 3, y - 3, x + 5, y - 3);
7846: g.drawLine(x + 4, y - 4, x + 4, y - 4);
7847: } else {
7848: g.drawLine(x, y, x + 8, y);
7849: g.drawLine(x, y, x + 4, y - 4);
7850: g.drawLine(x + 8, y, x + 4, y - 4);
7851: }
7852: }
7853: }
7854: break;
7855: }
7856: case LIST_BUTTON: {
7857: int x = centerX + 2, y = centerY; // start point. mark as
7858: // * above
7859: g.drawLine(x - 6, y - 4, x - 6, y + 4);
7860: g.drawLine(x + 1, y - 4, x + 1, y + 4);
7861: g.drawLine(x - 6, y - 4, x + 1, y - 4);
7862: g.drawLine(x - 4, y - 2, x - 1, y - 2);
7863: g.drawLine(x - 4, y, x - 1, y);
7864: g.drawLine(x - 4, y + 2, x - 1, y + 2);
7865: g.drawLine(x - 6, y + 4, x + 1, y + 4);
7866: break;
7867: }
7868: }
7869: }
7870:
7871: @Override
7872: public boolean isFocusable() {
7873: return false;
7874: }
7875:
7876: @Override
7877: public void requestFocus() {
7878: }
7879:
7880: @Override
7881: public boolean isOpaque() {
7882: return false;
7883: }
7884:
7885: public boolean scrollsForward() {
7886: return getType() == EAST_BUTTON
7887: || getType() == SOUTH_BUTTON;
7888: }
7889:
7890: public void mouseDragged(MouseEvent e) {
7891: }
7892:
7893: public void mouseMoved(MouseEvent e) {
7894: if (!isEnabled())
7895: return;
7896: setMouseOver(true);
7897: repaint();
7898: }
7899:
7900: public void mouseClicked(MouseEvent e) {
7901: if (!isEnabled())
7902: return;
7903: setMouseOver(true);
7904: setMousePressed(false);
7905: }
7906:
7907: public void mousePressed(MouseEvent e) {
7908: if (!isEnabled())
7909: return;
7910: setMousePressed(true);
7911: repaint();
7912: }
7913:
7914: public void mouseReleased(MouseEvent e) {
7915: if (!isEnabled())
7916: return;
7917: setMousePressed(false);
7918: setMouseOver(false);
7919: }
7920:
7921: public void mouseEntered(MouseEvent e) {
7922: if (!isEnabled())
7923: return;
7924: setMouseOver(true);
7925: repaint();
7926: }
7927:
7928: public void mouseExited(MouseEvent e) {
7929: if (!isEnabled())
7930: return;
7931: setMouseOver(false);
7932: setMousePressed(false);
7933: _tabScroller.tabPanel.repaint();
7934: }
7935:
7936: public int getType() {
7937: return _type;
7938: }
7939:
7940: public void setType(int type) {
7941: _type = type;
7942: }
7943:
7944: protected boolean isMouseOver() {
7945: return _mouseOver;
7946: }
7947:
7948: protected void setMouseOver(boolean mouseOver) {
7949: _mouseOver = mouseOver;
7950: }
7951:
7952: protected boolean isMousePressed() {
7953: return _mousePressed;
7954: }
7955:
7956: protected void setMousePressed(boolean mousePressed) {
7957: _mousePressed = mousePressed;
7958: }
7959: }
7960:
7961: // Controller: event listeners
7962:
7963: /**
7964: * This inner class is marked "public" due to a compiler bug.
7965: * This class should be treated as a "protected" inner class.
7966: * Instantiate it only within subclasses of VsnetJideTabbedPaneUI.
7967: */
7968: public class PropertyChangeHandler implements
7969: PropertyChangeListener {
7970: public void propertyChange(PropertyChangeEvent e) {
7971: JTabbedPane pane = (JTabbedPane) e.getSource();
7972: String name = e.getPropertyName();
7973: if ("mnemonicAt".equals(name)) {
7974: updateMnemonics();
7975: pane.repaint();
7976: } else if ("displayedMnemonicIndexAt".equals(name)) {
7977: pane.repaint();
7978: } else if (name.equals("indexForTitle")) {
7979: int index = (Integer) e.getNewValue();
7980: String title = _tabPane.getDisplayTitleAt(index);
7981: if (BasicHTML.isHTMLString(title)) {
7982: if (htmlViews == null) { // Initialize vector
7983: htmlViews = createHTMLVector();
7984: } else { // Vector already exists
7985: View v = BasicHTML.createHTMLView(_tabPane,
7986: title);
7987: htmlViews.setElementAt(v, index);
7988: }
7989: } else {
7990: if (htmlViews != null
7991: && htmlViews.elementAt(index) != null) {
7992: htmlViews.setElementAt(null, index);
7993: }
7994: }
7995: updateMnemonics();
7996: } else if (name.equals("tabLayoutPolicy")) {
7997: _tabPane.updateUI();
7998: } else if (name.equals("closeTabAction")) {
7999: ActionMap map = getActionMap();
8000: Action action = _tabPane.getCloseAction();
8001: map.put("closeTabAction", action != null ? action
8002: : new CloseTabAction());
8003: ensureCloseButtonCreated();
8004: } else if (name
8005: .equals(JideTabbedPane.PROPERTY_DRAG_OVER_DISABLED)) {
8006: _tabPane.updateUI();
8007: } else if (name
8008: .equals(JideTabbedPane.PROPERTY_TAB_COLOR_PROVIDER)) {
8009: _tabPane.repaint();
8010: } else if (name
8011: .equals(JideTabbedPane.BOLDACTIVETAB_PROPERTY)) {
8012: getTabPanel().invalidate();
8013: _tabPane.invalidate();
8014: if (scrollableTabLayoutEnabled()) {
8015: _tabScroller.viewport.setViewSize(new Dimension(
8016: _tabPane.getWidth(), _tabScroller.viewport
8017: .getViewSize().height));
8018: ensureActiveTabIsVisible(true);
8019: }
8020: } else if (name
8021: .equals(JideTabbedPane.PROPERTY_TAB_LEADING_COMPONENT)) {
8022: ensureCurrentLayout();
8023: if (_tabLeadingComponent != null) {
8024: _tabLeadingComponent.setVisible(false);
8025: _tabPane.remove(_tabLeadingComponent);
8026: }
8027: _tabLeadingComponent = (Component) e.getNewValue();
8028: if (_tabLeadingComponent != null) {
8029: _tabLeadingComponent.setVisible(true);
8030: _tabPane.add(_tabLeadingComponent);
8031: }
8032: _tabScroller.tabPanel.updateUI();
8033: } else if (name
8034: .equals(JideTabbedPane.PROPERTY_TAB_TRAILING_COMPONENT)) {
8035: ensureCurrentLayout();
8036: if (_tabTrailingComponent != null) {
8037: _tabTrailingComponent.setVisible(false);
8038: _tabPane.remove(_tabTrailingComponent);
8039: }
8040: _tabTrailingComponent = (Component) e.getNewValue();
8041: if (_tabTrailingComponent != null) {
8042: _tabPane.add(_tabTrailingComponent);
8043: _tabTrailingComponent.setVisible(true);
8044: }
8045: _tabScroller.tabPanel.updateUI();
8046: } else if (name.equals(JideTabbedPane.SHRINK_TAB_PROPERTY)
8047: || name
8048: .equals(JideTabbedPane.HIDE_IF_ONE_TAB_PROPERTY)
8049: || name
8050: .equals(JideTabbedPane.SHOW_TAB_AREA_PROPERTY)
8051: || name
8052: .equals(JideTabbedPane.SHOW_TAB_CONTENT_PROPERTY)
8053: || name.equals(JideTabbedPane.BOX_STYLE_PROPERTY)
8054: || name.equals(JideTabbedPane.SHOW_ICONS_PROPERTY)
8055: || name
8056: .equals(JideTabbedPane.SHOW_CLOSE_BUTTON_PROPERTY)
8057: || name
8058: .equals(JideTabbedPane.USE_DEFAULT_SHOW_ICONS_PROPERTY)
8059: || name
8060: .equals(JideTabbedPane.SHOW_CLOSE_BUTTON_ON_TAB_PROPERTY)
8061: || name
8062: .equals(JideTabbedPane.USE_DEFAULT_SHOW_CLOSE_BUTTON_ON_TAB_PROPERTY)
8063: || name
8064: .equals(JideTabbedPane.TAB_CLOSABLE_PROPERTY)
8065: || name.equals(JideTabbedPane.PROPERTY_TAB_SHAPE)
8066: || name.equals(JideTabbedPane.PROPERTY_COLOR_THEME)
8067: || name
8068: .equals(JideTabbedPane.PROPERTY_TAB_RESIZE_MODE)
8069: || name
8070: .equals(JideTabbedPane.SHOW_TAB_BUTTONS_PROPERTY)) {
8071: if ((name
8072: .equals(JideTabbedPane.USE_DEFAULT_SHOW_CLOSE_BUTTON_ON_TAB_PROPERTY) || name
8073: .equals(JideTabbedPane.SHOW_CLOSE_BUTTON_ON_TAB_PROPERTY))
8074: && isShowCloseButton()
8075: && isShowCloseButtonOnTab()) {
8076: ensureCloseButtonCreated();
8077: }
8078: _tabPane.updateUI();
8079: }
8080: }
8081: }
8082:
8083: /**
8084: * This inner class is marked "public" due to a compiler bug.
8085: * This class should be treated as a "protected" inner class.
8086: * Instantiate it only within subclasses of VsnetJideTabbedPaneUI.
8087: */
8088: public class TabSelectionHandler implements ChangeListener {
8089: public void stateChanged(ChangeEvent e) {
8090: ensureCloseButtonCreated();
8091: Runnable runnable = new Runnable() {
8092: public void run() {
8093: ensureActiveTabIsVisible(false);
8094: }
8095: };
8096: SwingUtilities.invokeLater(runnable);
8097: }
8098: }
8099:
8100: public class TabFocusListener implements FocusListener {
8101: public void focusGained(FocusEvent e) {
8102: repaintSelectedTab();
8103: }
8104:
8105: public void focusLost(FocusEvent e) {
8106: repaintSelectedTab();
8107: }
8108:
8109: private void repaintSelectedTab() {
8110: if (_tabPane.getTabCount() > 0) {
8111: Rectangle rect = getTabBounds(_tabPane, _tabPane
8112: .getSelectedIndex());
8113: if (rect != null) {
8114: _tabPane.repaint(rect);
8115: }
8116: }
8117: }
8118: }
8119:
8120: public class MouseMotionHandler extends MouseMotionAdapter {
8121:
8122: }
8123:
8124: /**
8125: * This inner class is marked "public" due to a compiler bug.
8126: * This class should be treated as a "protected" inner class.
8127: * Instantiate it only within subclasses of VsnetJideTabbedPaneUI.
8128: */
8129: public class MouseHandler extends MouseAdapter {
8130: @Override
8131: public void mousePressed(MouseEvent e) {
8132: if (!_tabPane.isEnabled()) {
8133: return;
8134: }
8135:
8136: if (SwingUtilities.isLeftMouseButton(e)
8137: || _tabPane.isRightClickSelect()) {
8138: int tabIndex = getTabAtLocation(e.getX(), e.getY());
8139: if (tabIndex >= 0 && _tabPane.isEnabledAt(tabIndex)) {
8140: if (tabIndex == _tabPane.getSelectedIndex()
8141: && JideSwingUtilities
8142: .isAncestorOfFocusOwner(_tabPane)) {
8143: if (_tabPane.isRequestFocusEnabled()) {
8144: if (!_tabPane.requestFocusInWindow()) {
8145: _tabPane.requestFocus();
8146: }
8147: }
8148: } else {
8149: _tabPane.setSelectedIndex(tabIndex);
8150: final Component comp = _tabPane
8151: .getComponentAt(tabIndex);
8152: if (!comp.isVisible()
8153: && SystemInfo.isJdk15Above()
8154: && !SystemInfo.isJdk16Above()) {
8155: comp
8156: .addComponentListener(new ComponentAdapter() {
8157: @Override
8158: public void componentShown(
8159: ComponentEvent e) {
8160: // remove the listener
8161: comp
8162: .removeComponentListener(this );
8163:
8164: Component lastFocused = _tabPane
8165: .getLastFocusedComponent(comp);
8166: if (lastFocused != null) {
8167: // this code works in JDK6 but on JDK5
8168: if (!lastFocused
8169: .requestFocusInWindow()) {
8170: lastFocused
8171: .requestFocus();
8172: }
8173: } else if (_tabPane
8174: .isRequestFocusEnabled()) {
8175: if (!_tabPane
8176: .requestFocusInWindow()) {
8177: _tabPane
8178: .requestFocus();
8179: }
8180: }
8181: }
8182: });
8183: } else {
8184: Component lastFocused = _tabPane
8185: .getLastFocusedComponent(comp);
8186: if (lastFocused != null) {
8187: // this code works in JDK6 but on JDK5
8188: if (!lastFocused.requestFocusInWindow()) {
8189: lastFocused.requestFocus();
8190: }
8191: } else if (_tabPane.isRequestFocusEnabled()) {
8192: if (!_tabPane.requestFocusInWindow()) {
8193: _tabPane.requestFocus();
8194: }
8195: }
8196: }
8197: }
8198: }
8199: }
8200: startEditing(e); // start editing tab
8201: }
8202:
8203: }
8204:
8205: private class ComponentHandler implements ComponentListener {
8206: public void componentResized(ComponentEvent e) {
8207: if (scrollableTabLayoutEnabled()) {
8208: _tabScroller.viewport.setViewSize(new Dimension(
8209: _tabPane.getWidth(), _tabScroller.viewport
8210: .getViewSize().height));
8211: ensureActiveTabIsVisible(true);
8212: }
8213: }
8214:
8215: public void componentMoved(ComponentEvent e) {
8216: }
8217:
8218: public void componentShown(ComponentEvent e) {
8219: }
8220:
8221: public void componentHidden(ComponentEvent e) {
8222: }
8223: }
8224:
8225: /* GES 2/3/99:
8226: The container listener code was added to support HTML
8227: rendering of tab titles.
8228:
8229: Ideally, we would be able to listen for property changes
8230: when a tab is added or its text modified. At the moment
8231: there are no such events because the Beans spec doesn't
8232: allow 'indexed' property changes (i.e. tab 2's text changed
8233: from A to B).
8234:
8235: In order to get around this, we listen for tabs to be added
8236: or removed by listening for the container events. we then
8237: queue up a runnable (so the component has a chance to complete
8238: the add) which checks the tab title of the new component to see
8239: if it requires HTML rendering.
8240:
8241: The Views (one per tab title requiring HTML rendering) are
8242: stored in the htmlViews Vector, which is only allocated after
8243: the first time we run into an HTML tab. Note that this vector
8244: is kept in step with the number of pages, and nulls are added
8245: for those pages whose tab title do not require HTML rendering.
8246:
8247: This makes it easy for the paint and layout code to tell
8248: whether to invoke the HTML engine without having to check
8249: the string during time-sensitive operations.
8250:
8251: When we have added a way to listen for tab additions and
8252: changes to tab text, this code should be removed and
8253: replaced by something which uses that. */
8254:
8255: private class ContainerHandler implements ContainerListener {
8256: public void componentAdded(ContainerEvent e) {
8257: JideTabbedPane tp = (JideTabbedPane) e.getContainer();
8258: // updateTabPanel();
8259: Component child = e.getChild();
8260: if (child instanceof UIResource
8261: || child == tp.getTabLeadingComponent()
8262: || child == tp.getTabTrailingComponent()) {
8263: return;
8264: }
8265:
8266: int index = tp.indexOfComponent(child);
8267: String title = tp.getDisplayTitleAt(index);
8268: boolean isHTML = BasicHTML.isHTMLString(title);
8269: if (isHTML) {
8270: if (htmlViews == null) { // Initialize vector
8271: htmlViews = createHTMLVector();
8272: } else { // Vector already exists
8273: View v = BasicHTML.createHTMLView(tp, title);
8274: htmlViews.insertElementAt(v, index);
8275: }
8276: } else { // Not HTML
8277: if (htmlViews != null) { // Add placeholder
8278: htmlViews.insertElementAt(null, index);
8279: } // else nada!
8280: }
8281:
8282: if (_tabPane.isTabEditing()) {
8283: _tabPane.stopTabEditing();
8284: }
8285:
8286: ensureCloseButtonCreated();
8287: ensureActiveTabIsVisible(true);
8288: }
8289:
8290: public void componentRemoved(ContainerEvent e) {
8291: JideTabbedPane tp = (JideTabbedPane) e.getContainer();
8292: // updateTabPanel();
8293: Component child = e.getChild();
8294: if (child instanceof UIResource
8295: || child == tp.getTabLeadingComponent()
8296: || child == tp.getTabTrailingComponent()) {
8297: return;
8298: }
8299:
8300: // NOTE 4/15/2002 (joutwate):
8301: // This fix is implemented using client properties since there is
8302: // currently no IndexPropertyChangeEvent. Once
8303: // IndexPropertyChangeEvents have been added this code should be
8304: // modified to use it.
8305: Integer indexObj = (Integer) tp
8306: .getClientProperty("__index_to_remove__");
8307: if (indexObj != null) {
8308: int index = indexObj;
8309: if (htmlViews != null && htmlViews.size() >= index) {
8310: htmlViews.removeElementAt(index);
8311: }
8312: }
8313:
8314: if (_tabPane.isTabEditing()) {
8315: _tabPane.stopTabEditing();
8316: }
8317:
8318: ensureCloseButtonCreated();
8319: ensureActiveTabIsVisible(true);
8320: }
8321: }
8322:
8323: private Vector createHTMLVector() {
8324: Vector htmlViews = new Vector();
8325: int count = _tabPane.getTabCount();
8326: if (count > 0) {
8327: for (int i = 0; i < count; i++) {
8328: String title = _tabPane.getDisplayTitleAt(i);
8329: if (BasicHTML.isHTMLString(title)) {
8330: htmlViews.addElement(BasicHTML.createHTMLView(
8331: _tabPane, title));
8332: } else {
8333: htmlViews.addElement(null);
8334: }
8335: }
8336: }
8337: return htmlViews;
8338: }
8339:
8340: @Override
8341: public Component getTabPanel() {
8342: if (scrollableTabLayoutEnabled())
8343: return _tabScroller.tabPanel;
8344: else
8345: return _tabPane;
8346: }
8347:
8348: static class AbstractTab {
8349: int width;
8350:
8351: int id;
8352:
8353: public void copy(AbstractTab tab) {
8354: this .width = tab.width;
8355: this .id = tab.id;
8356: }
8357: }
8358:
8359: public static class TabSpaceAllocator {
8360: static final int startOffset = 4;
8361:
8362: private Insets insets = null;
8363:
8364: static final int tabWidth = 24;
8365:
8366: static final int textIconGap = 8;
8367:
8368: private AbstractTab tabs[];
8369:
8370: private void setInsets(Insets insets) {
8371: this .insets = (Insets) insets.clone();
8372: }
8373:
8374: private void init(Rectangle rects[], Insets insets) {
8375: setInsets(insets);
8376: tabs = new AbstractTab[rects.length];
8377: // fill up internal datastructure
8378: for (int i = 0; i < rects.length; i++) {
8379: tabs[i] = new AbstractTab();
8380: tabs[i].id = i;
8381: tabs[i].width = rects[i].width;
8382: }
8383: tabSort();
8384: }
8385:
8386: private void bestfit(AbstractTab tabs[], int freeWidth,
8387: int startTab) {
8388: int tabCount = tabs.length;
8389: int worstWidth;
8390: int currentTabWidth;
8391:
8392: int initialPos;
8393: currentTabWidth = tabs[startTab].width;
8394: initialPos = startTab;
8395:
8396: if (startTab == tabCount - 1) {
8397: // directly fill as worst case
8398: tabs[startTab].width = freeWidth;
8399: return;
8400: }
8401: worstWidth = freeWidth / (tabCount - startTab);
8402:
8403: while (currentTabWidth < worstWidth) {
8404: freeWidth -= currentTabWidth;
8405: if (++startTab < tabCount - 1) {
8406: currentTabWidth = tabs[startTab].width;
8407: } else {
8408: tabs[startTab].width = worstWidth;
8409: return;
8410: }
8411: }
8412:
8413: if (startTab == initialPos) {
8414: // didn't find anything smaller
8415: for (int i = startTab; i < tabCount; i++) {
8416: tabs[i].width = worstWidth;
8417: }
8418: } else if (startTab < tabCount - 1) {
8419: bestfit(tabs, freeWidth, startTab);
8420: }
8421: }
8422:
8423: // bubble sort for now
8424: private void tabSort() {
8425: int tabCount = tabs.length;
8426: AbstractTab tempTab = new AbstractTab();
8427: for (int i = 0; i < tabCount - 1; i++) {
8428: for (int j = i + 1; j < tabCount; j++) {
8429: if (tabs[i].width > tabs[j].width) {
8430: tempTab.copy(tabs[j]);
8431: tabs[j].copy(tabs[i]);
8432: tabs[i].copy(tempTab);
8433: }
8434: }
8435: }
8436: }
8437:
8438: // directly modify the rects
8439: private void outpush(Rectangle rects[]) {
8440: for (int i = 0; i < tabs.length; i++) {
8441: rects[tabs[i].id].width = tabs[i].width;
8442: }
8443: rects[0].x = startOffset;
8444: for (int i = 1; i < rects.length; i++) {
8445: rects[i].x = rects[i - 1].x + rects[i - 1].width;
8446: }
8447: }
8448:
8449: public void reArrange(Rectangle rects[], Insets insets,
8450: int totalAvailableSpace) {
8451: init(rects, insets);
8452: bestfit(tabs, totalAvailableSpace, 0);
8453: outpush(rects);
8454: clearup();
8455: }
8456:
8457: private void clearup() {
8458: for (int i = 0; i < tabs.length; i++) {
8459: tabs[i] = null;
8460: }
8461: tabs = null;
8462: }
8463: }
8464:
8465: public void ensureActiveTabIsVisible(boolean scrollLeft) {
8466: if (_tabPane == null || _tabPane.getWidth() == 0) {
8467: return;
8468: }
8469:
8470: if (scrollableTabLayoutEnabled()) {
8471: ensureCurrentLayout();
8472: if (scrollLeft && _rects.length > 0) {
8473: _tabScroller.viewport.setViewPosition(new Point(0, 0));
8474: _tabScroller.tabPanel.scrollRectToVisible(_rects[0]);
8475: }
8476: int index = _tabPane.getSelectedIndex();
8477: if ((!scrollLeft || index != 0) && index < _rects.length
8478: && index != -1) {
8479: _tabScroller.tabPanel.getParent().doLayout();
8480: _tabScroller.tabPanel
8481: .scrollRectToVisible(_rects[index]);
8482: }
8483: _tabPane.revalidate();
8484: _tabPane.repaint();
8485: }
8486: }
8487:
8488: protected boolean isShowCloseButtonOnTab() {
8489: if (_tabPane.isUseDefaultShowCloseButtonOnTab()) {
8490: if (_showCloseButtonOnTab) {
8491: return true;
8492: } else {
8493: return false;
8494: }
8495: } else if (_tabPane.isShowCloseButtonOnTab()) {
8496: return true;
8497: } else {
8498: return false;
8499: }
8500: }
8501:
8502: protected boolean isShowCloseButton() {
8503: if (_tabPane.isShowCloseButton()) {
8504: return true;
8505: } else {
8506: return false;
8507: }
8508: }
8509:
8510: public void ensureCloseButtonCreated() {
8511: if (isShowCloseButton() && isShowCloseButtonOnTab()
8512: && scrollableTabLayoutEnabled()) {
8513: if (_closeButtons == null) {
8514: _closeButtons = new TabCloseButton[_tabPane
8515: .getTabCount()];
8516: } else if (_closeButtons.length > _tabPane.getTabCount()) {
8517: TabCloseButton[] temp = new TabCloseButton[_tabPane
8518: .getTabCount()];
8519: System
8520: .arraycopy(_closeButtons, 0, temp, 0,
8521: temp.length);
8522: for (int i = temp.length; i < _closeButtons.length; i++) {
8523: TabCloseButton tabCloseButton = _closeButtons[i];
8524: _tabScroller.tabPanel.remove(tabCloseButton);
8525: }
8526: _closeButtons = temp;
8527: } else if (_closeButtons.length < _tabPane.getTabCount()) {
8528: TabCloseButton[] temp = new TabCloseButton[_tabPane
8529: .getTabCount()];
8530: System.arraycopy(_closeButtons, 0, temp, 0,
8531: _closeButtons.length);
8532: _closeButtons = temp;
8533: }
8534: ActionMap am = getActionMap();
8535: for (int i = 0; i < _closeButtons.length; i++) {
8536: TabCloseButton closeButton = _closeButtons[i];
8537: if (closeButton == null) {
8538: closeButton = createNoFocusButton(TabCloseButton.CLOSE_BUTTON);
8539: closeButton.setName("TabClose");
8540: _closeButtons[i] = closeButton;
8541: closeButton.setBounds(0, 0, 0, 0);
8542: closeButton.setAction(am.get("closeTabAction"));
8543: _tabScroller.tabPanel.add(closeButton);
8544: }
8545: closeButton.setIndex(i);
8546: }
8547: }
8548: }
8549:
8550: protected boolean isShowTabButtons() {
8551: if (_tabPane.getTabCount() == 0) {
8552: return false;
8553: } else {
8554: return _tabPane.isShowTabArea()
8555: && _tabPane.isShowTabButtons();
8556: }
8557: }
8558:
8559: protected boolean isShrinkTabs() {
8560: if (_tabPane.getTabCount() == 0) {
8561: return false;
8562: } else {
8563: return _tabPane.getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIT;
8564: }
8565: }
8566:
8567: protected TabEditor _tabEditor;
8568:
8569: protected boolean _isEditing;
8570:
8571: protected int _editingTab = -1;
8572:
8573: protected String _oldValue;
8574:
8575: protected String _oldPrefix;
8576:
8577: protected String _oldPostfix;
8578:
8579: @Override
8580: public boolean isTabEditing() {
8581: return _isEditing;
8582: }
8583:
8584: protected TabEditor createDefaultTabEditor() {
8585: TabEditor editor = new TabEditor();
8586: editor.getDocument().addDocumentListener(this );
8587: editor.addFocusListener(new FocusAdapter() {
8588: @Override
8589: public void focusLost(FocusEvent e) {
8590: if (_tabPane.isTabEditing()) {
8591: _tabPane.stopTabEditing();
8592: }
8593: }
8594: });
8595: editor.addActionListener(new ActionListener() {
8596: public void actionPerformed(ActionEvent e) {
8597: _tabPane.stopTabEditing();
8598: }
8599: });
8600: editor.addKeyListener(new KeyAdapter() {
8601: @Override
8602: public void keyPressed(KeyEvent e) {
8603: if (_isEditing
8604: && (e.getKeyCode() == KeyEvent.VK_ESCAPE)) {
8605: if (_editingTab >= 0
8606: && _editingTab < _tabPane.getTabCount()) {
8607: _tabPane.setTitleAt(_editingTab, _oldValue);
8608: }
8609: _tabPane.cancelTabEditing();
8610: }
8611: }
8612: });
8613: editor.setFont(_tabPane.getFont());
8614:
8615: return editor;
8616: }
8617:
8618: @Override
8619: public void stopTabEditing() {
8620: if (_editingTab >= 0 && _editingTab < _tabPane.getTabCount()) {
8621: _tabPane.setTitleAt(_editingTab, _oldPrefix
8622: + _tabEditor.getText() + _oldPostfix);
8623: }
8624: cancelTabEditing();
8625: }
8626:
8627: @Override
8628: public void cancelTabEditing() {
8629: if (_tabEditor != null) {
8630: _isEditing = false;
8631:
8632: ((Container) getTabPanel()).remove(_tabEditor);
8633:
8634: if (_editingTab >= 0
8635: && _editingTab < _tabPane.getTabCount()) {
8636: Rectangle tabRect = _tabPane.getBoundsAt(_editingTab);
8637: getTabPanel().repaint(tabRect.x, tabRect.y,
8638: tabRect.width, tabRect.height);
8639: } else {
8640: getTabPanel().repaint();
8641: }
8642:
8643: _tabPane.requestFocusInWindow();
8644:
8645: _editingTab = -1;
8646: _oldValue = null;
8647: }
8648: }
8649:
8650: @Override
8651: public boolean editTabAt(int tabIndex) {
8652: if (_isEditing) {
8653: return false;
8654: }
8655:
8656: if (_tabEditor == null)
8657: _tabEditor = createDefaultTabEditor();
8658:
8659: if (_tabEditor != null) {
8660: prepareEditor(_tabEditor, tabIndex);
8661: ((Container) getTabPanel()).add(_tabEditor);
8662: Rectangle tabsTextBoundsAt = getTabsTextBoundsAt(tabIndex);
8663: if (tabsTextBoundsAt.isEmpty()) {
8664: return false;
8665: }
8666: _tabEditor.setBounds(SwingUtilities.convertRectangle(
8667: _tabPane, tabsTextBoundsAt, getTabPanel()));
8668: _tabEditor.invalidate();
8669: _tabEditor.validate();
8670:
8671: _editingTab = tabIndex;
8672: _isEditing = true;
8673:
8674: getTabPanel().repaint();
8675: _tabEditor.requestFocusInWindow();
8676: _tabEditor.selectAll();
8677: return true;
8678: }
8679: return false;
8680: }
8681:
8682: @Override
8683: public int getEditingTabIndex() {
8684: return _editingTab;
8685: }
8686:
8687: protected void prepareEditor(TabEditor e, int tabIndex) {
8688: _oldValue = _tabPane.getTitleAt(tabIndex);
8689: if (_oldValue.startsWith("<HTML>")
8690: && _oldValue.endsWith("/HTML>")) {
8691: _oldPrefix = "<HTML>";
8692: _oldPostfix = "</HTML>";
8693: String title = _oldValue.substring("<HTML>".length(),
8694: _oldValue.length() - "</HTML>".length());
8695: if (title.startsWith("<B>") && title.endsWith("/B>")) {
8696: title = title.substring("<B>".length(), title.length()
8697: - "</B>".length());
8698: _oldPrefix += "<B>";
8699: _oldPostfix = "</B>" + _oldPostfix;
8700: }
8701: e.setText(title);
8702: } else {
8703: _oldPrefix = "";
8704: _oldPostfix = "";
8705: e.setText(_oldValue);
8706: }
8707: e.selectAll();
8708: e.setForeground(_tabPane.getForegroundAt(tabIndex));
8709: }
8710:
8711: protected Rectangle getTabsTextBoundsAt(int tabIndex) {
8712: Rectangle tabRect = _tabPane.getBoundsAt(tabIndex);
8713: Rectangle iconRect = new Rectangle(), textRect = new Rectangle();
8714:
8715: String title = _tabPane.getDisplayTitleAt(tabIndex);
8716: if (title == null || title.length() < 4) {
8717: title = " ";
8718: }
8719: Icon icon = getIconForTab(tabIndex);
8720:
8721: Font font = _tabPane.getFont();
8722: if (tabIndex == _tabPane.getSelectedIndex()
8723: && _tabPane.isBoldActiveTab()) {
8724: font = font.deriveFont(Font.BOLD);
8725: }
8726: SwingUtilities.layoutCompoundLabel(_tabPane, _tabPane
8727: .getGraphics().getFontMetrics(font), title, icon,
8728: SwingUtilities.CENTER, SwingUtilities.CENTER,
8729: SwingUtilities.CENTER, SwingUtilities.TRAILING,
8730: tabRect, iconRect, textRect, icon == null ? 0
8731: : _textIconGap);
8732:
8733: if (_tabPane.getTabPlacement() == TOP
8734: || _tabPane.getTabPlacement() == BOTTOM) {
8735: iconRect.x = tabRect.x + _iconMargin;
8736: textRect.x = (icon != null ? iconRect.x + iconRect.width
8737: + _textIconGap : tabRect.x + _textPadding);
8738: textRect.width += 2;
8739: } else {
8740: iconRect.y = tabRect.y + _iconMargin;
8741: textRect.y = (icon != null ? iconRect.y + iconRect.height
8742: + _textIconGap : tabRect.y + _textPadding);
8743: iconRect.x = tabRect.x + 2;
8744: textRect.x = tabRect.x + 2;
8745: textRect.height += 2;
8746: }
8747:
8748: return textRect;
8749: }
8750:
8751: private void updateTab() {
8752: if (_isEditing) {
8753: getTabPanel().invalidate();
8754: _tabEditor.validate();
8755: _tabEditor.repaint();
8756: getTabPanel().repaint();
8757: }
8758: }
8759:
8760: public void insertUpdate(DocumentEvent e) {
8761: updateTab();
8762: }
8763:
8764: public void removeUpdate(DocumentEvent e) {
8765: updateTab();
8766: }
8767:
8768: public void changedUpdate(DocumentEvent e) {
8769: updateTab();
8770: }
8771:
8772: protected class TabEditor extends JTextField implements UIResource {
8773: TabEditor() {
8774: setBorder(BorderFactory.createEmptyBorder());
8775: }
8776:
8777: public boolean stopEditing() {
8778: return true;
8779: }
8780: }
8781:
8782: public void startEditing(MouseEvent e) {
8783: Point p = SwingUtilities
8784: .convertPoint((Component) e.getSource(), e.getX(), e
8785: .getY(), _tabPane);
8786: int tabIndex = tabForCoordinate(_tabPane, p.x, p.y);
8787:
8788: if (!e.isPopupTrigger() && tabIndex >= 0
8789: && _tabPane.isEnabledAt(tabIndex)
8790: && _tabPane.isTabEditingAllowed()
8791: && (e.getClickCount() == 2)) {
8792: e.consume();
8793: _tabPane.editTabAt(tabIndex);
8794: }
8795: if (e.getClickCount() == 1) {
8796: if (_tabPane.isTabEditing()) {
8797: _tabPane.stopTabEditing();
8798: }
8799: }
8800: }
8801:
8802: public ThemePainter getPainter() {
8803: return _painter;
8804: }
8805:
8806: private class DragOverTimer extends Timer implements ActionListener {
8807: private int _index;
8808:
8809: public DragOverTimer(int index) {
8810: super (500, null);
8811: _index = index;
8812: addActionListener(this );
8813: setRepeats(false);
8814: }
8815:
8816: public void actionPerformed(ActionEvent e) {
8817: if (_tabPane.getTabCount() == 0) {
8818: return;
8819: }
8820: if (_index == _tabPane.getSelectedIndex()) {
8821: if (_tabPane.isRequestFocusEnabled()) {
8822: _tabPane.requestFocusInWindow();
8823: _tabPane.repaint(getTabBounds(_tabPane, _index));
8824: }
8825: } else {
8826: if (_tabPane.isRequestFocusEnabled()) {
8827: _tabPane.requestFocusInWindow();
8828: }
8829: _tabPane.setSelectedIndex(_index);
8830: }
8831: stop();
8832: }
8833: }
8834:
8835: private class DropListener implements DropTargetListener {
8836: private DragOverTimer _timer;
8837:
8838: int _index = -1;
8839:
8840: public DropListener() {
8841: }
8842:
8843: public void dragEnter(DropTargetDragEvent dtde) {
8844: }
8845:
8846: public void dragOver(DropTargetDragEvent dtde) {
8847: if (!_tabPane.isEnabled()) {
8848: return;
8849: }
8850:
8851: int tabIndex = getTabAtLocation(dtde.getLocation().x, dtde
8852: .getLocation().y);
8853: if (tabIndex >= 0 && _tabPane.isEnabledAt(tabIndex)) {
8854: if (tabIndex == _tabPane.getSelectedIndex()) {
8855: // selected already, do nothing
8856: } else if (tabIndex == _index) {
8857: // same tab, timer has started
8858: } else {
8859: stopTimer();
8860: startTimer(tabIndex);
8861: _index = tabIndex; // save the index
8862: }
8863: } else {
8864: stopTimer();
8865: }
8866: }
8867:
8868: private void startTimer(int tabIndex) {
8869: _timer = new DragOverTimer(tabIndex);
8870: _timer.start();
8871: }
8872:
8873: private void stopTimer() {
8874: if (_timer != null) {
8875: _timer.stop();
8876: _timer = null;
8877: _index = -1;
8878: }
8879: }
8880:
8881: public void dropActionChanged(DropTargetDragEvent dtde) {
8882: }
8883:
8884: public void dragExit(DropTargetEvent dte) {
8885: stopTimer();
8886: }
8887:
8888: public void drop(DropTargetDropEvent dtde) {
8889: stopTimer();
8890: }
8891: }
8892:
8893: protected void paintFocusIndicator(Graphics g, int tabPlacement,
8894: Rectangle[] rects, int tabIndex, Rectangle iconRect,
8895: Rectangle textRect, boolean isSelected) {
8896: Rectangle tabRect = rects[tabIndex];
8897: if (_tabPane.hasFocus() && isSelected) {
8898: int x, y, w, h;
8899: g.setColor(_focus);
8900: switch (tabPlacement) {
8901: case LEFT:
8902: x = tabRect.x + 3;
8903: y = tabRect.y + 3;
8904: w = tabRect.width - 5;
8905: h = tabRect.height - 6 - getTabGap();
8906: break;
8907: case RIGHT:
8908: x = tabRect.x + 2;
8909: y = tabRect.y + 3;
8910: w = tabRect.width - 5;
8911: h = tabRect.height - 6 - getTabGap();
8912: break;
8913: case BOTTOM:
8914: x = tabRect.x + 3;
8915: y = tabRect.y + 2;
8916: w = tabRect.width - 6 - getTabGap();
8917: h = tabRect.height - 5;
8918: break;
8919: case TOP:
8920: default:
8921: x = tabRect.x + 3;
8922: y = tabRect.y + 3;
8923: w = tabRect.width - 6 - getTabGap();
8924: h = tabRect.height - 5;
8925: }
8926: BasicGraphicsUtils.drawDashedRect(g, x, y, w, h);
8927: }
8928: }
8929:
8930: protected boolean isRoundedCorner() {
8931: return "true".equals(SecurityUtils.getProperty("shadingtheme",
8932: "false"));
8933: }
8934:
8935: protected int getTabShape() {
8936: return _tabPane.getTabShape();
8937: }
8938:
8939: protected int getTabResizeMode() {
8940: return _tabPane.getTabResizeMode();
8941: }
8942:
8943: protected int getColorTheme() {
8944: return _tabPane.getColorTheme();
8945: }
8946:
8947: // for debug purpose
8948: final protected boolean PAINT_TAB = true;
8949:
8950: final protected boolean PAINT_TAB_BORDER = true;
8951:
8952: final protected boolean PAINT_TAB_BACKGROUND = true;
8953:
8954: final protected boolean PAINT_TABAREA = true;
8955:
8956: final protected boolean PAINT_CONTENT_BORDER = true;
8957:
8958: final protected boolean PAINT_CONTENT_BORDER_EDGE = true;
8959:
8960: protected int getLeftMargin() {
8961: if (getTabShape() == JideTabbedPane.SHAPE_OFFICE2003) {
8962: return OFFICE2003_LEFT_MARGIN;
8963: } else if (getTabShape() == JideTabbedPane.SHAPE_EXCEL) {
8964: return EXCEL_LEFT_MARGIN;
8965: } else {
8966: return DEFAULT_LEFT_MARGIN;
8967: }
8968: }
8969:
8970: protected int getTabGap() {
8971: if (getTabShape() == JideTabbedPane.SHAPE_OFFICE2003) {
8972: return 4;
8973: } else {
8974: return 0;
8975: }
8976: }
8977:
8978: protected int getLayoutSize() {
8979: int tabShape = getTabShape();
8980: if (tabShape == JideTabbedPane.SHAPE_EXCEL) {
8981: return EXCEL_LEFT_MARGIN;
8982: } else if (tabShape == JideTabbedPane.SHAPE_ECLIPSE3X) {
8983: return 15;
8984: } else if (_tabPane.getTabShape() == JideTabbedPane.SHAPE_FLAT
8985: || _tabPane.getTabShape() == JideTabbedPane.SHAPE_ROUNDED_FLAT) {
8986: return 2;
8987: } else if (tabShape == JideTabbedPane.SHAPE_WINDOWS
8988: || tabShape == JideTabbedPane.SHAPE_WINDOWS_SELECTED) {
8989: return 6;
8990: } else {
8991: return 0;
8992: }
8993: }
8994:
8995: protected int getTabRightPadding() {
8996: if (getTabShape() == JideTabbedPane.SHAPE_EXCEL) {
8997: return 4;
8998: } else {
8999: return 0;
9000: }
9001: }
9002:
9003: protected MouseListener createMouseListener() {
9004: if (getTabShape() == JideTabbedPane.SHAPE_WINDOWS
9005: || getTabShape() == JideTabbedPane.SHAPE_WINDOWS_SELECTED) {
9006: return new RolloverMouseHandler();
9007: } else {
9008: return new MouseHandler();
9009: }
9010: }
9011:
9012: protected MouseMotionListener createMouseMotionListener() {
9013: if (getTabShape() == JideTabbedPane.SHAPE_WINDOWS
9014: || getTabShape() == JideTabbedPane.SHAPE_WINDOWS_SELECTED) {
9015: return new RolloverMouseMotionHandler();
9016: } else {
9017: return new MouseMotionHandler();
9018: }
9019: }
9020:
9021: public class DefaultMouseMotionHandler extends MouseMotionAdapter {
9022: @Override
9023: public void mouseMoved(MouseEvent e) {
9024: super .mouseMoved(e);
9025: int tabIndex = getTabAtLocation(e.getX(), e.getY());
9026: if (tabIndex != _indexMouseOver) {
9027: _indexMouseOver = tabIndex;
9028: _tabPane.repaint();
9029: }
9030:
9031: }
9032:
9033: }
9034:
9035: public class DefaultMouseHandler extends
9036: BasicJideTabbedPaneUI.MouseHandler {
9037: @Override
9038: public void mousePressed(MouseEvent e) {
9039: super .mousePressed(e);
9040: }
9041:
9042: @Override
9043: public void mouseEntered(MouseEvent e) {
9044: super .mouseEntered(e);
9045: int tabIndex = getTabAtLocation(e.getX(), e.getY());
9046: _mouseEnter = true;
9047: _indexMouseOver = tabIndex;
9048: _tabPane.repaint();
9049: }
9050:
9051: @Override
9052: public void mouseExited(MouseEvent e) {
9053: super .mouseExited(e);
9054: _indexMouseOver = -1;
9055: _mouseEnter = false;
9056: _tabPane.repaint();
9057: }
9058: }
9059:
9060: public class RolloverMouseMotionHandler extends MouseMotionAdapter {
9061: @Override
9062: public void mouseMoved(MouseEvent e) {
9063: super .mouseMoved(e);
9064: int tabIndex = getTabAtLocation(e.getX(), e.getY());
9065: if (tabIndex != _indexMouseOver) {
9066: _indexMouseOver = tabIndex;
9067: _tabPane.repaint();
9068: }
9069:
9070: }
9071:
9072: }
9073:
9074: public class RolloverMouseHandler extends
9075: BasicJideTabbedPaneUI.MouseHandler {
9076: @Override
9077: public void mouseEntered(MouseEvent e) {
9078: super .mouseEntered(e);
9079: int tabIndex = getTabAtLocation(e.getX(), e.getY());
9080: _mouseEnter = true;
9081: _indexMouseOver = tabIndex;
9082: _tabPane.repaint();
9083: }
9084:
9085: @Override
9086: public void mouseExited(MouseEvent e) {
9087: super .mouseExited(e);
9088: _indexMouseOver = -1;
9089: _mouseEnter = false;
9090: _tabPane.repaint();
9091: }
9092: }
9093:
9094: protected boolean isTabLeadingComponentVisible() {
9095: return _tabPane.isTabShown() && _tabLeadingComponent != null
9096: && _tabLeadingComponent.isVisible();
9097: }
9098:
9099: protected boolean isTabTrailingComponentVisible() {
9100: return _tabPane.isTabShown() && _tabTrailingComponent != null
9101: && _tabTrailingComponent.isVisible();
9102: }
9103:
9104: protected boolean isTabTopVisible(int tabPlacement) {
9105: switch (tabPlacement) {
9106: case LEFT:
9107: case RIGHT:
9108: return (isTabLeadingComponentVisible() && _tabLeadingComponent
9109: .getPreferredSize().width > calculateMaxTabWidth(tabPlacement))
9110: || (isTabTrailingComponentVisible() && _tabTrailingComponent
9111: .getPreferredSize().width > calculateMaxTabWidth(tabPlacement));
9112: case TOP:
9113: case BOTTOM:
9114: default:
9115: return (isTabLeadingComponentVisible() && _tabLeadingComponent
9116: .getPreferredSize().height > calculateMaxTabHeight(tabPlacement))
9117: || (isTabTrailingComponentVisible() && _tabTrailingComponent
9118: .getPreferredSize().height > calculateMaxTabHeight(tabPlacement));
9119: }
9120: }
9121:
9122: protected boolean showFocusIndicator() {
9123: return _tabPane.hasFocusComponent() && _showFocusIndicator;
9124: }
9125: }
|