/* * @(#)Eclipse3xJideTabbedPaneUI.java 8/28/2006 * * Copyright 2002 - 2006 JIDE Software Inc. All rights reserved. */ package com.jidesoft.plaf.eclipse; import com.jidesoft.plaf.UIDefaultsLookup; import com.jidesoft.plaf.vsnet.VsnetJideTabbedPaneUI; import com.jidesoft.swing.JideSwingUtilities; import com.jidesoft.swing.JideTabbedPane; import javax.swing.*; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicGraphicsUtils; import javax.swing.text.View; import java.awt.*; /** * A eclipse L&f implementation of JideTabbedPaneUI */ public class Eclipse3xJideTabbedPaneUI extends VsnetJideTabbedPaneUI { // pixels protected int _closeButtonMargin;// margin around the close button protected int _closeButtonMarginSize;// margin of the close button when every tab has a close button protected int _iconMarginHorizon;// distance from icon to tab rect start when the tab is on the top or bottom protected int _iconMarginVertical;// distance from icon to tab rect start when the tab is on the left or right @SuppressWarnings({"UnusedDeclaration"}) public static ComponentUI createUI(JComponent c) { return new Eclipse3xJideTabbedPaneUI(); } @Override public void installUI(JComponent c) { super.installUI(c); _rectSizeExtend = 12; } @Override protected void installDefaults() { super.installDefaults(); // set the border of the TabbedPane LookAndFeel.installBorder(_tabPane, "JideTabbedPane.border"); _closeButtonMargin = UIDefaultsLookup.getInt("JideTabbedPane.closeButtonMargin"); _closeButtonMarginSize = UIDefaultsLookup.getInt("JideTabbedPane.closeButtonMarginSize"); _iconMarginHorizon = UIDefaultsLookup.getInt("JideTabbedPane.iconMarginHorizon"); _iconMarginVertical = UIDefaultsLookup.getInt("JideTabbedPane.iconMarginVertical"); } @Override public void paintBackground(Graphics g, Component c) { if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { if (_tabPane.isOpaque()) { int width = c.getWidth(); int height = c.getHeight(); int temp1 = -1; int temp2 = -1; if (isTabLeadingComponentVisible()) { if (height < _tabLeadingComponent.getSize().height) { height = _tabLeadingComponent.getSize().height; temp1 = _tabLeadingComponent.getSize().height; } if (width < _tabLeadingComponent.getSize().width) { width = _tabLeadingComponent.getSize().width; temp2 = _tabLeadingComponent.getSize().width; } } if (isTabTrailingComponentVisible()) { if (height < _tabTrailingComponent.getSize().height && temp1 < _tabTrailingComponent.getSize().height) { height = _tabTrailingComponent.getSize().height; } if (width < _tabTrailingComponent.getSize().width && temp2 < _tabTrailingComponent.getSize().width) { width = _tabTrailingComponent.getSize().width; } } g.setColor(_background); g.fillRect(0, 0, width, height); } } else { super.paintBackground(g, c); } } @Override protected void ensureCurrentLayout() { /* * If tabPane doesn't have a peer yet, the validate() call will silently * fail. We handle that by forcing a layout if tabPane is still invalid. * See bug 4237677. */ if (!_tabPane.isValid()) { TabbedPaneLayout layout = (TabbedPaneLayout) _tabPane.getLayout(); layout.calculateLayoutInfo(); } // ensure the bounds of the close buttons when they are showed on the // tab if (scrollableTabLayoutEnabled() && isShowCloseButton() && isShowCloseButtonOnTab()) { for (int i = 0; i < _closeButtons.length; i++) { if (_tabPane.isShowCloseButtonOnSelectedTab()) { if (i != _tabPane.getSelectedIndex()) { _closeButtons[i].setBounds(0, 0, 0, 0); continue; } } else { if (i >= _rects.length) { _closeButtons[i].setBounds(0, 0, 0, 0); continue; } } if (!_tabPane.isTabClosableAt(i)) { _closeButtons[i].setBounds(0, 0, 0, 0); continue; } Dimension size = _closeButtons[i].getPreferredSize(); Rectangle bounds; if (_closeButtonAlignment == SwingConstants.TRAILING) { if (_tabPane.getTabPlacement() == JideTabbedPane.TOP || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM) { if (_tabPane.getComponentOrientation().isLeftToRight()) { bounds = new Rectangle(_rects[i].x + _rects[i].width - size.width - 16, _rects[i].y + ((_rects[i].height - size.height) >> 1), size.width, size.height); } else { bounds = new Rectangle(_rects[i].x + 4, ((_rects[i].height - size.height) >> 1), size.width, size.height); } } else if (_tabPane.getTabPlacement() == JideTabbedPane.LEFT) { bounds = new Rectangle(_rects[i].x + ((_rects[i].width - size.width) >> 1), _rects[i].y + _rects[i].height - size.height - 16, size.width, size.height); } else /*if (_tabPane.getTabPlacement() == JideTabbedPane.RIGHT)*/ { bounds = new Rectangle(_rects[i].x + ((_rects[i].width - size.width) >> 1), _rects[i].y + _rects[i].height - size.height - 16, size.width, size.height); } } else { bounds = new Rectangle(_rects[i].x + 4, ((_rects[i].height - size.height) >> 1), size.width, size.height); if (!_tabPane.getComponentOrientation().isLeftToRight() && (_tabPane.getTabPlacement() == JideTabbedPane.TOP || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM)) { bounds = new Rectangle(_rects[i].x + _rects[i].width - size.width - 16, _rects[i].y + ((_rects[i].height - size.height) >> 1), size.width, size.height); } } if (_closeButtons[i] instanceof JideTabbedPane.NoFocusButton) { ((JideTabbedPane.NoFocusButton) _closeButtons[i]).setIndex(i); } if (!bounds.equals(_closeButtons[i].getBounds())) { _closeButtons[i].setBounds(bounds); } if (_tabPane.getSelectedIndex() == i) { _closeButtons[i].setBackground(_selectedColor == null ? _tabPane.getBackgroundAt(i) : _selectedColor); } else { _closeButtons[i].setBackground(_tabPane.getBackgroundAt(i)); } } } } /** * Paints the tabs in the tab area. Invoked by paint(). The graphics parameter must be a valid <code>Graphics</code> * object. Tab placement may be either: <code>JTabbedPane.TOP</code>, <code>JTabbedPane.BOTTOM</code>, * <code>JTabbedPane.LEFT</code>, or <code>JTabbedPane.RIGHT</code>. The selected index must be a valid tabbed pane * tab index (0 to tab count - 1, inclusive) or -1 if no tab is currently selected. The handling of invalid * parameters is unspecified. * * @param g the graphics object to use for rendering * @param tabPlacement the placement for the tabs within the JTabbedPane * @param selectedIndex the tab index of the selected component */ @Override protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex, Component c) { if (!PAINT_TABAREA) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { int tabCount = _tabPane.getTabCount(); Rectangle iconRect = new Rectangle(), textRect = new Rectangle(); Rectangle clipRect = g.getClipBounds(); Rectangle viewRect = _tabScroller.viewport.getViewRect(); if (_tabPane.isOpaque()) { g.setColor(_tabBackground); g.fillRect(clipRect.x, clipRect.y, clipRect.width, clipRect.height); } // Paint tabRuns of tabs from back to front for (int i = _runCount - 1; i >= 0; i--) { int start = _tabRuns[i]; int next = _tabRuns[(i == _runCount - 1) ? 0 : i + 1]; int end = (next != 0 ? next - 1 : tabCount - 1); for (int j = start; j <= end; j++) { if (_rects[j].intersects(clipRect)) { paintTab(g, tabPlacement, _rects, j, iconRect, textRect); } } } // Paint selected tab if its in the front run // since it may overlap other tabs if (selectedIndex >= 0 && getRunForTab(tabCount, selectedIndex) == 0) { if (_rects[selectedIndex].intersects(clipRect)) { paintTab(g, tabPlacement, _rects, selectedIndex, iconRect, textRect); } } if (_tabPane.isOpaque()) { g.setColor(_shadow); switch (tabPlacement) { case LEFT: if (!isTabLeadingComponentVisible()) { g.fillRect(viewRect.x, viewRect.y + 3, 1, 2); g.fillRect(viewRect.x + 1, viewRect.y + 2, 1, 1); g.fillRect(viewRect.x + 2, viewRect.y + 1, 1, 1); g.fillRect(viewRect.x + 3, viewRect.y, 2, 1); } if (isNoneTabTrailingComponentVisible()) { g.fillRect(viewRect.x + 3, viewRect.y + viewRect.height - 1, 2, 1); g.fillRect(viewRect.x + 2, viewRect.y + viewRect.height - 2, 1, 1); g.fillRect(viewRect.x + 1, viewRect.y + viewRect.height - 3, 1, 1); g.fillRect(viewRect.x, viewRect.y + viewRect.height - 5, 1, 2); } g.setColor(_tabBackground); g.fillRect(viewRect.x, viewRect.y, 3, 1); g.fillRect(viewRect.x, viewRect.y + 1, 2, 1); g.fillRect(viewRect.x, viewRect.y + 2, 1, 1); break; case RIGHT: if (!isTabLeadingComponentVisible()) { g.fillRect(viewRect.x + viewRect.width - 5, viewRect.y, 2, 1); g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y + 1, 1, 1); g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + 2, 1, 1); g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + 3, 1, 2); } if (isNoneTabTrailingComponentVisible()) { g.fillRect(viewRect.x + viewRect.width - 5, viewRect.y + viewRect.height - 1, 2, 1); g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y + viewRect.height - 2, 1, 1); g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + viewRect.height - 3, 1, 1); g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + viewRect.height - 5, 1, 2); } g.setColor(_tabBackground); g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y, 3, 1); g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + 1, 2, 1); g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + 2, 1, 1); break; case BOTTOM: if (!isTabLeadingComponentVisible()) { g.fillRect(viewRect.x + 3, viewRect.y + viewRect.height - 1, 2, 1); g.fillRect(viewRect.x + 2, viewRect.y + viewRect.height - 2, 1, 1); g.fillRect(viewRect.x + 1, viewRect.y + viewRect.height - 3, 1, 1); g.fillRect(viewRect.x, viewRect.y + viewRect.height - 5, 1, 2); } if (isNoneTabTrailingComponentVisible()) { g.fillRect(viewRect.x + viewRect.width - 5, viewRect.y + viewRect.height - 1, 2, 1); g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y + viewRect.height - 2, 1, 1); g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + viewRect.height - 3, 1, 1); g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + viewRect.height - 5, 1, 2); } g.setColor(_tabBackground); g.fillRect(viewRect.x, viewRect.y + viewRect.height - 1, 3, 1); g.fillRect(viewRect.x, viewRect.y + viewRect.height - 2, 2, 1); g.fillRect(viewRect.x, viewRect.y + viewRect.height - 3, 1, 1); break; case TOP: default: if (!isTabLeadingComponentVisible()) { g.fillRect(viewRect.x + 3, viewRect.y, 2, 1); g.fillRect(viewRect.x + 2, viewRect.y + 1, 1, 1); g.fillRect(viewRect.x + 1, viewRect.y + 2, 1, 1); g.fillRect(viewRect.x, viewRect.y + 3, 1, 2); } if (isNoneTabTrailingComponentVisible()) { g.fillRect(viewRect.x + viewRect.width - 5, viewRect.y, 2, 1); g.fillRect(viewRect.x + viewRect.width - 3, viewRect.y + 1, 1, 1); g.fillRect(viewRect.x + viewRect.width - 2, viewRect.y + 2, 1, 1); g.fillRect(viewRect.x + viewRect.width - 1, viewRect.y + 3, 1, 2); } g.setColor(_tabBackground); g.fillRect(viewRect.x, viewRect.y, 3, 1); g.fillRect(viewRect.x, viewRect.y + 1, 2, 1); g.fillRect(viewRect.x, viewRect.y + 2, 1, 1); } } } else { super.paintTabArea(g, tabPlacement, selectedIndex, c); } } private boolean isNoneTabTrailingComponentVisible() { return !_tabScroller.scrollForwardButton.isVisible() && !_tabScroller.scrollBackwardButton.isVisible() && !_tabScroller.closeButton.isVisible() && !isTabTrailingComponentVisible(); } @Override protected void layoutLabel(int tabPlacement, FontMetrics metrics, int tabIndex, String title, Icon icon, Rectangle tabRect, Rectangle iconRect, Rectangle textRect, boolean isSelected) { textRect.x = textRect.y = iconRect.x = iconRect.y = 0; View v = getTextViewForTab(tabIndex); if (v != null) { _tabPane.putClientProperty("html", v); } SwingUtilities.layoutCompoundLabel(_tabPane, metrics, title, icon, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.TRAILING, tabRect, iconRect, textRect, _textIconGap); _tabPane.putClientProperty("html", null); if (tabPlacement == JideTabbedPane.TOP || tabPlacement == JideTabbedPane.BOTTOM) { iconRect.x = tabRect.x + _iconMarginHorizon; textRect.x = (icon != null ? iconRect.x + iconRect.width + _textIconGap : tabRect.x + _textPadding); iconRect.width = Math.min(iconRect.width, tabRect.width - _tabRectPadding); textRect.width = tabRect.width - _tabRectPadding - iconRect.width - (icon != null ? _textIconGap : _noIconMargin); if ((getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIT || _tabPane.getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIXED)) { textRect.width -= 10; if (isShowCloseButton() && isShowCloseButtonOnTab()) { if (_tabPane.isShowCloseButtonOnSelectedTab()) { if (isSelected) { textRect.width -= _closeButtons[tabIndex].getPreferredSize().width; } } else { textRect.width -= _closeButtons[tabIndex].getPreferredSize().width; } } } else if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_COMPRESSED && isShowCloseButton() && isShowCloseButtonOnTab()) { if (!_tabPane.isShowCloseButtonOnSelectedTab()) { if (!isSelected) { iconRect.width = iconRect.width + _closeButtons[tabIndex].getPreferredSize().width + _closeButtonMarginSize; textRect.width = 0; } } } } else { iconRect.y = tabRect.y + _iconMarginVertical; textRect.y = (icon != null ? iconRect.y + iconRect.height + _textIconGap : tabRect.y + _textPadding); iconRect.x = tabRect.x + 3; textRect.x = tabRect.x + 3; textRect.width = tabRect.width - _textMarginVertical; textRect.height = tabRect.height - _tabRectPadding - iconRect.height - (icon != null ? _textIconGap : _noIconMargin); if ((getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIT || _tabPane .getTabResizeMode() == JideTabbedPane.RESIZE_MODE_FIXED)) { textRect.height -= 10; if (isShowCloseButton() && isShowCloseButtonOnTab()) { if (_tabPane.isShowCloseButtonOnSelectedTab()) { if (isSelected) { textRect.height -= _closeButtons[tabIndex].getPreferredSize().height; } } else { textRect.height -= _closeButtons[tabIndex].getPreferredSize().height; } } } else if (getTabResizeMode() == JideTabbedPane.RESIZE_MODE_COMPRESSED && isShowCloseButton() && isShowCloseButtonOnTab()) { if (!_tabPane.isShowCloseButtonOnSelectedTab()) { if (!isSelected) { iconRect.height = iconRect.height + _closeButtons[tabIndex].getPreferredSize().height + _closeButtonMarginSize; textRect.height = 0; } } } } } /** * this function draws the border around each tab note that this function does now draw the background of the tab. * that is done elsewhere */ @Override protected void paintTabBorder(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { if (!PAINT_TAB_BORDER) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { g.setColor(_lightHighlight); boolean leftToRight = _tabPane.getComponentOrientation().isLeftToRight(); switch (tabPlacement) { case LEFT: if (!isTabLeadingComponentVisible()) y--; if (isSelected) { g.setColor(_shadow); g.drawLine(x + 5, y, x + w - 1, y);// top // top left arc g.drawLine(x + 4, y + 1, x + 3, y + 1); g.drawLine(x + 2, y + 2, x + 2, y + 2); g.drawLine(x + 1, y + 3, x + 1, y + 3); g.drawLine(x, y + 4, x, y + 5); if (isTabTopVisible(tabPlacement)) { g.drawLine(x, y + 5, x, y + h - 21); } // bottom left arc g.drawLine(x, y + h - 21, x, y + h - 19); g.drawLine(x + 1, y + h - 18, x + 1, y + h - 16); g.drawLine(x + 2, y + h - 15, x + 2, y + h - 14); g.drawLine(x + 3, y + h - 13, x + 3, y + h - 13); g.drawLine(x + 4, y + h - 12, x + 4, y + h - 11); // bottom for (int i = 0; i < w - 10; i++) { g.drawLine(x + 5 + i, y + h - 10 + i, x + 5 + i, y + h - 10 + i); } // bottom right arc g.drawLine(x + w - 5, y + h + w - 20, x + w - 5, y + h + w - 19); g.drawLine(x + w - 4, y + h + w - 18, x + w - 4, y + h + w - 18); g.drawLine(x + w - 3, y + h + w - 17, x + w - 3, y + h + w - 16); g.drawLine(x + w - 2, y + h + w - 15, x + w - 2, y + h + w - 13); g.drawLine(x + w - 1, y + h + w - 12, x + w - 1, y + h + w - 10); if (!isTabLeadingComponentVisible()) y++; break; } // not selected if (tabIndex > _tabPane.getSelectedIndex()) { g.setColor(_shadow); g.drawLine(x, y + h - 1, (x + w) - 1, y + h - 1);// bottom break; } if (tabIndex >= _tabPane.getSelectedIndex() || tabIndex == 0) break; g.setColor(_shadow); g.drawLine(x, y - 1, x + w - 1, y - 1);// top break; case RIGHT: if (!isTabLeadingComponentVisible()) y--; if (isSelected) { g.setColor(_shadow); g.drawLine(x, y, x + w - 6, y);// top // top right arc g.drawLine(x + w - 5, y + 1, x + w - 4, y + 1); g.drawLine(x + w - 3, y + 2, x + w - 3, y + 2); g.drawLine(x + w - 2, y + 3, x + w - 2, y + 3); g.drawLine(x + w - 1, y + 4, x + w - 1, y + 5); if (isTabTopVisible(tabPlacement)) { g.drawLine(x + w - 1, y + 5, x + w - 1, y + h - 21); } // bottom right arc g.drawLine(x + w - 1, y + h - 21, x + w - 1, y + h - 19); g.drawLine(x + w - 2, y + h - 18, x + w - 2, y + h - 16); g.drawLine(x + w - 3, y + h - 15, x + w - 3, y + h - 14); g.drawLine(x + w - 4, y + h - 13, x + w - 4, y + h - 13); g.drawLine(x + w - 5, y + h - 12, x + w - 5, y + h - 11); // bottom for (int i = 0; i < w - 10; i++) { g.drawLine(x + w - 6 - i, y + h - 10 + i, x + w - 6 - i, y + h - 10 + i); } // bottom left arc g.drawLine(x + 4, y + h + w - 20, x + 4, y + h + w - 19); g.drawLine(x + 3, y + h + w - 18, x + 3, y + h + w - 18); g.drawLine(x + 2, y + h + w - 17, x + 2, y + h + w - 16); g.drawLine(x + 1, y + h + w - 15, x + 1, y + h + w - 13); g.drawLine(x, y + h + w - 12, x, y + h + w - 10); break; } // not selected if (tabIndex > _tabPane.getSelectedIndex()) { g.setColor(_shadow); g.drawLine(x, y + h - 1, (x + w) - 1, y + h - 1);// bottom break; } if (tabIndex >= _tabPane.getSelectedIndex() || tabIndex == 0) break; g.setColor(_shadow); g.drawLine(x, y - 1, x + w - 1, y - 1);// top break; case BOTTOM: if (!isTabLeadingComponentVisible()) { x--; } if (isSelected) { g.setColor(_shadow); g.drawLine(x, y + h - 6, x, y);// left // left bottom arc g.drawLine(x + 1, y + h - 5, x + 1, y + h - 4); g.drawLine(x + 2, y + h - 3, x + 2, y + h - 3); g.drawLine(x + 3, y + h - 2, x + 3, y + h - 2); g.drawLine(x + 4, y + h - 1, x + 5, y + h - 1); if (isTabTopVisible(tabPlacement)) { g.drawLine(x + 5, y + h - 1, x + w - 20, y + h - 1); } // right bottom arc g.drawLine(x + w - 20, y + h - 1, x + w - 18, y + h - 1); g.drawLine(x + w - 17, y + h - 2, x + w - 15, y + h - 2); g.drawLine(x + w - 14, y + h - 3, x + w - 13, y + h - 3); g.drawLine(x + w - 12, y + h - 4, x + w - 12, y + h - 4); g.drawLine(x + w - 11, y + h - 5, x + w - 10, y + h - 5); // right for (int i = 0; i < h - 10; i++) { g.drawLine(x + w - 9 + i, y + h - 6 - i, x + w - 9 + i, y + h - 6 - i); } // right top arc g.drawLine(x + w + h - 19, y + 4, x + w + h - 18, y + 4); g.drawLine(x + w + h - 17, y + 3, x + w + h - 17, y + 3); g.drawLine(x + w + h - 16, y + 2, x + w + h - 15, y + 2); g.drawLine(x + w + h - 14, y + 1, x + w + h - 12, y + 1); g.drawLine(x + w + h - 11, y, x + w + h - 9, y); break; } // not selected if (tabIndex > _tabPane.getSelectedIndex()) { g.setColor(_shadow); if (leftToRight) { g.drawLine(x + w - 2, y - 1, x + w - 2, y + h);// right } else { g.drawLine(x, y - 1, x, y + h);// right } break; } if (tabIndex >= _tabPane.getSelectedIndex() || tabIndex == 0) break; g.setColor(_shadow); if (leftToRight) { g.drawLine(x, y - 1, x, y + h);// left } else { g.drawLine(x + w - 2, y - 1, x + w - 2, y + h);// left } break; case TOP: default: if (!isTabLeadingComponentVisible()) x--; if (isSelected) { g.setColor(_shadow); g.drawLine(x, y + 5, x, y + h);// left // left top arc g.drawLine(x + 4, y, x + 5, y); g.drawLine(x + 3, y + 1, x + 3, y + 1); g.drawLine(x + 2, y + 2, x + 2, y + 2); g.drawLine(x + 1, y + 3, x + 1, y + 4); if (isTabTopVisible(tabPlacement)) { g.drawLine(x + 5, y, x + w - 20, y); } // right top arc g.drawLine(x + w - 20, y, x + w - 18, y); g.drawLine(x + w - 17, y + 1, x + w - 15, y + 1); g.drawLine(x + w - 14, y + 2, x + w - 13, y + 2); g.drawLine(x + w - 12, y + 3, x + w - 12, y + 3); g.drawLine(x + w - 11, y + 4, x + w - 10, y + 4); // right for (int i = 0; i < h - 10; i++) { g.drawLine(x + w - 9 + i, y + 5 + i, x + w - 9 + i, y + 5 + i); } // right bottom arc g.drawLine(x + w + h - 19, y + h - 5, x + w + h - 18, y + h - 5); g.drawLine(x + w + h - 17, y + h - 4, x + w + h - 17, y + h - 4); g.drawLine(x + w + h - 16, y + h - 3, x + w + h - 15, y + h - 3); g.drawLine(x + w + h - 14, y + h - 2, x + w + h - 12, y + h - 2); g.drawLine(x + w + h - 11, y + h - 1, x + w + h - 9, y + h - 1); break; } if (tabIndex > _tabPane.getSelectedIndex()) { g.setColor(_shadow); if (leftToRight) { g.drawLine(x + w - 2, y, x + w - 2, y + (h - 1));// right } else { g.drawLine(x, y, x, y + (h - 1));// left } break; } if (tabIndex >= _tabPane.getSelectedIndex() || tabIndex == 0) break; g.setColor(_shadow); if (leftToRight) { g.drawLine(x, y, x, y + (h - 1));// left } else { g.drawLine(x + w - 2, y, x + w - 2, y + (h - 1));// left } break; } } else { super.paintTabBorder(g, tabPlacement, tabIndex, x, y, w, h, isSelected); } } @Override protected void paintTabBackground(Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, boolean isSelected) { if (!PAINT_TAB_BACKGROUND) { return; } if (!isSelected) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { Graphics2D g2d = (Graphics2D) g; Color background1; Color background2; if (showFocusIndicator()) { background1 = _activeBackground; background2 = UIDefaultsLookup.getColor("DockableFrame.activeTitleBackground2"); } else { background1 = _activeBackground; background2 = _background; } switch (tabPlacement) { case LEFT: { if (!isTabLeadingComponentVisible()) y--; int[] xp = {x + w, x + 5, x, x, x + 6, x + w - 6, x + w}; int[] yp = {y, y, y + 4, y + h - 19, y + h - 8, y + h + w - 21, y + h + w - 10}; int np = yp.length; Polygon p = new Polygon(xp, yp, np); JideSwingUtilities.fillGradient(g2d, p, background1, background2, false); } break; case RIGHT: { if (!isTabLeadingComponentVisible()) y--; int[] xp = {x, x + w - 6, x + w, x + w, x + w - 5, x + 5, x}; int[] yp = {y, y, y + 4, y + h - 21, y + h - 10, y + h + w - 21, y + h + w - 10}; int np = yp.length; Polygon p = new Polygon(xp, yp, np); JideSwingUtilities.fillGradient(g2d, p, background2, background1, false); } break; case BOTTOM: { if (!isTabLeadingComponentVisible()) x--; // not box style int[] xp = {x, x, x + 6, x + w - 20, x + w - 16, x + w - 14, x + w - 12, x + w - 9, x + w + h - 19, x + w + h - 10, x + w + h - 12}; int[] yp = {y, y + h - 6, y + h, y + h, y + h - 2, y + h - 3, y + h - 4, y + h - 6, y + 4, y + 1, y}; int np = yp.length; Polygon p = new Polygon(xp, yp, np); JideSwingUtilities.fillGradient(g2d, p, background2, background1, true); } break; case TOP: default: { if (!isTabLeadingComponentVisible()) x--; int[] xp = {x, x, x + 2, x + 3, x + 6, x + w - 20, x + w - 14, x + w - 12, x + w - 9, x + w + h - 20, x + w + h - 9}; int[] yp = {y + h, y + 5, y + 2, y + 1, y, y, y + 2, y + 3, y + 5, y + h - 6, y + h}; int np = xp.length; Polygon p = new Polygon(xp, yp, np); JideSwingUtilities.fillGradient(g2d, p, background1, background2, true); } break; } } else { super.paintTabBackground(g, tabPlacement, tabIndex, x, y, w, h, isSelected); } } @Override protected void paintContentBorder(Graphics g, int tabPlacement, int selectedIndex) { if (selectedIndex < 0) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { int width = _tabPane.getWidth(); int height = _tabPane.getHeight(); Insets insets = _tabPane.getInsets(); int x = insets.left; int y = insets.top; int w = width - insets.right - insets.left; int h = height - insets.top - insets.bottom; int temp = -1; switch (tabPlacement) { case LEFT: x += calculateTabAreaWidth(tabPlacement, _runCount, _maxTabWidth); if (isTabLeadingComponentVisible()) { if (_tabLeadingComponent.getSize().width > calculateTabAreaWidth(tabPlacement, _runCount, _maxTabWidth)) { x = insets.left + _tabLeadingComponent.getSize().width; temp = _tabLeadingComponent.getSize().width; } } if (isTabTrailingComponentVisible()) { if (_maxTabWidth < _tabTrailingComponent.getSize().width && temp < _tabTrailingComponent.getSize().width) { x = insets.left + _tabTrailingComponent.getSize().width; } } w -= (x - insets.left); break; case RIGHT: w -= calculateTabAreaWidth(tabPlacement, _runCount, _maxTabWidth); break; case BOTTOM: h -= calculateTabAreaHeight(tabPlacement, _runCount, _maxTabHeight); break; case TOP: default: y += calculateTabAreaHeight(tabPlacement, _runCount, _maxTabHeight); if (isTabLeadingComponentVisible()) { if (_tabLeadingComponent.getSize().height > calculateTabAreaHeight(tabPlacement, _runCount, _maxTabHeight)) { y = insets.top + _tabLeadingComponent.getSize().height; temp = _tabLeadingComponent.getSize().height; } } if (isTabTrailingComponentVisible()) { if (_maxTabHeight < _tabTrailingComponent.getSize().height && temp < _tabTrailingComponent.getSize().height) { y = insets.top + _tabTrailingComponent.getSize().height; } } h -= (y - insets.top); } // Fill region behind content area paintContentBorder(g, x, y, w, h); Rectangle viewRect = _tabScroller.viewport.getViewRect(); Rectangle r = _rects[selectedIndex]; Rectangle button = _tabScroller.scrollForwardButton.getBounds(); Rectangle panel = _tabScroller.tabPanel.getBounds(); int lsize = 0; if (_tabPane.getTabPlacement() == TOP || _tabPane.getTabPlacement() == BOTTOM) { if (isTabLeadingComponentVisible()) { lsize = _tabLeadingComponent.getSize().width; } } else { if (isTabLeadingComponentVisible()) { lsize = _tabLeadingComponent.getSize().height; } } switch (tabPlacement) { case LEFT: if (r.y < viewRect.y + viewRect.height && r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 > viewRect.y + viewRect.height) { if (selectedIndex != _tabPane.getTabCount() - 1) { viewRect.y += (r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 - (viewRect.y + viewRect.height)); _tabScroller.viewport.setViewPosition(new Point( viewRect.x, viewRect.y)); } else { if (panel.y + panel.height + lsize > button.y) { viewRect.y += (r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 - (viewRect.y + viewRect.height)); _tabScroller.viewport.setViewPosition(new Point( viewRect.x, viewRect.y)); } else { _tabScroller.viewport.setSize(viewRect.width, viewRect.height + getLayoutSize()); } } } paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h); break; case RIGHT: if (r.y < viewRect.y + viewRect.height && r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 > viewRect.y + viewRect.height) { if (selectedIndex != _tabPane.getTabCount() - 1) { viewRect.y += (r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 - (viewRect.y + viewRect.height)); _tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y)); } else { if (panel.y + panel.height + lsize > button.y) { viewRect.y += (r.y + r.height + _tabPane.getBoundsAt(selectedIndex).width - 9 - (viewRect.y + viewRect.height)); _tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y)); } else { _tabScroller.viewport.setSize(viewRect.width, viewRect.height + getLayoutSize()); } } } paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h); break; case BOTTOM: if (r.x < viewRect.x + viewRect.width && r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 > viewRect.x + viewRect.width) { if (selectedIndex != _tabPane.getTabCount() - 1) { viewRect.x += (r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 - (viewRect.x + viewRect.width)); _tabScroller.viewport.setViewPosition(new Point( viewRect.x, viewRect.y)); } else { if (panel.x + panel.width + lsize > button.x) { viewRect.x += (r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 - (viewRect.x + viewRect.width)); _tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y)); } else { _tabScroller.viewport.setSize(viewRect.width + getLayoutSize(), viewRect.height); } } } paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h); break; case TOP: default: if (r.x < viewRect.x + viewRect.width && r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 > viewRect.x + viewRect.width) { if (selectedIndex != _tabPane.getTabCount() - 1) { viewRect.x += (r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 - (viewRect.x + viewRect.width)); _tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y)); } else { if (panel.x + panel.width + lsize > button.x) { viewRect.x += (r.x + r.width + _tabPane.getBoundsAt(selectedIndex).height - 9 - (viewRect.x + viewRect.width)); _tabScroller.viewport.setViewPosition(new Point(viewRect.x, viewRect.y)); } else { _tabScroller.viewport.setSize(viewRect.width + getLayoutSize(), viewRect.height); } } } paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h); break; } g.setColor(_shadow); if (_tabPane.isTabShown()) { switch (tabPlacement) { case LEFT: g.drawLine(width - 1, 0, width - 1, height - 1); g.drawLine(6, 0, width - 1, 0); g.drawLine(6, height - 1, width - 1, height - 1); g.drawLine(0, 6, 0, height - 7); g.drawLine(1, height - 6, 1, height - 5); g.drawLine(2, height - 4, 2, height - 4); g.drawLine(3, height - 3, 3, height - 3); g.drawLine(4, height - 2, 5, height - 2); g.drawLine(4, 1, 5, 1); g.drawLine(3, 2, 3, 2); g.drawLine(2, 3, 2, 3); g.drawLine(1, 4, 1, 5); break; case RIGHT: g.drawLine(0, 0, 0, height - 1); g.drawLine(0, 0, width - 7, 0); g.drawLine(0, height - 1, width - 7, height - 1); g.drawLine(width - 1, 6, width - 1, height - 7); g.drawLine(width - 2, height - 6, width - 2, height - 5); g.drawLine(width - 3, height - 4, width - 3, height - 4); g.drawLine(width - 4, height - 3, width - 4, height - 3); g.drawLine(width - 5, height - 2, width - 6, height - 2); g.drawLine(width - 6, 1, width - 5, 1); g.drawLine(width - 4, 2, width - 4, 2); g.drawLine(width - 3, 3, width - 3, 3); g.drawLine(width - 2, 4, width - 2, 5); break; case BOTTOM: g.drawLine(0, 0, width - 1, 0); g.drawLine(0, 0, 0, height - 7); g.drawLine(width - 1, 0, width - 1, height - 7); g.drawLine(6, height - 1, width - 7, height - 1); g.drawLine(width - 6, height - 2, width - 5, height - 2); g.drawLine(width - 4, height - 3, width - 4, height - 3); g.drawLine(width - 3, height - 4, width - 3, height - 4); g.drawLine(width - 2, height - 5, width - 2, height - 6); g.drawLine(1, height - 6, 1, height - 5); g.drawLine(2, height - 4, 2, height - 4); g.drawLine(3, height - 3, 3, height - 3); g.drawLine(4, height - 2, 5, height - 2); break; case TOP: default: g.drawLine(6, 0, width - 7, 0); g.drawLine(0, height - 1, width - 1, height - 1); g.drawLine(width - 1, 6, width - 1, height - 1); g.drawLine(0, 6, 0, height - 1); g.drawLine(width - 6, 1, width - 5, 1); g.drawLine(width - 4, 2, width - 4, 2); g.drawLine(width - 3, 3, width - 3, 3); g.drawLine(width - 2, 4, width - 2, 5); g.drawLine(4, 1, 5, 1); g.drawLine(3, 2, 3, 2); g.drawLine(2, 3, 2, 3); g.drawLine(1, 4, 1, 5); break; } } else { g.drawRect(0, 0, width - 1, height - 1); } } else { super.paintContentBorder(g, tabPlacement, selectedIndex); } } // paint the component border of every tab @Override protected void paintContentBorder(Graphics g, int x, int y, int w, int h) { if (!PAINT_CONTENT_BORDER) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { if (showFocusIndicator()) { Insets insets = getContentBorderInsets(_tabPane.getTabPlacement()); Color selectedTitleColor2 = UIDefaultsLookup.getColor("DockableFrame.activeTitleBackground2"); g.setColor(selectedTitleColor2); g.fillRect(x, y, w, insets.top); // top g.fillRect(x, y, insets.left, h); // left g.fillRect(x, y + h - insets.bottom, w, insets.bottom); // bottom g.fillRect(x + w - insets.right, y, insets.right, h); // right } } else { super.paintContentBorder(g, x, y, w, h); } } // paint the top line of the content when the tab is on the top @Override protected void paintContentBorderTopEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { if (!PAINT_CONTENT_BORDER_EDGE) { return; } if (selectedIndex < 0) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { Rectangle selRect = getTabBounds(selectedIndex, _calcRect); Rectangle viewRect = _tabScroller.viewport.getViewRect(); Rectangle r = _rects[selectedIndex]; g.setColor(getPainter().getControlShadow()); // Break line to show visual connection to selected tab if (isTabLeadingComponentVisible() && selRect.x > 0) { g.drawLine(x, y, selRect.x, y); } if (r.x > viewRect.x) { g.drawLine(x, y, selRect.x - 1, y); } if (_tabPane.isTabShown()) { if (r.x >= viewRect.x + viewRect.width) { g.drawLine(x, y, x + w - 1, y); } else { g.drawLine(selRect.x + selRect.width + _tabPane.getBoundsAt(selectedIndex).height - 9, y, x + w - 1, y); } } } else { super.paintContentBorderTopEdge(g, tabPlacement, selectedIndex, x, y, w, h); } } // paint the bottom line of the content when the tab is on the bottom @Override protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { if (!PAINT_CONTENT_BORDER_EDGE) { return; } if (selectedIndex < 0) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { Rectangle selRect = getTabBounds(selectedIndex, _calcRect); g.setColor(getPainter().getControlShadow()); Rectangle viewRect = _tabScroller.viewport.getViewRect(); Rectangle r = _rects[selectedIndex]; if (isTabLeadingComponentVisible() && selRect.x > 0) { g.drawLine(x, y + h - 1, selRect.x, y + h - 1); } // Break line to show visual connection to selected tab if (r.x > viewRect.x) { g.drawLine(x, y + h - 1, selRect.x - 1, y + h - 1); } if (_tabPane.isTabShown()) { if (r.x >= viewRect.x + viewRect.width) { g.drawLine(x, y + h - 1, x + w - 1, y + h - 1); } else { g.drawLine(selRect.x + selRect.width + _tabPane.getBoundsAt(selectedIndex).height - 9, y + h - 1, x + w - 1, y + h - 1); } } } else { super.paintContentBorderBottomEdge(g, tabPlacement, selectedIndex, x, y, w, h); } } // paint the left line of the content when the tab is on the left @Override protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { if (!PAINT_CONTENT_BORDER_EDGE) { return; } if (selectedIndex < 0) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { Rectangle selRect = getTabBounds(selectedIndex, _calcRect); Rectangle viewRect = _tabScroller.viewport.getViewRect(); Rectangle r = _rects[selectedIndex]; g.setColor(getPainter().getControlShadow()); if (isTabLeadingComponentVisible() && selRect.y > 0) { g.drawLine(x, y, x, selRect.y); } // Break line to show visual connection to selected tab if (r.y - 2 > viewRect.y) { g.drawLine(x, y, x, selRect.y - 3); } if (_tabPane.isTabShown()) { if (r.y >= viewRect.y + viewRect.height) { g.drawLine(x, y, x, y + h - 1); } else { g.drawLine(x, selRect.y + selRect.height + _tabPane.getBoundsAt(selectedIndex).width - 9, x, y + h - 1); } } } else { super.paintContentBorderLeftEdge(g, tabPlacement, selectedIndex, x, y, w, h); } } // paint the right line of the content when the tab is on the right @Override protected void paintContentBorderRightEdge(Graphics g, int tabPlacement, int selectedIndex, int x, int y, int w, int h) { if (!PAINT_CONTENT_BORDER_EDGE) { return; } if (selectedIndex < 0) { return; } if (getTabShape() == JideTabbedPane.SHAPE_ECLIPSE3X) { Rectangle selRect = getTabBounds(selectedIndex, _calcRect); Rectangle viewRect = _tabScroller.viewport.getViewRect(); Rectangle r = _rects[selectedIndex]; g.setColor(getPainter().getControlShadow()); if (isTabLeadingComponentVisible() && selRect.y > 0) { g.drawLine(x + w - 1, y, x + w - 1, selRect.y); } // Break line to show visual connection to selected tab if (r.y - 2 > viewRect.y) { g.drawLine(x + w - 1, y, x + w - 1, selRect.y - 3); } if (_tabPane.isTabShown()) { if (r.y >= viewRect.y + viewRect.height) { g.drawLine(x + w - 1, y, x + w - 1, y + h - 1); } else { g.drawLine(x + w - 1, selRect.y + selRect.height + _tabPane.getBoundsAt(selectedIndex).width - 9, x + w - 1, y + h - 1); } } } else { super.paintContentBorderRightEdge(g, tabPlacement, selectedIndex, x, y, w, h); } } @Override protected Rectangle getTabsTextBoundsAt(int tabIndex) { Rectangle tabRect = _tabPane.getBoundsAt(tabIndex); Rectangle iconRect = new Rectangle(), textRect = new Rectangle(); String title = _tabPane.getDisplayTitleAt(tabIndex); Icon icon = _tabPane.getIconForTab(tabIndex); SwingUtilities.layoutCompoundLabel(_tabPane, _tabPane.getGraphics() .getFontMetrics(_tabPane.getFont()), title, icon, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.CENTER, SwingUtilities.TRAILING, tabRect, iconRect, textRect, icon == null ? 0 : _textIconGap); if (_tabPane.getTabPlacement() == JideTabbedPane.TOP || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM) { iconRect.x = tabRect.x + _iconMarginHorizon; textRect.x = (icon != null ? iconRect.x + iconRect.width + _textIconGap : tabRect.x + _textPadding); } else { iconRect.y = tabRect.y + _iconMarginVertical; textRect.y = (icon != null ? iconRect.y + iconRect.height + _textIconGap : tabRect.y + _textPadding); iconRect.x = tabRect.x + 2; textRect.x = tabRect.x + 2; } return textRect; } @Override protected void paintFocusIndicator(Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, Rectangle iconRect, Rectangle textRect, boolean isSelected) { Rectangle tabRect = rects[tabIndex]; if (_tabPane.hasFocus() && isSelected) { int x, y, w, h; g.setColor(_focus); switch (tabPlacement) { case LEFT: x = tabRect.x + 2; y = tabRect.y + 3; w = tabRect.width - 4; h = tabRect.height - 19; break; case RIGHT: x = tabRect.x + 2; y = tabRect.y + 3; w = tabRect.width - 4; h = tabRect.height - 19; break; case BOTTOM: x = tabRect.x + 3; y = tabRect.y + 2; w = tabRect.width - 19; h = tabRect.height - 3; break; case TOP: default: x = tabRect.x + 3; y = tabRect.y + 2; w = tabRect.width - 19; h = tabRect.height - 3; } BasicGraphicsUtils.drawDashedRect(g, x, y, w, h); } } @Override protected TabCloseButton createNoFocusButton(int type) { return new Eclipse3xTabCloseButton(type); } public class Eclipse3xTabCloseButton extends TabCloseButton { public Eclipse3xTabCloseButton(int type) { super(type); } @Override public Dimension getPreferredSize() { return new Dimension(15, 15); } @Override protected void paintComponent(Graphics g) { if (!isEnabled()) { setMouseOver(false); setMousePressed(false); } g.setColor(UIDefaultsLookup.getColor("controlShadow").darker()); int centerX = getWidth() >> 1; int centerY = getHeight() >> 1; switch (getType()) { case CLOSE_BUTTON: g.drawLine(centerX - 4, centerY - 4, centerX - 2, centerY - 4); // top-left top g.drawLine(centerX - 4, centerY - 4, centerX - 4, centerY - 2); // top-left left g.drawLine(centerX - 1, centerY - 3, centerX - 0, centerY - 2); // top-left top-diag g.drawLine(centerX - 3, centerY - 1, centerX - 2, centerY - 0); // top-left left-diag g.drawLine(centerX + 3, centerY - 4, centerX + 5, centerY - 4); // top-right top g.drawLine(centerX + 5, centerY - 4, centerX + 5, centerY - 2); // top-right right g.drawLine(centerX + 2, centerY - 3, centerX + 1, centerY - 2); // top-right top-diag g.drawLine(centerX + 4, centerY - 1, centerX + 3, centerY - 0); // top-right right-diag g.drawLine(centerX - 4, centerY + 5, centerX - 2, centerY + 5); // bottom-left bottom g.drawLine(centerX - 4, centerY + 5, centerX - 4, centerY + 3); // bottom-left left g.drawLine(centerX - 1, centerY + 4, centerX - 0, centerY + 3); // bottom-left bottom-diag g.drawLine(centerX - 3, centerY + 2, centerX - 2, centerY + 1); // bottom-left left-diag g.drawLine(centerX + 3, centerY + 5, centerX + 5, centerY + 5); // bottom-right bottom g.drawLine(centerX + 5, centerY + 5, centerX + 5, centerY + 3); // bottom-right right g.drawLine(centerX + 2, centerY + 4, centerX + 1, centerY + 3); // bottom-right bottom-diag g.drawLine(centerX + 4, centerY + 2, centerX + 3, centerY + 1); // bottom-right right-diag if (isMouseOver()) { g.setColor(new Color(252, 160, 160)); } else { g.setColor(Color.WHITE); } g.drawLine(centerX - 2, centerY - 3, centerX + 4, centerY + 3); g.drawLine(centerX - 3, centerY - 3, centerX + 4, centerY + 4); g.drawLine(centerX - 3, centerY - 2, centerX + 3, centerY + 4); g.drawLine(centerX - 3, centerY + 3, centerX + 3, centerY - 3); g.drawLine(centerX - 3, centerY + 4, centerX + 4, centerY - 3); g.drawLine(centerX - 2, centerY + 4, centerX + 4, centerY - 2); break; default: super.paintComponent(g); } } } }