diff --git a/CHANGELOG.md b/CHANGELOG.md index 0df448425..d3be7f274 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ FlatLaf Change Log #### New features and improvements +- TabbedPane: Support vertical tabs. (PR #758, issue #633) - ToolBar: Added styling properties `separatorWidth` and `separatorColor`. #### Fixed bugs diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java index 1aad7959a..d92fe2212 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/FlatClientProperties.java @@ -932,6 +932,59 @@ public interface FlatClientProperties */ String TABBED_PANE_TAB_ICON_PLACEMENT = "JTabbedPane.tabIconPlacement"; + /** + * Specifies the rotation of the tabs (title, icon, etc). + *

+ * Component {@link javax.swing.JTabbedPane}
+ * Value type {@link java.lang.Integer} or {@link java.lang.String}
+ * Allowed Values + * {@link SwingConstants#LEFT}, + * {@link SwingConstants#RIGHT}, + * {@link #TABBED_PANE_TAB_ROTATION_NONE}, (default) + * {@link #TABBED_PANE_TAB_ROTATION_AUTO}, + * {@link #TABBED_PANE_TAB_ROTATION_LEFT} or + * {@link #TABBED_PANE_TAB_ROTATION_RIGHT} + * + * @since 3.3 + */ + String TABBED_PANE_TAB_ROTATION = "JTabbedPane.tabRotation"; + + /** + * Tabs are not rotated. + * + * @see #TABBED_PANE_TAB_ROTATION + * @since 3.3 + */ + String TABBED_PANE_TAB_ROTATION_NONE = "none"; + + /** + * Tabs are rotated depending on tab placement. + *

+ * For top and bottom tab placement, the tabs are not rotated.
+ * For left tab placement, the tabs are rotated counter clockwise.
+ * For right tab placement, the tabs are rotated clockwise. + * + * @see #TABBED_PANE_TAB_ROTATION + * @since 3.3 + */ + String TABBED_PANE_TAB_ROTATION_AUTO = "auto"; + + /** + * Tabs are rotated counter clockwise. + * + * @see #TABBED_PANE_TAB_ROTATION + * @since 3.3 + */ + String TABBED_PANE_TAB_ROTATION_LEFT = "left"; + + /** + * Tabs are rotated clockwise. + * + * @see #TABBED_PANE_TAB_ROTATION + * @since 3.3 + */ + String TABBED_PANE_TAB_ROTATION_RIGHT = "right"; + /** * Specifies a component that will be placed at the leading edge of the tabs area. *

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 f235fcf1b..02f7bdbb6 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 @@ -49,6 +49,7 @@ import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.awt.event.MouseWheelEvent; +import java.awt.geom.AffineTransform; import java.awt.geom.Area; import java.awt.geom.Path2D; import java.awt.geom.Rectangle2D; @@ -164,6 +165,7 @@ * @uiDefault TabbedPane.tabAreaAlignment String leading (default), center, trailing or fill * @uiDefault TabbedPane.tabAlignment String leading, center (default) or trailing * @uiDefault TabbedPane.tabWidthMode String preferred (default), equal or compact + * @uiDefault TabbedPane.tabRotation String none (default), auto, left or right * @uiDefault ScrollPane.smoothScrolling boolean * @uiDefault TabbedPane.closeIcon Icon * @@ -198,10 +200,15 @@ public class FlatTabbedPaneUI // tab area alignment protected static final int FILL = 100; + // tab width mode protected static final int WIDTH_MODE_PREFERRED = 0; protected static final int WIDTH_MODE_EQUAL = 1; protected static final int WIDTH_MODE_COMPACT = 2; + // tab rotation + /** @since 3.3 */ protected static final int NONE = -1; + /** @since 3.3 */ protected static final int AUTO = -2; + private static Set focusForwardTraversalKeys; private static Set focusBackwardTraversalKeys; @@ -245,6 +252,7 @@ public class FlatTabbedPaneUI @Styleable(type=String.class) private int tabAreaAlignment; @Styleable(type=String.class) private int tabAlignment; @Styleable(type=String.class) private int tabWidthMode; + /** @since 3.3 */ @Styleable(type=String.class) private int tabRotation; protected Icon closeIcon; @Styleable protected String arrowType; @@ -375,6 +383,7 @@ protected void installDefaults() { tabAreaAlignment = parseAlignment( UIManager.getString( "TabbedPane.tabAreaAlignment" ), LEADING ); tabAlignment = parseAlignment( UIManager.getString( "TabbedPane.tabAlignment" ), CENTER ); tabWidthMode = parseTabWidthMode( UIManager.getString( "TabbedPane.tabWidthMode" ) ); + tabRotation = parseTabRotation( UIManager.getString( "TabbedPane.tabRotation" ) ); closeIcon = UIManager.getIcon( "TabbedPane.closeIcon" ); closeIconShared = true; @@ -680,6 +689,7 @@ protected Object applyStyleProperty( String key, Object value ) { case "tabAreaAlignment": value = parseAlignment( (String) value, LEADING ); break; case "tabAlignment": value = parseAlignment( (String) value, CENTER ); break; case "tabWidthMode": value = parseTabWidthMode( (String) value ); break; + case "tabRotation": value = parseTabRotation( (String) value ); break; case "tabIconPlacement": value = parseTabIconPlacement( (String) value ); break; } @@ -770,6 +780,15 @@ public Object getStyleableValue( JComponent c, String key ) { case WIDTH_MODE_COMPACT: return TABBED_PANE_TAB_WIDTH_MODE_COMPACT; } + case "tabRotation": + switch( tabRotation ) { + default: + case NONE: return TABBED_PANE_TAB_ROTATION_NONE; + case AUTO: return TABBED_PANE_TAB_ROTATION_AUTO; + case LEFT: return TABBED_PANE_TAB_ROTATION_LEFT; + case RIGHT: return TABBED_PANE_TAB_ROTATION_RIGHT; + } + case "tabIconPlacement": switch( tabIconPlacement ) { default: @@ -856,11 +875,19 @@ private void repaintTab( int tabIndex ) { @Override protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics metrics ) { + return (getRealTabRotation( tabPlacement ) == NONE) + ? calculateTabWidthImpl( tabPlacement, tabIndex, metrics, false ) + : calculateTabHeightImpl( tabPlacement, tabIndex, metrics.getHeight(), true ); + } + + private int calculateTabWidthImpl( int tabPlacement, int tabIndex, FontMetrics metrics, boolean rotated ) { int tabWidthMode = getTabWidthMode(); - if( tabWidthMode == WIDTH_MODE_EQUAL && isHorizontalTabPlacement() && !inCalculateEqual ) { + if( tabWidthMode == WIDTH_MODE_EQUAL && isHorizontalOrRotated( tabPlacement ) && !inCalculateEqual ) { inCalculateEqual = true; try { - return calculateMaxTabWidth( tabPlacement ); + return isHorizontalTabPlacement( tabPlacement ) + ? calculateMaxTabWidth( tabPlacement ) + : calculateMaxTabHeight( tabPlacement ); } finally { inCalculateEqual = false; } @@ -873,7 +900,7 @@ protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics met Icon icon; if( tabWidthMode == WIDTH_MODE_COMPACT && tabIndex != tabPane.getSelectedIndex() && - isHorizontalTabPlacement() && + isHorizontalOrRotated( tabPlacement ) && tabPane.getTabComponentAt( tabIndex ) == null && (icon = getIconForTab( tabIndex )) != null ) { @@ -899,8 +926,16 @@ protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics met Insets tabInsets = getTabInsets( tabPlacement, tabIndex ); tabWidth += tabInsets.left + tabInsets.right; - } else + } else { tabWidth = super.calculateTabWidth( tabPlacement, tabIndex, metrics ) - 3 /* was added by superclass */; + + // tab components are not rotated + Component tabComponent; + if( rotated && (tabComponent = tabPane.getTabComponentAt( tabIndex )) != null ) { + Dimension prefSize = tabComponent.getPreferredSize(); + tabWidth = tabWidth - prefSize.width + prefSize.height; + } + } } // make tab wider if closable @@ -920,6 +955,12 @@ protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics met @Override protected int calculateTabHeight( int tabPlacement, int tabIndex, int fontHeight ) { + return (getRealTabRotation( tabPlacement ) == NONE) + ? calculateTabHeightImpl( tabPlacement, tabIndex, fontHeight, false ) + : calculateTabWidthImpl( tabPlacement, tabIndex, getFontMetrics(), true ); + } + + private int calculateTabHeightImpl( int tabPlacement, int tabIndex, int fontHeight, boolean rotated ) { int tabHeight; Icon icon; @@ -939,9 +980,17 @@ else if( tabPane.getTitleAt( tabIndex ) != null ) Insets tabInsets = getTabInsets( tabPlacement, tabIndex ); tabHeight += tabInsets.top + tabInsets.bottom; - } else + } else { tabHeight = super.calculateTabHeight( tabPlacement, tabIndex, fontHeight ) - 2 /* was added by superclass */; + // tab components are not rotated + Component tabComponent; + if( rotated && (tabComponent = tabPane.getTabComponentAt( tabIndex )) != null ) { + Dimension prefSize = tabComponent.getPreferredSize(); + tabHeight = tabHeight - prefSize.height + prefSize.width; + } + } + return Math.max( tabHeight, scale( clientPropertyInt( tabPane, TABBED_PANE_TAB_HEIGHT, this.tabHeight ) ) ); } @@ -973,6 +1022,16 @@ protected Insets getTabInsets( int tabPlacement, int tabIndex ) { : super.getTabInsets( tabPlacement, tabIndex ) ); } + /** @since 3.3 */ + protected Insets getTabInsetsRotated( int tabPlacement, int tabIndex, int rotation ) { + Insets insets = getTabInsets( tabPlacement, tabIndex ); + switch( rotation ) { + case LEFT: return new Insets( insets.right, insets.top, insets.left, insets.bottom ); + case RIGHT: return new Insets( insets.left, insets.bottom, insets.right, insets.top ); + default: return insets; + } + } + @Override protected Insets getSelectedTabPadInsets( int tabPlacement ) { return new Insets( 0, 0, 0, 0 ); @@ -1012,7 +1071,7 @@ protected Insets getTabAreaInsets( int tabPlacement ) { // increase insets for wrap layout if using leading/trailing components if( tabPane.getTabLayoutPolicy() == JTabbedPane.WRAP_TAB_LAYOUT ) { - if( isHorizontalTabPlacement() ) { + if( isHorizontalTabPlacement( tabPlacement ) ) { insets.left += getLeadingPreferredWidth(); insets.right += getTrailingPreferredWidth(); } else { @@ -1045,7 +1104,7 @@ protected Insets getContentBorderInsets( int tabPlacement ) { @Override protected int getTabLabelShiftX( int tabPlacement, int tabIndex, boolean isSelected ) { - if( isTabClosable( tabIndex ) ) { + if( isTabClosable( tabIndex ) && getRealTabRotation( tabPlacement ) == NONE ) { int shift = closeIcon.getIconWidth() / 2; return isLeftToRight() ? -shift : shift; } @@ -1054,6 +1113,10 @@ protected int getTabLabelShiftX( int tabPlacement, int tabIndex, boolean isSelec @Override protected int getTabLabelShiftY( int tabPlacement, int tabIndex, boolean isSelected ) { + if( isTabClosable( tabIndex ) && getRealTabRotation( tabPlacement ) != NONE ) { + int shift = closeIcon.getIconHeight() / 2; + return isLeftToRight() ? shift : -shift; + } return 0; } @@ -1128,11 +1191,31 @@ protected void paintTab( Graphics g, int tabPlacement, Rectangle[] rects, Icon icon = getIconForTab( tabIndex ); Font font = tabPane.getFont(); FontMetrics metrics = tabPane.getFontMetrics( font ); - boolean isCompact = (icon != null && !isSelected && getTabWidthMode() == WIDTH_MODE_COMPACT && isHorizontalTabPlacement()); + boolean isCompact = (icon != null && !isSelected && getTabWidthMode() == WIDTH_MODE_COMPACT && isHorizontalOrRotated( tabPlacement )); if( isCompact ) title = null; String clippedTitle = layoutAndClipLabel( tabPlacement, metrics, tabIndex, title, icon, tabRect, iconRect, textRect, isSelected ); +/*debug + g.setColor( Color.red ); + g.drawRect( tabRect.x, tabRect.y, tabRect.width - 1, tabRect.height - 1 ); + g.setColor( Color.green ); + Rectangle tabRect2 = FlatUIUtils.subtractInsets( tabRect, getTabInsetsRotated( tabPlacement, tabIndex, getRealTabRotation( tabPlacement ) ) ); + g.drawRect( tabRect2.x, tabRect2.y, tabRect2.width - 1, tabRect2.height - 1 ); + g.setColor( Color.blue ); + g.drawRect( iconRect.x, iconRect.y, iconRect.width - 1, iconRect.height - 1 ); + g.setColor( Color.magenta ); + g.drawRect( textRect.x, textRect.y, textRect.width - 1, textRect.height - 1 ); + g.setColor( Color.orange ); + Rectangle closeHitArea = getTabCloseHitArea( tabIndex ); + if( moreTabsButton != null ) { + Point viewPosition = tabViewport.getViewPosition(); + closeHitArea.x -= tabViewport.getX() - viewPosition.x; + closeHitArea.y -= tabViewport.getY() - viewPosition.y; + } + g.drawRect( closeHitArea.x, closeHitArea.y, closeHitArea.width - 1, closeHitArea.height - 1 ); +debug*/ + // special title clipping for scroll layout where title of last visible tab on right side may be truncated if( tabViewport != null && (tabPlacement == TOP || tabPlacement == BOTTOM) ) { Rectangle viewRect = tabViewport.getViewRect(); @@ -1160,18 +1243,70 @@ protected void paintText( Graphics g, int tabPlacement, Font font, FontMetrics m // html View view = getTextViewForTab( tabIndex ); if( view != null ) { - view.paint( g, textRect ); + AffineTransform oldTransform = rotateGraphics( g, tabPlacement, textRect ); + Rectangle textRect2 = (oldTransform != null) + ? new Rectangle( textRect.x, textRect.y, textRect.height, textRect.width ) + : textRect; + + view.paint( g, textRect2 ); + + if( oldTransform != null ) + ((Graphics2D)g).setTransform( oldTransform ); return; } + // rotate text if necessary + AffineTransform oldTransform = rotateGraphics( g, tabPlacement, textRect ); + // plain text int mnemIndex = FlatLaf.isShowMnemonics() ? tabPane.getDisplayedMnemonicIndexAt( tabIndex ) : -1; g.setColor( getTabForeground( tabPlacement, tabIndex, isSelected ) ); FlatUIUtils.drawStringUnderlineCharAt( tabPane, g, title, mnemIndex, textRect.x, textRect.y + metrics.getAscent() ); + + if( oldTransform != null ) + ((Graphics2D)g).setTransform( oldTransform ); } ); } + @Override + protected void paintIcon( Graphics g, int tabPlacement, int tabIndex, Icon icon, Rectangle iconRect, boolean isSelected ) { + if( icon == null ) + return; + + // clip icon painting (also done in JDK since Java 10) + Shape oldClip = g.getClip(); + ((Graphics2D)g).clip( iconRect ); + + // rotate icon if necessary + AffineTransform oldTransform = rotateGraphics( g, tabPlacement, iconRect ); + + // paint icon + icon.paintIcon( tabPane, g, iconRect.x, iconRect.y ); + + if( oldTransform != null ) + ((Graphics2D)g).setTransform( oldTransform ); + g.setClip( oldClip ); + } + + private AffineTransform rotateGraphics( Graphics g, int tabPlacement, Rectangle r ) { + Graphics2D g2 = (Graphics2D) g; + AffineTransform oldTransform = null; + + int rotation = getRealTabRotation( tabPlacement ); + if( rotation == LEFT ) { + oldTransform = g2.getTransform(); + g2.translate( 0, r.height ); + g2.rotate( Math.toRadians( 270 ), r.x, r.y ); + } else if( rotation == RIGHT ) { + oldTransform = g2.getTransform(); + g2.translate( r.width, 0 ); + g2.rotate( Math.toRadians( 90 ), r.x, r.y ); + } + + return oldTransform; + } + /** @since 3.1 */ protected Color getTabForeground( int tabPlacement, int tabIndex, boolean isSelected ) { // tabbed pane or tab is disabled @@ -1518,7 +1653,7 @@ protected void paintContentBorder( Graphics g, int tabPlacement, int selectedInd Rectangle2D.intersect( tabViewport.getBounds(), innerTabRect, innerTabRect ); Rectangle2D.Float gap = null; - if( isHorizontalTabPlacement() ) { + if( isHorizontalTabPlacement( tabPlacement ) ) { if( innerTabRect.width > 0 ) { float y2 = (tabPlacement == TOP) ? y : y + h - csh; gap = new Rectangle2D.Float( innerTabRect.x, y2, innerTabRect.width, csh ); @@ -1553,7 +1688,7 @@ protected void paintContentBorder( Graphics g, int tabPlacement, int selectedInd // (left and right if horizontal, top and bottom if vertical) Shape oldClip = g.getClip(); Rectangle vr = tabViewport.getBounds(); - if( isHorizontalTabPlacement() ) + if( isHorizontalTabPlacement( tabPlacement ) ) g.clipRect( vr.x, 0, vr.width, tabPane.getHeight() ); else g.clipRect( 0, vr.y, tabPane.getWidth(), vr.height ); @@ -1572,13 +1707,24 @@ protected void paintFocusIndicator( Graphics g, int tabPlacement, Rectangle[] re protected String layoutAndClipLabel( int tabPlacement, FontMetrics metrics, int tabIndex, String title, Icon icon, Rectangle tabRect, Rectangle iconRect, Rectangle textRect, boolean isSelected ) { + int rotation = getRealTabRotation( tabPlacement ); + boolean leftToRight = isLeftToRight(); + // remove tab insets and space for close button from the tab rectangle // to get correctly clipped title - tabRect = FlatUIUtils.subtractInsets( tabRect, getTabInsets( tabPlacement, tabIndex ) ); + tabRect = FlatUIUtils.subtractInsets( tabRect, getTabInsetsRotated( tabPlacement, tabIndex, rotation ) ); if( isTabClosable( tabIndex ) ) { - tabRect.width -= closeIcon.getIconWidth(); - if( !isLeftToRight() ) - tabRect.x += closeIcon.getIconWidth(); + if( rotation == NONE ) { + int iconWidth = closeIcon.getIconWidth(); + tabRect.width -= iconWidth; + if( !leftToRight ) + tabRect.x += iconWidth; + } else { + int iconHeight = closeIcon.getIconHeight(); + tabRect.height -= iconHeight; + if( (rotation == LEFT && leftToRight) || (rotation == RIGHT && !leftToRight) ) + tabRect.y += iconHeight; + } } // icon placement @@ -1602,9 +1748,13 @@ protected String layoutAndClipLabel( int tabPlacement, FontMetrics metrics, int tabPane.putClientProperty( "html", view ); // layout label - String clippedTitle = SwingUtilities.layoutCompoundLabel( tabPane, metrics, title, icon, - CENTER, getTabAlignment( tabIndex ), verticalTextPosition, horizontalTextPosition, - tabRect, iconRect, textRect, scale( textIconGapUnscaled ) ); + String clippedTitle = (rotation == NONE) + ? SwingUtilities.layoutCompoundLabel( tabPane, metrics, title, icon, + CENTER, getTabAlignment( tabIndex ), verticalTextPosition, horizontalTextPosition, + tabRect, iconRect, textRect, scale( textIconGapUnscaled ) ) + : layoutVerticalCompoundLabel( rotation, tabPane, metrics, title, icon, + CENTER, getTabAlignment( tabIndex ), verticalTextPosition, horizontalTextPosition, + tabRect, iconRect, textRect, scale( textIconGapUnscaled ) ); // remove temporary client property tabPane.putClientProperty( "html", null ); @@ -1612,6 +1762,50 @@ CENTER, getTabAlignment( tabIndex ), verticalTextPosition, horizontalTextPositio return clippedTitle; } + private String layoutVerticalCompoundLabel( int rotation, JComponent c, FontMetrics fm, String text, Icon icon, + int verticalAlignment, int horizontalAlignment, int verticalTextPosition, int horizontalTextPosition, + Rectangle viewR, Rectangle iconR, Rectangle textR, int textIconGap ) + { + // layout non-rotated + Rectangle viewR2 = new Rectangle( viewR.height, viewR.width ); + String clippedTitle = SwingUtilities.layoutCompoundLabel( c, fm, text, icon, + verticalAlignment, horizontalAlignment, verticalTextPosition, horizontalTextPosition, + viewR2, iconR, textR, textIconGap ); + + // rotate icon and text rectangles + if( rotation == LEFT ) { + rotateLeft( viewR, iconR ); + rotateLeft( viewR, textR ); + } else { + rotateRight( viewR, iconR ); + rotateRight( viewR, textR ); + } + + return clippedTitle; + } + + private void rotateLeft( Rectangle viewR, Rectangle r ) { + int x = viewR.x + r.y; + int y = viewR.y + (viewR.height - (r.x + r.width)); + r.setBounds( x, y, r.height, r.width ); + } + + private void rotateRight( Rectangle viewR, Rectangle r ) { + int x = viewR.x + (viewR.width - (r.y + r.height)); + int y = viewR.y + r.x; + r.setBounds( x, y, r.height, r.width ); + } + + /** @since 3.3 */ + protected int getRealTabRotation( int tabPlacement ) { + int rotation = getTabRotation(); + int realRotation = (rotation == AUTO) + ? (tabPlacement == LEFT ? LEFT : (tabPlacement == RIGHT ? RIGHT : NONE)) + : (rotation == LEFT || rotation == RIGHT ? rotation : NONE); + assert realRotation == NONE || realRotation == LEFT || realRotation == RIGHT; + return realRotation; + } + @Override public int tabForCoordinate( JTabbedPane pane, int x, int y ) { if( moreTabsButton != null ) { @@ -1646,13 +1840,23 @@ protected Rectangle getTabBounds( int tabIndex, Rectangle dest ) { protected Rectangle getTabCloseBounds( int tabIndex, int x, int y, int w, int h, Rectangle dest ) { int iconWidth = closeIcon.getIconWidth(); int iconHeight = closeIcon.getIconHeight(); - Insets tabInsets = getTabInsets( tabPane.getTabPlacement(), tabIndex ); + int tabPlacement = tabPane.getTabPlacement(); + int rotation = getRealTabRotation( tabPlacement ); + Insets tabInsets = getTabInsetsRotated( tabPlacement, tabIndex, rotation ); + boolean leftToRight = isLeftToRight(); // use one-third of right/left tab insets as gap between tab text and close button - dest.x = isLeftToRight() - ? (x + w - (tabInsets.right / 3 * 2) - iconWidth) - : (x + (tabInsets.left / 3 * 2)); - dest.y = y + (h - iconHeight) / 2; + if( rotation == NONE ) { + dest.x = leftToRight + ? (x + w - (tabInsets.right / 3 * 2) - iconWidth) // right + : (x + (tabInsets.left / 3 * 2)); // left + dest.y = y + (h - iconHeight) / 2; + } else { + dest.x = x + (w - iconWidth) / 2; + dest.y = ((rotation == RIGHT && leftToRight) || (rotation == LEFT && !leftToRight)) + ? (y + h - (tabInsets.bottom / 3 * 2) - iconHeight) // bottom + : (y + (tabInsets.top / 3 * 2)); // top + } dest.width = iconWidth; dest.height = iconHeight; return dest; @@ -1661,7 +1865,9 @@ protected Rectangle getTabCloseBounds( int tabIndex, int x, int y, int w, int h, protected Rectangle getTabCloseHitArea( int tabIndex ) { Rectangle tabRect = getTabBounds( tabPane, tabIndex ); Rectangle tabCloseRect = getTabCloseBounds( tabIndex, tabRect.x, tabRect.y, tabRect.width, tabRect.height, calcRect ); - return new Rectangle( tabCloseRect.x, tabRect.y, tabCloseRect.width, tabRect.height ); + return (getRealTabRotation( tabPane.getTabPlacement() ) == NONE) + ? new Rectangle( tabCloseRect.x, tabRect.y, tabCloseRect.width, tabRect.height ) + : new Rectangle( tabRect.x, tabCloseRect.y, tabRect.width, tabCloseRect.height ); } protected boolean isTabClosable( int tabIndex ) { @@ -1729,11 +1935,19 @@ private boolean isLeftToRight() { return tabPane.getComponentOrientation().isLeftToRight(); } - protected boolean isHorizontalTabPlacement() { - int tabPlacement = tabPane.getTabPlacement(); + /** @since 3.3 */ + protected boolean isHorizontalTabPlacement( int tabPlacement ) { return tabPlacement == TOP || tabPlacement == BOTTOM; } + /** + * Returns {@code true} if tab placement is top/bottom and text is painted horizontally or + * if tab placement is left/right and text is painted vertically (rotated). + */ + private boolean isHorizontalOrRotated( int tabPlacement ) { + return isHorizontalTabPlacement( tabPlacement ) == (getRealTabRotation( tabPlacement ) == NONE); + } + protected boolean isSmoothScrollingEnabled() { if( !Animator.useAnimation() ) return false; @@ -1812,6 +2026,17 @@ protected int getTabWidthMode() { : tabWidthMode; } + /** @since 3.3 */ + protected int getTabRotation() { + Object value = tabPane.getClientProperty( TABBED_PANE_TAB_ROTATION ); + if( value instanceof Integer ) + return (Integer) value; + + return (value instanceof String) + ? parseTabRotation( (String) value ) + : tabRotation; + } + /** @since 2 */ protected static int parseTabType( String str ) { if( str == null ) @@ -1893,6 +2118,20 @@ protected static int parseTabWidthMode( String str ) { } } + /** @since 3.3 */ + protected static int parseTabRotation( String str ) { + if( str == null ) + return WIDTH_MODE_PREFERRED; + + switch( str ) { + default: + case TABBED_PANE_TAB_ROTATION_NONE: return NONE; + case TABBED_PANE_TAB_ROTATION_AUTO: return AUTO; + case TABBED_PANE_TAB_ROTATION_LEFT: return LEFT; + case TABBED_PANE_TAB_ROTATION_RIGHT: return RIGHT; + } + } + protected static int parseTabIconPlacement( String str ) { if( str == null ) return LEADING; @@ -2432,7 +2671,7 @@ else if( preciseWheelRotation < 0 ) ? targetViewPosition : tabViewport.getViewPosition(); Dimension viewSize = tabViewport.getViewSize(); - boolean horizontal = isHorizontalTabPlacement(); + boolean horizontal = isHorizontalTabPlacement( tabPane.getTabPlacement() ); int x = viewPosition.x; int y = viewPosition.y; if( horizontal ) @@ -2839,6 +3078,7 @@ public void propertyChange( PropertyChangeEvent e ) { case TABBED_PANE_TAB_AREA_ALIGNMENT: case TABBED_PANE_TAB_ALIGNMENT: case TABBED_PANE_TAB_WIDTH_MODE: + case TABBED_PANE_TAB_ROTATION: case TABBED_PANE_TAB_ICON_PLACEMENT: case TABBED_PANE_TAB_CLOSABLE: tabPane.revalidate(); @@ -2974,8 +3214,8 @@ protected boolean isContentEmpty() { } protected Dimension calculateTabAreaSize() { - boolean horizontal = isHorizontalTabPlacement(); int tabPlacement = tabPane.getTabPlacement(); + boolean horizontal = isHorizontalTabPlacement( tabPlacement ); FontMetrics metrics = getFontMetrics(); int fontHeight = metrics.getHeight(); @@ -3172,7 +3412,7 @@ protected Dimension calculateTabAreaSize() { Dimension size = super.calculateTabAreaSize(); // limit width/height in scroll layout - if( isHorizontalTabPlacement() ) + if( isHorizontalTabPlacement( tabPane.getTabPlacement() ) ) size.width = Math.min( size.width, scale( 100 ) ); else size.height = Math.min( size.height, scale( 100 ) ); @@ -3230,7 +3470,7 @@ public void layoutContainer( Container parent ) { // because methods scrollForward() and scrollBackward() in class // BasicTabbedPaneUI.ScrollableTabSupport do not work for right-to-left boolean leftToRight = isLeftToRight(); - if( !leftToRight && isHorizontalTabPlacement() ) { + if( !leftToRight && isHorizontalTabPlacement( tabPane.getTabPlacement() ) ) { useMoreTabsButton = true; useScrollButtons = false; } diff --git a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties index 367637140..ffe416616 100644 --- a/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties +++ b/flatlaf-core/src/main/resources/com/formdev/flatlaf/FlatLaf.properties @@ -697,6 +697,8 @@ TabbedPane.tabAreaAlignment = leading TabbedPane.tabAlignment = center # allowed values: preferred, equal or compact TabbedPane.tabWidthMode = preferred +# allowed values: none, auto, left or right +TabbedPane.tabRotation = none # allowed values: underlined or card TabbedPane.tabType = underlined diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java index 645dc9200..d86ab7c9f 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableInfo.java @@ -752,6 +752,7 @@ void tabbedPane() { "tabAreaAlignment", String.class, "tabAlignment", String.class, "tabWidthMode", String.class, + "tabRotation", String.class, "arrowType", String.class, "buttonInsets", Insets.class, diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java index a7199f712..f85f0d128 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyleableValue.java @@ -758,6 +758,7 @@ void tabbedPane() { testString( c, ui, "tabAreaAlignment", "leading" ); testString( c, ui, "tabAlignment", "center" ); testString( c, ui, "tabWidthMode", "preferred" ); + testString( c, ui, "tabRotation", "none" ); testString( c, ui, "arrowType", "chevron" ); testInsets( c, ui, "buttonInsets", 1,2,3,4 ); diff --git a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java index 927086c36..e16583759 100644 --- a/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java +++ b/flatlaf-core/src/test/java/com/formdev/flatlaf/ui/TestFlatStyling.java @@ -937,6 +937,7 @@ void tabbedPane() { ui.applyStyle( "tabAreaAlignment: leading" ); ui.applyStyle( "tabAlignment: center" ); ui.applyStyle( "tabWidthMode: preferred" ); + ui.applyStyle( "tabRotation: none" ); ui.applyStyle( "arrowType: chevron" ); ui.applyStyle( "buttonInsets: 1,2,3,4" ); diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/ScrollablePanel.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/ScrollablePanel.java index 73a18a0f9..7f91e141f 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/ScrollablePanel.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/ScrollablePanel.java @@ -34,7 +34,7 @@ public class ScrollablePanel { @Override public Dimension getPreferredScrollableViewportSize() { - return UIScale.scale( new Dimension( 400, 400 ) ); + return new Dimension( getPreferredSize().width, UIScale.scale( 400 ) ); } @Override @@ -49,7 +49,7 @@ public int getScrollableBlockIncrement( Rectangle visibleRect, int orientation, @Override public boolean getScrollableTracksViewportWidth() { - return false; + return true; } @Override diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.java b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.java index 473c996e1..37921f538 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.java +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.java @@ -313,6 +313,14 @@ private void showTabSeparatorsChanged() { putTabbedPanesClientProperty( TABBED_PANE_SHOW_TAB_SEPARATORS, showTabSeparators ); } + private void tabRotationChanged() { + String tabRotation = rotationAutoButton.isSelected() ? TABBED_PANE_TAB_ROTATION_AUTO + : rotationLeftButton.isSelected() ? TABBED_PANE_TAB_ROTATION_LEFT + : rotationRightButton.isSelected() ? TABBED_PANE_TAB_ROTATION_RIGHT + : null; + putTabbedPanesClientProperty( TABBED_PANE_TAB_ROTATION, tabRotation ); + } + private void putTabbedPanesClientProperty( String key, Object value ) { updateTabbedPanesRecur( this, tabbedPane -> tabbedPane.putClientProperty( key, value ) ); } @@ -331,6 +339,8 @@ private void updateTabbedPanesRecur( Container container, Consumer private void initComponents() { // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + JScrollPane tabsScrollPane = new JScrollPane(); + ScrollablePanel panel6 = new ScrollablePanel(); JPanel panel1 = new JPanel(); JLabel tabPlacementLabel = new JLabel(); tabPlacementToolBar = new JToolBar(); @@ -397,344 +407,369 @@ private void initComponents() { scrollAsNeededSingleButton = new JToggleButton(); scrollAsNeededButton = new JToggleButton(); scrollNeverButton = new JToggleButton(); - scrollButtonsPlacementLabel = new JLabel(); - scrollButtonsPlacementToolBar = new JToolBar(); - scrollBothButton = new JToggleButton(); - scrollTrailingButton = new JToggleButton(); - showTabSeparatorsCheckBox = new JCheckBox(); tabsPopupPolicyLabel = new JLabel(); tabsPopupPolicyToolBar = new JToolBar(); popupAsNeededButton = new JToggleButton(); popupNeverButton = new JToggleButton(); + showTabSeparatorsCheckBox = new JCheckBox(); + scrollButtonsPlacementLabel = new JLabel(); + scrollButtonsPlacementToolBar = new JToolBar(); + scrollBothButton = new JToggleButton(); + scrollTrailingButton = new JToggleButton(); tabTypeLabel = new JLabel(); tabTypeToolBar = new JToolBar(); underlinedTabTypeButton = new JToggleButton(); cardTabTypeButton = new JToggleButton(); + tabRotationLabel = new JLabel(); + tabRotationToolBar = new JToolBar(); + rotationNoneButton = new JToggleButton(); + rotationAutoButton = new JToggleButton(); + rotationLeftButton = new JToggleButton(); + rotationRightButton = new JToggleButton(); //======== this ======== setLayout(new MigLayout( - "insets dialog,hidemode 3", + "insets 0,hidemode 3", // columns - "[grow,fill]para" + - "[fill]para" + - "[fill]", + "[grow,fill]", // rows - "[grow,fill]para" + - "[]" + + "[grow,fill]0" + + "[]0" + "[]")); - //======== panel1 ======== - { - panel1.setLayout(new MigLayout( - "insets 0,hidemode 3", - // columns - "[grow,fill]", - // rows - "[]" + - "[fill]para" + - "[]0" + - "[]" + - "[]para" + - "[]" + - "[]para" + - "[]" + - "[]")); - - //---- tabPlacementLabel ---- - tabPlacementLabel.setText("Tab placement"); - tabPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel1.add(tabPlacementLabel, "cell 0 0"); - - //======== tabPlacementToolBar ======== - { - tabPlacementToolBar.setFloatable(false); - tabPlacementToolBar.setBorder(BorderFactory.createEmptyBorder()); - - //---- topPlacementButton ---- - topPlacementButton.setText("top"); - topPlacementButton.setSelected(true); - topPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); - topPlacementButton.addActionListener(e -> tabPlacementChanged()); - tabPlacementToolBar.add(topPlacementButton); - - //---- bottomPlacementButton ---- - bottomPlacementButton.setText("bottom"); - bottomPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); - bottomPlacementButton.addActionListener(e -> tabPlacementChanged()); - tabPlacementToolBar.add(bottomPlacementButton); - - //---- leftPlacementButton ---- - leftPlacementButton.setText("left"); - leftPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); - leftPlacementButton.addActionListener(e -> tabPlacementChanged()); - tabPlacementToolBar.add(leftPlacementButton); - - //---- rightPlacementButton ---- - rightPlacementButton.setText("right"); - rightPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); - rightPlacementButton.addActionListener(e -> tabPlacementChanged()); - tabPlacementToolBar.add(rightPlacementButton); - tabPlacementToolBar.addSeparator(); - - //---- scrollButton ---- - scrollButton.setText("scroll"); - scrollButton.putClientProperty("FlatLaf.styleClass", "small"); - scrollButton.addActionListener(e -> scrollChanged()); - tabPlacementToolBar.add(scrollButton); - - //---- borderButton ---- - borderButton.setText("border"); - borderButton.putClientProperty("FlatLaf.styleClass", "small"); - borderButton.addActionListener(e -> borderChanged()); - tabPlacementToolBar.add(borderButton); - } - panel1.add(tabPlacementToolBar, "cell 0 0,alignx right,growx 0"); - panel1.add(tabPlacementTabbedPane, "cell 0 1,width 300:300,height 100:100"); - - //---- tabLayoutLabel ---- - tabLayoutLabel.setText("Tab layout"); - tabLayoutLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel1.add(tabLayoutLabel, "cell 0 2"); - - //======== tabLayoutToolBar ======== - { - tabLayoutToolBar.setFloatable(false); - tabLayoutToolBar.setBorder(BorderFactory.createEmptyBorder()); - - //---- scrollTabLayoutButton ---- - scrollTabLayoutButton.setText("scroll"); - scrollTabLayoutButton.setSelected(true); - scrollTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small"); - scrollTabLayoutButton.addActionListener(e -> tabLayoutChanged()); - tabLayoutToolBar.add(scrollTabLayoutButton); - - //---- wrapTabLayoutButton ---- - wrapTabLayoutButton.setText("wrap"); - wrapTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small"); - wrapTabLayoutButton.addActionListener(e -> tabLayoutChanged()); - tabLayoutToolBar.add(wrapTabLayoutButton); - } - panel1.add(tabLayoutToolBar, "cell 0 2,alignx right,growx 0"); - - //---- scrollLayoutNoteLabel ---- - scrollLayoutNoteLabel.setText("(use mouse wheel to scroll; arrow button shows hidden tabs)"); - scrollLayoutNoteLabel.setEnabled(false); - scrollLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); - panel1.add(scrollLayoutNoteLabel, "cell 0 3"); - - //---- wrapLayoutNoteLabel ---- - wrapLayoutNoteLabel.setText("(probably better to use scroll layout?)"); - wrapLayoutNoteLabel.setEnabled(false); - wrapLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); - panel1.add(wrapLayoutNoteLabel, "cell 0 3"); - panel1.add(scrollLayoutTabbedPane, "cell 0 4"); - panel1.add(wrapLayoutTabbedPane, "cell 0 4,width 100:100,height pref*2px"); - - //---- closableTabsLabel ---- - closableTabsLabel.setText("Closable tabs"); - closableTabsLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel1.add(closableTabsLabel, "cell 0 5"); - - //======== closableTabsToolBar ======== - { - closableTabsToolBar.setFloatable(false); - closableTabsToolBar.setBorder(BorderFactory.createEmptyBorder()); - - //---- squareCloseButton ---- - squareCloseButton.setText("square"); - squareCloseButton.setSelected(true); - squareCloseButton.putClientProperty("FlatLaf.styleClass", "small"); - squareCloseButton.addActionListener(e -> closeButtonStyleChanged()); - closableTabsToolBar.add(squareCloseButton); - - //---- circleCloseButton ---- - circleCloseButton.setText("circle"); - circleCloseButton.putClientProperty("FlatLaf.styleClass", "small"); - circleCloseButton.addActionListener(e -> closeButtonStyleChanged()); - closableTabsToolBar.add(circleCloseButton); - - //---- redCrossCloseButton ---- - redCrossCloseButton.setText("red cross"); - redCrossCloseButton.putClientProperty("FlatLaf.styleClass", "small"); - redCrossCloseButton.addActionListener(e -> closeButtonStyleChanged()); - closableTabsToolBar.add(redCrossCloseButton); - } - panel1.add(closableTabsToolBar, "cell 0 5,alignx right,growx 0"); - panel1.add(closableTabsTabbedPane, "cell 0 6"); - - //---- tabAreaComponentsLabel ---- - tabAreaComponentsLabel.setText("Custom tab area components"); - tabAreaComponentsLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel1.add(tabAreaComponentsLabel, "cell 0 7"); - - //======== tabAreaComponentsToolBar ======== - { - tabAreaComponentsToolBar.setFloatable(false); - tabAreaComponentsToolBar.setBorder(BorderFactory.createEmptyBorder()); - - //---- leadingComponentButton ---- - leadingComponentButton.setText("leading"); - leadingComponentButton.setSelected(true); - leadingComponentButton.putClientProperty("FlatLaf.styleClass", "small"); - leadingComponentButton.addActionListener(e -> customComponentsChanged()); - tabAreaComponentsToolBar.add(leadingComponentButton); - - //---- trailingComponentButton ---- - trailingComponentButton.setText("trailing"); - trailingComponentButton.setSelected(true); - trailingComponentButton.putClientProperty("FlatLaf.styleClass", "small"); - trailingComponentButton.addActionListener(e -> customComponentsChanged()); - tabAreaComponentsToolBar.add(trailingComponentButton); - } - panel1.add(tabAreaComponentsToolBar, "cell 0 7,alignx right,growx 0"); - panel1.add(customComponentsTabbedPane, "cell 0 8"); - } - add(panel1, "cell 0 0"); - - //======== panel2 ======== + //======== tabsScrollPane ======== { - panel2.setLayout(new MigLayout( - "insets 0,hidemode 3", - // columns - "[grow,fill]", - // rows - "[]0" + - "[]" + - "[fill]" + - "[center]" + - "[center]" + - "[center]para" + - "[center]0" + - "[]" + - "[center]" + - "[center]" + - "[center]" + - "[]")); - - //---- tabIconPlacementLabel ---- - tabIconPlacementLabel.setText("Tab icon placement"); - tabIconPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel2.add(tabIconPlacementLabel, "cell 0 0"); - - //---- tabIconPlacementNodeLabel ---- - tabIconPlacementNodeLabel.setText("(top/bottom/leading/trailing)"); - tabIconPlacementNodeLabel.setEnabled(false); - tabIconPlacementNodeLabel.putClientProperty("FlatLaf.styleClass", "small"); - panel2.add(tabIconPlacementNodeLabel, "cell 0 1"); - panel2.add(iconTopTabbedPane, "cell 0 2"); - panel2.add(iconBottomTabbedPane, "cell 0 3"); - panel2.add(iconLeadingTabbedPane, "cell 0 4"); - panel2.add(iconTrailingTabbedPane, "cell 0 5"); - - //---- tabAreaAlignmentLabel ---- - tabAreaAlignmentLabel.setText("Tab area alignment"); - tabAreaAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel2.add(tabAreaAlignmentLabel, "cell 0 6"); - - //---- tabAreaAlignmentNoteLabel ---- - tabAreaAlignmentNoteLabel.setText("(leading/center/trailing/fill)"); - tabAreaAlignmentNoteLabel.setEnabled(false); - tabAreaAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); - panel2.add(tabAreaAlignmentNoteLabel, "cell 0 7"); - panel2.add(alignLeadingTabbedPane, "cell 0 8"); - panel2.add(alignCenterTabbedPane, "cell 0 9"); - panel2.add(alignTrailingTabbedPane, "cell 0 10"); - panel2.add(alignFillTabbedPane, "cell 0 11"); - } - add(panel2, "cell 1 0,growy"); + tabsScrollPane.setBorder(BorderFactory.createEmptyBorder()); - //======== panel3 ======== - { - panel3.setLayout(new MigLayout( - "insets 0,hidemode 3", - // columns - "[grow,fill]", - // rows - "[]0" + - "[]" + - "[]" + - "[]" + - "[]para" + - "[]" + - "[]" + - "[]para" + - "[]0" + - "[]")); - - //---- tabWidthModeLabel ---- - tabWidthModeLabel.setText("Tab width mode"); - tabWidthModeLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel3.add(tabWidthModeLabel, "cell 0 0"); - - //---- tabWidthModeNoteLabel ---- - tabWidthModeNoteLabel.setText("(preferred/equal/compact)"); - tabWidthModeNoteLabel.setEnabled(false); - tabWidthModeNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); - panel3.add(tabWidthModeNoteLabel, "cell 0 1"); - panel3.add(widthPreferredTabbedPane, "cell 0 2"); - panel3.add(widthEqualTabbedPane, "cell 0 3"); - panel3.add(widthCompactTabbedPane, "cell 0 4"); - - //---- minMaxTabWidthLabel ---- - minMaxTabWidthLabel.setText("Minimum/maximum tab width"); - minMaxTabWidthLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel3.add(minMaxTabWidthLabel, "cell 0 5"); - panel3.add(minimumTabWidthTabbedPane, "cell 0 6"); - panel3.add(maximumTabWidthTabbedPane, "cell 0 7"); - - //---- tabAlignmentLabel ---- - tabAlignmentLabel.setText("Tab title alignment"); - tabAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3"); - panel3.add(tabAlignmentLabel, "cell 0 8"); - - //======== panel5 ======== + //======== panel6 ======== { - panel5.setLayout(new MigLayout( - "insets 0,hidemode 3", + panel6.setLayout(new MigLayout( + "insets dialog,hidemode 3", // columns "[grow,fill]para" + + "[fill]para" + "[fill]", // rows - "[]" + - "[]" + - "[]" + - "[]")); - - //---- tabAlignmentNoteLabel ---- - tabAlignmentNoteLabel.setText("(leading/center/trailing)"); - tabAlignmentNoteLabel.setEnabled(false); - tabAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); - panel5.add(tabAlignmentNoteLabel, "cell 0 0"); - - //---- tabAlignmentNoteLabel2 ---- - tabAlignmentNoteLabel2.setText("(trailing)"); - tabAlignmentNoteLabel2.setEnabled(false); - tabAlignmentNoteLabel2.putClientProperty("FlatLaf.styleClass", "small"); - panel5.add(tabAlignmentNoteLabel2, "cell 1 0,alignx right,growx 0"); - panel5.add(tabAlignLeadingTabbedPane, "cell 0 1"); - - //======== tabAlignVerticalTabbedPane ======== + "[grow,fill]")); + + //======== panel1 ======== { - tabAlignVerticalTabbedPane.setTabPlacement(SwingConstants.LEFT); + panel1.setLayout(new MigLayout( + "insets 0,hidemode 3", + // columns + "[grow,fill]", + // rows + "[]" + + "[fill]para" + + "[]0" + + "[]" + + "[]para" + + "[]" + + "[]para" + + "[]" + + "[]")); + + //---- tabPlacementLabel ---- + tabPlacementLabel.setText("Tab placement"); + tabPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel1.add(tabPlacementLabel, "cell 0 0"); + + //======== tabPlacementToolBar ======== + { + tabPlacementToolBar.setFloatable(false); + tabPlacementToolBar.setBorder(BorderFactory.createEmptyBorder()); + + //---- topPlacementButton ---- + topPlacementButton.setText("top"); + topPlacementButton.setSelected(true); + topPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); + topPlacementButton.addActionListener(e -> tabPlacementChanged()); + tabPlacementToolBar.add(topPlacementButton); + + //---- bottomPlacementButton ---- + bottomPlacementButton.setText("bottom"); + bottomPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); + bottomPlacementButton.addActionListener(e -> tabPlacementChanged()); + tabPlacementToolBar.add(bottomPlacementButton); + + //---- leftPlacementButton ---- + leftPlacementButton.setText("left"); + leftPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); + leftPlacementButton.addActionListener(e -> tabPlacementChanged()); + tabPlacementToolBar.add(leftPlacementButton); + + //---- rightPlacementButton ---- + rightPlacementButton.setText("right"); + rightPlacementButton.putClientProperty("FlatLaf.styleClass", "small"); + rightPlacementButton.addActionListener(e -> tabPlacementChanged()); + tabPlacementToolBar.add(rightPlacementButton); + tabPlacementToolBar.addSeparator(); + + //---- scrollButton ---- + scrollButton.setText("scroll"); + scrollButton.putClientProperty("FlatLaf.styleClass", "small"); + scrollButton.addActionListener(e -> scrollChanged()); + tabPlacementToolBar.add(scrollButton); + + //---- borderButton ---- + borderButton.setText("border"); + borderButton.putClientProperty("FlatLaf.styleClass", "small"); + borderButton.addActionListener(e -> borderChanged()); + tabPlacementToolBar.add(borderButton); + } + panel1.add(tabPlacementToolBar, "cell 0 0,alignx right,growx 0"); + panel1.add(tabPlacementTabbedPane, "cell 0 1,width 300:300,height 100:100"); + + //---- tabLayoutLabel ---- + tabLayoutLabel.setText("Tab layout"); + tabLayoutLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel1.add(tabLayoutLabel, "cell 0 2"); + + //======== tabLayoutToolBar ======== + { + tabLayoutToolBar.setFloatable(false); + tabLayoutToolBar.setBorder(BorderFactory.createEmptyBorder()); + + //---- scrollTabLayoutButton ---- + scrollTabLayoutButton.setText("scroll"); + scrollTabLayoutButton.setSelected(true); + scrollTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small"); + scrollTabLayoutButton.addActionListener(e -> tabLayoutChanged()); + tabLayoutToolBar.add(scrollTabLayoutButton); + + //---- wrapTabLayoutButton ---- + wrapTabLayoutButton.setText("wrap"); + wrapTabLayoutButton.putClientProperty("FlatLaf.styleClass", "small"); + wrapTabLayoutButton.addActionListener(e -> tabLayoutChanged()); + tabLayoutToolBar.add(wrapTabLayoutButton); + } + panel1.add(tabLayoutToolBar, "cell 0 2,alignx right,growx 0"); + + //---- scrollLayoutNoteLabel ---- + scrollLayoutNoteLabel.setText("(use mouse wheel to scroll; arrow button shows hidden tabs)"); + scrollLayoutNoteLabel.setEnabled(false); + scrollLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); + panel1.add(scrollLayoutNoteLabel, "cell 0 3"); + + //---- wrapLayoutNoteLabel ---- + wrapLayoutNoteLabel.setText("(probably better to use scroll layout?)"); + wrapLayoutNoteLabel.setEnabled(false); + wrapLayoutNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); + panel1.add(wrapLayoutNoteLabel, "cell 0 3"); + panel1.add(scrollLayoutTabbedPane, "cell 0 4"); + panel1.add(wrapLayoutTabbedPane, "cell 0 4,width 100:100,height pref*2px"); + + //---- closableTabsLabel ---- + closableTabsLabel.setText("Closable tabs"); + closableTabsLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel1.add(closableTabsLabel, "cell 0 5"); + + //======== closableTabsToolBar ======== + { + closableTabsToolBar.setFloatable(false); + closableTabsToolBar.setBorder(BorderFactory.createEmptyBorder()); + + //---- squareCloseButton ---- + squareCloseButton.setText("square"); + squareCloseButton.setSelected(true); + squareCloseButton.putClientProperty("FlatLaf.styleClass", "small"); + squareCloseButton.addActionListener(e -> closeButtonStyleChanged()); + closableTabsToolBar.add(squareCloseButton); + + //---- circleCloseButton ---- + circleCloseButton.setText("circle"); + circleCloseButton.putClientProperty("FlatLaf.styleClass", "small"); + circleCloseButton.addActionListener(e -> closeButtonStyleChanged()); + closableTabsToolBar.add(circleCloseButton); + + //---- redCrossCloseButton ---- + redCrossCloseButton.setText("red cross"); + redCrossCloseButton.putClientProperty("FlatLaf.styleClass", "small"); + redCrossCloseButton.addActionListener(e -> closeButtonStyleChanged()); + closableTabsToolBar.add(redCrossCloseButton); + } + panel1.add(closableTabsToolBar, "cell 0 5,alignx right,growx 0"); + panel1.add(closableTabsTabbedPane, "cell 0 6"); + + //---- tabAreaComponentsLabel ---- + tabAreaComponentsLabel.setText("Custom tab area components"); + tabAreaComponentsLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel1.add(tabAreaComponentsLabel, "cell 0 7"); + + //======== tabAreaComponentsToolBar ======== + { + tabAreaComponentsToolBar.setFloatable(false); + tabAreaComponentsToolBar.setBorder(BorderFactory.createEmptyBorder()); + + //---- leadingComponentButton ---- + leadingComponentButton.setText("leading"); + leadingComponentButton.setSelected(true); + leadingComponentButton.putClientProperty("FlatLaf.styleClass", "small"); + leadingComponentButton.addActionListener(e -> customComponentsChanged()); + tabAreaComponentsToolBar.add(leadingComponentButton); + + //---- trailingComponentButton ---- + trailingComponentButton.setText("trailing"); + trailingComponentButton.setSelected(true); + trailingComponentButton.putClientProperty("FlatLaf.styleClass", "small"); + trailingComponentButton.addActionListener(e -> customComponentsChanged()); + tabAreaComponentsToolBar.add(trailingComponentButton); + } + panel1.add(tabAreaComponentsToolBar, "cell 0 7,alignx right,growx 0"); + panel1.add(customComponentsTabbedPane, "cell 0 8"); } - panel5.add(tabAlignVerticalTabbedPane, "cell 1 1 1 3,growy"); - panel5.add(tabAlignCenterTabbedPane, "cell 0 2"); - panel5.add(tabAlignTrailingTabbedPane, "cell 0 3"); + panel6.add(panel1, "cell 0 0"); + + //======== panel2 ======== + { + panel2.setLayout(new MigLayout( + "insets 0,hidemode 3", + // columns + "[grow,fill]", + // rows + "[]0" + + "[]" + + "[fill]" + + "[center]" + + "[center]" + + "[center]para" + + "[center]0" + + "[]" + + "[center]" + + "[center]" + + "[center]" + + "[]")); + + //---- tabIconPlacementLabel ---- + tabIconPlacementLabel.setText("Tab icon placement"); + tabIconPlacementLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel2.add(tabIconPlacementLabel, "cell 0 0"); + + //---- tabIconPlacementNodeLabel ---- + tabIconPlacementNodeLabel.setText("(top/bottom/leading/trailing)"); + tabIconPlacementNodeLabel.setEnabled(false); + tabIconPlacementNodeLabel.putClientProperty("FlatLaf.styleClass", "small"); + panel2.add(tabIconPlacementNodeLabel, "cell 0 1"); + panel2.add(iconTopTabbedPane, "cell 0 2"); + panel2.add(iconBottomTabbedPane, "cell 0 3"); + panel2.add(iconLeadingTabbedPane, "cell 0 4"); + panel2.add(iconTrailingTabbedPane, "cell 0 5"); + + //---- tabAreaAlignmentLabel ---- + tabAreaAlignmentLabel.setText("Tab area alignment"); + tabAreaAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel2.add(tabAreaAlignmentLabel, "cell 0 6"); + + //---- tabAreaAlignmentNoteLabel ---- + tabAreaAlignmentNoteLabel.setText("(leading/center/trailing/fill)"); + tabAreaAlignmentNoteLabel.setEnabled(false); + tabAreaAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); + panel2.add(tabAreaAlignmentNoteLabel, "cell 0 7"); + panel2.add(alignLeadingTabbedPane, "cell 0 8"); + panel2.add(alignCenterTabbedPane, "cell 0 9"); + panel2.add(alignTrailingTabbedPane, "cell 0 10"); + panel2.add(alignFillTabbedPane, "cell 0 11"); + } + panel6.add(panel2, "cell 1 0,growy"); + + //======== panel3 ======== + { + panel3.setLayout(new MigLayout( + "insets 0,hidemode 3", + // columns + "[grow,fill]", + // rows + "[]0" + + "[]" + + "[]" + + "[]" + + "[]para" + + "[]" + + "[]" + + "[]para" + + "[]0" + + "[]")); + + //---- tabWidthModeLabel ---- + tabWidthModeLabel.setText("Tab width mode"); + tabWidthModeLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel3.add(tabWidthModeLabel, "cell 0 0"); + + //---- tabWidthModeNoteLabel ---- + tabWidthModeNoteLabel.setText("(preferred/equal/compact)"); + tabWidthModeNoteLabel.setEnabled(false); + tabWidthModeNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); + panel3.add(tabWidthModeNoteLabel, "cell 0 1"); + panel3.add(widthPreferredTabbedPane, "cell 0 2"); + panel3.add(widthEqualTabbedPane, "cell 0 3"); + panel3.add(widthCompactTabbedPane, "cell 0 4"); + + //---- minMaxTabWidthLabel ---- + minMaxTabWidthLabel.setText("Minimum/maximum tab width"); + minMaxTabWidthLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel3.add(minMaxTabWidthLabel, "cell 0 5"); + panel3.add(minimumTabWidthTabbedPane, "cell 0 6"); + panel3.add(maximumTabWidthTabbedPane, "cell 0 7"); + + //---- tabAlignmentLabel ---- + tabAlignmentLabel.setText("Tab title alignment"); + tabAlignmentLabel.putClientProperty("FlatLaf.styleClass", "h3"); + panel3.add(tabAlignmentLabel, "cell 0 8"); + + //======== panel5 ======== + { + panel5.setLayout(new MigLayout( + "insets 0,hidemode 3", + // columns + "[grow,fill]para" + + "[fill]", + // rows + "[]" + + "[]" + + "[]" + + "[]" + + "[]")); + + //---- tabAlignmentNoteLabel ---- + tabAlignmentNoteLabel.setText("(leading/center/trailing)"); + tabAlignmentNoteLabel.setEnabled(false); + tabAlignmentNoteLabel.putClientProperty("FlatLaf.styleClass", "small"); + panel5.add(tabAlignmentNoteLabel, "cell 0 0"); + + //---- tabAlignmentNoteLabel2 ---- + tabAlignmentNoteLabel2.setText("(trailing)"); + tabAlignmentNoteLabel2.setEnabled(false); + tabAlignmentNoteLabel2.putClientProperty("FlatLaf.styleClass", "small"); + panel5.add(tabAlignmentNoteLabel2, "cell 1 0,alignx right,growx 0"); + panel5.add(tabAlignLeadingTabbedPane, "cell 0 1"); + + //======== tabAlignVerticalTabbedPane ======== + { + tabAlignVerticalTabbedPane.setTabPlacement(SwingConstants.LEFT); + } + panel5.add(tabAlignVerticalTabbedPane, "cell 1 1 1 4,growy"); + panel5.add(tabAlignCenterTabbedPane, "cell 0 2"); + panel5.add(tabAlignTrailingTabbedPane, "cell 0 3"); + } + panel3.add(panel5, "cell 0 9"); + } + panel6.add(panel3, "cell 2 0"); } - panel3.add(panel5, "cell 0 9"); + tabsScrollPane.setViewportView(panel6); } - add(panel3, "cell 2 0"); - add(separator2, "cell 0 1 3 1"); + add(tabsScrollPane, "cell 0 0"); + add(separator2, "cell 0 1"); //======== panel4 ======== { panel4.setLayout(new MigLayout( - "insets 0,hidemode 3", + "insets panel,hidemode 3", // columns "[]" + "[fill]para" + "[fill]" + "[fill]para" + + "[fill]" + "[fill]", // rows "[]" + @@ -770,38 +805,9 @@ private void initComponents() { } panel4.add(scrollButtonsPolicyToolBar, "cell 1 0"); - //---- scrollButtonsPlacementLabel ---- - scrollButtonsPlacementLabel.setText("Scroll buttons placement:"); - panel4.add(scrollButtonsPlacementLabel, "cell 2 0"); - - //======== scrollButtonsPlacementToolBar ======== - { - scrollButtonsPlacementToolBar.setFloatable(false); - scrollButtonsPlacementToolBar.setBorder(BorderFactory.createEmptyBorder()); - - //---- scrollBothButton ---- - scrollBothButton.setText("both"); - scrollBothButton.setSelected(true); - scrollBothButton.putClientProperty("FlatLaf.styleClass", "small"); - scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged()); - scrollButtonsPlacementToolBar.add(scrollBothButton); - - //---- scrollTrailingButton ---- - scrollTrailingButton.setText("trailing"); - scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small"); - scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged()); - scrollButtonsPlacementToolBar.add(scrollTrailingButton); - } - panel4.add(scrollButtonsPlacementToolBar, "cell 3 0"); - - //---- showTabSeparatorsCheckBox ---- - showTabSeparatorsCheckBox.setText("Show tab separators"); - showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged()); - panel4.add(showTabSeparatorsCheckBox, "cell 4 0"); - //---- tabsPopupPolicyLabel ---- tabsPopupPolicyLabel.setText("Tabs popup policy:"); - panel4.add(tabsPopupPolicyLabel, "cell 0 1"); + panel4.add(tabsPopupPolicyLabel, "cell 2 0"); //======== tabsPopupPolicyToolBar ======== { @@ -821,7 +827,36 @@ private void initComponents() { popupNeverButton.addActionListener(e -> tabsPopupPolicyChanged()); tabsPopupPolicyToolBar.add(popupNeverButton); } - panel4.add(tabsPopupPolicyToolBar, "cell 1 1"); + panel4.add(tabsPopupPolicyToolBar, "cell 3 0"); + + //---- showTabSeparatorsCheckBox ---- + showTabSeparatorsCheckBox.setText("Show tab separators"); + showTabSeparatorsCheckBox.addActionListener(e -> showTabSeparatorsChanged()); + panel4.add(showTabSeparatorsCheckBox, "cell 4 0 2 1,alignx left,growx 0"); + + //---- scrollButtonsPlacementLabel ---- + scrollButtonsPlacementLabel.setText("Scroll buttons placement:"); + panel4.add(scrollButtonsPlacementLabel, "cell 0 1"); + + //======== scrollButtonsPlacementToolBar ======== + { + scrollButtonsPlacementToolBar.setFloatable(false); + scrollButtonsPlacementToolBar.setBorder(BorderFactory.createEmptyBorder()); + + //---- scrollBothButton ---- + scrollBothButton.setText("both"); + scrollBothButton.setSelected(true); + scrollBothButton.putClientProperty("FlatLaf.styleClass", "small"); + scrollBothButton.addActionListener(e -> scrollButtonsPlacementChanged()); + scrollButtonsPlacementToolBar.add(scrollBothButton); + + //---- scrollTrailingButton ---- + scrollTrailingButton.setText("trailing"); + scrollTrailingButton.putClientProperty("FlatLaf.styleClass", "small"); + scrollTrailingButton.addActionListener(e -> scrollButtonsPlacementChanged()); + scrollButtonsPlacementToolBar.add(scrollTrailingButton); + } + panel4.add(scrollButtonsPlacementToolBar, "cell 1 1"); //---- tabTypeLabel ---- tabTypeLabel.setText("Tab type:"); @@ -845,8 +880,44 @@ private void initComponents() { tabTypeToolBar.add(cardTabTypeButton); } panel4.add(tabTypeToolBar, "cell 3 1"); + + //---- tabRotationLabel ---- + tabRotationLabel.setText("Tab rotation:"); + panel4.add(tabRotationLabel, "cell 4 1"); + + //======== tabRotationToolBar ======== + { + tabRotationToolBar.setFloatable(false); + tabRotationToolBar.setBorder(BorderFactory.createEmptyBorder()); + + //---- rotationNoneButton ---- + rotationNoneButton.setText("none"); + rotationNoneButton.setSelected(true); + rotationNoneButton.putClientProperty("FlatLaf.styleClass", "small"); + rotationNoneButton.addActionListener(e -> tabRotationChanged()); + tabRotationToolBar.add(rotationNoneButton); + + //---- rotationAutoButton ---- + rotationAutoButton.setText("auto"); + rotationAutoButton.putClientProperty("FlatLaf.styleClass", "small"); + rotationAutoButton.addActionListener(e -> tabRotationChanged()); + tabRotationToolBar.add(rotationAutoButton); + + //---- rotationLeftButton ---- + rotationLeftButton.setText("left"); + rotationLeftButton.putClientProperty("FlatLaf.styleClass", "small"); + rotationLeftButton.addActionListener(e -> tabRotationChanged()); + tabRotationToolBar.add(rotationLeftButton); + + //---- rotationRightButton ---- + rotationRightButton.setText("right"); + rotationRightButton.putClientProperty("FlatLaf.styleClass", "small"); + rotationRightButton.addActionListener(e -> tabRotationChanged()); + tabRotationToolBar.add(rotationRightButton); + } + panel4.add(tabRotationToolBar, "cell 5 1"); } - add(panel4, "cell 0 2 3 1"); + add(panel4, "cell 0 2"); //---- tabPlacementButtonGroup ---- ButtonGroup tabPlacementButtonGroup = new ButtonGroup(); @@ -872,20 +943,27 @@ private void initComponents() { scrollButtonsPolicyButtonGroup.add(scrollAsNeededButton); scrollButtonsPolicyButtonGroup.add(scrollNeverButton); - //---- scrollButtonsPlacementButtonGroup ---- - ButtonGroup scrollButtonsPlacementButtonGroup = new ButtonGroup(); - scrollButtonsPlacementButtonGroup.add(scrollBothButton); - scrollButtonsPlacementButtonGroup.add(scrollTrailingButton); - //---- tabsPopupPolicyButtonGroup ---- ButtonGroup tabsPopupPolicyButtonGroup = new ButtonGroup(); tabsPopupPolicyButtonGroup.add(popupAsNeededButton); tabsPopupPolicyButtonGroup.add(popupNeverButton); + //---- scrollButtonsPlacementButtonGroup ---- + ButtonGroup scrollButtonsPlacementButtonGroup = new ButtonGroup(); + scrollButtonsPlacementButtonGroup.add(scrollBothButton); + scrollButtonsPlacementButtonGroup.add(scrollTrailingButton); + //---- tabTypeButtonGroup ---- ButtonGroup tabTypeButtonGroup = new ButtonGroup(); tabTypeButtonGroup.add(underlinedTabTypeButton); tabTypeButtonGroup.add(cardTabTypeButton); + + //---- tabRotationButtonGroup ---- + ButtonGroup tabRotationButtonGroup = new ButtonGroup(); + tabRotationButtonGroup.add(rotationNoneButton); + tabRotationButtonGroup.add(rotationAutoButton); + tabRotationButtonGroup.add(rotationLeftButton); + tabRotationButtonGroup.add(rotationRightButton); // JFormDesigner - End of component initialization //GEN-END:initComponents if( FlatLafDemo.screenshotsMode ) { @@ -961,18 +1039,24 @@ private void initComponents() { private JToggleButton scrollAsNeededSingleButton; private JToggleButton scrollAsNeededButton; private JToggleButton scrollNeverButton; - private JLabel scrollButtonsPlacementLabel; - private JToolBar scrollButtonsPlacementToolBar; - private JToggleButton scrollBothButton; - private JToggleButton scrollTrailingButton; - private JCheckBox showTabSeparatorsCheckBox; private JLabel tabsPopupPolicyLabel; private JToolBar tabsPopupPolicyToolBar; private JToggleButton popupAsNeededButton; private JToggleButton popupNeverButton; + private JCheckBox showTabSeparatorsCheckBox; + private JLabel scrollButtonsPlacementLabel; + private JToolBar scrollButtonsPlacementToolBar; + private JToggleButton scrollBothButton; + private JToggleButton scrollTrailingButton; private JLabel tabTypeLabel; private JToolBar tabTypeToolBar; private JToggleButton underlinedTabTypeButton; private JToggleButton cardTabTypeButton; + private JLabel tabRotationLabel; + private JToolBar tabRotationToolBar; + private JToggleButton rotationNoneButton; + private JToggleButton rotationAutoButton; + private JToggleButton rotationLeftButton; + private JToggleButton rotationRightButton; // JFormDesigner - End of variables declaration //GEN-END:variables } diff --git a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.jfd b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.jfd index c241b05e9..aa9a1b161 100644 --- a/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.jfd +++ b/flatlaf-demo/src/main/java/com/formdev/flatlaf/demo/TabsPanel.jfd @@ -1,462 +1,481 @@ -JFDML JFormDesigner: "7.0.5.0.404" Java: "17" encoding: "UTF-8" +JFDML JFormDesigner: "8.2.0.0.331" Java: "21" encoding: "UTF-8" new FormModel { contentType: "form/swing" root: new FormRoot { add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { - "$layoutConstraints": "insets dialog,hidemode 3" - "$columnConstraints": "[grow,fill]para[fill]para[fill]" - "$rowConstraints": "[grow,fill]para[][]" + "$layoutConstraints": "insets 0,hidemode 3" + "$columnConstraints": "[grow,fill]" + "$rowConstraints": "[grow,fill]0[]0[]" } ) { name: "this" - add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { - "$layoutConstraints": "insets 0,hidemode 3" - "$columnConstraints": "[grow,fill]" - "$rowConstraints": "[][fill]para[]0[][]para[][]para[][]" - } ) { - name: "panel1" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabPlacementLabel" - "text": "Tab placement" - "$client.FlatLaf.styleClass": "h3" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 0" - } ) - add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { - name: "tabPlacementToolBar" - "floatable": false - "border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "topPlacementButton" - "text": "top" - "selected": true - "$buttonGroup": new FormReference( "tabPlacementButtonGroup" ) - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "bottomPlacementButton" - "text": "bottom" - "$buttonGroup": new FormReference( "tabPlacementButtonGroup" ) - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "leftPlacementButton" - "text": "left" - "$buttonGroup": new FormReference( "tabPlacementButtonGroup" ) - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "rightPlacementButton" - "text": "right" - "$buttonGroup": new FormReference( "tabPlacementButtonGroup" ) - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToolBar$Separator" ) { - name: "separator1" - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "scrollButton" - "text": "scroll" - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "borderButton" - "text": "border" - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "borderChanged", false ) ) - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 0,alignx right,growx 0" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "tabPlacementTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 1,width 300:300,height 100:100" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabLayoutLabel" - "text": "Tab layout" - "$client.FlatLaf.styleClass": "h3" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2" - } ) - add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { - name: "tabLayoutToolBar" - "floatable": false - "border": &EmptyBorder0 new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "scrollTabLayoutButton" - "text": "scroll" - "$buttonGroup": new FormReference( "tabLayoutButtonGroup" ) - "selected": true - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabLayoutChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "wrapTabLayoutButton" - "text": "wrap" - "$buttonGroup": new FormReference( "tabLayoutButtonGroup" ) - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabLayoutChanged", false ) ) - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2,alignx right,growx 0" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "scrollLayoutNoteLabel" - "text": "(use mouse wheel to scroll; arrow button shows hidden tabs)" - "enabled": false - "$client.FlatLaf.styleClass": "small" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 3" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "wrapLayoutNoteLabel" - "text": "(probably better to use scroll layout?)" - "enabled": false - "$client.FlatLaf.styleClass": "small" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 3" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "scrollLayoutTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 4" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "wrapLayoutTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 4,width 100:100,height pref*2px" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "closableTabsLabel" - "text": "Closable tabs" - "$client.FlatLaf.styleClass": "h3" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 5" - } ) - add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { - name: "closableTabsToolBar" - "floatable": false - "border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "squareCloseButton" - "text": "square" - "$buttonGroup": new FormReference( "closableTabsButtonGroup" ) - "selected": true - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "circleCloseButton" - "text": "circle" - "$buttonGroup": new FormReference( "closableTabsButtonGroup" ) - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "redCrossCloseButton" - "text": "red cross" - "$buttonGroup": new FormReference( "closableTabsButtonGroup" ) - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) ) - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 5,alignx right,growx 0" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "closableTabsTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 6" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabAreaComponentsLabel" - "text": "Custom tab area components" - "$client.FlatLaf.styleClass": "h3" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 7" - } ) - add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { - name: "tabAreaComponentsToolBar" - "floatable": false - "border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "leadingComponentButton" - "text": "leading" - "selected": true - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customComponentsChanged", false ) ) - } ) - add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "trailingComponentButton" - "text": "trailing" - "selected": true - "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customComponentsChanged", false ) ) - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 7,alignx right,growx 0" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "customComponentsTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 8" - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 0" - } ) - add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { - "$layoutConstraints": "insets 0,hidemode 3" - "$columnConstraints": "[grow,fill]" - "$rowConstraints": "[]0[][fill][center][center][center]para[center]0[][center][center][center][]" - } ) { - name: "panel2" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabIconPlacementLabel" - "text": "Tab icon placement" - "$client.FlatLaf.styleClass": "h3" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 0" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabIconPlacementNodeLabel" - "text": "(top/bottom/leading/trailing)" - "enabled": false - "$client.FlatLaf.styleClass": "small" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 1" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "iconTopTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "iconBottomTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 3" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "iconLeadingTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 4" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "iconTrailingTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 5" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabAreaAlignmentLabel" - "text": "Tab area alignment" - "$client.FlatLaf.styleClass": "h3" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 6" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabAreaAlignmentNoteLabel" - "text": "(leading/center/trailing/fill)" - "enabled": false - "$client.FlatLaf.styleClass": "small" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 7" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "alignLeadingTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 8" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "alignCenterTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 9" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "alignTrailingTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 10" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "alignFillTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 11" - } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 0,growy" - } ) - add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { - "$layoutConstraints": "insets 0,hidemode 3" - "$columnConstraints": "[grow,fill]" - "$rowConstraints": "[]0[][][][]para[][][]para[]0[]" - } ) { - name: "panel3" + add( new FormContainer( "javax.swing.JScrollPane", new FormLayoutManager( class javax.swing.JScrollPane ) ) { + name: "tabsScrollPane" + "border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) auxiliary() { "JavaCodeGenerator.variableLocal": true } - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabWidthModeLabel" - "text": "Tab width mode" - "$client.FlatLaf.styleClass": "h3" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 0" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabWidthModeNoteLabel" - "text": "(preferred/equal/compact)" - "enabled": false - "$client.FlatLaf.styleClass": "small" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 1" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "widthPreferredTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "widthEqualTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 3" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "widthCompactTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 4" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "minMaxTabWidthLabel" - "text": "Minimum/maximum tab width" - "$client.FlatLaf.styleClass": "h3" - auxiliary() { - "JavaCodeGenerator.variableLocal": true - } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 5" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "minimumTabWidthTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 6" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "maximumTabWidthTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 7" - } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabAlignmentLabel" - "text": "Tab title alignment" - "$client.FlatLaf.styleClass": "h3" + add( new FormContainer( "com.formdev.flatlaf.demo.ScrollablePanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$columnConstraints": "[grow,fill]para[fill]para[fill]" + "$rowConstraints": "[grow,fill]" + "$layoutConstraints": "insets dialog,hidemode 3" + } ) { + name: "panel6" auxiliary() { "JavaCodeGenerator.variableLocal": true } - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 8" - } ) - add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { - "$columnConstraints": "[grow,fill]para[fill]" - "$rowConstraints": "[][][][]" - "$layoutConstraints": "insets 0,hidemode 3" - } ) { - name: "panel5" - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabAlignmentNoteLabel" - "text": "(leading/center/trailing)" - "enabled": false - "$client.FlatLaf.styleClass": "small" + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets 0,hidemode 3" + "$columnConstraints": "[grow,fill]" + "$rowConstraints": "[][fill]para[]0[][]para[][]para[][]" + } ) { + name: "panel1" auxiliary() { "JavaCodeGenerator.variableLocal": true } + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabPlacementLabel" + "text": "Tab placement" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "tabPlacementToolBar" + "floatable": false + "border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "topPlacementButton" + "text": "top" + "selected": true + "$buttonGroup": new FormReference( "tabPlacementButtonGroup" ) + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "bottomPlacementButton" + "text": "bottom" + "$buttonGroup": new FormReference( "tabPlacementButtonGroup" ) + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "leftPlacementButton" + "text": "left" + "$buttonGroup": new FormReference( "tabPlacementButtonGroup" ) + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "rightPlacementButton" + "text": "right" + "$buttonGroup": new FormReference( "tabPlacementButtonGroup" ) + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToolBar$Separator" ) { + name: "separator1" + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "scrollButton" + "text": "scroll" + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "borderButton" + "text": "border" + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "borderChanged", false ) ) + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0,alignx right,growx 0" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabPlacementTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1,width 300:300,height 100:100" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabLayoutLabel" + "text": "Tab layout" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "tabLayoutToolBar" + "floatable": false + "border": &EmptyBorder0 new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "scrollTabLayoutButton" + "text": "scroll" + "$buttonGroup": new FormReference( "tabLayoutButtonGroup" ) + "selected": true + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabLayoutChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "wrapTabLayoutButton" + "text": "wrap" + "$buttonGroup": new FormReference( "tabLayoutButtonGroup" ) + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabLayoutChanged", false ) ) + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2,alignx right,growx 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "scrollLayoutNoteLabel" + "text": "(use mouse wheel to scroll; arrow button shows hidden tabs)" + "enabled": false + "$client.FlatLaf.styleClass": "small" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 3" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "wrapLayoutNoteLabel" + "text": "(probably better to use scroll layout?)" + "enabled": false + "$client.FlatLaf.styleClass": "small" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 3" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "scrollLayoutTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "wrapLayoutTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4,width 100:100,height pref*2px" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "closableTabsLabel" + "text": "Closable tabs" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 5" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "closableTabsToolBar" + "floatable": false + "border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "squareCloseButton" + "text": "square" + "$buttonGroup": new FormReference( "closableTabsButtonGroup" ) + "selected": true + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "circleCloseButton" + "text": "circle" + "$buttonGroup": new FormReference( "closableTabsButtonGroup" ) + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "redCrossCloseButton" + "text": "red cross" + "$buttonGroup": new FormReference( "closableTabsButtonGroup" ) + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "closeButtonStyleChanged", false ) ) + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 5,alignx right,growx 0" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "closableTabsTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 6" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabAreaComponentsLabel" + "text": "Custom tab area components" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 7" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "tabAreaComponentsToolBar" + "floatable": false + "border": new javax.swing.border.EmptyBorder( 0, 0, 0, 0 ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "leadingComponentButton" + "text": "leading" + "selected": true + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customComponentsChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "trailingComponentButton" + "text": "trailing" + "selected": true + "$client.FlatLaf.styleClass": "small" + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "customComponentsChanged", false ) ) + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 7,alignx right,growx 0" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "customComponentsTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 8" + } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 0" } ) - add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabAlignmentNoteLabel2" - "text": "(trailing)" - "enabled": false - "$client.FlatLaf.styleClass": "small" + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets 0,hidemode 3" + "$columnConstraints": "[grow,fill]" + "$rowConstraints": "[]0[][fill][center][center][center]para[center]0[][center][center][center][]" + } ) { + name: "panel2" auxiliary() { "JavaCodeGenerator.variableLocal": true } + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabIconPlacementLabel" + "text": "Tab icon placement" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabIconPlacementNodeLabel" + "text": "(top/bottom/leading/trailing)" + "enabled": false + "$client.FlatLaf.styleClass": "small" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "iconTopTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "iconBottomTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 3" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "iconLeadingTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "iconTrailingTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 5" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabAreaAlignmentLabel" + "text": "Tab area alignment" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 6" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabAreaAlignmentNoteLabel" + "text": "(leading/center/trailing/fill)" + "enabled": false + "$client.FlatLaf.styleClass": "small" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 7" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "alignLeadingTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 8" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "alignCenterTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 9" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "alignTrailingTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 10" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "alignFillTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 11" + } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 0,alignx right,growx 0" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "tabAlignLeadingTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 1" + "value": "cell 1 0,growy" } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "tabAlignVerticalTabbedPane" - "tabPlacement": 2 - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 1 1 1 3,growy" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "tabAlignCenterTabbedPane" - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2" - } ) - add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { - name: "tabAlignTrailingTabbedPane" + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets 0,hidemode 3" + "$columnConstraints": "[grow,fill]" + "$rowConstraints": "[]0[][][][]para[][][]para[]0[]" + } ) { + name: "panel3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabWidthModeLabel" + "text": "Tab width mode" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabWidthModeNoteLabel" + "text": "(preferred/equal/compact)" + "enabled": false + "$client.FlatLaf.styleClass": "small" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "widthPreferredTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "widthEqualTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 3" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "widthCompactTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 4" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "minMaxTabWidthLabel" + "text": "Minimum/maximum tab width" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 5" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "minimumTabWidthTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 6" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "maximumTabWidthTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 7" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabAlignmentLabel" + "text": "Tab title alignment" + "$client.FlatLaf.styleClass": "h3" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 8" + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$columnConstraints": "[grow,fill]para[fill]" + "$rowConstraints": "[][][][][]" + "$layoutConstraints": "insets 0,hidemode 3" + } ) { + name: "panel5" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabAlignmentNoteLabel" + "text": "(leading/center/trailing)" + "enabled": false + "$client.FlatLaf.styleClass": "small" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabAlignmentNoteLabel2" + "text": "(trailing)" + "enabled": false + "$client.FlatLaf.styleClass": "small" + auxiliary() { + "JavaCodeGenerator.variableLocal": true + } + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 0,alignx right,growx 0" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabAlignLeadingTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 1" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabAlignVerticalTabbedPane" + "tabPlacement": 2 + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 1 1 4,growy" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabAlignCenterTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 2" + } ) + add( new FormContainer( "javax.swing.JTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabAlignTrailingTabbedPane" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 3" + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 9" + } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 3" + "value": "cell 2 0" } ) - }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 9" } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 2 0" + "value": "cell 0 0" } ) add( new FormComponent( "javax.swing.JSeparator" ) { name: "separator2" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 1 3 1" + "value": "cell 0 1" } ) add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { - "$layoutConstraints": "insets 0,hidemode 3" - "$columnConstraints": "[][fill]para[fill][fill]para[fill]" + "$layoutConstraints": "insets panel,hidemode 3" + "$columnConstraints": "[][fill]para[fill][fill]para[fill][fill]" "$rowConstraints": "[][center]" } ) { name: "panel4" @@ -499,29 +518,29 @@ new FormModel { "value": "cell 1 0" } ) add( new FormComponent( "javax.swing.JLabel" ) { - name: "scrollButtonsPlacementLabel" - "text": "Scroll buttons placement:" + name: "tabsPopupPolicyLabel" + "text": "Tabs popup policy:" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 2 0" } ) add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { - name: "scrollButtonsPlacementToolBar" + name: "tabsPopupPolicyToolBar" "floatable": false "border": #EmptyBorder0 add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "scrollBothButton" - "text": "both" + name: "popupAsNeededButton" + "text": "asNeeded" "selected": true - "$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" ) + "$buttonGroup": new FormReference( "tabsPopupPolicyButtonGroup" ) "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "scrollTrailingButton" - "text": "trailing" - "$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" ) + name: "popupNeverButton" + "text": "never" + "$buttonGroup": new FormReference( "tabsPopupPolicyButtonGroup" ) "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) ) } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 3 0" @@ -534,32 +553,32 @@ new FormModel { } addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showTabSeparatorsChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 4 0" + "value": "cell 4 0 2 1,alignx left,growx 0" } ) add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabsPopupPolicyLabel" - "text": "Tabs popup policy:" + name: "scrollButtonsPlacementLabel" + "text": "Scroll buttons placement:" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 1" } ) add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { - name: "tabsPopupPolicyToolBar" + name: "scrollButtonsPlacementToolBar" "floatable": false "border": #EmptyBorder0 add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "popupAsNeededButton" - "text": "asNeeded" + name: "scrollBothButton" + "text": "both" "selected": true - "$buttonGroup": new FormReference( "tabsPopupPolicyButtonGroup" ) + "$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" ) "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) ) } ) add( new FormComponent( "javax.swing.JToggleButton" ) { - name: "popupNeverButton" - "text": "never" - "$buttonGroup": new FormReference( "tabsPopupPolicyButtonGroup" ) + name: "scrollTrailingButton" + "text": "trailing" + "$buttonGroup": new FormReference( "scrollButtonsPlacementButtonGroup" ) "$client.FlatLaf.styleClass": "small" - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) ) } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 1" @@ -591,47 +610,94 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 3 1" } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabRotationLabel" + "text": "Tab rotation:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 4 1" + } ) + add( new FormContainer( "javax.swing.JToolBar", new FormLayoutManager( class javax.swing.JToolBar ) ) { + name: "tabRotationToolBar" + "floatable": false + "border": #EmptyBorder0 + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "rotationNoneButton" + "text": "none" + "selected": true + "$client.FlatLaf.styleClass": "small" + "$buttonGroup": new FormReference( "tabRotationButtonGroup" ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "rotationAutoButton" + "text": "auto" + "$client.FlatLaf.styleClass": "small" + "$buttonGroup": new FormReference( "tabRotationButtonGroup" ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "rotationLeftButton" + "text": "left" + "$client.FlatLaf.styleClass": "small" + "$buttonGroup": new FormReference( "tabRotationButtonGroup" ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) ) + } ) + add( new FormComponent( "javax.swing.JToggleButton" ) { + name: "rotationRightButton" + "text": "right" + "$client.FlatLaf.styleClass": "small" + "$buttonGroup": new FormReference( "tabRotationButtonGroup" ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) ) + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 5 1" + } ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { - "value": "cell 0 2 3 1" + "value": "cell 0 2" } ) }, new FormLayoutConstraints( null ) { "location": new java.awt.Point( 0, 0 ) - "size": new java.awt.Dimension( 1145, 895 ) + "size": new java.awt.Dimension( 1145, 1045 ) } ) add( new FormNonVisual( "javax.swing.ButtonGroup" ) { name: "tabPlacementButtonGroup" }, new FormLayoutConstraints( null ) { - "location": new java.awt.Point( 5, 915 ) + "location": new java.awt.Point( 5, 1080 ) } ) add( new FormNonVisual( "javax.swing.ButtonGroup" ) { name: "closableTabsButtonGroup" }, new FormLayoutConstraints( null ) { - "location": new java.awt.Point( 5, 970 ) + "location": new java.awt.Point( 5, 1135 ) } ) add( new FormNonVisual( "javax.swing.ButtonGroup" ) { name: "tabLayoutButtonGroup" }, new FormLayoutConstraints( null ) { - "location": new java.awt.Point( 5, 1020 ) + "location": new java.awt.Point( 5, 1185 ) } ) add( new FormNonVisual( "javax.swing.ButtonGroup" ) { name: "tabsPopupPolicyButtonGroup" }, new FormLayoutConstraints( null ) { - "location": new java.awt.Point( 200, 915 ) + "location": new java.awt.Point( 200, 1080 ) } ) add( new FormNonVisual( "javax.swing.ButtonGroup" ) { name: "scrollButtonsPolicyButtonGroup" }, new FormLayoutConstraints( null ) { - "location": new java.awt.Point( 200, 965 ) + "location": new java.awt.Point( 200, 1130 ) } ) add( new FormNonVisual( "javax.swing.ButtonGroup" ) { name: "scrollButtonsPlacementButtonGroup" }, new FormLayoutConstraints( null ) { - "location": new java.awt.Point( 200, 1020 ) + "location": new java.awt.Point( 200, 1185 ) } ) add( new FormNonVisual( "javax.swing.ButtonGroup" ) { name: "tabTypeButtonGroup" }, new FormLayoutConstraints( null ) { - "location": new java.awt.Point( 0, 1072 ) + "location": new java.awt.Point( 0, 1235 ) + } ) + add( new FormNonVisual( "javax.swing.ButtonGroup" ) { + name: "tabRotationButtonGroup" + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 200, 1235 ) } ) } } diff --git a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTabbedPane.java b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTabbedPane.java index 37687c823..77fd3e29a 100644 --- a/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTabbedPane.java +++ b/flatlaf-extras/src/main/java/com/formdev/flatlaf/extras/components/FlatTabbedPane.java @@ -502,6 +502,25 @@ public void setTabWidthMode( TabWidthMode tabWidthMode ) { } + // NOTE: enum names must be equal to allowed strings + public enum TabRotation { none, auto, left, right } + + /** + * Returns how the tabs should be rotated. + */ + public TabRotation getTabRotation() { + return getClientPropertyEnumString( TABBED_PANE_TAB_ROTATION, TabRotation.class, + "TabbedPane.tabRotation", TabRotation.none ); + } + + /** + * Specifies how the tabs should be rotated. + */ + public void setTabRotation( TabRotation tabRotation ) { + putClientPropertyEnumString( TABBED_PANE_TAB_ROTATION, tabRotation ); + } + + /** * Returns the tab icon placement (relative to tab title). */ diff --git a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt index d2dcd9c6f..3c32dd0d8 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatDarkLaf_1.8.0.txt @@ -1081,6 +1081,7 @@ TabbedPane.tabAreaAlignment leading TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabHeight 32 TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI] +TabbedPane.tabRotation none TabbedPane.tabRunOverlay 0 TabbedPane.tabSelectionArc 0 TabbedPane.tabSelectionHeight 3 diff --git a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt index 7871f3ee7..5517fb52c 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatLightLaf_1.8.0.txt @@ -1086,6 +1086,7 @@ TabbedPane.tabAreaAlignment leading TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabHeight 32 TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI] +TabbedPane.tabRotation none TabbedPane.tabRunOverlay 0 TabbedPane.tabSelectionArc 0 TabbedPane.tabSelectionHeight 3 diff --git a/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt index 14e4925fc..d7b40f423 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatMacDarkLaf_1.8.0.txt @@ -1091,6 +1091,7 @@ TabbedPane.tabAreaAlignment leading TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabHeight 32 TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI] +TabbedPane.tabRotation none TabbedPane.tabRunOverlay 0 TabbedPane.tabSelectionArc 999 TabbedPane.tabSelectionHeight 3 diff --git a/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt index 4b09126df..56ed4bdc1 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatMacLightLaf_1.8.0.txt @@ -1095,6 +1095,7 @@ TabbedPane.tabAreaAlignment leading TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabHeight 32 TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI] +TabbedPane.tabRotation none TabbedPane.tabRunOverlay 0 TabbedPane.tabSelectionArc 999 TabbedPane.tabSelectionHeight 3 diff --git a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt index 3ff67dd1c..7e484eefe 100644 --- a/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt +++ b/flatlaf-testing/dumps/uidefaults/FlatTestLaf_1.8.0.txt @@ -1116,6 +1116,7 @@ TabbedPane.tabAreaAlignment leading TabbedPane.tabAreaInsets 0,0,0,0 javax.swing.plaf.InsetsUIResource [UI] TabbedPane.tabHeight 32 TabbedPane.tabInsets 4,12,4,12 javax.swing.plaf.InsetsUIResource [UI] +TabbedPane.tabRotation none TabbedPane.tabRunOverlay 0 TabbedPane.tabSelectionArc 0 TabbedPane.tabSelectionHeight 3 diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.java index b57204f1d..f30a845a3 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.java +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.java @@ -32,6 +32,7 @@ import com.formdev.flatlaf.extras.components.FlatTriStateCheckBox; import com.formdev.flatlaf.icons.FlatInternalFrameCloseIcon; import com.formdev.flatlaf.util.ScaledImageIcon; +import com.jgoodies.forms.factories.CC; import com.jgoodies.forms.layout.*; import net.miginfocom.swing.*; @@ -62,6 +63,7 @@ public FlatContainerTest() { tabAreaAlignmentField.init( TabAreaAlignment.class, true ); tabAlignmentField.init( TabAlignment.class, true ); tabWidthModeField.init( TabWidthMode.class, true ); + tabRotationField.init( TabRotation.class, true ); tabCountChanged(); @@ -74,6 +76,18 @@ public FlatContainerTest() { tabScrollChanged(); } + private void showOnlyOne() { + boolean showOnlyOne = showOnlyOneCheckBox.isSelected(); + + tabbedPane2.setVisible( !showOnlyOne ); + tabbedPane3.setVisible( !showOnlyOne ); + tabbedPane4.setVisible( !showOnlyOne ); + + int span = showOnlyOne ? 3 : 1; + FormLayout formLayout = (FormLayout) tabbedPane1.getParent().getLayout(); + formLayout.setConstraints( tabbedPane1, CC.xywh( 1, 7, span, span ) ); + } + private void tabScrollChanged() { int tabLayoutPolicy = tabScrollCheckBox.isSelected() ? JTabbedPane.SCROLL_TAB_LAYOUT : JTabbedPane.WRAP_TAB_LAYOUT; for( JTabbedPane tabbedPane : allTabbedPanes ) @@ -314,6 +328,12 @@ private void tabWidthModeChanged() { tabbedPane.setTabWidthMode( value ); } + private void tabRotationChanged() { + TabRotation value = tabRotationField.getSelectedValue(); + for( FlatTabbedPane tabbedPane : allTabbedPanes ) + tabbedPane.setTabRotation( value ); + } + private void tabTypeChanged() { TabType value = tabTypeComboBox.getSelectedValue(); for( FlatTabbedPane tabbedPane : allTabbedPanes ) @@ -509,6 +529,7 @@ private void initComponents() { JPanel panel13 = new JPanel(); JLabel label4 = new JLabel(); JLabel tabbedPaneLabel = new JLabel(); + showOnlyOneCheckBox = new JCheckBox(); tabbedPane1 = new FlatTabbedPane(); tabbedPane3 = new FlatTabbedPane(); tabbedPane2 = new FlatTabbedPane(); @@ -520,19 +541,19 @@ private void initComponents() { customTabsCheckBox = new JCheckBox(); htmlTabsCheckBox = new JCheckBox(); multiLineTabsCheckBox = new JCheckBox(); + JLabel tabPlacementLabel = new JLabel(); + tabPlacementField = new FlatTestEnumSelector<>(); + tabBackForegroundCheckBox = new JCheckBox(); JLabel tabsPopupPolicyLabel = new JLabel(); tabsPopupPolicyField = new FlatTestEnumSelector<>(); - tabBackForegroundCheckBox = new JCheckBox(); - JLabel scrollButtonsPolicyLabel = new JLabel(); - scrollButtonsPolicyField = new FlatTestEnumSelector<>(); tabIconsCheckBox = new JCheckBox(); tabIconSizeSpinner = new JSpinner(); iconPlacementField = new FlatTestEnumSelector<>(); + JLabel scrollButtonsPolicyLabel = new JLabel(); + scrollButtonsPolicyField = new FlatTestEnumSelector<>(); + tabsClosableCheckBox = new JCheckBox(); JLabel scrollButtonsPlacementLabel = new JLabel(); scrollButtonsPlacementField = new FlatTestEnumSelector<>(); - tabsClosableCheckBox = new JCheckBox(); - JLabel tabPlacementLabel = new JLabel(); - tabPlacementField = new FlatTestEnumSelector<>(); secondTabClosableCheckBox = new FlatTriStateCheckBox(); JLabel tabAreaAlignmentLabel = new JLabel(); tabAreaAlignmentField = new FlatTestEnumSelector<>(); @@ -540,6 +561,8 @@ private void initComponents() { tabWidthModeField = new FlatTestEnumSelector<>(); JLabel tabAlignmentLabel = new JLabel(); tabAlignmentField = new FlatTestEnumSelector<>(); + JLabel tabRotationLabel = new JLabel(); + tabRotationField = new FlatTestEnumSelector<>(); JLabel tabTypeLabel = new JLabel(); tabTypeComboBox = new FlatTestEnumSelector<>(); leadingComponentCheckBox = new JCheckBox(); @@ -636,6 +659,12 @@ private void initComponents() { //---- tabbedPaneLabel ---- tabbedPaneLabel.setText("JTabbedPane:"); panel9.add(tabbedPaneLabel, cc.xy(1, 5)); + + //---- showOnlyOneCheckBox ---- + showOnlyOneCheckBox.setText("show only one tabbed pane"); + showOnlyOneCheckBox.setMnemonic('W'); + showOnlyOneCheckBox.addActionListener(e -> showOnlyOne()); + panel9.add(showOnlyOneCheckBox, cc.xy(3, 5, CellConstraints.RIGHT, CellConstraints.DEFAULT)); panel9.add(tabbedPane1, cc.xy(1, 7)); //======== tabbedPane3 ======== @@ -713,26 +742,26 @@ private void initComponents() { multiLineTabsCheckBox.addActionListener(e -> htmlTabsChanged()); tabbedPaneControlPanel.add(multiLineTabsCheckBox, "cell 2 0 2 1"); - //---- tabsPopupPolicyLabel ---- - tabsPopupPolicyLabel.setText("Tabs popup policy:"); - tabbedPaneControlPanel.add(tabsPopupPolicyLabel, "cell 0 1"); + //---- tabPlacementLabel ---- + tabPlacementLabel.setText("Tab placement:"); + tabbedPaneControlPanel.add(tabPlacementLabel, "cell 0 1"); - //---- tabsPopupPolicyField ---- - tabsPopupPolicyField.addActionListener(e -> tabsPopupPolicyChanged()); - tabbedPaneControlPanel.add(tabsPopupPolicyField, "cell 1 1"); + //---- tabPlacementField ---- + tabPlacementField.addActionListener(e -> tabPlacementChanged()); + tabbedPaneControlPanel.add(tabPlacementField, "cell 1 1"); //---- tabBackForegroundCheckBox ---- tabBackForegroundCheckBox.setText("Tab back/foreground"); tabBackForegroundCheckBox.addActionListener(e -> tabBackForegroundChanged()); tabbedPaneControlPanel.add(tabBackForegroundCheckBox, "cell 2 1 2 1"); - //---- scrollButtonsPolicyLabel ---- - scrollButtonsPolicyLabel.setText("Scroll buttons policy:"); - tabbedPaneControlPanel.add(scrollButtonsPolicyLabel, "cell 0 2"); + //---- tabsPopupPolicyLabel ---- + tabsPopupPolicyLabel.setText("Tabs popup policy:"); + tabbedPaneControlPanel.add(tabsPopupPolicyLabel, "cell 0 2"); - //---- scrollButtonsPolicyField ---- - scrollButtonsPolicyField.addActionListener(e -> scrollButtonsPolicyChanged()); - tabbedPaneControlPanel.add(scrollButtonsPolicyField, "cell 1 2"); + //---- tabsPopupPolicyField ---- + tabsPopupPolicyField.addActionListener(e -> tabsPopupPolicyChanged()); + tabbedPaneControlPanel.add(tabsPopupPolicyField, "cell 1 2"); //---- tabIconsCheckBox ---- tabIconsCheckBox.setText("Tab icons"); @@ -750,26 +779,26 @@ private void initComponents() { iconPlacementField.addActionListener(e -> iconPlacementChanged()); tabbedPaneControlPanel.add(iconPlacementField, "cell 2 2 2 1"); - //---- scrollButtonsPlacementLabel ---- - scrollButtonsPlacementLabel.setText("Scroll buttons placement:"); - tabbedPaneControlPanel.add(scrollButtonsPlacementLabel, "cell 0 3"); + //---- scrollButtonsPolicyLabel ---- + scrollButtonsPolicyLabel.setText("Scroll buttons policy:"); + tabbedPaneControlPanel.add(scrollButtonsPolicyLabel, "cell 0 3"); - //---- scrollButtonsPlacementField ---- - scrollButtonsPlacementField.addActionListener(e -> scrollButtonsPlacementChanged()); - tabbedPaneControlPanel.add(scrollButtonsPlacementField, "cell 1 3"); + //---- scrollButtonsPolicyField ---- + scrollButtonsPolicyField.addActionListener(e -> scrollButtonsPolicyChanged()); + tabbedPaneControlPanel.add(scrollButtonsPolicyField, "cell 1 3"); //---- tabsClosableCheckBox ---- tabsClosableCheckBox.setText("Tabs closable"); tabsClosableCheckBox.addActionListener(e -> tabsClosableChanged()); tabbedPaneControlPanel.add(tabsClosableCheckBox, "cell 2 3 2 1"); - //---- tabPlacementLabel ---- - tabPlacementLabel.setText("Tab placement:"); - tabbedPaneControlPanel.add(tabPlacementLabel, "cell 0 4"); + //---- scrollButtonsPlacementLabel ---- + scrollButtonsPlacementLabel.setText("Scroll buttons placement:"); + tabbedPaneControlPanel.add(scrollButtonsPlacementLabel, "cell 0 4"); - //---- tabPlacementField ---- - tabPlacementField.addActionListener(e -> tabPlacementChanged()); - tabbedPaneControlPanel.add(tabPlacementField, "cell 1 4"); + //---- scrollButtonsPlacementField ---- + scrollButtonsPlacementField.addActionListener(e -> scrollButtonsPlacementChanged()); + tabbedPaneControlPanel.add(scrollButtonsPlacementField, "cell 1 4"); //---- secondTabClosableCheckBox ---- secondTabClosableCheckBox.setText("Second Tab closable"); @@ -800,6 +829,14 @@ private void initComponents() { tabAlignmentField.addActionListener(e -> tabAlignmentChanged()); tabbedPaneControlPanel.add(tabAlignmentField, "cell 1 6"); + //---- tabRotationLabel ---- + tabRotationLabel.setText("Tab rotation:"); + tabbedPaneControlPanel.add(tabRotationLabel, "cell 2 6"); + + //---- tabRotationField ---- + tabRotationField.addActionListener(e -> tabRotationChanged()); + tabbedPaneControlPanel.add(tabRotationField, "cell 3 6"); + //---- tabTypeLabel ---- tabTypeLabel.setText("Tab type:"); tabbedPaneControlPanel.add(tabTypeLabel, "cell 0 7"); @@ -892,6 +929,7 @@ private void initComponents() { } // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + private JCheckBox showOnlyOneCheckBox; private FlatTabbedPane tabbedPane1; private FlatTabbedPane tabbedPane3; private FlatTabbedPane tabbedPane2; @@ -901,19 +939,20 @@ private void initComponents() { private JCheckBox customTabsCheckBox; private JCheckBox htmlTabsCheckBox; private JCheckBox multiLineTabsCheckBox; - private FlatTestEnumSelector tabsPopupPolicyField; + private FlatTestEnumSelector tabPlacementField; private JCheckBox tabBackForegroundCheckBox; - private FlatTestEnumSelector scrollButtonsPolicyField; + private FlatTestEnumSelector tabsPopupPolicyField; private JCheckBox tabIconsCheckBox; private JSpinner tabIconSizeSpinner; private FlatTestEnumSelector iconPlacementField; - private FlatTestEnumSelector scrollButtonsPlacementField; + private FlatTestEnumSelector scrollButtonsPolicyField; private JCheckBox tabsClosableCheckBox; - private FlatTestEnumSelector tabPlacementField; + private FlatTestEnumSelector scrollButtonsPlacementField; private FlatTriStateCheckBox secondTabClosableCheckBox; private FlatTestEnumSelector tabAreaAlignmentField; private FlatTestEnumSelector tabWidthModeField; private FlatTestEnumSelector tabAlignmentField; + private FlatTestEnumSelector tabRotationField; private FlatTestEnumSelector tabTypeComboBox; private JCheckBox leadingComponentCheckBox; private JCheckBox customBorderCheckBox; diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.jfd index caf2c1f48..771ebd6f6 100644 --- a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.jfd +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/FlatContainerTest.jfd @@ -91,13 +91,25 @@ new FormModel { "gridX": 1 "gridY": 5 } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "showOnlyOneCheckBox" + "text": "show only one tabbed pane" + "mnemonic": 87 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "showOnlyOne", false ) ) + }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { + "gridX": 3 + "gridY": 5 + "hAlign": sfield com.jgoodies.forms.layout.CellConstraints RIGHT + } ) add( new FormContainer( "com.formdev.flatlaf.extras.components.FlatTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { name: "tabbedPane1" auxiliary() { "JavaCodeGenerator.variableLocal": false } }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { - "gridX": 1 "gridY": 7 } ) add( new FormContainer( "com.formdev.flatlaf.extras.components.FlatTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { @@ -198,18 +210,18 @@ new FormModel { "value": "cell 2 0 2 1" } ) add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabsPopupPolicyLabel" - "text": "Tabs popup policy:" + name: "tabPlacementLabel" + "text": "Tab placement:" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 1" } ) add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumSelector" ) { - name: "tabsPopupPolicyField" + name: "tabPlacementField" auxiliary() { "JavaCodeGenerator.variableLocal": false - "JavaCodeGenerator.typeParameters": "TabsPopupPolicy" + "JavaCodeGenerator.typeParameters": "TabPlacement" } - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 1" } ) @@ -224,18 +236,18 @@ new FormModel { "value": "cell 2 1 2 1" } ) add( new FormComponent( "javax.swing.JLabel" ) { - name: "scrollButtonsPolicyLabel" - "text": "Scroll buttons policy:" + name: "tabsPopupPolicyLabel" + "text": "Tabs popup policy:" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 2" } ) add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumSelector" ) { - name: "scrollButtonsPolicyField" + name: "tabsPopupPolicyField" auxiliary() { "JavaCodeGenerator.variableLocal": false - "JavaCodeGenerator.typeParameters": "ScrollButtonsPolicy" + "JavaCodeGenerator.typeParameters": "TabsPopupPolicy" } - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPolicyChanged", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabsPopupPolicyChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 2" } ) @@ -280,18 +292,18 @@ new FormModel { "value": "cell 2 2 2 1" } ) add( new FormComponent( "javax.swing.JLabel" ) { - name: "scrollButtonsPlacementLabel" - "text": "Scroll buttons placement:" + name: "scrollButtonsPolicyLabel" + "text": "Scroll buttons policy:" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 3" } ) add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumSelector" ) { - name: "scrollButtonsPlacementField" + name: "scrollButtonsPolicyField" auxiliary() { "JavaCodeGenerator.variableLocal": false - "JavaCodeGenerator.typeParameters": "ScrollButtonsPlacement" + "JavaCodeGenerator.typeParameters": "ScrollButtonsPolicy" } - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPolicyChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 3" } ) @@ -306,18 +318,18 @@ new FormModel { "value": "cell 2 3 2 1" } ) add( new FormComponent( "javax.swing.JLabel" ) { - name: "tabPlacementLabel" - "text": "Tab placement:" + name: "scrollButtonsPlacementLabel" + "text": "Scroll buttons placement:" }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 0 4" } ) add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumSelector" ) { - name: "tabPlacementField" + name: "scrollButtonsPlacementField" auxiliary() { "JavaCodeGenerator.variableLocal": false - "JavaCodeGenerator.typeParameters": "TabPlacement" + "JavaCodeGenerator.typeParameters": "ScrollButtonsPlacement" } - addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabPlacementChanged", false ) ) + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "scrollButtonsPlacementChanged", false ) ) }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 4" } ) @@ -379,6 +391,22 @@ new FormModel { }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { "value": "cell 1 6" } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabRotationLabel" + "text": "Tab rotation:" + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 6" + } ) + add( new FormComponent( "com.formdev.flatlaf.testing.FlatTestEnumSelector" ) { + name: "tabRotationField" + auxiliary() { + "JavaCodeGenerator.typeParameters": "TabRotation" + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabRotationChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 3 6" + } ) add( new FormComponent( "javax.swing.JLabel" ) { name: "tabTypeLabel" "text": "Tab type:" diff --git a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt index 6545b7d28..d3ed29937 100644 --- a/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt +++ b/flatlaf-theme-editor/src/main/resources/com/formdev/flatlaf/themeeditor/FlatLafUIKeys.txt @@ -881,6 +881,7 @@ TabbedPane.tabAreaAlignment TabbedPane.tabAreaInsets TabbedPane.tabHeight TabbedPane.tabInsets +TabbedPane.tabRotation TabbedPane.tabRunOverlay TabbedPane.tabSelectionArc TabbedPane.tabSelectionHeight