mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-27 03:46:17 -06:00
Merge pull request #306 from JFormDesigner/jidetabbedpane
JideTabbedPane improvements
This commit is contained in:
@@ -107,4 +107,22 @@ public class FlatJidePainter
|
||||
} else
|
||||
super.paintBackground( c, g, rect, borderColor, background, orientation );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paintGripper( JComponent c, Graphics g, Rectangle rect, int orientation, int state ) {
|
||||
float userScaleFactor = UIScale.getUserScaleFactor();
|
||||
if( userScaleFactor > 1 ) {
|
||||
// scale gripper
|
||||
Graphics2D g2 = (Graphics2D) g.create();
|
||||
try {
|
||||
g2.translate( rect.x, rect.y );
|
||||
g2.scale( userScaleFactor, userScaleFactor );
|
||||
Rectangle rect2 = new Rectangle( 0, 0, UIScale.unscale( rect.width ), UIScale.unscale( rect.height ) );
|
||||
super.paintGripper( c, g2, rect2, orientation, state );
|
||||
} finally {
|
||||
g2.dispose();
|
||||
}
|
||||
} else
|
||||
super.paintGripper( c, g, rect, orientation, state );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,15 +17,19 @@
|
||||
package com.formdev.flatlaf.jideoss.ui;
|
||||
|
||||
import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_HAS_FULL_BORDER;
|
||||
import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_SHOW_TAB_SEPARATORS;
|
||||
import static com.formdev.flatlaf.FlatClientProperties.clientPropertyBoolean;
|
||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
import java.awt.Container;
|
||||
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.LayoutManager;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.MouseListener;
|
||||
@@ -33,15 +37,20 @@ import java.awt.event.MouseMotionListener;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.icons.FlatTabbedPaneCloseIcon;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
import com.formdev.flatlaf.util.Graphics2DProxy;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
import com.jidesoft.plaf.LookAndFeelFactory;
|
||||
import com.jidesoft.plaf.UIDefaultsLookup;
|
||||
import com.jidesoft.plaf.basic.BasicJideTabbedPaneUI;
|
||||
import com.jidesoft.swing.JideTabbedPane;
|
||||
import com.jidesoft.swing.JideTabbedPane.NoFocusButton;
|
||||
|
||||
/**
|
||||
* Provides the Flat LaF UI delegate for {@link com.jidesoft.swing.JideTabbedPane}.
|
||||
@@ -51,18 +60,36 @@ import com.jidesoft.swing.JideTabbedPane;
|
||||
public class FlatJideTabbedPaneUI
|
||||
extends BasicJideTabbedPaneUI
|
||||
{
|
||||
protected Color foreground;
|
||||
protected Color disabledForeground;
|
||||
protected Color selectedBackground;
|
||||
protected Color underlineColor;
|
||||
protected Color disabledUnderlineColor;
|
||||
protected Color hoverColor;
|
||||
protected Color focusColor;
|
||||
protected Color tabSeparatorColor;
|
||||
protected Color contentAreaColor;
|
||||
|
||||
protected int tabHeight;
|
||||
protected int tabSelectionHeight;
|
||||
protected int contentSeparatorHeight;
|
||||
protected boolean showTabSeparators;
|
||||
protected boolean tabSeparatorsFullHeight;
|
||||
protected boolean hasFullBorder;
|
||||
protected boolean tabsOverlapBorder;
|
||||
|
||||
protected Icon closeIcon;
|
||||
protected Icon arrowIcon;
|
||||
|
||||
protected String arrowType;
|
||||
protected Insets buttonInsets;
|
||||
protected int buttonArc;
|
||||
protected Color buttonHoverBackground;
|
||||
protected Color buttonPressedBackground;
|
||||
|
||||
protected int closeButtonLeftMarginUnscaled;
|
||||
protected int closeButtonRightMarginUnscaled;
|
||||
|
||||
private Object[] oldRenderingHints;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
@@ -79,18 +106,33 @@ public class FlatJideTabbedPaneUI
|
||||
|
||||
_background = UIDefaultsLookup.getColor( "JideTabbedPane.background" );
|
||||
|
||||
foreground = UIManager.getColor( "TabbedPane.foreground" );
|
||||
disabledForeground = UIManager.getColor( "TabbedPane.disabledForeground" );
|
||||
selectedBackground = UIManager.getColor( "TabbedPane.selectedBackground" );
|
||||
underlineColor = UIManager.getColor( "TabbedPane.underlineColor" );
|
||||
disabledUnderlineColor = UIManager.getColor( "TabbedPane.disabledUnderlineColor" );
|
||||
hoverColor = UIManager.getColor( "TabbedPane.hoverColor" );
|
||||
focusColor = UIManager.getColor( "TabbedPane.focusColor" );
|
||||
tabSeparatorColor = UIManager.getColor( "TabbedPane.tabSeparatorColor" );
|
||||
contentAreaColor = UIManager.getColor( "TabbedPane.contentAreaColor" );
|
||||
|
||||
tabHeight = UIManager.getInt( "TabbedPane.tabHeight" );
|
||||
tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" );
|
||||
contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" );
|
||||
showTabSeparators = UIManager.getBoolean( "TabbedPane.showTabSeparators" );
|
||||
tabSeparatorsFullHeight = UIManager.getBoolean( "TabbedPane.tabSeparatorsFullHeight" );
|
||||
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
||||
tabsOverlapBorder = UIManager.getBoolean( "TabbedPane.tabsOverlapBorder" );
|
||||
|
||||
arrowType = UIManager.getString( "TabbedPane.arrowType" );
|
||||
buttonInsets = UIManager.getInsets( "TabbedPane.buttonInsets" );
|
||||
buttonArc = UIManager.getInt( "TabbedPane.buttonArc" );
|
||||
buttonHoverBackground = UIManager.getColor( "TabbedPane.buttonHoverBackground" );
|
||||
buttonPressedBackground = UIManager.getColor( "TabbedPane.buttonPressedBackground" );
|
||||
|
||||
closeButtonLeftMarginUnscaled = _closeButtonLeftMargin;
|
||||
closeButtonRightMarginUnscaled = _closeButtonRightMargin;
|
||||
|
||||
// scale
|
||||
_textIconGap = scale( _textIconGap );
|
||||
tabHeight = scale( tabHeight );
|
||||
@@ -101,11 +143,46 @@ public class FlatJideTabbedPaneUI
|
||||
protected void uninstallDefaults() {
|
||||
super.uninstallDefaults();
|
||||
|
||||
foreground = null;
|
||||
disabledForeground = null;
|
||||
selectedBackground = null;
|
||||
underlineColor = null;
|
||||
disabledUnderlineColor = null;
|
||||
hoverColor = null;
|
||||
focusColor = null;
|
||||
tabSeparatorColor = null;
|
||||
contentAreaColor = null;
|
||||
|
||||
buttonHoverBackground = null;
|
||||
buttonPressedBackground = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void installComponents() {
|
||||
super.installComponents();
|
||||
|
||||
closeIcon = new FlatJideTabCloseIcon();
|
||||
arrowIcon = new FlatJideTabAreaArrowIcon();
|
||||
|
||||
if( _tabScroller != null ) {
|
||||
_tabScroller.scrollForwardButton.setIcon( arrowIcon );
|
||||
_tabScroller.scrollBackwardButton.setIcon( arrowIcon );
|
||||
_tabScroller.listButton.setIcon( arrowIcon );
|
||||
_tabScroller.closeButton.setIcon( closeIcon );
|
||||
|
||||
_tabScroller.scrollForwardButton.setContentAreaFilled( false );
|
||||
_tabScroller.scrollBackwardButton.setContentAreaFilled( false );
|
||||
_tabScroller.listButton.setContentAreaFilled( false );
|
||||
_tabScroller.closeButton.setContentAreaFilled( false );
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallComponents() {
|
||||
super.uninstallComponents();
|
||||
|
||||
closeIcon = null;
|
||||
arrowIcon = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -114,13 +191,20 @@ public class FlatJideTabbedPaneUI
|
||||
return e -> {
|
||||
superListener.propertyChange( e );
|
||||
|
||||
String propertyName = e.getPropertyName();
|
||||
if( JideTabbedPane.PROPERTY_SELECTED_INDEX.equals( propertyName ) ) {
|
||||
repaintTab( (Integer) e.getOldValue() );
|
||||
repaintTab( (Integer) e.getNewValue() );
|
||||
} else if( FlatClientProperties.TABBED_PANE_HAS_FULL_BORDER.equals( propertyName ) ) {
|
||||
_tabPane.revalidate();
|
||||
_tabPane.repaint();
|
||||
switch( e.getPropertyName() ) {
|
||||
case JideTabbedPane.PROPERTY_SELECTED_INDEX:
|
||||
repaintTab( (Integer) e.getOldValue() );
|
||||
repaintTab( (Integer) e.getNewValue() );
|
||||
break;
|
||||
|
||||
case JideTabbedPane.PROPERTY_TAB_AREA_INSETS:
|
||||
case JideTabbedPane.PROPERTY_TAB_INSETS:
|
||||
case JideTabbedPane.GRIPPER_PROPERTY:
|
||||
case TABBED_PANE_SHOW_TAB_SEPARATORS:
|
||||
case TABBED_PANE_HAS_FULL_BORDER:
|
||||
_tabPane.revalidate();
|
||||
_tabPane.repaint();
|
||||
break;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -144,14 +228,23 @@ public class FlatJideTabbedPaneUI
|
||||
return new RolloverMouseMotionHandler();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected LayoutManager createLayoutManager() {
|
||||
return (_tabPane.getTabLayoutPolicy() == JideTabbedPane.SCROLL_TAB_LAYOUT)
|
||||
? new FlatJideTabbedPaneScrollLayout()
|
||||
: super.createLayoutManager();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateTabHeight( int tabPlacement, int tabIndex, FontMetrics metrics ) {
|
||||
updateCloseButtonMargins();
|
||||
return Math.max( tabHeight, super.calculateTabHeight( tabPlacement, tabIndex, metrics ) );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics metrics ) {
|
||||
return Math.max( tabHeight, super.calculateTabWidth( tabPlacement, tabIndex, metrics ) );
|
||||
updateCloseButtonMargins();
|
||||
return Math.max( tabHeight, super.calculateTabWidth( tabPlacement, tabIndex, metrics ) - 3 );
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -174,6 +267,26 @@ public class FlatJideTabbedPaneUI
|
||||
return JideTabbedPane.SHAPE_BOX;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLeftMargin() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTabGap() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getLayoutSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getTabRightPadding() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The content border insets are used to create a separator between tabs and content.
|
||||
* If client property JTabbedPane.hasFullBorder is true, then the content border insets
|
||||
@@ -226,7 +339,9 @@ public class FlatJideTabbedPaneUI
|
||||
? hoverColor
|
||||
: (enabled && isSelected && FlatUIUtils.isPermanentFocusOwner( _tabPane )
|
||||
? focusColor
|
||||
: _tabPane.getBackgroundAt( tabIndex )) );
|
||||
: (selectedBackground != null && enabled && isSelected
|
||||
? selectedBackground
|
||||
: _tabPane.getBackgroundAt( tabIndex ))) );
|
||||
g.fillRect( x, y, w, h );
|
||||
}
|
||||
|
||||
@@ -234,8 +349,38 @@ public class FlatJideTabbedPaneUI
|
||||
protected void paintText( Graphics g, int tabPlacement, Font font, FontMetrics metrics,
|
||||
int tabIndex, String title, Rectangle textRect, boolean isSelected )
|
||||
{
|
||||
if( !_tabPane.isEnabled() || !_tabPane.isEnabledAt( tabIndex ) ) {
|
||||
// super method paints disabled text twice with different colors
|
||||
// and one pixel offset to simulate disabled text
|
||||
// --> draw only once with disabledForeground
|
||||
class DisabledTextGraphics extends Graphics2DProxy {
|
||||
private int count;
|
||||
|
||||
public DisabledTextGraphics( Graphics delegate ) {
|
||||
super( (Graphics2D) delegate );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Graphics create() {
|
||||
return new DisabledTextGraphics( super.create() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void drawString( String str, int x, int y ) {
|
||||
count++;
|
||||
if( (count % 2) != 1 )
|
||||
return;
|
||||
|
||||
setColor( disabledForeground );
|
||||
super.drawString( str, x, y );
|
||||
}
|
||||
}
|
||||
g = new DisabledTextGraphics( g );
|
||||
}
|
||||
|
||||
Graphics g2 = g;
|
||||
FlatUIUtils.runWithoutRenderingHints( g, oldRenderingHints, () -> {
|
||||
super.paintText( g, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected );
|
||||
super.paintText( g2, tabPlacement, font, metrics, tabIndex, title, textRect, isSelected );
|
||||
} );
|
||||
}
|
||||
|
||||
@@ -243,11 +388,36 @@ public class FlatJideTabbedPaneUI
|
||||
protected void paintTabBorder( Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h,
|
||||
boolean isSelected )
|
||||
{
|
||||
// paint tab separators
|
||||
if( clientPropertyBoolean( _tabPane, TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators ) &&
|
||||
!isLastInRun( tabIndex ) )
|
||||
paintTabSeparator( g, tabPlacement, x, y, w, h );
|
||||
|
||||
if( isSelected )
|
||||
paintTabSelection( g, tabPlacement, x, y, w, h );
|
||||
}
|
||||
|
||||
protected void paintTabSeparator( Graphics g, int tabPlacement, int x, int y, int w, int h ) {
|
||||
float sepWidth = UIScale.scale( 1f );
|
||||
float offset = tabSeparatorsFullHeight ? 0 : UIScale.scale( 5f );
|
||||
|
||||
g.setColor( (tabSeparatorColor != null) ? tabSeparatorColor : contentAreaColor );
|
||||
if( tabPlacement == LEFT || tabPlacement == RIGHT ) {
|
||||
// paint tab separator at bottom side
|
||||
((Graphics2D)g).fill( new Rectangle2D.Float( x + offset, y + h - sepWidth, w - (offset * 2), sepWidth ) );
|
||||
} else if( _tabPane.getComponentOrientation().isLeftToRight() ) {
|
||||
// paint tab separator at right side
|
||||
((Graphics2D)g).fill( new Rectangle2D.Float( x + w - sepWidth, y + offset, sepWidth, h - (offset * 2) ) );
|
||||
} else {
|
||||
// paint tab separator at left side
|
||||
((Graphics2D)g).fill( new Rectangle2D.Float( x, y + offset, sepWidth, h - (offset * 2) ) );
|
||||
}
|
||||
}
|
||||
|
||||
protected void paintTabSelection( Graphics g, int tabPlacement, int x, int y, int w, int h ) {
|
||||
if( !_tabPane.isTabShown() )
|
||||
return;
|
||||
|
||||
// increase clip bounds in scroll-tab-layout to paint over the separator line
|
||||
Rectangle clipBounds = scrollableTabLayoutEnabled() ? g.getClipBounds() : null;
|
||||
if( clipBounds != null ) {
|
||||
@@ -313,7 +483,7 @@ public class FlatJideTabbedPaneUI
|
||||
*/
|
||||
@Override
|
||||
protected void paintContentBorder( Graphics g, int tabPlacement, int selectedIndex ) {
|
||||
if( _tabPane.getTabCount() <= 0 )
|
||||
if( !_tabPane.isTabShown() )
|
||||
return;
|
||||
|
||||
Insets insets = _tabPane.getInsets();
|
||||
@@ -386,4 +556,354 @@ public class FlatJideTabbedPaneUI
|
||||
Rectangle iconRect, Rectangle textRect, boolean isSelected )
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void layoutLabel( int tabPlacement, FontMetrics metrics, int tabIndex, String title, Icon icon,
|
||||
Rectangle tabRect, Rectangle iconRect, Rectangle textRect, boolean isSelected )
|
||||
{
|
||||
if( tabPlacement == LEFT || tabPlacement == RIGHT ) {
|
||||
Rectangle tabRect2 = new Rectangle( 0, 0, tabRect.height, tabRect.width );
|
||||
Rectangle iconRect2 = new Rectangle();
|
||||
Rectangle textRect2 = new Rectangle();
|
||||
|
||||
super.layoutLabel( TOP, metrics, tabIndex, title, icon, tabRect2, iconRect2, textRect2, isSelected );
|
||||
|
||||
textRect.x = tabRect.x + textRect2.y;
|
||||
textRect.y = tabRect.y + textRect2.x;
|
||||
textRect.width = textRect2.height;
|
||||
textRect.height = textRect2.width;
|
||||
|
||||
if( tabPlacement == LEFT )
|
||||
textRect.y += metrics.getHeight() / 2;
|
||||
|
||||
iconRect.x = tabRect.x + iconRect2.y;
|
||||
iconRect.y = tabRect.y + iconRect2.x;
|
||||
iconRect.width = iconRect2.height;
|
||||
iconRect.height = iconRect2.width;
|
||||
} else
|
||||
super.layoutLabel( tabPlacement, metrics, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Rectangle getTabsTextBoundsAt( int tabIndex ) {
|
||||
Rectangle rect = super.getTabsTextBoundsAt( tabIndex );
|
||||
rect.x += getTabInsets( _tabPane.getTabPlacement(), tabIndex ).left;
|
||||
return rect;
|
||||
}
|
||||
|
||||
private boolean isLastInRun( int tabIndex ) {
|
||||
int run = getRunForTab( _tabPane.getTabCount(), tabIndex );
|
||||
return lastTabInRun( _tabPane.getTabCount(), run ) == tabIndex;
|
||||
}
|
||||
|
||||
private boolean isLeftToRight() {
|
||||
return _tabPane.getComponentOrientation().isLeftToRight();
|
||||
}
|
||||
|
||||
private boolean isHorizontalTabPlacement() {
|
||||
int tabPlacement = _tabPane.getTabPlacement();
|
||||
return tabPlacement == TOP || tabPlacement == BOTTOM;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void ensureCurrentRects( int leftMargin, int tabCount ) {
|
||||
int oldFitStyleBoundSize = _fitStyleBoundSize;
|
||||
int oldFitStyleFirstTabMargin = _fitStyleFirstTabMargin;
|
||||
int oldCompressedStyleNoIconRectSize = _compressedStyleNoIconRectSize;
|
||||
int oldCompressedStyleIconMargin = _compressedStyleIconMargin;
|
||||
int oldFixedStyleRectSize = _fixedStyleRectSize;
|
||||
|
||||
_fitStyleBoundSize = scale( _fitStyleBoundSize );
|
||||
_fitStyleFirstTabMargin = scale( _fitStyleFirstTabMargin );
|
||||
_compressedStyleNoIconRectSize = scale( _compressedStyleNoIconRectSize );
|
||||
_compressedStyleIconMargin = scale( _compressedStyleIconMargin );
|
||||
_fixedStyleRectSize = scale( _fixedStyleRectSize );
|
||||
|
||||
super.ensureCurrentRects( leftMargin, tabCount );
|
||||
|
||||
_fitStyleBoundSize = oldFitStyleBoundSize;
|
||||
_fitStyleFirstTabMargin = oldFitStyleFirstTabMargin;
|
||||
_compressedStyleNoIconRectSize = oldCompressedStyleNoIconRectSize;
|
||||
_compressedStyleIconMargin = oldCompressedStyleIconMargin;
|
||||
_fixedStyleRectSize = oldFixedStyleRectSize;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void ensureCloseButtonCreated() {
|
||||
super.ensureCloseButtonCreated();
|
||||
|
||||
if( _closeButtons == null )
|
||||
return;
|
||||
|
||||
// make sure that close buttons use our icon and do not fill background
|
||||
for( JButton closeButton : _closeButtons ) {
|
||||
if( closeButton.getIcon() != closeIcon )
|
||||
closeButton.setIcon( closeIcon );
|
||||
if( closeButton.isContentAreaFilled() )
|
||||
closeButton.setContentAreaFilled( false );
|
||||
}
|
||||
}
|
||||
|
||||
protected void updateCloseButtonMargins() {
|
||||
// scale close button margins
|
||||
_closeButtonLeftMargin = scale( closeButtonLeftMarginUnscaled );
|
||||
_closeButtonRightMargin = scale( closeButtonRightMarginUnscaled );
|
||||
|
||||
// since close button size is hardcoded to 16x16 in NoFocusButton.getPreferredSize(),
|
||||
// add difference between scaled and unscaled close button size to margins
|
||||
int offset = (closeIcon.getIconWidth() - 16) / 2;
|
||||
_closeButtonLeftMargin += offset;
|
||||
_closeButtonRightMargin += offset;
|
||||
}
|
||||
|
||||
//---- class FlatJideTabbedPaneScrollLayout -------------------------------
|
||||
|
||||
protected class FlatJideTabbedPaneScrollLayout
|
||||
extends TabbedPaneScrollLayout
|
||||
{
|
||||
@Override
|
||||
public void layoutContainer( Container parent ) {
|
||||
updateCloseButtonMargins();
|
||||
|
||||
super.layoutContainer( parent );
|
||||
|
||||
updateCloseButtons();
|
||||
updateArrowButtons();
|
||||
}
|
||||
|
||||
private void updateCloseButtons() {
|
||||
if( !scrollableTabLayoutEnabled() || !isShowCloseButton() || !isShowCloseButtonOnTab() )
|
||||
return;
|
||||
|
||||
Color background = _tabPane.getBackground();
|
||||
|
||||
for( int i = 0; i < _closeButtons.length; i++ ) {
|
||||
JButton closeButton = _closeButtons[i];
|
||||
if( closeButton.getWidth() == 0 || closeButton.getHeight() == 0 )
|
||||
continue; // not visible
|
||||
|
||||
closeButton.setBounds( getTabCloseBounds( i ) );
|
||||
closeButton.setBackground( background );
|
||||
}
|
||||
}
|
||||
|
||||
private Rectangle getTabCloseBounds( int tabIndex ) {
|
||||
int iconWidth = closeIcon.getIconWidth();
|
||||
int iconHeight = closeIcon.getIconHeight();
|
||||
Rectangle tabRect = _rects[tabIndex];
|
||||
Insets tabInsets = getTabInsets( _tabPane.getTabPlacement(), tabIndex );
|
||||
|
||||
// use one-third of right/left tab insets as gap between tab text and close button
|
||||
if( _tabPane.getTabPlacement() == JideTabbedPane.TOP || _tabPane.getTabPlacement() == JideTabbedPane.BOTTOM ) {
|
||||
return new Rectangle(
|
||||
_tabPane.getComponentOrientation().isLeftToRight()
|
||||
? (tabRect.x + tabRect.width - (tabInsets.right / 3 * 2) - iconWidth)
|
||||
: (tabRect.x + (tabInsets.left / 3 * 2)),
|
||||
tabRect.y + (tabRect.height - iconHeight) / 2,
|
||||
iconWidth,
|
||||
iconHeight );
|
||||
} else {
|
||||
return new Rectangle(
|
||||
tabRect.x + (tabRect.width - iconWidth) / 2,
|
||||
tabRect.y + tabRect.height - (tabInsets.bottom / 3 * 2) - iconHeight,
|
||||
iconWidth,
|
||||
iconHeight );
|
||||
}
|
||||
}
|
||||
|
||||
private void updateArrowButtons() {
|
||||
if( !scrollableTabLayoutEnabled() || !_tabPane.isTabShown() )
|
||||
return;
|
||||
|
||||
Insets insets = _tabPane.getInsets();
|
||||
int tabPlacement = _tabPane.getTabPlacement();
|
||||
Insets tabAreaInsets = getTabAreaInsets( tabPlacement );
|
||||
Dimension tsize = isTabTrailingComponentVisible() ? _tabTrailingComponent.getSize() : new Dimension();
|
||||
|
||||
if( tabPlacement == TOP || tabPlacement == BOTTOM ) {
|
||||
// for BOTTOM tab placement, _maxTabHeight is not correct if having tall leading/trailing component
|
||||
int maxTabHeight = (tabPlacement == BOTTOM)
|
||||
? calculateMaxTabHeight( tabPlacement )
|
||||
: _maxTabHeight;
|
||||
|
||||
// button bounds
|
||||
boolean leftToRight = isLeftToRight();
|
||||
int x = leftToRight
|
||||
? _tabPane.getWidth() - insets.right - tsize.width
|
||||
: insets.left + tsize.width;
|
||||
int y = _tabScroller.viewport.getY();
|
||||
int h = maxTabHeight;
|
||||
if( tabPlacement == TOP ) {
|
||||
// if leading or trailing component is taller than tab area then
|
||||
// _tabScroller.viewport has same height as leading/trailing component
|
||||
// but tabs are painted smaller
|
||||
y += (_tabScroller.viewport.getHeight() - h - tabAreaInsets.bottom);
|
||||
} else
|
||||
y += tabAreaInsets.top;
|
||||
|
||||
// layout buttons
|
||||
if( !isShowCloseButtonOnTab() )
|
||||
x = layoutButtonHorizontal( _tabScroller.closeButton, 16, x, y, h, leftToRight );
|
||||
x = layoutButtonHorizontal( _tabScroller.listButton, 24, x, y, h, leftToRight );
|
||||
x = layoutButtonHorizontal( _tabScroller.scrollForwardButton, 16, x, y, h, leftToRight );
|
||||
x = layoutButtonHorizontal( _tabScroller.scrollBackwardButton, 16, x, y, h, leftToRight );
|
||||
|
||||
// layout tab area
|
||||
Rectangle r = _tabScroller.viewport.getBounds();
|
||||
if( leftToRight )
|
||||
_tabScroller.viewport.setSize( x - r.x, r.height );
|
||||
else
|
||||
_tabScroller.viewport.setBounds( x, r.y, r.width - (x - r.x), r.height );
|
||||
|
||||
} else { // LEFT and RIGHT tab placement
|
||||
// for RIGHT tab placement, _maxTabWidth is not correct if having wide leading/trailing component
|
||||
int maxTabWidth = (tabPlacement == RIGHT)
|
||||
? calculateMaxTabWidth( tabPlacement )
|
||||
: _maxTabWidth;
|
||||
|
||||
// button bounds
|
||||
int x = _tabScroller.viewport.getX();
|
||||
int y = _tabPane.getHeight() - insets.bottom - tsize.height;
|
||||
int w = maxTabWidth;
|
||||
if( tabPlacement == LEFT ) {
|
||||
// if leading or trailing component is wider than tab area then
|
||||
// _tabScroller.viewport has same width as leading/trailing component
|
||||
// but tabs are painted smaller
|
||||
x += (_tabScroller.viewport.getWidth() - w - tabAreaInsets.right);
|
||||
} else
|
||||
x += tabAreaInsets.left;
|
||||
|
||||
// layout buttons
|
||||
if( !isShowCloseButtonOnTab() )
|
||||
y = layoutButtonVertical( _tabScroller.closeButton, 16, x, y, w );
|
||||
y = layoutButtonVertical( _tabScroller.listButton, 24, x, y, w );
|
||||
y = layoutButtonVertical( _tabScroller.scrollForwardButton, 16, x, y, w );
|
||||
y = layoutButtonVertical( _tabScroller.scrollBackwardButton, 16, x, y, w );
|
||||
|
||||
// layout tab area
|
||||
Rectangle r = _tabScroller.viewport.getBounds();
|
||||
_tabScroller.viewport.setSize( r.width, y - r.y );
|
||||
}
|
||||
}
|
||||
|
||||
private int layoutButtonHorizontal( JButton button, int wu, int x, int y, int h, boolean leftToRight ) {
|
||||
if( button.isVisible() ) {
|
||||
int w = scale( wu );
|
||||
if( leftToRight )
|
||||
x -= w;
|
||||
button.setBounds( x, y, w, h );
|
||||
if( !leftToRight )
|
||||
x += w;
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
private int layoutButtonVertical( JButton button, int hu, int x, int y, int w ) {
|
||||
if( button.isVisible() ) {
|
||||
int h = scale( hu );
|
||||
y -= h;
|
||||
button.setBounds( x, y, w, h );
|
||||
}
|
||||
return y;
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatJideTabCloseIcon -----------------------------------------
|
||||
|
||||
protected class FlatJideTabCloseIcon
|
||||
extends FlatTabbedPaneCloseIcon
|
||||
{
|
||||
@Override
|
||||
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||
NoFocusButton button = (NoFocusButton) c;
|
||||
|
||||
if( _tabPane.isShowCloseButtonOnMouseOver() && !button.isMouseOver() ) {
|
||||
Object property = _tabPane.getClientProperty( "JideTabbedPane.mouseOverTabIndex" );
|
||||
if( property instanceof Integer && button.getIndex() >= 0 && (Integer) property != button.getIndex() )
|
||||
return;
|
||||
}
|
||||
|
||||
super.paintIcon( c, g, x, y );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class FlatJideTabAreaArrowIcon -------------------------------------
|
||||
|
||||
protected class FlatJideTabAreaArrowIcon
|
||||
implements Icon
|
||||
{
|
||||
@Override
|
||||
public void paintIcon( Component c, Graphics g, int x, int y ) {
|
||||
NoFocusButton button = (NoFocusButton) c;
|
||||
|
||||
Object[] oldRenderingHints = FlatUIUtils.setRenderingHints( g );
|
||||
|
||||
// paint hover or pressed background
|
||||
if( button.isEnabled() ) {
|
||||
Color background = (buttonPressedBackground != null && button.isMousePressed())
|
||||
? buttonPressedBackground
|
||||
: (buttonHoverBackground != null && button.isMouseOver()
|
||||
? buttonHoverBackground
|
||||
: null);
|
||||
|
||||
if( background != null ) {
|
||||
// rotate button insets
|
||||
Insets insets = new Insets( 0, 0, 0, 0 );
|
||||
rotateInsets( buttonInsets, insets, _tabPane.getTabPlacement() );
|
||||
|
||||
// fill background
|
||||
g.setColor( FlatUIUtils.deriveColor( background, _tabPane.getBackground() ) );
|
||||
FlatUIUtils.paintComponentBackground( (Graphics2D) g,
|
||||
insets.left, insets.top,
|
||||
button.getWidth() - insets.left - insets.right,
|
||||
button.getHeight() - insets.top - insets.bottom,
|
||||
0, scale( (float) buttonArc ) );
|
||||
}
|
||||
}
|
||||
|
||||
// arrow direction
|
||||
int direction = -1;
|
||||
switch( button.getType() ) {
|
||||
case JideTabbedPane.BUTTON_WEST:
|
||||
direction = isHorizontalTabPlacement()
|
||||
? (isLeftToRight() ? WEST : EAST)
|
||||
: NORTH;
|
||||
break;
|
||||
|
||||
case JideTabbedPane.BUTTON_EAST:
|
||||
direction = isHorizontalTabPlacement()
|
||||
? (isLeftToRight() ? EAST : WEST)
|
||||
: SOUTH;
|
||||
break;
|
||||
|
||||
case JideTabbedPane.BUTTON_LIST:
|
||||
switch( _tabPane.getTabPlacement() ) {
|
||||
default:
|
||||
case TOP: direction = SOUTH; break;
|
||||
case BOTTOM: direction = NORTH; break;
|
||||
case LEFT: direction = EAST; break;
|
||||
case RIGHT: direction = WEST; break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// paint arrow
|
||||
g.setColor( button.isEnabled() ? foreground : disabledForeground );
|
||||
FlatUIUtils.paintArrow( (Graphics2D) g,
|
||||
0, 0, button.getWidth(), button.getHeight(),
|
||||
direction, FlatUIUtils.isChevron( arrowType ), 10, 0, 0 );
|
||||
|
||||
FlatUIUtils.resetRenderingHints( g, oldRenderingHints );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconWidth() {
|
||||
return scale( 16 );
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getIconHeight() {
|
||||
return scale( 16 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,3 +81,8 @@ JideTabbedPane.tabAreaInsets = $TabbedPane.tabAreaInsets
|
||||
JideTabbedPane.contentBorderInsets = 0,0,0,0
|
||||
JideTabbedPane.tabRunOverlay = $TabbedPane.tabRunOverlay
|
||||
JideTabbedPane.shadow = $TabbedPane.shadow
|
||||
|
||||
JideTabbedPane.closeButtonLeftMargin = 0
|
||||
JideTabbedPane.closeButtonRightMargin = 0
|
||||
JideTabbedPane.fitStyleBoundSize = {integer}0
|
||||
JideTabbedPane.fitStyleFirstTabMargin = 0
|
||||
|
||||
Reference in New Issue
Block a user