📄 visualstudio2005tabbedpaneui.java
字号:
/* ====================================================================
*
* Office Look and Feels License
* http://sourceforge.net/projects/officelnfs
*
* Copyright (c) 2003-2005 Robert Futrell. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* 3. The names "Office Look And Feels" and "OfficeLnFs" must not
* be used to endorse or promote products derived from this software
* without prior written permission. For written permission, please
* contact robert_futrell@users.sourceforge.net.
*
* 4. Products derived from this software may not be called "OfficeLnFs"
* nor may "OfficeLnFs" appear in their names without prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
* ====================================================================
*/
package org.fife.plaf.VisualStudio2005;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JTabbedPane;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import javax.swing.text.StyleContext;
import javax.swing.text.View;
/**
* The UI for tabbed panes.
*
* @author Robert Futrell
* @version 1.0
*/
public class VisualStudio2005TabbedPaneUI extends BasicTabbedPaneUI {
private boolean oldFocusable;
private static final int TAB_HEIGHT = 16;
private static final int INSETS_LEFT = 3+8;
private static final int INSETS_RIGHT = 3;
protected int calculateTabHeight(int tabPlacement, int tabIndex,
int fontHeight) {
return TAB_HEIGHT;
}
protected int calculateTabWidth(int tabPlacement, int tabIndex,
FontMetrics metrics) {
// Ensure we use the font metrics for the bold font used for the
// selected tab; this ensures that tabs don't "grow" when they are
// selected to accomodate the bold font.
metrics = tabPane.getFontMetrics(getBoldFont(tabPane.getFont()));
int width = super.calculateTabWidth(tabPlacement, tabIndex, metrics);
return width;
}
/**
* Returns the UI to use for the specified tabbed pane.
*
* @param c The tabbed pane.
* @return The UI.
*/
public static ComponentUI createUI(JComponent c){
return new VisualStudio2005TabbedPaneUI();
}
/**
* WORKAROUND for Sun JRE bug 6282887: calling Font.deriveFont(style) to
* get a bold/italic Japanese (Asian?) font instead returns a font that
* prints squares for all (non-ASCII) characters. This is fixed in
* 1.5.0-b45, but since we run on 1.4+, we'll keep this workaround.
*
* @param font The non-bold font.
* @return A bold version of the font.
*/
protected static Font getBoldFont(Font font) {
//return font.deriveFont(Font.BOLD);
StyleContext sc = StyleContext.getDefaultStyleContext();
return sc.getFont(font.getFamily(), Font.BOLD, font.getSize());
}
/**
* This method is overridden because, as of 1.5, the layout manager used by
* <code>BasicTabbedPaneUI</code> for the wrapped tab layout uses a "fast"
* method of calculating the minimum width needed for the tabbed pane,
* which is evidently incompatible with this UI (probably since we
* change the font to be bold when calculating tab widths). So we have to
* do this ourselves.
*
* @param c The tabbed pane.
* @return The minimum size of the tabbed pane.
*/
public Dimension getMinimumSize(JComponent c) {
Dimension d = super.getMinimumSize(c);
if (d==null && tabPane.
getTabLayoutPolicy()==JTabbedPane.WRAP_TAB_LAYOUT)
{
int tabPlacement = tabPane.getTabPlacement();
d = new Dimension(calculateMaxTabWidth(tabPlacement),
calculateMaxTabHeight(tabPlacement));
d.width += tabAreaInsets.left + tabAreaInsets.right;
}
return d;
}
protected int getTabLabelShiftX(int tabPlacement, int tabIndex,
boolean isSelected) {
switch (tabPlacement) {
case SwingConstants.TOP:
case SwingConstants.BOTTOM:
return 0;
default: // LEFT or RIGHT
return 8; // Just to get out of the curved part.
}
}
protected int getTabLabelShiftY(int tabPlacement, int tabIndex,
boolean isSelected) {
// For some reason we need to shift the text up when the tabs are
// at the bottom.
return tabPlacement==SwingConstants.BOTTOM ? -1 : 0;
}
/**
* Overridden to ensure the selected tab does not get "padded" to appear
* larger.
*/
protected void installDefaults() {
super.installDefaults();
contentBorderInsets = new Insets(1,1,1,1);
selectedTabPadInsets = new Insets(0,0,0,0);
tabAreaInsets = new Insets(2,INSETS_LEFT,0,INSETS_RIGHT);
oldFocusable = tabPane.isFocusable();
tabPane.setFocusable(false);
}
protected void layoutLabel(int tabPlacement,
FontMetrics metrics, int tabIndex,
String title, Icon icon,
Rectangle tabRect, Rectangle iconRect,
Rectangle textRect, boolean isSelected ) {
// Use a bold font for the selected tab.
if (tabIndex==tabPane.getSelectedIndex()) {
metrics = tabPane.getFontMetrics(getBoldFont(tabPane.getFont()));
}
textRect.x = textRect.y = iconRect.x = iconRect.y = 0;
View v = getTextViewForTab(tabIndex);
if (v != null)
tabPane.putClientProperty("html", v);
int horizontalAlignment = (tabPlacement==SwingUtilities.TOP ||
tabPlacement==SwingUtilities.BOTTOM) ?
SwingUtilities.CENTER : // Top or bottom.
SwingUtilities.LEFT; // Left or right.
SwingUtilities.layoutCompoundLabel((JComponent) tabPane,
metrics, title, icon,
SwingUtilities.CENTER,
horizontalAlignment,
SwingUtilities.CENTER,//LEFT,
SwingUtilities.TRAILING,
tabRect,
iconRect,
textRect,
textIconGap);
tabPane.putClientProperty("html", null);
int xNudge = getTabLabelShiftX(tabPlacement, tabIndex, isSelected);
int yNudge = getTabLabelShiftY(tabPlacement, tabIndex, isSelected);
iconRect.x += xNudge;
iconRect.y += yNudge;
textRect.x += xNudge;
textRect.y += yNudge;
}
/**
* Paints the bottom part of the border surrounding the content.
*/
protected void paintContentBorderBottomEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
g.setColor(UIManager.getColor("VisualStudio2005.TabBorderColor"));
y += h - 1;
if (tabPlacement!=SwingConstants.BOTTOM || selectedIndex==-1) {
g.drawLine(x+1,y, x+w-1,y);
}
else {
// The selected tab is always in the "bottommost" run, so we
// don't need to check what run the tab is in.
Rectangle tabBounds = new Rectangle();
tabBounds = getTabBounds(selectedIndex, tabBounds);
// "Offset" the bounds since our tabs "overlap."
tabBounds.x -= 9;
tabBounds.width += 8;
g.drawLine(x,y,tabBounds.x-1,y);
g.drawLine(tabBounds.x+tabBounds.width,y, x+w-1,y);
g.setColor(java.awt.Color.WHITE);
g.drawLine(tabBounds.x,y, tabBounds.x+tabBounds.width-1,y);
}
}
/**
* Paints the left part of the border surrounding the content.
*/
protected void paintContentBorderLeftEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
}
/**
* Paints the right part of the border surrounding the content.
*/
protected void paintContentBorderRightEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
}
/**
* Paints the top part of the border surrounding the content.
*/
protected void paintContentBorderTopEdge(Graphics g, int tabPlacement,
int selectedIndex, int x, int y, int w, int h) {
g.setColor(UIManager.getColor("VisualStudio2005.TabBorderColor"));
if (tabPlacement!=SwingConstants.TOP || selectedIndex==-1) {
g.drawLine(x+1,y, x+w-1,y);
}
else {
// The selected tab is always in the "bottommost" run, so we
// don't need to check what run the tab is in.
Rectangle tabBounds = new Rectangle();
tabBounds = getTabBounds(selectedIndex, tabBounds);
// "Offset" the bounds since our tabs "overlap."
tabBounds.x -= 9;
tabBounds.width += 8;
g.drawLine(x,y,tabBounds.x-1,y);
g.drawLine(tabBounds.x+tabBounds.width,y, x+w-1,y);
g.setColor(java.awt.Color.WHITE);
g.drawLine(tabBounds.x,y, tabBounds.x+tabBounds.width-1,y);
}
}
/**
* Paints the "tab area" and the tabs inside it.
*/
protected void paintTabArea(Graphics g, int tabPlacement, int selectedIndex) {
int tabCount = tabPane.getTabCount();
Rectangle iconRect = new Rectangle();
Rectangle textRect = new Rectangle();
Rectangle clipRect = g.getClipBounds();
Graphics2D g2d = (Graphics2D)g;
AffineTransform oldTransform = g2d.getTransform();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -