Source Code Cross Referenced for BasicTabbedPaneUI.java in  » Apache-Harmony-Java-SE » javax-package » javax » swing » plaf » basic » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Apache Harmony Java SE » javax package » javax.swing.plaf.basic 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *     http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         */
0017:
0018:        /**
0019:         * @author Vadim L. Bogdanov
0020:         * @version $Revision$
0021:         */package javax.swing.plaf.basic;
0022:
0023:        import java.awt.Color;
0024:        import java.awt.Component;
0025:        import java.awt.Container;
0026:        import java.awt.Dimension;
0027:        import java.awt.Font;
0028:        import java.awt.FontMetrics;
0029:        import java.awt.Graphics;
0030:        import java.awt.Insets;
0031:        import java.awt.KeyboardFocusManager;
0032:        import java.awt.LayoutManager;
0033:        import java.awt.Point;
0034:        import java.awt.Rectangle;
0035:        import java.awt.Shape;
0036:
0037:        import java.awt.event.ActionEvent;
0038:        import java.awt.event.ActionListener;
0039:        import java.awt.event.FocusAdapter;
0040:        import java.awt.event.FocusEvent;
0041:        import java.awt.event.FocusListener;
0042:        import java.awt.event.MouseAdapter;
0043:        import java.awt.event.MouseEvent;
0044:        import java.awt.event.MouseListener;
0045:        import java.awt.event.MouseMotionAdapter;
0046:
0047:        import java.beans.PropertyChangeEvent;
0048:        import java.beans.PropertyChangeListener;
0049:
0050:        import javax.swing.AbstractAction;
0051:        import javax.swing.ActionMap;
0052:        import javax.swing.Icon;
0053:        import javax.swing.InputMap;
0054:        import javax.swing.JButton;
0055:        import javax.swing.JComponent;
0056:        import javax.swing.JTabbedPane;
0057:        import javax.swing.KeyStroke;
0058:        import javax.swing.LookAndFeel;
0059:        import javax.swing.SwingConstants;
0060:        import javax.swing.SwingUtilities;
0061:        import javax.swing.UIManager;
0062:
0063:        import javax.swing.event.ChangeEvent;
0064:        import javax.swing.event.ChangeListener;
0065:
0066:        import javax.swing.plaf.ActionMapUIResource;
0067:        import javax.swing.plaf.ComponentUI;
0068:        import javax.swing.plaf.TabbedPaneUI;
0069:        import javax.swing.plaf.UIResource;
0070:
0071:        import javax.swing.text.View;
0072:
0073:        import org.apache.harmony.x.swing.ButtonCommons;
0074:        import org.apache.harmony.x.swing.StringConstants;
0075:        import org.apache.harmony.x.swing.Utilities;
0076:
0077:        public class BasicTabbedPaneUI extends TabbedPaneUI implements 
0078:                SwingConstants {
0079:
0080:            public class FocusHandler extends FocusAdapter {
0081:                public void focusGained(final FocusEvent e) {
0082:                    tabPane.repaint();
0083:                }
0084:
0085:                public void focusLost(final FocusEvent e) {
0086:                    tabPane.repaint();
0087:                }
0088:            }
0089:
0090:            public class MouseHandler extends MouseAdapter {
0091:                public void mousePressed(final MouseEvent e) {
0092:                    int index = calculateTabIndexByMouseEvent(e);
0093:
0094:                    if (index != -1 && tabPane.isEnabledAt(index)) {
0095:                        // tab is clicked
0096:                        if (!isSelectedTab(index)) {
0097:                            boolean visibleComponentFocused = getFocusIndex() == -1;
0098:                            tabPane.setSelectedIndex(index);
0099:                            if (visibleComponentFocused
0100:                                    && getVisibleComponent() != null) {
0101:                                getVisibleComponent().requestFocus();
0102:                            }
0103:                        } else {
0104:                            tabPane.requestFocus();
0105:                        }
0106:                    }
0107:                }
0108:            }
0109:
0110:            private class MouseMotionHandler extends MouseMotionAdapter {
0111:                public void mouseMoved(final MouseEvent e) {
0112:                    setRolloverTab(calculateTabIndexByMouseEvent(e));
0113:                }
0114:            }
0115:
0116:            public class PropertyChangeHandler implements 
0117:                    PropertyChangeListener {
0118:                public void propertyChange(final PropertyChangeEvent e) {
0119:                    if ("tabPlacement".equals(e.getPropertyName())) {
0120:                        if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) {
0121:                            installScrollableTabsComponents();
0122:                        }
0123:                        tabPane.revalidate();
0124:                        tabPane.repaint();
0125:                    } else if ("tabLayoutPolicy".equals(e.getPropertyName())) {
0126:                        if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) {
0127:                            installScrollableTabsComponents();
0128:                        } else {
0129:                            uninstallScrollableTabsComponents();
0130:                        }
0131:                        tabPane.setLayout(createLayoutManager());
0132:                        tabPane.revalidate();
0133:                        tabPane.repaint();
0134:                    }
0135:                }
0136:            }
0137:
0138:            public class TabbedPaneLayout implements  LayoutManager {
0139:                public void addLayoutComponent(final String name,
0140:                        final Component comp) {
0141:                    if (!(comp instanceof  UIResource)) {
0142:                        calculateLayoutInfo();
0143:                    }
0144:                }
0145:
0146:                public void calculateLayoutInfo() {
0147:                    if (tabPane == null) {
0148:                        return;
0149:                    }
0150:                    int tabCount = tabPane.getTabCount();
0151:                    final Component selectedComponent = tabPane
0152:                            .getSelectedComponent();
0153:                    if (selectedComponent != null) {
0154:                        setVisibleComponent(selectedComponent);
0155:                    }
0156:
0157:                    assureRectsCreated(tabCount);
0158:                    calculateTabRects(tabPane.getTabPlacement(), tabCount);
0159:                }
0160:
0161:                /**
0162:                 * Implements both minimum and preferred size calculations.
0163:                 */
0164:                protected Dimension calculateSize(final boolean minimum) {
0165:                    int tabPlacement = tabPane.getTabPlacement();
0166:                    Dimension size = calculateTabAreaSize(tabPlacement);
0167:
0168:                    Dimension contentAreaSize = calculateContentAreaSize(minimum);
0169:                    Utilities.addInsets(contentAreaSize,
0170:                            getContentBorderInsets(tabPlacement));
0171:
0172:                    if (isVerticalRun(tabPlacement)) {
0173:                        size.width += contentAreaSize.width;
0174:                        size.height = Math.max(size.height,
0175:                                contentAreaSize.height);
0176:                    } else {
0177:                        size.height += contentAreaSize.height;
0178:                        size.width = Math
0179:                                .max(size.width, contentAreaSize.width);
0180:                    }
0181:
0182:                    Utilities.addInsets(size, tabPane.getInsets());
0183:                    return size;
0184:                }
0185:
0186:                private Dimension calculateTabAreaSize(final int tabPlacement) {
0187:                    Dimension size = new Dimension();
0188:                    Insets insets = getTabAreaInsets(tabPlacement);
0189:
0190:                    if (isVerticalRun(tabPlacement)) {
0191:                        size.height = calculateMaxTabHeight(tabPlacement);
0192:                        size.height += insets.top + insets.bottom;
0193:                        size.width = preferredTabAreaWidth(tabPlacement,
0194:                                size.height);
0195:                    } else {
0196:                        size.width = calculateMaxTabWidth(tabPlacement);
0197:                        size.width += insets.left + insets.right;
0198:                        size.height = preferredTabAreaHeight(tabPlacement,
0199:                                size.width);
0200:                    }
0201:
0202:                    return size;
0203:                }
0204:
0205:                private Dimension calculateContentAreaSize(final boolean minimum) {
0206:                    Dimension contentAreaSize = new Dimension();
0207:
0208:                    for (int i = 0; i < tabPane.getComponentCount(); i++) {
0209:                        Dimension size;
0210:                        if (minimum) {
0211:                            size = tabPane.getComponentAt(i).getMinimumSize();
0212:                        } else {
0213:                            size = tabPane.getComponentAt(i).getPreferredSize();
0214:                        }
0215:                        if (size.width > contentAreaSize.width) {
0216:                            contentAreaSize.width = size.width;
0217:                        }
0218:                        if (size.height > contentAreaSize.height) {
0219:                            contentAreaSize.height = size.height;
0220:                        }
0221:                    }
0222:
0223:                    return contentAreaSize;
0224:                }
0225:
0226:                private void getNewTabRunOffsets(final int tabPlacement,
0227:                        final int runCount, final Point initialOffset,
0228:                        final Point newTabRunOffset) {
0229:                    newTabRunOffset.setLocation(initialOffset);
0230:                    int tabRunIndent = getTabRunIndent(tabPlacement, runCount);
0231:                    if (isVerticalRun(tabPlacement)) {
0232:                        newTabRunOffset.y += tabRunIndent;
0233:                    } else {
0234:                        newTabRunOffset.x += tabRunIndent;
0235:                    }
0236:                }
0237:
0238:                void calculateAvailableRectangleToPlaceTabs(
0239:                        final int tabPlacement, final Rectangle tabsRect,
0240:                        final Rectangle tabAreaInnerBounds) {
0241:                    SwingUtilities.calculateInnerArea(tabPane, tabsRect);
0242:                    Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
0243:                    calculateInnerArea(tabsRect, tabAreaInsets);
0244:                    tabAreaInnerBounds.setBounds(tabsRect);
0245:                }
0246:
0247:                protected void calculateTabRects(final int tabPlacement,
0248:                        final int tabCount) {
0249:                    if (tabCount == 0) {
0250:                        return;
0251:                    }
0252:
0253:                    runCount = 1;
0254:                    tabRuns[0] = 0;
0255:
0256:                    FontMetrics fm = getFontMetrics();
0257:                    maxTabHeight = calculateMaxTabHeight(tabPlacement);
0258:                    maxTabWidth = calculateMaxTabWidth(tabPlacement);
0259:
0260:                    calculateAvailableRectangleToPlaceTabs(tabPlacement,
0261:                            calcRect, tabAreaInnerBounds);
0262:
0263:                    // split tabs into runs
0264:                    Point initialOffset = calcRect.getLocation();
0265:                    Point currentOffset = new Point();
0266:                    getNewTabRunOffsets(tabPlacement, runCount, initialOffset,
0267:                            currentOffset);
0268:                    boolean isVerticalRun = isVerticalRun(tabPlacement);
0269:                    boolean justStartedNewRun = true; // not very good to use this flag
0270:                    for (int i = 0; i < tabCount; i++) {
0271:                        int tabWidth = calculateTabWidth(tabPlacement, i, fm);
0272:                        int tabHeight = calculateTabHeight(tabPlacement, i, fm
0273:                                .getHeight());
0274:                        if (isVerticalRun) {
0275:                            rects[i].setSize(maxTabWidth, tabHeight);
0276:                        } else {
0277:                            rects[i].setSize(tabWidth, maxTabHeight);
0278:                        }
0279:                        rects[i].setLocation(currentOffset);
0280:                        if (!calcRect.contains(rects[i]) && !justStartedNewRun) {
0281:                            // start a new tab run
0282:                            getNewTabRunOffsets(tabPlacement, runCount,
0283:                                    initialOffset, currentOffset);
0284:                            if (runCount >= tabRuns.length) {
0285:                                expandTabRunsArray();
0286:                            }
0287:                            tabRuns[runCount] = i;
0288:                            runCount++;
0289:                        }
0290:                        rects[i].setLocation(currentOffset);
0291:                        if (isVerticalRun) {
0292:                            currentOffset.y += tabHeight;
0293:                        } else {
0294:                            currentOffset.x += tabWidth;
0295:                        }
0296:                        justStartedNewRun = false;
0297:                    }
0298:                    int start = isVerticalRun ? tabAreaInnerBounds.y
0299:                            : tabAreaInnerBounds.x;
0300:                    int length = isVerticalRun ? tabAreaInnerBounds.height
0301:                            : tabAreaInnerBounds.width;
0302:                    normalizeTabRuns(tabPlacement, tabCount, start, start
0303:                            + length);
0304:
0305:                    selectedRun = getRunForTab(tabCount, tabPane
0306:                            .getSelectedIndex());
0307:                    if (shouldRotateTabRuns(tabPlacement)) {
0308:                        rotateTabRuns(tabPlacement, selectedRun);
0309:                    }
0310:
0311:                    // calculate remaining coordinate (x or y depending on tabPlacement)
0312:                    for (int i = 0; i < tabCount; i++) {
0313:                        int sign = 1;
0314:                        if (tabPlacement == JTabbedPane.BOTTOM) {
0315:                            sign = -1;
0316:                            rects[i].y += tabAreaInnerBounds.height
0317:                                    - maxTabHeight;
0318:                        } else if (tabPlacement == JTabbedPane.RIGHT) {
0319:                            sign = -1;
0320:                            rects[i].x += tabAreaInnerBounds.width
0321:                                    - maxTabWidth;
0322:                        }
0323:                        if (isVerticalRun) {
0324:                            rects[i].x += sign
0325:                                    * (runCount - getRunForTab(tabCount, i) - 1)
0326:                                    * (maxTabWidth - getTabRunOverlay(tabPlacement));
0327:                        } else {
0328:                            rects[i].y += sign
0329:                                    * (runCount - getRunForTab(tabCount, i) - 1)
0330:                                    * (maxTabHeight - getTabRunOverlay(tabPlacement));
0331:                        }
0332:                    }
0333:
0334:                    // pad tab runs
0335:                    int lastTabInRun = -1;
0336:                    int curRun = getRunForTab(tabCount, 0);
0337:                    for (int i = 0; i < runCount; i++) {
0338:                        int firstTabInRun = getNextElementInRing(lastTabInRun,
0339:                                tabCount);
0340:                        lastTabInRun = lastTabInRun(tabCount, curRun);
0341:                        if (shouldPadTabRun(tabPlacement, curRun)) {
0342:                            int max = isVerticalRun ? calcRect.height
0343:                                    : calcRect.width;
0344:                            padTabRun(tabPlacement, firstTabInRun,
0345:                                    lastTabInRun, max);
0346:                        }
0347:                        curRun = getNextTabRun(curRun);
0348:                    }
0349:
0350:                    padSelectedTab(tabPlacement, tabPane.getSelectedIndex());
0351:                }
0352:
0353:                public void layoutContainer(final Container parent) {
0354:                    calculateLayoutInfo();
0355:
0356:                    int tabPlacement = tabPane.getTabPlacement();
0357:
0358:                    int tabAreaSize;
0359:                    if (isVerticalRun(tabPlacement)) {
0360:                        tabAreaSize = calculateTabAreaWidth(tabPlacement,
0361:                                runCount, maxTabWidth);
0362:                    } else {
0363:                        tabAreaSize = calculateTabAreaHeight(tabPlacement,
0364:                                runCount, maxTabHeight);
0365:                    }
0366:
0367:                    Rectangle rect = SwingUtilities.calculateInnerArea(tabPane,
0368:                            null);
0369:                    if (tabPlacement == JTabbedPane.TOP) {
0370:                        rect.y += tabAreaSize;
0371:                        rect.height -= tabAreaSize;
0372:                    } else if (tabPlacement == JTabbedPane.BOTTOM) {
0373:                        rect.height -= tabAreaSize;
0374:                    } else if (tabPlacement == JTabbedPane.LEFT) {
0375:                        rect.x += tabAreaSize;
0376:                        rect.width -= tabAreaSize;
0377:                    } else if (tabPlacement == JTabbedPane.RIGHT) {
0378:                        rect.width -= tabAreaSize;
0379:                    }
0380:                    contentAreaBounds.setBounds(rect);
0381:
0382:                    calculateInnerArea(rect,
0383:                            getContentBorderInsets(tabPlacement));
0384:
0385:                    if (getVisibleComponent() != null) {
0386:                        getVisibleComponent().setBounds(rect);
0387:                    }
0388:
0389:                    calculateTabAreaClipRect(tabPlacement);
0390:                }
0391:
0392:                public Dimension minimumLayoutSize(final Container parent) {
0393:                    return calculateSize(true);
0394:                }
0395:
0396:                /**
0397:                 * This function prevents from appearing of runs with
0398:                 * small number of tabs. If it is necessary, tabs are
0399:                 * moved from the next to last tab run to the last tab run.
0400:                 */
0401:                protected void normalizeTabRuns(final int tabPlacement,
0402:                        final int tabCount, final int start, final int max) {
0403:                    if (runCount < 2) {
0404:                        return;
0405:                    }
0406:
0407:                    final float NORMALIZE_THRESHOLD = 5f / 8f;
0408:
0409:                    // find out the last tab in the next to last tab run
0410:                    boolean isVerticalRun = isVerticalRun(tabPlacement);
0411:                    int lastTabPos = isVerticalRun ? (int) rects[tabCount - 1]
0412:                            .getMaxY() : (int) rects[tabCount - 1].getMaxX();
0413:                    int desiredPos = start
0414:                            + (int) ((max - start) * NORMALIZE_THRESHOLD);
0415:                    int lastTab = lastTabInRun(tabCount, runCount - 2);
0416:                    int firstTab = firstTabInRun(tabCount, runCount - 2);
0417:                    while (lastTab - firstTab >= 2 && lastTabPos < desiredPos) {
0418:                        lastTabPos += isVerticalRun ? rects[lastTab].height
0419:                                : rects[lastTab].width;
0420:                        lastTab--;
0421:                    }
0422:
0423:                    lastTab = getNextTabIndex(lastTab);
0424:
0425:                    if (tabRuns[runCount - 1] == lastTab) {
0426:                        return; // no tabs were moved
0427:                    }
0428:
0429:                    tabRuns[runCount - 1] = lastTab;
0430:
0431:                    // correct bounds of tabs in the last tab run
0432:                    lastTabPos = start;
0433:                    for (; lastTab < tabCount; lastTab++) {
0434:                        if (isVerticalRun) {
0435:                            rects[lastTab].y = lastTabPos;
0436:                            lastTabPos += rects[lastTab].height;
0437:                        } else {
0438:                            rects[lastTab].x = lastTabPos;
0439:                            lastTabPos += rects[lastTab].width;
0440:                        }
0441:                    }
0442:                }
0443:
0444:                /**
0445:                 * Increases size of the selected tab using selected tab pad insets.
0446:                 */
0447:                protected void padSelectedTab(final int tabPlacement,
0448:                        final int selectedIndex) {
0449:                    if (selectedIndex == -1) {
0450:                        return;
0451:                    }
0452:
0453:                    Insets insets = getSelectedTabPadInsets(tabPlacement);
0454:                    Rectangle rect = rects[selectedIndex];
0455:
0456:                    rect.translate(-insets.left, -insets.top);
0457:                    rect.width += insets.left + insets.right;
0458:                    rect.height += insets.top + insets.bottom;
0459:                }
0460:
0461:                /**
0462:                 * Increases size of tabs in the given tab run to make width or height
0463:                 * of the tab run (depending on <code>tabPlacement</code>) equal
0464:                 * to <code>max</code>.
0465:                 *
0466:                 * @param tabPlacement the tab placement
0467:                 * @param start index of the first tab in the tab run
0468:                 * @param end index of the last tab in the tab run
0469:                 * @param max the desired width or height of the tab run
0470:                 */
0471:                protected void padTabRun(final int tabPlacement,
0472:                        final int start, final int end, final int max) {
0473:                    int size = 0;
0474:                    for (int i = start; i <= end; i++) {
0475:                        size += isVerticalRun(tabPlacement) ? rects[i].height
0476:                                : rects[i].width;
0477:                    }
0478:                    int increment = (max - size) / (end - start + 1);
0479:                    int additionalIncrementToLast = (max - size)
0480:                            % (end - start + 1);
0481:
0482:                    for (int i = 0; i <= end - start; i++) {
0483:                        if (isVerticalRun(tabPlacement)) {
0484:                            rects[start + i].height += increment;
0485:                            rects[start + i].y += i * increment;
0486:                        } else {
0487:                            rects[start + i].width += increment;
0488:                            rects[start + i].x += i * increment;
0489:                        }
0490:                    }
0491:                    if (isVerticalRun(tabPlacement)) {
0492:                        rects[end].height += additionalIncrementToLast;
0493:                    } else {
0494:                        rects[end].width += additionalIncrementToLast;
0495:                    }
0496:                }
0497:
0498:                public Dimension preferredLayoutSize(final Container parent) {
0499:                    return calculateSize(false);
0500:                }
0501:
0502:                protected int preferredTabAreaHeight(final int tabPlacement,
0503:                        final int width) {
0504:                    int horizRunCount = isVerticalRun(tabPlacement) ? 0
0505:                            : getTabRunCount(tabPane);
0506:                    int height = calculateTabAreaHeight(tabPlacement,
0507:                            horizRunCount, calculateMaxTabHeight(tabPlacement));
0508:                    return height;
0509:                }
0510:
0511:                protected int preferredTabAreaWidth(final int tabPlacement,
0512:                        final int height) {
0513:                    int vertRunCount = isVerticalRun(tabPlacement) ? getTabRunCount(tabPane)
0514:                            : 0;
0515:                    int width = calculateTabAreaWidth(tabPlacement,
0516:                            vertRunCount, calculateMaxTabWidth(tabPlacement));
0517:                    return width;
0518:                }
0519:
0520:                public void removeLayoutComponent(final Component comp) {
0521:                    if (!(comp instanceof  UIResource)) {
0522:                        calculateLayoutInfo();
0523:                    }
0524:                }
0525:
0526:                protected void rotateTabRuns(final int tabPlacement,
0527:                        final int selectedRun) {
0528:                    // rotate tabRuns to move selectedRun to the last position
0529:                    int[] temp = new int[selectedRun];
0530:                    System.arraycopy(tabRuns, 0, temp, 0, selectedRun);
0531:                    System.arraycopy(tabRuns, selectedRun, tabRuns, 0, runCount
0532:                            - selectedRun);
0533:                    System.arraycopy(temp, 0, tabRuns, runCount - selectedRun,
0534:                            selectedRun);
0535:                }
0536:
0537:                void calculateTabAreaClipRect(final int tabPlacement) {
0538:                    SwingUtilities.calculateInnerArea(tabPane, tabAreaClipRect);
0539:                    if (tabPlacement == TOP) {
0540:                        tabAreaClipRect.height = contentAreaBounds.y
0541:                                - tabAreaClipRect.y;
0542:                    } else if (tabPlacement == LEFT) {
0543:                        tabAreaClipRect.width = contentAreaBounds.x
0544:                                - tabAreaClipRect.x;
0545:                    } else if (tabPlacement == BOTTOM) {
0546:                        tabAreaClipRect.y = (int) contentAreaBounds.getMaxY();
0547:                        tabAreaClipRect.height -= tabAreaClipRect.y;
0548:                    } else if (tabPlacement == RIGHT) {
0549:                        tabAreaClipRect.x = (int) contentAreaBounds.getMaxX();
0550:                        tabAreaClipRect.width -= tabAreaClipRect.x;
0551:                    }
0552:                }
0553:            }
0554:
0555:            private class ScrollableTabLayout extends TabbedPaneLayout {
0556:                void calculateAvailableRectangleToPlaceTabs(
0557:                        final int tabPlacement, final Rectangle tabsRect,
0558:                        final Rectangle tabAreaInnerBounds) {
0559:                    super .calculateAvailableRectangleToPlaceTabs(tabPlacement,
0560:                            tabsRect, tabAreaInnerBounds);
0561:                    tabsRect.setSize(Short.MAX_VALUE, Short.MAX_VALUE);
0562:
0563:                    if (isVerticalRun(tabPlacement)) {
0564:                        tabAreaInnerBounds.height -= leftScrollButton
0565:                                .getHeight()
0566:                                + rightScrollButton.getHeight();
0567:                    } else {
0568:                        tabAreaInnerBounds.width -= leftScrollButton.getWidth()
0569:                                + rightScrollButton.getWidth();
0570:                    }
0571:                }
0572:
0573:                public void layoutContainer(final Container parent) {
0574:                    super .layoutContainer(parent);
0575:                    updateScrollButtons();
0576:                    layoutScrollButtons();
0577:                }
0578:
0579:                protected void padSelectedTab(final int tabPlacement,
0580:                        final int selectedIndex) {
0581:                    // overridden to do nothing
0582:                }
0583:
0584:                protected void calculateTabRects(final int tabPlacement,
0585:                        final int tabCount) {
0586:                    super .calculateTabRects(tabPlacement, tabCount);
0587:                }
0588:
0589:                private void layoutScrollButtons() {
0590:                    if (!leftScrollButton.isVisible()) {
0591:                        return;
0592:                    }
0593:
0594:                    rightScrollButton.getBounds(calcRect);
0595:
0596:                    int tabPlacement = tabPane.getTabPlacement();
0597:                    Rectangle c = contentAreaBounds;
0598:                    Rectangle b = rightScrollButton.getBounds();
0599:
0600:                    if (tabPlacement == TOP) {
0601:                        b.setLocation(c.x + c.width - b.width, c.y - b.height);
0602:                        rightScrollButton.setBounds(b);
0603:                        b.translate(-b.width, 0);
0604:                        leftScrollButton.setBounds(b);
0605:                    } else if (tabPlacement == BOTTOM) {
0606:                        b.setLocation(c.x + c.width - b.width, c.y + c.height);
0607:                        rightScrollButton.setBounds(b);
0608:                        b.translate(-b.width, 0);
0609:                        leftScrollButton.setBounds(b);
0610:                    } else if (tabPlacement == LEFT) {
0611:                        b.setLocation(c.x - b.width, c.y + c.height - b.height);
0612:                        rightScrollButton.setBounds(b);
0613:                        b.translate(0, -b.height);
0614:                        leftScrollButton.setBounds(b);
0615:                    } else if (tabPlacement == RIGHT) {
0616:                        b.setLocation(c.x + c.width, c.y + c.height - b.height);
0617:                        rightScrollButton.setBounds(b);
0618:                        b.translate(0, -b.height);
0619:                        leftScrollButton.setBounds(b);
0620:                    }
0621:                }
0622:
0623:                void calculateTabAreaClipRect(final int tabPlacement) {
0624:                    super .calculateTabAreaClipRect(tabPlacement);
0625:                    if (isVerticalRun(tabPlacement)) {
0626:                        tabAreaClipRect.y = tabAreaInnerBounds.y;
0627:                        tabAreaClipRect.height = tabAreaInnerBounds.height;
0628:                    } else {
0629:                        tabAreaClipRect.x = tabAreaInnerBounds.x;
0630:                        tabAreaClipRect.width = tabAreaInnerBounds.width;
0631:                    }
0632:                }
0633:            }
0634:
0635:            private class ScrollButton extends BasicArrowButton implements 
0636:                    UIResource, ActionListener {
0637:
0638:                public ScrollButton(final int direction) {
0639:                    super (direction);
0640:
0641:                    setSize(16, 16);
0642:                    setFocusable(false);
0643:                    addActionListener(this );
0644:                }
0645:
0646:                public void actionPerformed(final ActionEvent e) {
0647:                    if (direction == EAST || direction == SOUTH) {
0648:                        scrollToShowTab(true);
0649:                    } else if (direction == WEST || direction == NORTH) {
0650:                        scrollToShowTab(false);
0651:                    }
0652:                    tabPane.repaint();
0653:                }
0654:            }
0655:
0656:            public class TabSelectionHandler implements  ChangeListener {
0657:                public void stateChanged(final ChangeEvent e) {
0658:                    // we have to relayout immediatelly; in other case we can get
0659:                    // in listeners/actions inconsistent state (ex.: NavigateAction)
0660:                    tabPane.doLayout();
0661:
0662:                    scrollToShowTab(tabPane.getSelectedIndex());
0663:                    tabPane.revalidate();
0664:                    tabPane.repaint();
0665:                }
0666:            }
0667:
0668:            private class NavigateAction extends AbstractAction {
0669:                private int direction;
0670:
0671:                public NavigateAction(final int direction) {
0672:                    this .direction = direction;
0673:                }
0674:
0675:                public void actionPerformed(final ActionEvent e) {
0676:                    boolean visibleComponentFocused = getFocusIndex() == -1;
0677:                    navigateSelectedTab(direction);
0678:                    if (visibleComponentFocused
0679:                            && getVisibleComponent() != null) {
0680:                        getVisibleComponent().requestFocus();
0681:                    }
0682:                }
0683:            }
0684:
0685:            private static class MnemonicAction extends AbstractAction {
0686:                public void actionPerformed(final ActionEvent e) {
0687:                    JTabbedPane tabPane = (JTabbedPane) e.getSource();
0688:
0689:                    int keyCode = Utilities.keyCharToKeyCode(e
0690:                            .getActionCommand().charAt(0));
0691:                    for (int i = 0; i < tabPane.getTabCount(); i++) {
0692:                        if (keyCode == tabPane.getMnemonicAt(i)) {
0693:                            tabPane.setSelectedIndex(i);
0694:                            break;
0695:                        }
0696:                    }
0697:                }
0698:            }
0699:
0700:            public static ComponentUI createUI(final JComponent c) {
0701:                return new BasicTabbedPaneUI();
0702:            }
0703:
0704:            protected static void rotateInsets(final Insets topInsets,
0705:                    final Insets targetInsets, final int targetPlacement) {
0706:                if (targetPlacement == JTabbedPane.TOP) {
0707:                    targetInsets.set(topInsets.top, topInsets.left,
0708:                            topInsets.bottom, topInsets.right);
0709:                } else if (targetPlacement == JTabbedPane.LEFT) {
0710:                    targetInsets.set(topInsets.left, topInsets.top,
0711:                            topInsets.right, topInsets.bottom);
0712:                } else if (targetPlacement == JTabbedPane.BOTTOM) {
0713:                    targetInsets.set(topInsets.bottom, topInsets.left,
0714:                            topInsets.top, topInsets.right);
0715:                } else if (targetPlacement == JTabbedPane.RIGHT) {
0716:                    targetInsets.set(topInsets.left, topInsets.bottom,
0717:                            topInsets.right, topInsets.top);
0718:                } else {
0719:                    assert false : "incorrect targetPlacement";
0720:                }
0721:            }
0722:
0723:            private static int TAB_RUNS_ARRAY_SIZE_INCREMENT = 5;
0724:            private static AbstractAction MNEMONIC_ACTION = new MnemonicAction();
0725:
0726:            protected transient Rectangle calcRect = new Rectangle();
0727:
0728:            protected Color highlight;
0729:            protected Color lightHighlight;
0730:            protected Color shadow;
0731:            protected Color darkShadow;
0732:            protected Color focus;
0733:
0734:            protected int maxTabHeight;
0735:            protected int maxTabWidth;
0736:
0737:            protected FocusListener focusListener;
0738:            protected MouseListener mouseListener;
0739:            protected ChangeListener tabChangeListener;
0740:            protected PropertyChangeListener propertyChangeListener;
0741:
0742:            protected JTabbedPane tabPane;
0743:
0744:            protected Rectangle[] rects = { new Rectangle() };
0745:            protected int runCount;
0746:            protected int selectedRun;
0747:
0748:            protected Insets contentBorderInsets;
0749:            protected Insets selectedTabPadInsets;
0750:            protected Insets tabAreaInsets;
0751:            protected Insets tabInsets;
0752:            protected int tabRunOverlay;
0753:
0754:            private JButton leftScrollButton;
0755:            private JButton rightScrollButton;
0756:            private Component visibleComponent;
0757:
0758:            private ActionMap actionMap;
0759:
0760:            private MouseMotionAdapter mouseMotionListener;
0761:
0762:            /**
0763:             * Tab area's inner area bounds (excluding tab area insets).
0764:             * It is calculated by a layout manager.
0765:             */
0766:            private Rectangle tabAreaInnerBounds = new Rectangle();
0767:
0768:            /**
0769:             * Tab area's clip region. It is used to prevent from painting on
0770:             * content area and on scroll buttons when <code>SCROLL_TAB_LAYOUT</code>
0771:             * is used.
0772:             */
0773:            private Rectangle tabAreaClipRect = new Rectangle();
0774:            private int scrollableTabsOffset = 0;
0775:
0776:            /**
0777:             * Content area bounds including content area insets but excluding
0778:             * tabbed pane insets. It is calculated by a layout manager.
0779:             */
0780:            private Rectangle contentAreaBounds = new Rectangle();
0781:
0782:            private Color selectedTabBackground;
0783:
0784:            private int rolloverTab = -1;
0785:
0786:            protected int[] tabRuns = new int[5];
0787:            protected int textIconGap;
0788:
0789:            /**
0790:             * @deprecated
0791:             */
0792:            protected KeyStroke leftKey;
0793:            /**
0794:             * @deprecated
0795:             */
0796:            protected KeyStroke rightKey;
0797:            /**
0798:             * @deprecated
0799:             */
0800:            protected KeyStroke upKey;
0801:            /**
0802:             * @deprecated
0803:             */
0804:            protected KeyStroke downKey;
0805:
0806:            protected void assureRectsCreated(final int tabCount) {
0807:                Rectangle[] oldRects = rects;
0808:                if (rects.length < tabCount) {
0809:                    rects = new Rectangle[tabCount];
0810:                }
0811:
0812:                System.arraycopy(oldRects, 0, rects, 0, oldRects.length);
0813:                for (int i = oldRects.length; i < rects.length; i++) {
0814:                    rects[i] = new Rectangle();
0815:                }
0816:            }
0817:
0818:            protected int calculateMaxTabHeight(final int tabPlacement) {
0819:                int height = 0;
0820:                int fontHeight = getFontMetrics().getHeight();
0821:                for (int i = 0; i < tabPane.getTabCount(); i++) {
0822:                    height = Math.max(calculateTabHeight(tabPlacement, i,
0823:                            fontHeight), height);
0824:                }
0825:                return height;
0826:            }
0827:
0828:            protected int calculateMaxTabWidth(final int tabPlacement) {
0829:                int width = 0;
0830:                FontMetrics fm = getFontMetrics();
0831:                for (int i = 0; i < tabPane.getTabCount(); i++) {
0832:                    width = Math.max(calculateTabWidth(tabPlacement, i, fm),
0833:                            width);
0834:                }
0835:                return width;
0836:            }
0837:
0838:            protected int calculateTabAreaHeight(final int tabPlacement,
0839:                    final int horizRunCount, final int maxTabHeight) {
0840:                int height = maxTabHeight * horizRunCount
0841:                        - getTabRunOverlay(tabPlacement) * (horizRunCount - 1);
0842:                Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
0843:                return height + tabAreaInsets.top + tabAreaInsets.bottom;
0844:            }
0845:
0846:            protected int calculateTabAreaWidth(final int tabPlacement,
0847:                    final int vertRunCount, final int maxTabWidth) {
0848:                int width = maxTabWidth * vertRunCount
0849:                        - getTabRunOverlay(tabPlacement) * (vertRunCount - 1);
0850:                Insets tabAreaInsets = getTabAreaInsets(tabPlacement);
0851:                return width + tabAreaInsets.left + tabAreaInsets.right;
0852:            }
0853:
0854:            protected int calculateTabHeight(final int tabPlacement,
0855:                    final int tabIndex, final int fontHeight) {
0856:                int height = fontHeight;
0857:
0858:                Icon icon = getIconForTab(tabIndex);
0859:                if (icon != null) {
0860:                    height = Math.max(height, icon.getIconHeight());
0861:                }
0862:
0863:                height += Math.abs(getTabLabelShiftY(tabPlacement, tabIndex,
0864:                        true)
0865:                        - getTabLabelShiftY(tabPlacement, tabIndex, false));
0866:
0867:                // add space to paint a focus indicator and a tab's border
0868:                height += 4;
0869:
0870:                Insets insets = getTabInsets(tabPlacement, tabIndex);
0871:                return height + insets.top + insets.bottom;
0872:            }
0873:
0874:            protected int calculateTabWidth(final int tabPlacement,
0875:                    final int tabIndex, final FontMetrics fm) {
0876:                int width = fm.stringWidth(tabPane.getTitleAt(tabIndex));
0877:
0878:                Icon icon = getIconForTab(tabIndex);
0879:                if (icon != null) {
0880:                    width += textIconGap + icon.getIconWidth();
0881:                }
0882:
0883:                width += Math.abs(getTabLabelShiftX(tabPlacement, tabIndex,
0884:                        true)
0885:                        - getTabLabelShiftX(tabPlacement, tabIndex, false));
0886:
0887:                // add space to paint a focus indicator and a tab's border
0888:                width += 3;
0889:
0890:                Insets insets = getTabInsets(tabPlacement, tabIndex);
0891:                return width + insets.left + insets.right;
0892:            }
0893:
0894:            protected ChangeListener createChangeListener() {
0895:                return new TabSelectionHandler();
0896:            }
0897:
0898:            protected FocusListener createFocusListener() {
0899:                return new FocusHandler();
0900:            }
0901:
0902:            protected LayoutManager createLayoutManager() {
0903:                if (tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT) {
0904:                    return new TabbedPaneLayout();
0905:                } else {
0906:                    return new ScrollableTabLayout();
0907:                }
0908:            }
0909:
0910:            protected MouseListener createMouseListener() {
0911:                return new MouseHandler();
0912:            }
0913:
0914:            protected PropertyChangeListener createPropertyChangeListener() {
0915:                return new PropertyChangeHandler();
0916:            }
0917:
0918:            protected JButton createScrollButton(final int direction) {
0919:                if (direction != NORTH && direction != SOUTH
0920:                        && direction != EAST && direction != WEST) {
0921:                    throw new IllegalArgumentException();
0922:                }
0923:
0924:                return new ScrollButton(direction);
0925:            }
0926:
0927:            protected void expandTabRunsArray() {
0928:                int[] oldTabRuns = tabRuns;
0929:                tabRuns = new int[oldTabRuns.length
0930:                        + TAB_RUNS_ARRAY_SIZE_INCREMENT];
0931:                System.arraycopy(oldTabRuns, 0, tabRuns, 0, oldTabRuns.length);
0932:            }
0933:
0934:            protected Insets getContentBorderInsets(final int tabPlacement) {
0935:                return contentBorderInsets;
0936:            }
0937:
0938:            protected int getFocusIndex() {
0939:                Component focusOwner = KeyboardFocusManager
0940:                        .getCurrentKeyboardFocusManager().getFocusOwner();
0941:                if (focusOwner != tabPane) {
0942:                    return -1;
0943:                }
0944:
0945:                return tabPane.getSelectedIndex();
0946:            }
0947:
0948:            protected FontMetrics getFontMetrics() {
0949:                return Utilities.getFontMetrics(tabPane);
0950:            }
0951:
0952:            protected Icon getIconForTab(final int index) {
0953:                return tabPane.isEnabledAt(index) ? tabPane.getIconAt(index)
0954:                        : tabPane.getDisabledIconAt(index);
0955:            }
0956:
0957:            public Dimension getMaximumSize(final JComponent c) {
0958:                return null;
0959:            }
0960:
0961:            public Dimension getMinimumSize(final JComponent c) {
0962:                return null;
0963:            }
0964:
0965:            protected int getNextTabIndex(final int base) {
0966:                return getNextElementInRing(base, tabPane.getTabCount());
0967:            }
0968:
0969:            protected int getPreviousTabIndex(final int base) {
0970:                return getPreviousElementInRing(base, tabPane.getTabCount());
0971:            }
0972:
0973:            protected int getNextTabIndexInRun(final int tabCount,
0974:                    final int base) {
0975:                int run = getRunForTab(tabCount, base);
0976:                int firstTabInRun = firstTabInRun(tabCount, run);
0977:                int lastTabInRun = lastTabInRun(tabCount, run);
0978:                return firstTabInRun
0979:                        + getNextElementInRing(base - firstTabInRun,
0980:                                lastTabInRun - firstTabInRun + 1);
0981:            }
0982:
0983:            protected int getPreviousTabIndexInRun(final int tabCount,
0984:                    final int base) {
0985:                int run = getRunForTab(tabCount, base);
0986:                int firstTabInRun = firstTabInRun(tabCount, run);
0987:                int lastTabInRun = lastTabInRun(tabCount, run);
0988:                return firstTabInRun
0989:                        + getPreviousElementInRing(base - firstTabInRun,
0990:                                lastTabInRun - firstTabInRun + 1);
0991:            }
0992:
0993:            protected int getNextTabRun(final int baseRun) {
0994:                // using getTabRunCount() instead of runCount leads to stack overflow
0995:                return getNextElementInRing(baseRun, runCount);
0996:            }
0997:
0998:            protected int getPreviousTabRun(final int baseRun) {
0999:                return getPreviousElementInRing(baseRun, runCount);
1000:            }
1001:
1002:            protected int getRunForTab(final int tabCount, final int tabIndex) {
1003:                for (int run = 0; run < runCount; run++) {
1004:                    int firstTabInRun = tabRuns[run];
1005:                    if (firstTabInRun <= tabIndex
1006:                            && tabIndex <= lastTabInRun(tabCount, run)) {
1007:                        return run;
1008:                    }
1009:                }
1010:                assert false : "incorrect tabIndex";
1011:                return 0;
1012:            }
1013:
1014:            protected Insets getSelectedTabPadInsets(final int tabPlacement) {
1015:                Insets rotatedInsets = new Insets(0, 0, 0, 0);
1016:                rotateInsets(selectedTabPadInsets, rotatedInsets, tabPlacement);
1017:                return rotatedInsets;
1018:            }
1019:
1020:            protected Insets getTabAreaInsets(final int tabPlacement) {
1021:                Insets rotatedInsets = new Insets(0, 0, 0, 0);
1022:                rotateInsets(tabAreaInsets, rotatedInsets, tabPlacement);
1023:                return rotatedInsets;
1024:            }
1025:
1026:            protected Rectangle getTabBounds(final int tabIndex,
1027:                    final Rectangle dest) {
1028:                dest.setBounds(rects[tabIndex]);
1029:                if (isVerticalRun(tabPane.getTabPlacement())) {
1030:                    dest.translate(0, scrollableTabsOffset);
1031:                } else {
1032:                    dest.translate(scrollableTabsOffset, 0);
1033:                }
1034:                return dest;
1035:            }
1036:
1037:            public Rectangle getTabBounds(final JTabbedPane pane,
1038:                    final int index) {
1039:                Rectangle result = new Rectangle();
1040:                return getTabBounds(index, result);
1041:            }
1042:
1043:            protected Insets getTabInsets(final int tabPlacement,
1044:                    final int tabIndex) {
1045:                return tabInsets;
1046:            }
1047:
1048:            protected int getTabLabelShiftX(final int tabPlacement,
1049:                    final int tabIndex, final boolean isSelected) {
1050:                int offset = -1;
1051:                if (isSelected) {
1052:                    if (tabPlacement == RIGHT) {
1053:                        offset = 1;
1054:                    }
1055:                } else {
1056:                    if (tabPlacement == LEFT) {
1057:                        offset = 1;
1058:                    }
1059:                }
1060:
1061:                return offset;
1062:            }
1063:
1064:            protected int getTabLabelShiftY(final int tabPlacement,
1065:                    final int tabIndex, final boolean isSelected) {
1066:                int offset = 1;
1067:                if (isSelected) {
1068:                    if (tabPlacement == TOP) {
1069:                        offset = -1;
1070:                    }
1071:                } else {
1072:                    if (tabPlacement == BOTTOM) {
1073:                        offset = -1;
1074:                    }
1075:                }
1076:
1077:                return offset;
1078:            }
1079:
1080:            public int getTabRunCount(final JTabbedPane pane) {
1081:                tabPane.doLayout();
1082:                return runCount;
1083:            }
1084:
1085:            protected int getTabRunIndent(final int tabPlacement, final int run) {
1086:                return 0;
1087:            }
1088:
1089:            protected int getTabRunOffset(final int tabPlacement,
1090:                    final int tabCount, final int tabIndex,
1091:                    final boolean forward) {
1092:                int curRun = getRunForTab(tabCount, tabIndex);
1093:                int newRun = !forward ? getNextTabRun(curRun)
1094:                        : getPreviousTabRun(curRun);
1095:
1096:                int lastTab = lastTabInRun(tabCount, newRun);
1097:                int rc;
1098:                if (isVerticalRun(tabPlacement)) {
1099:                    rc = (int) rects[lastTab].getCenterX()
1100:                            - (int) rects[tabIndex].getCenterX();
1101:                } else {
1102:                    rc = (int) rects[lastTab].getCenterY()
1103:                            - (int) rects[tabIndex].getCenterY();
1104:                }
1105:                return rc;
1106:            }
1107:
1108:            protected int getTabRunOverlay(final int tabPlacement) {
1109:                return tabRunOverlay;
1110:            }
1111:
1112:            protected View getTextViewForTab(final int tabIndex) {
1113:                //TODO: implement when HTML styled text is supported
1114:                return null;
1115:            }
1116:
1117:            protected void installComponents() {
1118:                if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) {
1119:                    installScrollableTabsComponents();
1120:                }
1121:            }
1122:
1123:            protected void uninstallComponents() {
1124:                if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) {
1125:                    uninstallScrollableTabsComponents();
1126:                }
1127:            }
1128:
1129:            protected void installDefaults() {
1130:                LookAndFeel.installColorsAndFont(tabPane,
1131:                        "TabbedPane.background", "TabbedPane.foreground",
1132:                        "TabbedPane.font");
1133:
1134:                darkShadow = UIManager.getColor("TabbedPane.darkShadow");
1135:                shadow = UIManager.getColor("TabbedPane.shadow");
1136:                highlight = UIManager.getColor("TabbedPane.light");
1137:                lightHighlight = UIManager.getColor("TabbedPane.highlight");
1138:                focus = UIManager.getColor("TabbedPane.focus");
1139:
1140:                contentBorderInsets = UIManager
1141:                        .getInsets("TabbedPane.contentBorderInsets");
1142:                selectedTabPadInsets = UIManager
1143:                        .getInsets("TabbedPane.selectedTabPadInsets");
1144:                tabAreaInsets = UIManager.getInsets("TabbedPane.tabAreaInsets");
1145:                tabInsets = UIManager.getInsets("TabbedPane.tabInsets");
1146:
1147:                tabRunOverlay = UIManager.getInt("TabbedPane.tabRunOverlay");
1148:                textIconGap = UIManager.getInt("TabbedPane.textIconGap");
1149:
1150:                selectedTabBackground = UIManager.getColor("control");
1151:            }
1152:
1153:            protected void uninstallDefaults() {
1154:            }
1155:
1156:            private ActionMap getUIActionMap() {
1157:                if (actionMap != null) {
1158:                    return actionMap;
1159:                }
1160:
1161:                actionMap = new ActionMapUIResource();
1162:                final AbstractAction navigateEastAction = new NavigateAction(
1163:                        EAST);
1164:                actionMap.put("navigateRight", navigateEastAction);
1165:                final AbstractAction navigateWestAction = new NavigateAction(
1166:                        WEST);
1167:                actionMap.put("navigateLeft", navigateWestAction);
1168:                actionMap.put("navigateUp", new NavigateAction(NORTH));
1169:                actionMap.put("navigateDown", new NavigateAction(SOUTH));
1170:
1171:                // "ctrl DOWN", "ctrl KP_DOWN"
1172:                actionMap.put("requestFocusForVisibleComponent",
1173:                        new AbstractAction() {
1174:                            public void actionPerformed(final ActionEvent e) {
1175:                                if (getVisibleComponent() != null) {
1176:                                    getVisibleComponent().requestFocus();
1177:                                }
1178:                            }
1179:                        });
1180:
1181:                // "ctrl PAGE_DOWN", "navigatePageDown"
1182:                actionMap.put("navigatePageDown", navigateWestAction);
1183:                // "ctrl PAGE_UP", "navigatePageUp"
1184:                actionMap.put("navigatePageUp", navigateEastAction);
1185:
1186:                // "ctrl KP_UP", "ctrl UP"
1187:                actionMap.put("requestFocus", new AbstractAction() {
1188:                    public void actionPerformed(final ActionEvent e) {
1189:                        tabPane.requestFocus();
1190:                    }
1191:                });
1192:
1193:                actionMap.put(StringConstants.MNEMONIC_ACTION, MNEMONIC_ACTION);
1194:
1195:                return actionMap;
1196:            }
1197:
1198:            protected void installKeyboardActions() {
1199:                SwingUtilities.replaceUIInputMap(tabPane,
1200:                        JComponent.WHEN_FOCUSED, (InputMap) UIManager
1201:                                .get("TabbedPane.focusInputMap"));
1202:
1203:                SwingUtilities
1204:                        .replaceUIInputMap(tabPane,
1205:                                JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
1206:                                (InputMap) UIManager
1207:                                        .get("TabbedPane.ancestorInputMap"));
1208:
1209:                SwingUtilities.replaceUIActionMap(tabPane, getUIActionMap());
1210:            }
1211:
1212:            protected void uninstallKeyboardActions() {
1213:                SwingUtilities.replaceUIInputMap(tabPane,
1214:                        JComponent.WHEN_FOCUSED, null);
1215:                SwingUtilities.replaceUIInputMap(tabPane,
1216:                        JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, null);
1217:                SwingUtilities.replaceUIActionMap(tabPane, null);
1218:            }
1219:
1220:            protected void installListeners() {
1221:                if (focusListener == null) {
1222:                    focusListener = createFocusListener();
1223:                }
1224:                tabPane.addFocusListener(focusListener);
1225:
1226:                if (mouseListener == null) {
1227:                    mouseListener = createMouseListener();
1228:                }
1229:                tabPane.addMouseListener(mouseListener);
1230:
1231:                if (mouseMotionListener == null) {
1232:                    mouseMotionListener = new MouseMotionHandler();
1233:                }
1234:                tabPane.addMouseMotionListener(mouseMotionListener);
1235:
1236:                if (tabChangeListener == null) {
1237:                    tabChangeListener = createChangeListener();
1238:                }
1239:                tabPane.addChangeListener(tabChangeListener);
1240:
1241:                if (propertyChangeListener == null) {
1242:                    propertyChangeListener = createPropertyChangeListener();
1243:                }
1244:                tabPane.addPropertyChangeListener(propertyChangeListener);
1245:            }
1246:
1247:            protected void uninstallListeners() {
1248:                tabPane.removeFocusListener(focusListener);
1249:                tabPane.removeMouseListener(mouseListener);
1250:                tabPane.removeMouseMotionListener(mouseMotionListener);
1251:                tabPane.removeChangeListener(tabChangeListener);
1252:                tabPane.removePropertyChangeListener(propertyChangeListener);
1253:            }
1254:
1255:            public void installUI(final JComponent c) {
1256:                tabPane = (JTabbedPane) c;
1257:                setRolloverTab(-1);
1258:
1259:                installDefaults();
1260:                tabPane.setLayout(createLayoutManager());
1261:                installComponents();
1262:                installListeners();
1263:                installKeyboardActions();
1264:            }
1265:
1266:            public void uninstallUI(final JComponent c) {
1267:                uninstallDefaults();
1268:                tabPane.setLayout(null);
1269:                uninstallComponents();
1270:                uninstallListeners();
1271:                uninstallKeyboardActions();
1272:            }
1273:
1274:            protected int lastTabInRun(final int tabCount, final int run) {
1275:                int nextRun = getNextTabRun(run);
1276:                int firstIndex = firstTabInRun(tabCount, nextRun);
1277:                return getPreviousTabIndex(firstIndex);
1278:            }
1279:
1280:            private int firstTabInRun(final int tabCount, final int run) {
1281:                return tabRuns[run];
1282:            }
1283:
1284:            protected void layoutLabel(final int tabPlacement,
1285:                    final FontMetrics metrics, final int tabIndex,
1286:                    final String title, final Icon icon,
1287:                    final Rectangle tabRect, final Rectangle iconRect,
1288:                    final Rectangle textRect, final boolean isSelected) {
1289:                iconRect.setBounds(0, 0, 0, 0);
1290:                textRect.setBounds(0, 0, 0, 0);
1291:
1292:                // calculate inner tab area
1293:                calcRect.setBounds(tabRect);
1294:                calculateInnerArea(calcRect, getTabInsets(tabPlacement,
1295:                        tabIndex));
1296:                calcRect.translate(getTabLabelShiftX(tabPlacement, tabIndex,
1297:                        isSelected), getTabLabelShiftY(tabPlacement, tabIndex,
1298:                        isSelected));
1299:                boolean isLTR = tabPane.getComponentOrientation()
1300:                        .isLeftToRight();
1301:                SwingUtilities.layoutCompoundLabel(getFontMetrics(), title,
1302:                        icon, CENTER, CENTER, CENTER, isLTR ? RIGHT : LEFT,
1303:                        calcRect, iconRect, textRect, textIconGap);
1304:            }
1305:
1306:            protected void navigateSelectedTab(final int direction) {
1307:                int tabPlacement = tabPane.getTabPlacement();
1308:                int correctedDirection = rotateDirection(tabPlacement,
1309:                        direction);
1310:                int selectedIndex = tabPane.getSelectedIndex();
1311:
1312:                if (correctedDirection == EAST) {
1313:                    selectNextTabInRun(selectedIndex);
1314:                } else if (correctedDirection == WEST) {
1315:                    selectPreviousTabInRun(selectedIndex);
1316:                } else {
1317:                    int tabRunOffset = getTabRunOffset(tabPlacement, tabPane
1318:                            .getTabCount(), selectedIndex,
1319:                            correctedDirection == SOUTH);
1320:                    selectAdjacentRunTab(tabPlacement, selectedIndex,
1321:                            tabRunOffset);
1322:                }
1323:            }
1324:
1325:            public void paint(final Graphics g, final JComponent c) {
1326:                if (g == null) {
1327:                    throw new NullPointerException();
1328:                }
1329:
1330:                if (tabPane.getTabCount() == 0) {
1331:                    return;
1332:                }
1333:
1334:                int tabPlacement = tabPane.getTabPlacement();
1335:                int selectedIndex = tabPane.getSelectedIndex();
1336:
1337:                paintTabArea(g, tabPlacement, selectedIndex);
1338:                paintContentBorder(g, tabPlacement, selectedIndex);
1339:            }
1340:
1341:            protected void paintContentBorder(final Graphics g,
1342:                    final int tabPlacement, final int selectedIndex) {
1343:                paintContentBorderTopEdge(g, tabPlacement, selectedIndex,
1344:                        contentAreaBounds.x, contentAreaBounds.y,
1345:                        contentAreaBounds.width, contentAreaBounds.height);
1346:                paintContentBorderLeftEdge(g, tabPlacement, selectedIndex,
1347:                        contentAreaBounds.x, contentAreaBounds.y,
1348:                        contentAreaBounds.width, contentAreaBounds.height);
1349:                paintContentBorderBottomEdge(g, tabPlacement, selectedIndex,
1350:                        contentAreaBounds.x, contentAreaBounds.y,
1351:                        contentAreaBounds.width, contentAreaBounds.height);
1352:                paintContentBorderRightEdge(g, tabPlacement, selectedIndex,
1353:                        contentAreaBounds.x, contentAreaBounds.y,
1354:                        contentAreaBounds.width, contentAreaBounds.height);
1355:            }
1356:
1357:            /**
1358:             * x, y, w, h are bounds of the content area including content area
1359:             * insets.
1360:             */
1361:            protected void paintContentBorderBottomEdge(final Graphics g,
1362:                    final int tabPlacement, final int selectedIndex,
1363:                    final int x, final int y, final int w, final int h) {
1364:                int xx = x;
1365:                if (tabPlacement == BOTTOM) {
1366:                    getTabBounds(selectedIndex, calcRect);
1367:                    if (calcRect.x == x) {
1368:                        xx++;
1369:                        calcRect.x++;
1370:                        calcRect.width--;
1371:                    }
1372:                }
1373:                g.setColor(darkShadow);
1374:                g.fillRect(xx, y + h - 1, w, 1);
1375:
1376:                g.setColor(highlight);
1377:                g.fillRect(x + 2, y + h - 3, w - 4, 2);
1378:
1379:                if (tabPlacement == BOTTOM
1380:                        && isTabAdjacentToContentAreaBorder(selectedIndex)) {
1381:                    g.setColor(selectedTabBackground);
1382:                    g.fillRect(calcRect.x, y + h - 2, calcRect.width, 1);
1383:                    g.fillRect(calcRect.x, y + h - 1, calcRect.width - 1, 1);
1384:                }
1385:            }
1386:
1387:            /**
1388:             * x, y, w, h are bounds of the content area including content area
1389:             * insets.
1390:             */
1391:            protected void paintContentBorderLeftEdge(final Graphics g,
1392:                    final int tabPlacement, final int selectedIndex,
1393:                    final int x, final int y, final int w, final int h) {
1394:                g.setColor(lightHighlight);
1395:                g.fillRect(x, y, 1, h - 1);
1396:
1397:                g.setColor(highlight);
1398:                g.fillRect(x + 1, y + 1, 1, h - 3);
1399:
1400:                if (tabPlacement == LEFT) {
1401:                    getTabBounds(selectedIndex, calcRect);
1402:                    if (calcRect.y == y) {
1403:                        calcRect.y++;
1404:                        calcRect.height--;
1405:                    }
1406:                    if (isTabAdjacentToContentAreaBorder(selectedIndex)) {
1407:                        g.setColor(selectedTabBackground);
1408:                        g.fillRect(x, calcRect.y, 1, calcRect.height);
1409:                    }
1410:                }
1411:            }
1412:
1413:            /**
1414:             * x, y, w, h are bounds of the content area including content area
1415:             * insets.
1416:             */
1417:            protected void paintContentBorderRightEdge(final Graphics g,
1418:                    final int tabPlacement, final int selectedIndex,
1419:                    final int x, final int y, final int w, final int h) {
1420:                int yy = y;
1421:                if (tabPlacement == RIGHT) {
1422:                    getTabBounds(selectedIndex, calcRect);
1423:                    if (calcRect.y == y) {
1424:                        yy++;
1425:                        calcRect.y++;
1426:                        calcRect.height--;
1427:                    }
1428:                }
1429:                g.setColor(darkShadow);
1430:                g.fillRect(x + w - 1, yy, 1, h);
1431:
1432:                g.setColor(highlight);
1433:                g.fillRect(x + w - 3, y + 2, 2, h - 4);
1434:
1435:                if (tabPlacement == RIGHT
1436:                        && isTabAdjacentToContentAreaBorder(selectedIndex)) {
1437:                    g.setColor(selectedTabBackground);
1438:                    g.fillRect(x + w - 1, calcRect.y, 1, calcRect.height - 1);
1439:                    g.fillRect(x + w - 2, calcRect.y, 1, calcRect.height);
1440:                }
1441:            }
1442:
1443:            /**
1444:             * x, y, w, h are bounds of the content area including content area
1445:             * insets.
1446:             */
1447:            protected void paintContentBorderTopEdge(final Graphics g,
1448:                    final int tabPlacement, final int selectedIndex,
1449:                    final int x, final int y, final int w, final int h) {
1450:                g.setColor(lightHighlight);
1451:                g.fillRect(x, y, w - 1, 1);
1452:
1453:                g.setColor(highlight);
1454:                g.fillRect(x + 1, y + 1, w - 3, 1);
1455:
1456:                if (tabPlacement == TOP
1457:                        && isTabAdjacentToContentAreaBorder(selectedIndex)) {
1458:                    getTabBounds(selectedIndex, calcRect);
1459:                    g.setColor(selectedTabBackground);
1460:                    g.fillRect(calcRect.x, y, calcRect.width, 1);
1461:                }
1462:            }
1463:
1464:            protected void paintFocusIndicator(final Graphics g,
1465:                    final int tabPlacement, final Rectangle[] rects,
1466:                    final int tabIndex, final Rectangle iconRect,
1467:                    final Rectangle textRect, final boolean isSelected) {
1468:                if (!isFocusPainted(tabIndex)) {
1469:                    return;
1470:                }
1471:
1472:                calcRect.setBounds(rects[tabIndex]);
1473:                calcRect.grow(-4, -4);
1474:                ButtonCommons.paintFocus(g, calcRect, focus);
1475:            }
1476:
1477:            private boolean isFocusPainted(final int tabIndex) {
1478:                if (tabIndex != getFocusIndex()) {
1479:                    return false;
1480:                }
1481:
1482:                return tabPane.getIconAt(tabIndex) != null
1483:                        || !Utilities.isEmptyString(tabPane
1484:                                .getTitleAt(tabIndex));
1485:            }
1486:
1487:            protected void paintIcon(final Graphics g, final int tabPlacement,
1488:                    final int tabIndex, final Icon icon,
1489:                    final Rectangle iconRect, final boolean isSelected) {
1490:                if (icon != null) {
1491:                    icon.paintIcon(tabPane, g, iconRect.x, iconRect.y);
1492:                }
1493:            }
1494:
1495:            protected void paintTab(final Graphics g, final int tabPlacement,
1496:                    final Rectangle[] rects, final int tabIndex,
1497:                    final Rectangle iconRect, final Rectangle textRect) {
1498:                Rectangle r = rects[tabIndex];
1499:                boolean isSelected = isSelectedTab(tabIndex);
1500:                String title = tabPane.getTitleAt(tabIndex);
1501:
1502:                paintTabBackground(g, tabPlacement, tabIndex, r.x, r.y,
1503:                        r.width, r.height, isSelected);
1504:
1505:                Icon icon = getIconForTab(tabIndex);
1506:                layoutLabel(tabPlacement, getFontMetrics(), tabIndex, title,
1507:                        icon, r, iconRect, textRect, isSelected);
1508:
1509:                paintIcon(g, tabPlacement, tabIndex, icon, iconRect, isSelected);
1510:                paintText(g, tabPlacement, tabPane.getFont(), getFontMetrics(),
1511:                        tabIndex, title, textRect, isSelected);
1512:                paintFocusIndicator(g, tabPlacement, rects, tabIndex, iconRect,
1513:                        textRect, isSelected);
1514:                paintTabBorder(g, tabPlacement, tabIndex, r.x, r.y, r.width,
1515:                        r.height, isSelected);
1516:            }
1517:
1518:            protected void paintTabArea(final Graphics g,
1519:                    final int tabPlacement, final int selectedIndex) {
1520:                Shape oldClip = g.getClip();
1521:                g.clipRect(tabAreaClipRect.x, tabAreaClipRect.y,
1522:                        tabAreaClipRect.width, tabAreaClipRect.height);
1523:
1524:                Point translate = new Point();
1525:                if (tabPane.getTabLayoutPolicy() == JTabbedPane.SCROLL_TAB_LAYOUT) {
1526:                    if (isVerticalRun(tabPlacement)) {
1527:                        translate.setLocation(0, scrollableTabsOffset);
1528:                    } else {
1529:                        translate.setLocation(scrollableTabsOffset, 0);
1530:                    }
1531:                    g.translate(translate.x, translate.y);
1532:                }
1533:
1534:                Rectangle iconRect = new Rectangle();
1535:                Rectangle textRect = new Rectangle();
1536:                int tabCount = tabPane.getTabCount();
1537:
1538:                for (int run = runCount - 1; run >= 0; run--) {
1539:                    for (int i = firstTabInRun(tabCount, run); i <= lastTabInRun(
1540:                            tabCount, run); i++) {
1541:
1542:                        paintTab(g, tabPlacement, rects, i, iconRect, textRect);
1543:                    }
1544:                    if (run == selectedRun) {
1545:                        paintTab(g, tabPlacement, rects, tabPane
1546:                                .getSelectedIndex(), iconRect, textRect);
1547:                    }
1548:                }
1549:
1550:                g.setClip(oldClip);
1551:                g.translate(-translate.x, -translate.y);
1552:            }
1553:
1554:            protected void paintTabBackground(final Graphics g,
1555:                    final int tabPlacement, final int tabIndex, final int x,
1556:                    final int y, final int w, final int h,
1557:                    final boolean isSelected) {
1558:                Color background = isSelected ? selectedTabBackground : tabPane
1559:                        .getBackgroundAt(tabIndex);
1560:                int xx = x;
1561:                int yy = y;
1562:                int ww = w;
1563:                int hh = h;
1564:                if (tabPlacement == JTabbedPane.TOP) {
1565:                    hh += 2;
1566:                } else if (tabPlacement == JTabbedPane.BOTTOM) {
1567:                    hh += 2;
1568:                    yy -= 2;
1569:                } else if (tabPlacement == JTabbedPane.LEFT) {
1570:                    ww += 2;
1571:                } else if (tabPlacement == JTabbedPane.RIGHT) {
1572:                    ww += 2;
1573:                    xx -= 2;
1574:                }
1575:
1576:                g.setColor(background);
1577:                g.fillRect(xx + 1, yy + 1, ww - 2, hh - 2);
1578:            }
1579:
1580:            protected void paintTabBorder(final Graphics g,
1581:                    final int tabPlacement, final int tabIndex, final int x,
1582:                    final int y, final int w, final int h,
1583:                    final boolean isSelected) {
1584:                int xx = x;
1585:                int yy = y;
1586:                int ww = w;
1587:                int hh = h;
1588:                if (tabPlacement == JTabbedPane.TOP) {
1589:                    hh += 2;
1590:                } else if (tabPlacement == JTabbedPane.BOTTOM) {
1591:                    hh += 2;
1592:                    yy -= 2;
1593:                } else if (tabPlacement == JTabbedPane.LEFT) {
1594:                    ww += 2;
1595:                } else if (tabPlacement == JTabbedPane.RIGHT) {
1596:                    ww += 2;
1597:                    xx -= 2;
1598:                }
1599:
1600:                int[] highlightX = { xx, xx, xx + ww - 2 };
1601:                int[] highlightY = { yy + hh - 2, yy, yy };
1602:                g.setColor(lightHighlight);
1603:                g.drawPolyline(highlightX, highlightY, highlightX.length);
1604:
1605:                int[] shadowX = { xx + ww - 1, xx + ww - 1, xx + 1 };
1606:                int[] shadowY = { yy + 1, yy + hh - 1, yy + hh - 1 };
1607:                g.setColor(darkShadow);
1608:                g.drawPolyline(shadowX, shadowY, shadowX.length);
1609:
1610:                g.setColor(shadow);
1611:                g.drawRect(xx + ww - 2, yy + 1, 0, hh - 3);
1612:                g.drawRect(xx + 1, yy + hh - 2, ww - 3, 0);
1613:            }
1614:
1615:            protected void paintText(final Graphics g, final int tabPlacement,
1616:                    final Font font, final FontMetrics metrics,
1617:                    final int tabIndex, final String title,
1618:                    final Rectangle textRect, final boolean isSelected) {
1619:                Color color = tabPane.isEnabledAt(tabIndex) ? tabPane
1620:                        .getForegroundAt(tabIndex) : tabPane.getBackgroundAt(
1621:                        tabIndex).darker();
1622:                ButtonCommons.paintText(g, metrics, title, tabPane
1623:                        .getDisplayedMnemonicIndexAt(tabIndex), textRect,
1624:                        title, color);
1625:            }
1626:
1627:            protected void selectAdjacentRunTab(final int tabPlacement,
1628:                    final int tabIndex, final int offset) {
1629:                getTabBounds(tabIndex, calcRect);
1630:                int x = (int) calcRect.getCenterX();
1631:                int y = (int) calcRect.getCenterY();
1632:                if (isVerticalRun(tabPlacement)) {
1633:                    x += offset;
1634:                } else {
1635:                    y += offset;
1636:                }
1637:                int newTabIndex = tabForCoordinate(tabPane, x, y);
1638:                if (newTabIndex != -1) {
1639:                    if (tabPane.isEnabledAt(newTabIndex)) {
1640:                        tabPane.setSelectedIndex(newTabIndex);
1641:                    } else {
1642:                        selectNextTab(newTabIndex);
1643:                    }
1644:                }
1645:            }
1646:
1647:            protected void selectNextTab(final int current) {
1648:                int i = current;
1649:                do {
1650:                    i = getNextTabIndex(i);
1651:                } while (i != current && !tabPane.isEnabledAt(i));
1652:
1653:                tabPane.setSelectedIndex(i);
1654:            }
1655:
1656:            protected void selectNextTabInRun(final int current) {
1657:                int tabCount = tabPane.getTabCount();
1658:
1659:                int i = current;
1660:                do {
1661:                    i = getNextTabIndexInRun(tabCount, i);
1662:                } while (i != current && !tabPane.isEnabledAt(i));
1663:
1664:                tabPane.setSelectedIndex(i);
1665:            }
1666:
1667:            protected void selectPreviousTab(final int current) {
1668:                int i = current;
1669:                do {
1670:                    i = getPreviousTabIndex(i);
1671:                } while (i != current && !tabPane.isEnabledAt(i));
1672:
1673:                tabPane.setSelectedIndex(i);
1674:            }
1675:
1676:            protected void selectPreviousTabInRun(final int current) {
1677:                int tabCount = tabPane.getTabCount();
1678:
1679:                int i = current;
1680:                do {
1681:                    i = getPreviousTabIndexInRun(tabCount, i);
1682:                } while (i != current && !tabPane.isEnabledAt(i));
1683:
1684:                tabPane.setSelectedIndex(i);
1685:            }
1686:
1687:            protected void setRolloverTab(final int index) {
1688:                rolloverTab = index;
1689:            }
1690:
1691:            protected int getRolloverTab() {
1692:                return rolloverTab;
1693:            }
1694:
1695:            protected void setVisibleComponent(final Component component) {
1696:                Component oldVisible = getVisibleComponent();
1697:                if (oldVisible != component) {
1698:                    if (oldVisible != null) {
1699:                        oldVisible.setVisible(false);
1700:                    }
1701:                    visibleComponent = component;
1702:                }
1703:
1704:                if (visibleComponent != null) {
1705:                    visibleComponent.setVisible(true);
1706:                }
1707:            }
1708:
1709:            protected Component getVisibleComponent() {
1710:                return visibleComponent;
1711:            }
1712:
1713:            protected boolean shouldPadTabRun(final int tabPlacement,
1714:                    final int run) {
1715:                return runCount > 1;
1716:            }
1717:
1718:            protected boolean shouldRotateTabRuns(final int tabPlacement) {
1719:                return true;
1720:            }
1721:
1722:            public int tabForCoordinate(final JTabbedPane pane, final int x,
1723:                    final int y) {
1724:                for (int i = 0; i < tabPane.getTabCount(); i++) {
1725:                    getTabBounds(i, calcRect);
1726:                    if (calcRect.contains(x, y)) {
1727:                        return i;
1728:                    }
1729:                }
1730:
1731:                return -1;
1732:            }
1733:
1734:            private int rotateDirection(final int tabPlacement,
1735:                    final int direction) {
1736:                if (tabPlacement == LEFT || tabPlacement == RIGHT) {
1737:                    switch (direction) {
1738:                    case NORTH:
1739:                        return WEST;
1740:                    case SOUTH:
1741:                        return EAST;
1742:                    case WEST:
1743:                        return NORTH;
1744:                    case EAST:
1745:                        return SOUTH;
1746:                    }
1747:                }
1748:                return direction;
1749:            }
1750:
1751:            private int getNextElementInRing(final int index, final int ringSize) {
1752:                return (index + 1) % ringSize;
1753:            }
1754:
1755:            private int getPreviousElementInRing(final int index,
1756:                    final int ringSize) {
1757:                return (index + ringSize - 1) % ringSize;
1758:            }
1759:
1760:            private void installScrollableTabsComponents() {
1761:                //        if (scrollableTabArea == null) {
1762:                //            scrollableTabArea = new ScrollableTabPanel();
1763:                //        }
1764:                //        tabPane.add(scrollableTabArea);
1765:                uninstallScrollableTabsComponents();
1766:
1767:                if (isVerticalRun(tabPane.getTabPlacement())) {
1768:                    leftScrollButton = createScrollButton(NORTH);
1769:                    rightScrollButton = createScrollButton(SOUTH);
1770:                } else {
1771:                    leftScrollButton = createScrollButton(WEST);
1772:                    rightScrollButton = createScrollButton(EAST);
1773:                }
1774:                tabPane.add(leftScrollButton);
1775:                tabPane.add(rightScrollButton);
1776:            }
1777:
1778:            private void uninstallScrollableTabsComponents() {
1779:                //        tabPane.remove(scrollableTabArea);
1780:                tabPane.remove(leftScrollButton);
1781:                tabPane.remove(rightScrollButton);
1782:                scrollableTabsOffset = 0;
1783:            }
1784:
1785:            private void calculateInnerArea(final Rectangle rect,
1786:                    final Insets insets) {
1787:                rect.x += insets.left;
1788:                rect.y += insets.top;
1789:                rect.width -= insets.left + insets.right;
1790:                rect.height -= insets.top + insets.bottom;
1791:            }
1792:
1793:            private boolean isVerticalRun(final int tabPlacement) {
1794:                return tabPlacement == LEFT || tabPlacement == RIGHT;
1795:            }
1796:
1797:            private boolean isSelectedTab(final int tabIndex) {
1798:                return tabPane.getSelectedIndex() == tabIndex;
1799:            }
1800:
1801:            private int findTruncatedTab(final boolean forward) {
1802:                int inc;
1803:                int start;
1804:                int end;
1805:
1806:                if (forward) {
1807:                    inc = -1;
1808:                    start = tabPane.getTabCount() - 1;
1809:                    end = 0;
1810:                } else {
1811:                    inc = 1;
1812:                    start = 0;
1813:                    end = tabPane.getTabCount() - 1;
1814:                }
1815:
1816:                int rc = end;
1817:                for (int i = start; i != end; i += inc) {
1818:                    if (tabAreaInnerBounds
1819:                            .intersects(getTabBounds(i, calcRect))) {
1820:                        rc = i;
1821:                        break;
1822:                    }
1823:                }
1824:
1825:                // correct the result if border of tabAreaInnerBounds lies
1826:                // exactly _between_ tabs
1827:                getTabBounds(rc, calcRect);
1828:                if (forward) {
1829:                    // "- 1" because contains() returns false for points on the border
1830:                    if (tabAreaInnerBounds.contains(calcRect.getMaxX() - 1,
1831:                            calcRect.getMaxY() - 1)
1832:                            && rc < tabPane.getTabCount() - 1) {
1833:                        rc++;
1834:                    }
1835:                } else {
1836:                    // "+ 1" because contains() returns false for points on the border
1837:                    if (tabAreaInnerBounds.contains(calcRect.x + 1,
1838:                            calcRect.y + 1)
1839:                            && rc > 0) {
1840:                        rc--;
1841:                    }
1842:                }
1843:
1844:                return rc;
1845:            }
1846:
1847:            private int calculateScrollDelta(final Rectangle r,
1848:                    final boolean forward) {
1849:                int delta = 0;
1850:
1851:                if (forward) {
1852:                    delta = Math.min(tabAreaInnerBounds.x
1853:                            + tabAreaInnerBounds.width - (r.x + r.width),
1854:                            tabAreaInnerBounds.y + tabAreaInnerBounds.height
1855:                                    - (r.y + r.height));
1856:                } else {
1857:                    delta = Math.max(tabAreaInnerBounds.x - r.x,
1858:                            tabAreaInnerBounds.y - r.y);
1859:                }
1860:
1861:                return delta;
1862:            }
1863:
1864:            private void scrollToShowTab(final boolean forward) {
1865:                if (tabPane.getTabLayoutPolicy() != JTabbedPane.SCROLL_TAB_LAYOUT) {
1866:                    return;
1867:                }
1868:
1869:                int tabIndex = findTruncatedTab(forward);
1870:                updateScrollableTabOffset(tabIndex, forward);
1871:            }
1872:
1873:            private void scrollToShowTab(final int selectedIndex) {
1874:                if (tabPane.getTabLayoutPolicy() != JTabbedPane.SCROLL_TAB_LAYOUT) {
1875:                    return;
1876:                }
1877:
1878:                getTabBounds(selectedIndex, calcRect);
1879:                if (tabAreaInnerBounds.contains(calcRect)) {
1880:                    return;
1881:                }
1882:
1883:                boolean forward = tabAreaInnerBounds.contains(calcRect.x,
1884:                        calcRect.y);
1885:                updateScrollableTabOffset(selectedIndex, forward);
1886:            }
1887:
1888:            private void updateScrollableTabOffset(final int tabIndex,
1889:                    final boolean forward) {
1890:                getTabBounds(tabIndex, calcRect);
1891:                int delta = calculateScrollDelta(calcRect, forward);
1892:                if (tabIndex > 0 && tabIndex < tabPane.getTabCount() - 1
1893:                /*                || tabIndex == 0 && forward
1894:                 || tabIndex == tabPane.getTabCount() - 1 && !forward*/) {
1895:                    // the idea of this code is to make visible part of the next tab
1896:                    if (delta > 0) {
1897:                        delta += 5;
1898:                    } else if (delta < 0) {
1899:                        delta -= 5;
1900:                    }
1901:                }
1902:                scrollableTabsOffset += delta;
1903:                updateScrollButtons();
1904:            }
1905:
1906:            private int calculateTabIndexByMouseEvent(final MouseEvent e) {
1907:                Point p = SwingUtilities.convertPoint(e.getComponent(), e
1908:                        .getX(), e.getY(), tabPane);
1909:                if (!tabAreaInnerBounds.contains(p)) {
1910:                    return -1;
1911:                }
1912:                return tabForCoordinate(tabPane, p.x, p.y);
1913:            }
1914:
1915:            private boolean isTabAdjacentToContentAreaBorder(
1916:                    final int selectedIndex) {
1917:                return getRunForTab(tabPane.getTabCount(), selectedIndex) == 0;
1918:            }
1919:
1920:            private void updateScrollButtons() {
1921:                leftScrollButton.setEnabled(!tabAreaInnerBounds
1922:                        .contains(getTabBounds(0, calcRect)));
1923:                rightScrollButton.setEnabled(!tabAreaInnerBounds
1924:                        .contains(getTabBounds(tabPane.getTabCount() - 1,
1925:                                calcRect)));
1926:
1927:                if (!leftScrollButton.isEnabled()
1928:                        && !rightScrollButton.isEnabled()) {
1929:                    leftScrollButton.setVisible(false);
1930:                    rightScrollButton.setVisible(false);
1931:                } else {
1932:                    leftScrollButton.setVisible(true);
1933:                    rightScrollButton.setVisible(true);
1934:                }
1935:            }
1936:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.