From 08f525de5f160bff2afc2452e66dcc3205e0b063 Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Sat, 9 Nov 2019 15:53:02 +0100 Subject: [PATCH] TabbedPane: content pane is no longer opaque and use antialiasing for painting separator and content border --- CHANGELOG.md | 2 ++ .../formdev/flatlaf/ui/FlatTabbedPaneUI.java | 27 ++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bf03de86..c4933b98 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,8 @@ FlatLaf Change Log greater than zero. - TabbedPane: In scroll-tab-layout, the separator line now spans the whole width and is no longer interrupted by the scroll buttons. +- TabbedPane: Content pane is no longer opaque. Use antialiasing for painting + separator and content border. ## 0.17 diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java index 630f9db8..e0746afb 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatTabbedPaneUI.java @@ -24,9 +24,12 @@ import java.awt.Container; 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.Shape; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JButton; @@ -112,7 +115,6 @@ public class FlatTabbedPaneUI tabAreaInsets = scale( tabAreaInsets ); tabHeight = scale( tabHeight ); tabSelectionHeight = scale( tabSelectionHeight ); - contentSeparatorHeight = scale( contentSeparatorHeight ); MigLayoutVisualPadding.install( tabPane, null ); } @@ -196,7 +198,7 @@ public class FlatTabbedPaneUI @Override protected Insets getContentBorderInsets( int tabPlacement ) { boolean hasFullBorder = this.hasFullBorder || clientPropertyEquals( tabPane, TABBED_PANE_HAS_FULL_BORDER, true ); - int sh = contentSeparatorHeight; + int sh = scale( contentSeparatorHeight ); Insets insets = hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 ); Insets contentBorderInsets = new Insets( 0, 0, 0, 0 ); @@ -214,6 +216,13 @@ public class FlatTabbedPaneUI return 0; } + @Override + public void update( Graphics g, JComponent c ) { + FlatUIUtils.setRenderingHints( (Graphics2D) g ); + + super.update( g, c ); + } + @Override protected void paintText( Graphics g, int tabPlacement, Font font, FontMetrics metrics, int tabIndex, String title, Rectangle textRect, boolean isSelected ) @@ -270,6 +279,7 @@ public class FlatTabbedPaneUI Rectangle clipBounds = isScrollTabLayout() ? g.getClipBounds() : null; if( clipBounds != null ) { Rectangle newClipBounds = new Rectangle( clipBounds ); + int contentSeparatorHeight = scale( this.contentSeparatorHeight ); switch( tabPlacement ) { case TOP: default: @@ -325,7 +335,6 @@ public class FlatTabbedPaneUI /** * Actually does the nearly the same as super.paintContentBorder() but - * - content pane is always opaque * - not using UIManager.getColor("TabbedPane.contentAreaColor") to be GUI builder friendly * - not invoking paintContentBorder*Edge() methods * - repaint selection @@ -369,9 +378,19 @@ public class FlatTabbedPaneUI h -= (y - insets.top); } + // compute insets for separator or full border + boolean hasFullBorder = this.hasFullBorder || clientPropertyEquals( tabPane, TABBED_PANE_HAS_FULL_BORDER, true ); + int sh = scale( contentSeparatorHeight * 100 ); // multiply by 100 because rotateInsets() does not use floats + Insets ci = new Insets( 0, 0, 0, 0 ); + rotateInsets( hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 ), ci, tabPlacement ); + // paint content area g.setColor( contentAreaColor ); - g.fillRect( x, y, w, h ); + Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD ); + path.append( new Rectangle2D.Float( x, y, w, h ), false ); + path.append( new Rectangle2D.Float( x + (ci.left / 100f), y + (ci.top / 100f), + w - (ci.left / 100f) - (ci.right / 100f), h - (ci.top / 100f) - (ci.bottom / 100f) ), false ); + ((Graphics2D)g).fill( path ); // repaint selection in scroll-tab-layout because it may be painted before // the content border was painted (from BasicTabbedPaneUI$ScrollableTabPanel)