mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-07 14:30:56 +03:00
JIDE: JideTabbedPane:
- use `FlatTabbedPaneCloseIcon` for tab close buttons - scale close buttons - fix close buttons location
This commit is contained in:
@@ -21,12 +21,15 @@ import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_SHOW_TAB_SEPA
|
|||||||
import static com.formdev.flatlaf.FlatClientProperties.clientPropertyBoolean;
|
import static com.formdev.flatlaf.FlatClientProperties.clientPropertyBoolean;
|
||||||
import static com.formdev.flatlaf.util.UIScale.scale;
|
import static com.formdev.flatlaf.util.UIScale.scale;
|
||||||
import java.awt.Color;
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.Container;
|
||||||
import java.awt.Dimension;
|
import java.awt.Dimension;
|
||||||
import java.awt.Font;
|
import java.awt.Font;
|
||||||
import java.awt.FontMetrics;
|
import java.awt.FontMetrics;
|
||||||
import java.awt.Graphics;
|
import java.awt.Graphics;
|
||||||
import java.awt.Graphics2D;
|
import java.awt.Graphics2D;
|
||||||
import java.awt.Insets;
|
import java.awt.Insets;
|
||||||
|
import java.awt.LayoutManager;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
@@ -34,15 +37,19 @@ import java.awt.event.MouseMotionListener;
|
|||||||
import java.awt.geom.Path2D;
|
import java.awt.geom.Path2D;
|
||||||
import java.awt.geom.Rectangle2D;
|
import java.awt.geom.Rectangle2D;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
|
import javax.swing.Icon;
|
||||||
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
import javax.swing.plaf.ComponentUI;
|
import javax.swing.plaf.ComponentUI;
|
||||||
|
import com.formdev.flatlaf.icons.FlatTabbedPaneCloseIcon;
|
||||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
import com.jidesoft.plaf.LookAndFeelFactory;
|
import com.jidesoft.plaf.LookAndFeelFactory;
|
||||||
import com.jidesoft.plaf.UIDefaultsLookup;
|
import com.jidesoft.plaf.UIDefaultsLookup;
|
||||||
import com.jidesoft.plaf.basic.BasicJideTabbedPaneUI;
|
import com.jidesoft.plaf.basic.BasicJideTabbedPaneUI;
|
||||||
import com.jidesoft.swing.JideTabbedPane;
|
import com.jidesoft.swing.JideTabbedPane;
|
||||||
|
import com.jidesoft.swing.JideTabbedPane.NoFocusButton;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the Flat LaF UI delegate for {@link com.jidesoft.swing.JideTabbedPane}.
|
* Provides the Flat LaF UI delegate for {@link com.jidesoft.swing.JideTabbedPane}.
|
||||||
@@ -68,6 +75,11 @@ public class FlatJideTabbedPaneUI
|
|||||||
protected boolean hasFullBorder;
|
protected boolean hasFullBorder;
|
||||||
protected boolean tabsOverlapBorder;
|
protected boolean tabsOverlapBorder;
|
||||||
|
|
||||||
|
protected Icon closeIcon;
|
||||||
|
|
||||||
|
protected int closeButtonLeftMarginUnscaled;
|
||||||
|
protected int closeButtonRightMarginUnscaled;
|
||||||
|
|
||||||
private Object[] oldRenderingHints;
|
private Object[] oldRenderingHints;
|
||||||
|
|
||||||
public static ComponentUI createUI( JComponent c ) {
|
public static ComponentUI createUI( JComponent c ) {
|
||||||
@@ -100,6 +112,11 @@ public class FlatJideTabbedPaneUI
|
|||||||
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
||||||
tabsOverlapBorder = UIManager.getBoolean( "TabbedPane.tabsOverlapBorder" );
|
tabsOverlapBorder = UIManager.getBoolean( "TabbedPane.tabsOverlapBorder" );
|
||||||
|
|
||||||
|
closeIcon = new FlatJideTabCloseIcon();
|
||||||
|
|
||||||
|
closeButtonLeftMarginUnscaled = _closeButtonLeftMargin;
|
||||||
|
closeButtonRightMarginUnscaled = _closeButtonRightMargin;
|
||||||
|
|
||||||
// scale
|
// scale
|
||||||
_textIconGap = scale( _textIconGap );
|
_textIconGap = scale( _textIconGap );
|
||||||
tabHeight = scale( tabHeight );
|
tabHeight = scale( tabHeight );
|
||||||
@@ -117,6 +134,7 @@ public class FlatJideTabbedPaneUI
|
|||||||
focusColor = null;
|
focusColor = null;
|
||||||
tabSeparatorColor = null;
|
tabSeparatorColor = null;
|
||||||
contentAreaColor = null;
|
contentAreaColor = null;
|
||||||
|
closeIcon = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -159,14 +177,23 @@ public class FlatJideTabbedPaneUI
|
|||||||
return new RolloverMouseMotionHandler();
|
return new RolloverMouseMotionHandler();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected LayoutManager createLayoutManager() {
|
||||||
|
return (_tabPane.getTabLayoutPolicy() == JideTabbedPane.SCROLL_TAB_LAYOUT)
|
||||||
|
? new FlatJideTabbedPaneScrollLayout()
|
||||||
|
: super.createLayoutManager();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int calculateTabHeight( int tabPlacement, int tabIndex, FontMetrics metrics ) {
|
protected int calculateTabHeight( int tabPlacement, int tabIndex, FontMetrics metrics ) {
|
||||||
|
updateCloseButtonMargins();
|
||||||
return Math.max( tabHeight, super.calculateTabHeight( tabPlacement, tabIndex, metrics ) );
|
return Math.max( tabHeight, super.calculateTabHeight( tabPlacement, tabIndex, metrics ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics metrics ) {
|
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
|
@Override
|
||||||
@@ -189,6 +216,26 @@ public class FlatJideTabbedPaneUI
|
|||||||
return JideTabbedPane.SHAPE_BOX;
|
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.
|
* 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
|
* If client property JTabbedPane.hasFullBorder is true, then the content border insets
|
||||||
@@ -430,4 +477,103 @@ public class FlatJideTabbedPaneUI
|
|||||||
int run = getRunForTab( _tabPane.getTabCount(), tabIndex );
|
int run = getRunForTab( _tabPane.getTabCount(), tabIndex );
|
||||||
return lastTabInRun( _tabPane.getTabCount(), run ) == tabIndex;
|
return lastTabInRun( _tabPane.getTabCount(), run ) == tabIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateCloseButtons() {
|
||||||
|
if( !scrollableTabLayoutEnabled() || !isShowCloseButton() || !isShowCloseButtonOnTab() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
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 ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//---- class FlatJideTabAreaArrowIcon -------------------------------------
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -81,3 +81,6 @@ JideTabbedPane.tabAreaInsets = $TabbedPane.tabAreaInsets
|
|||||||
JideTabbedPane.contentBorderInsets = 0,0,0,0
|
JideTabbedPane.contentBorderInsets = 0,0,0,0
|
||||||
JideTabbedPane.tabRunOverlay = $TabbedPane.tabRunOverlay
|
JideTabbedPane.tabRunOverlay = $TabbedPane.tabRunOverlay
|
||||||
JideTabbedPane.shadow = $TabbedPane.shadow
|
JideTabbedPane.shadow = $TabbedPane.shadow
|
||||||
|
|
||||||
|
JideTabbedPane.closeButtonLeftMargin = 0
|
||||||
|
JideTabbedPane.closeButtonRightMargin = 0
|
||||||
|
|||||||
@@ -489,6 +489,8 @@ JideSplitButtonUI com.formdev.flatlaf.jideoss.ui.FlatJideSplitButto
|
|||||||
#---- JideTabbedPane ----
|
#---- JideTabbedPane ----
|
||||||
|
|
||||||
JideTabbedPane.background #3c3f41 javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.background #3c3f41 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
JideTabbedPane.closeButtonLeftMargin 0
|
||||||
|
JideTabbedPane.closeButtonRightMargin 0
|
||||||
JideTabbedPane.contentBorderInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
|
JideTabbedPane.contentBorderInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
|
||||||
JideTabbedPane.foreground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.foreground #bbbbbb javax.swing.plaf.ColorUIResource [UI]
|
||||||
JideTabbedPane.shadow #3c3f41 javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.shadow #3c3f41 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
|||||||
@@ -494,6 +494,8 @@ JideSplitButtonUI com.formdev.flatlaf.jideoss.ui.FlatJideSplitButto
|
|||||||
#---- JideTabbedPane ----
|
#---- JideTabbedPane ----
|
||||||
|
|
||||||
JideTabbedPane.background #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.background #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
JideTabbedPane.closeButtonLeftMargin 0
|
||||||
|
JideTabbedPane.closeButtonRightMargin 0
|
||||||
JideTabbedPane.contentBorderInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
|
JideTabbedPane.contentBorderInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
|
||||||
JideTabbedPane.foreground #000000 javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.foreground #000000 javax.swing.plaf.ColorUIResource [UI]
|
||||||
JideTabbedPane.shadow #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.shadow #f2f2f2 javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
|||||||
@@ -485,6 +485,8 @@ JideSplitButtonUI com.formdev.flatlaf.jideoss.ui.FlatJideSplitButto
|
|||||||
#---- JideTabbedPane ----
|
#---- JideTabbedPane ----
|
||||||
|
|
||||||
JideTabbedPane.background #ccffcc javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.background #ccffcc javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
JideTabbedPane.closeButtonLeftMargin 0
|
||||||
|
JideTabbedPane.closeButtonRightMargin 0
|
||||||
JideTabbedPane.contentBorderInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
|
JideTabbedPane.contentBorderInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI]
|
||||||
JideTabbedPane.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
|
||||||
JideTabbedPane.shadow #ccffcc javax.swing.plaf.ColorUIResource [UI]
|
JideTabbedPane.shadow #ccffcc javax.swing.plaf.ColorUIResource [UI]
|
||||||
|
|||||||
@@ -108,12 +108,10 @@
|
|||||||
+ JideTabbedPane.buttonMargin 5
|
+ JideTabbedPane.buttonMargin 5
|
||||||
+ JideTabbedPane.buttonSize 18
|
+ JideTabbedPane.buttonSize 18
|
||||||
+ JideTabbedPane.closeButtonAlignment 11
|
+ JideTabbedPane.closeButtonAlignment 11
|
||||||
+ JideTabbedPane.closeButtonLeftMargin 2
|
|
||||||
+ JideTabbedPane.closeButtonMargin 2
|
+ JideTabbedPane.closeButtonMargin 2
|
||||||
+ JideTabbedPane.closeButtonMarginHorizonal 3
|
+ JideTabbedPane.closeButtonMarginHorizonal 3
|
||||||
+ JideTabbedPane.closeButtonMarginSize 6
|
+ JideTabbedPane.closeButtonMarginSize 6
|
||||||
+ JideTabbedPane.closeButtonMarginVertical 3
|
+ JideTabbedPane.closeButtonMarginVertical 3
|
||||||
+ JideTabbedPane.closeButtonRightMargin 2
|
|
||||||
+ JideTabbedPane.compressedStyleCloseButtonMarginHorizontal 0
|
+ JideTabbedPane.compressedStyleCloseButtonMarginHorizontal 0
|
||||||
+ JideTabbedPane.compressedStyleCloseButtonMarginVertical 0
|
+ JideTabbedPane.compressedStyleCloseButtonMarginVertical 0
|
||||||
+ JideTabbedPane.compressedStyleIconMargin 12
|
+ JideTabbedPane.compressedStyleIconMargin 12
|
||||||
|
|||||||
@@ -108,12 +108,10 @@
|
|||||||
+ JideTabbedPane.buttonMargin 5
|
+ JideTabbedPane.buttonMargin 5
|
||||||
+ JideTabbedPane.buttonSize 18
|
+ JideTabbedPane.buttonSize 18
|
||||||
+ JideTabbedPane.closeButtonAlignment 11
|
+ JideTabbedPane.closeButtonAlignment 11
|
||||||
+ JideTabbedPane.closeButtonLeftMargin 2
|
|
||||||
+ JideTabbedPane.closeButtonMargin 2
|
+ JideTabbedPane.closeButtonMargin 2
|
||||||
+ JideTabbedPane.closeButtonMarginHorizonal 3
|
+ JideTabbedPane.closeButtonMarginHorizonal 3
|
||||||
+ JideTabbedPane.closeButtonMarginSize 6
|
+ JideTabbedPane.closeButtonMarginSize 6
|
||||||
+ JideTabbedPane.closeButtonMarginVertical 3
|
+ JideTabbedPane.closeButtonMarginVertical 3
|
||||||
+ JideTabbedPane.closeButtonRightMargin 2
|
|
||||||
+ JideTabbedPane.compressedStyleCloseButtonMarginHorizontal 0
|
+ JideTabbedPane.compressedStyleCloseButtonMarginHorizontal 0
|
||||||
+ JideTabbedPane.compressedStyleCloseButtonMarginVertical 0
|
+ JideTabbedPane.compressedStyleCloseButtonMarginVertical 0
|
||||||
+ JideTabbedPane.compressedStyleIconMargin 12
|
+ JideTabbedPane.compressedStyleIconMargin 12
|
||||||
|
|||||||
@@ -343,6 +343,8 @@ JideSplitButton.selectionForeground
|
|||||||
JideSplitButton.textIconGap
|
JideSplitButton.textIconGap
|
||||||
JideSplitButtonUI
|
JideSplitButtonUI
|
||||||
JideTabbedPane.background
|
JideTabbedPane.background
|
||||||
|
JideTabbedPane.closeButtonLeftMargin
|
||||||
|
JideTabbedPane.closeButtonRightMargin
|
||||||
JideTabbedPane.contentBorderInsets
|
JideTabbedPane.contentBorderInsets
|
||||||
JideTabbedPane.foreground
|
JideTabbedPane.foreground
|
||||||
JideTabbedPane.shadow
|
JideTabbedPane.shadow
|
||||||
|
|||||||
Reference in New Issue
Block a user