mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2025-12-06 14:00:55 +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.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;
|
||||
@@ -34,15 +37,19 @@ 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.icons.FlatTabbedPaneCloseIcon;
|
||||
import com.formdev.flatlaf.ui.FlatUIUtils;
|
||||
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}.
|
||||
@@ -68,6 +75,11 @@ public class FlatJideTabbedPaneUI
|
||||
protected boolean hasFullBorder;
|
||||
protected boolean tabsOverlapBorder;
|
||||
|
||||
protected Icon closeIcon;
|
||||
|
||||
protected int closeButtonLeftMarginUnscaled;
|
||||
protected int closeButtonRightMarginUnscaled;
|
||||
|
||||
private Object[] oldRenderingHints;
|
||||
|
||||
public static ComponentUI createUI( JComponent c ) {
|
||||
@@ -100,6 +112,11 @@ public class FlatJideTabbedPaneUI
|
||||
hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" );
|
||||
tabsOverlapBorder = UIManager.getBoolean( "TabbedPane.tabsOverlapBorder" );
|
||||
|
||||
closeIcon = new FlatJideTabCloseIcon();
|
||||
|
||||
closeButtonLeftMarginUnscaled = _closeButtonLeftMargin;
|
||||
closeButtonRightMarginUnscaled = _closeButtonRightMargin;
|
||||
|
||||
// scale
|
||||
_textIconGap = scale( _textIconGap );
|
||||
tabHeight = scale( tabHeight );
|
||||
@@ -117,6 +134,7 @@ public class FlatJideTabbedPaneUI
|
||||
focusColor = null;
|
||||
tabSeparatorColor = null;
|
||||
contentAreaColor = null;
|
||||
closeIcon = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,14 +177,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
|
||||
@@ -189,6 +216,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
|
||||
@@ -430,4 +477,103 @@ public class FlatJideTabbedPaneUI
|
||||
int run = getRunForTab( _tabPane.getTabCount(), 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.tabRunOverlay = $TabbedPane.tabRunOverlay
|
||||
JideTabbedPane.shadow = $TabbedPane.shadow
|
||||
|
||||
JideTabbedPane.closeButtonLeftMargin = 0
|
||||
JideTabbedPane.closeButtonRightMargin = 0
|
||||
|
||||
@@ -489,6 +489,8 @@ JideSplitButtonUI com.formdev.flatlaf.jideoss.ui.FlatJideSplitButto
|
||||
#---- JideTabbedPane ----
|
||||
|
||||
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.foreground #bbbbbb 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.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.foreground #000000 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.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.foreground #ff0000 javax.swing.plaf.ColorUIResource [UI]
|
||||
JideTabbedPane.shadow #ccffcc javax.swing.plaf.ColorUIResource [UI]
|
||||
|
||||
@@ -108,12 +108,10 @@
|
||||
+ JideTabbedPane.buttonMargin 5
|
||||
+ JideTabbedPane.buttonSize 18
|
||||
+ JideTabbedPane.closeButtonAlignment 11
|
||||
+ JideTabbedPane.closeButtonLeftMargin 2
|
||||
+ JideTabbedPane.closeButtonMargin 2
|
||||
+ JideTabbedPane.closeButtonMarginHorizonal 3
|
||||
+ JideTabbedPane.closeButtonMarginSize 6
|
||||
+ JideTabbedPane.closeButtonMarginVertical 3
|
||||
+ JideTabbedPane.closeButtonRightMargin 2
|
||||
+ JideTabbedPane.compressedStyleCloseButtonMarginHorizontal 0
|
||||
+ JideTabbedPane.compressedStyleCloseButtonMarginVertical 0
|
||||
+ JideTabbedPane.compressedStyleIconMargin 12
|
||||
|
||||
@@ -108,12 +108,10 @@
|
||||
+ JideTabbedPane.buttonMargin 5
|
||||
+ JideTabbedPane.buttonSize 18
|
||||
+ JideTabbedPane.closeButtonAlignment 11
|
||||
+ JideTabbedPane.closeButtonLeftMargin 2
|
||||
+ JideTabbedPane.closeButtonMargin 2
|
||||
+ JideTabbedPane.closeButtonMarginHorizonal 3
|
||||
+ JideTabbedPane.closeButtonMarginSize 6
|
||||
+ JideTabbedPane.closeButtonMarginVertical 3
|
||||
+ JideTabbedPane.closeButtonRightMargin 2
|
||||
+ JideTabbedPane.compressedStyleCloseButtonMarginHorizontal 0
|
||||
+ JideTabbedPane.compressedStyleCloseButtonMarginVertical 0
|
||||
+ JideTabbedPane.compressedStyleIconMargin 12
|
||||
|
||||
@@ -343,6 +343,8 @@ JideSplitButton.selectionForeground
|
||||
JideSplitButton.textIconGap
|
||||
JideSplitButtonUI
|
||||
JideTabbedPane.background
|
||||
JideTabbedPane.closeButtonLeftMargin
|
||||
JideTabbedPane.closeButtonRightMargin
|
||||
JideTabbedPane.contentBorderInsets
|
||||
JideTabbedPane.foreground
|
||||
JideTabbedPane.shadow
|
||||
|
||||
Reference in New Issue
Block a user