From c0dd02ee1305126a3297684e9842385d53bd9bec Mon Sep 17 00:00:00 2001 From: Karl Tauber Date: Mon, 8 Jan 2024 13:22:59 +0100 Subject: [PATCH] TabbedPane: paint rounded tab area background for rounded cards (issue #717) --- CHANGELOG.md | 1 + .../formdev/flatlaf/ui/FlatTabbedPaneUI.java | 70 +++++++++++-------- 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b50462f..c3cc461f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ FlatLaf Change Log https://www.formdev.com/flatlaf/native-libraries/. - ScrollPane: Support rounded border. (PR #713) - TabbedPane: Support vertical tabs. (PR #758, issue #633) +- TabbedPane: Paint rounded tab area background for rounded cards. (issue #717) - ToolBar: Added styling properties `separatorWidth` and `separatorColor`. #### Fixed bugs 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 8ccdb5de..581c9994 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 @@ -837,6 +837,8 @@ public class FlatTabbedPaneUI EventQueue.invokeLater( () -> { repaintRolloverPending = false; + if( tabPane == null ) + return; int index = getRolloverTab(); if( index != oldIndex ) { @@ -1167,6 +1169,33 @@ public class FlatTabbedPaneUI paintContentBorder( g, tabPlacement, selectedIndex ); + // fill tabs area background + // - for rounded cards use partly rounded rectangle + if( tabsOpaque && !tabPane.isOpaque() && tabPane.getTabCount() > 0 ) { + Rectangle tr = null; + if( isScrollTabLayout() ) { + // scroll layout: use tab viewport bounds and add visible buttons + tr = tabViewport.getBounds(); + for( Component child : tabPane.getComponents() ) { + if( child instanceof FlatTabAreaButton && child.isVisible() ) + tr = tr.union( child.getBounds() ); + } + } else { + // wrap layout: use union of all tab rectangles + for( Rectangle r : rects ) + tr = (tr != null) ? tr.union( r ) : r; + } + + if( tr != null ) { + g.setColor( tabPane.getBackground() ); + + if( (getTabType() == TAB_TYPE_CARD) && cardTabArc > 0 ) { + ((Graphics2D)g).fill( createCardTabOuterPath( tabPlacement, tr.x, tr.y, tr.width, tr.height ) ); + } else + g.fillRect( tr.x, tr.y, tr.width, tr.height ); + } + } + if( !isScrollTabLayout() ) paintTabArea( g, tabPlacement, selectedIndex ); } @@ -1362,18 +1391,6 @@ debug*/ { boolean isCard = (getTabType() == TAB_TYPE_CARD); - // fill whole tab background if tab is rounded or has insets - if( (!isCard && tabArc > 0) || - (isCard && cardTabArc > 0) || - (!isCard && selectedInsets != null && - (selectedInsets.top != 0 || selectedInsets.left != 0 || - selectedInsets.bottom != 0 || selectedInsets.right != 0)) ) - { - Color background = tabPane.getBackgroundAt( tabIndex ); - g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) ); - g.fillRect( x, y, w, h ); - } - // apply insets if( !isCard && selectedInsets != null ) { Insets insets = new Insets( 0, 0, 0, 0 ); @@ -1387,14 +1404,16 @@ debug*/ // paint tab background Color background = getTabBackground( tabPlacement, tabIndex, isSelected ); - g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) ); - if( !isCard && tabArc > 0 ) { - float arc = scale( (float) tabArc ) / 2f; - FlatUIUtils.paintSelection( (Graphics2D) g, x, y, w, h, null, arc, arc, arc, arc, 0 ); - } else if( isCard && cardTabArc > 0 ) - ((Graphics2D)g).fill( createCardTabOuterPath( tabPlacement, x, y, w, h ) ); - else - g.fillRect( x, y, w, h ); + if( background != tabPane.getBackground() ) { + g.setColor( FlatUIUtils.deriveColor( background, tabPane.getBackground() ) ); + if( !isCard && tabArc > 0 ) { + float arc = scale( (float) tabArc ) / 2f; + FlatUIUtils.paintSelection( (Graphics2D) g, x, y, w, h, null, arc, arc, arc, arc, 0 ); + } else if( isCard && cardTabArc > 0 ) + ((Graphics2D)g).fill( createCardTabOuterPath( tabPlacement, x, y, w, h ) ); + else + g.fillRect( x, y, w, h ); + } } /** @since 2 */ @@ -2340,17 +2359,6 @@ debug*/ return FlatUIUtils.deriveColor( background, tabPane.getBackground() ); } - @Override - public void paint( Graphics g ) { - // fill button background - if( tabsOpaque || tabPane.isOpaque() ) { - g.setColor( tabPane.getBackground() ); - g.fillRect( 0, 0, getWidth(), getHeight() ); - } - - super.paint( g ); - } - @Override protected void paintBackground( Graphics2D g ) { // rotate button insets