diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java index 034177ae..e7679f9f 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatUIUtils.java @@ -73,6 +73,14 @@ public class FlatUIUtils dim.height + insets.top + insets.bottom ); } + public static Insets addInsets( Insets insets1, Insets insets2 ) { + return new Insets( + insets1.top + insets2.top, + insets1.left + insets2.left, + insets1.bottom + insets2.bottom, + insets1.right + insets2.right ); + } + public static Color getUIColor( String key, int defaultColorRGB ) { Color color = UIManager.getColor( key ); return (color != null) ? color : new Color( defaultColorRGB ); diff --git a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java index 70f968c2..a4ef5d1e 100644 --- a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java +++ b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/FlatJideOssDefaultsAddon.java @@ -17,7 +17,14 @@ package com.formdev.flatlaf.jideoss; import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import javax.swing.UIDefaults; import com.formdev.flatlaf.FlatDefaultsAddon; +import com.formdev.flatlaf.FlatLaf; +import com.jidesoft.plaf.LookAndFeelFactory; +import com.jidesoft.plaf.LookAndFeelFactory.UIDefaultsCustomizer; +import com.jidesoft.plaf.LookAndFeelFactory.UIDefaultsInitializer; /** * JIDE Common Layer addon for FlatLaf. @@ -33,9 +40,44 @@ public class FlatJideOssDefaultsAddon */ @Override public InputStream getDefaults( Class lafClass ) { + LookAndFeelFactory.registerDefaultInitializer( FlatLaf.class.getName(), FlatJideUIDefaultsCustomizer.class.getName() ); + LookAndFeelFactory.registerDefaultCustomizer( FlatLaf.class.getName(), FlatJideUIDefaultsCustomizer.class.getName() ); + Class addonClass = this.getClass(); String propertiesName = "/" + addonClass.getPackage().getName().replace( '.', '/' ) + '/' + lafClass.getSimpleName() + ".properties"; return addonClass.getResourceAsStream( propertiesName ); } + + //---- class FlatJideUIDefaultsCustomizer --------------------------------- + + /** + * Because JIDE overwrites our UI defaults (from properties files) with its + * own UI defaults, we have to first remember our UI defaults in the initializer + * (invoked before JIDE overwrites UI defaults) and then restore them in the customizer. + */ + public static class FlatJideUIDefaultsCustomizer + implements UIDefaultsInitializer, UIDefaultsCustomizer + { + private static HashMap jideDefaults; + + @Override + public void initialize( UIDefaults defaults ) { + jideDefaults = new HashMap<>(); + + for( Map.Entry e : defaults.entrySet() ) { + Object key = e.getKey(); + if( key instanceof String && ((String)key).startsWith( "Jide" ) ) + jideDefaults.put( key, e.getValue() ); + } + } + + @Override + public void customize( UIDefaults defaults ) { + if( jideDefaults != null ) { + defaults.putAll( jideDefaults ); + jideDefaults = null; + } + } + } } diff --git a/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatJideTabbedPaneUI.java b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatJideTabbedPaneUI.java new file mode 100644 index 00000000..e4220174 --- /dev/null +++ b/flatlaf-jide-oss/src/main/java/com/formdev/flatlaf/jideoss/ui/FlatJideTabbedPaneUI.java @@ -0,0 +1,371 @@ +/* + * Copyright 2019 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.jideoss.ui; + +import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_HAS_FULL_BORDER; +import static com.formdev.flatlaf.FlatClientProperties.clientPropertyEquals; +import static com.formdev.flatlaf.util.UIScale.scale; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Rectangle; +import java.awt.Shape; +import java.awt.event.MouseListener; +import java.awt.event.MouseMotionListener; +import java.awt.geom.Path2D; +import java.awt.geom.Rectangle2D; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import javax.swing.JComponent; +import javax.swing.UIManager; +import javax.swing.plaf.ComponentUI; +import com.formdev.flatlaf.FlatClientProperties; +import com.formdev.flatlaf.ui.FlatUIUtils; +import com.jidesoft.plaf.UIDefaultsLookup; +import com.jidesoft.plaf.basic.BasicJideTabbedPaneUI; +import com.jidesoft.swing.JideTabbedPane; + +/** + * Provides the Flat LaF UI delegate for {@link com.jidesoft.swing.JideTabbedPane}. + * + * @author Karl Tauber + */ +public class FlatJideTabbedPaneUI + extends BasicJideTabbedPaneUI +{ + protected Color underlineColor; + protected Color disabledUnderlineColor; + protected Color hoverColor; + protected Color focusColor; + protected Color contentAreaColor; + + protected int tabHeight; + protected int tabSelectionHeight; + protected int contentSeparatorHeight; + protected boolean hasFullBorder; + protected boolean tabsOverlapBorder; + + public static ComponentUI createUI( JComponent c ) { + return new FlatJideTabbedPaneUI(); + } + + @Override + protected void installDefaults() { + super.installDefaults(); + + _background = UIDefaultsLookup.getColor( "JideTabbedPane.background" ); + + underlineColor = UIManager.getColor( "TabbedPane.underlineColor" ); + disabledUnderlineColor = UIManager.getColor( "TabbedPane.disabledUnderlineColor" ); + hoverColor = UIManager.getColor( "TabbedPane.hoverColor" ); + focusColor = UIManager.getColor( "TabbedPane.focusColor" ); + contentAreaColor = UIManager.getColor( "TabbedPane.contentAreaColor" ); + + tabHeight = UIManager.getInt( "TabbedPane.tabHeight" ); + tabSelectionHeight = UIManager.getInt( "TabbedPane.tabSelectionHeight" ); + contentSeparatorHeight = UIManager.getInt( "TabbedPane.contentSeparatorHeight" ); + hasFullBorder = UIManager.getBoolean( "TabbedPane.hasFullBorder" ); + tabsOverlapBorder = UIManager.getBoolean( "TabbedPane.tabsOverlapBorder" ); + + // scale + _textIconGap = scale( _textIconGap ); + tabHeight = scale( tabHeight ); + tabSelectionHeight = scale( tabSelectionHeight ); + } + + @Override + protected void uninstallDefaults() { + super.uninstallDefaults(); + + underlineColor = null; + disabledUnderlineColor = null; + hoverColor = null; + focusColor = null; + contentAreaColor = null; + } + + @Override + protected PropertyChangeListener createPropertyChangeListener() { + return new PropertyChangeHandler() { + @Override + public void propertyChange( PropertyChangeEvent e ) { + super.propertyChange( e ); + + String propertyName = e.getPropertyName(); + if( JideTabbedPane.PROPERTY_SELECTED_INDEX.equals( propertyName ) ) { + repaintTab( (Integer) e.getOldValue() ); + repaintTab( (Integer) e.getNewValue() ); + } else if( FlatClientProperties.TABBED_PANE_HAS_FULL_BORDER.equals( propertyName ) ) { + _tabPane.revalidate(); + _tabPane.repaint(); + } + } + }; + } + + private void repaintTab( int tabIndex ) { + if( tabIndex < 0 || tabIndex >= _tabPane.getTabCount() ) + return; + + Rectangle r = getTabBounds( _tabPane, tabIndex ); + if( r != null ) + _tabPane.repaint( r ); + } + + @Override + protected MouseListener createMouseListener() { + return new RolloverMouseHandler(); + } + + @Override + protected MouseMotionListener createMouseMotionListener() { + return new RolloverMouseMotionHandler(); + } + + @Override + protected int calculateTabHeight( int tabPlacement, int tabIndex, FontMetrics metrics ) { + return Math.max( tabHeight, super.calculateTabHeight( tabPlacement, tabIndex, metrics ) ); + } + + @Override + protected int calculateTabWidth( int tabPlacement, int tabIndex, FontMetrics metrics ) { + return Math.max( tabHeight, super.calculateTabWidth( tabPlacement, tabIndex, metrics ) ); + } + + @Override + protected Insets getTabInsets( int tabPlacement, int tabIndex ) { + return scale( super.getTabInsets( tabPlacement, tabIndex ) ); + } + + @Override + protected Insets getSelectedTabPadInsets( int tabPlacement ) { + return scale( super.getSelectedTabPadInsets( tabPlacement ) ); + } + + @Override + protected Insets getTabAreaInsets( int tabPlacement ) { + return scale( super.getTabAreaInsets( tabPlacement ) ); + } + + @Override + protected int getTabShape() { + return JideTabbedPane.SHAPE_BOX; + } + + /** + * The content border insets are used to create a separator between tabs and content. + * If client property JTabbedPane.hasFullBorder is true, then the content border insets + * are also used for the border. + */ + @Override + protected Insets getContentBorderInsets( int tabPlacement ) { + return FlatUIUtils.addInsets( getContentBorderInsets0( tabPlacement ), + scale( super.getContentBorderInsets( tabPlacement ) ) ); + } + + private Insets getContentBorderInsets0( int tabPlacement ) { + boolean hasFullBorder = this.hasFullBorder || clientPropertyEquals( _tabPane, TABBED_PANE_HAS_FULL_BORDER, true ); + int sh = scale( contentSeparatorHeight ); + Insets insets = hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 ); + + Insets contentBorderInsets = new Insets( 0, 0, 0, 0 ); + rotateInsets( insets, contentBorderInsets, tabPlacement ); + + return contentBorderInsets; + } + + @Override + public void update( Graphics g, JComponent c ) { + FlatUIUtils.setRenderingHints( (Graphics2D) g ); + + super.update( g, c ); + } + + @Override + public void paint( Graphics g, JComponent c ) { + super.paint( g, c ); + + // must paint tab area after content border was painted + if( !scrollableTabLayoutEnabled() && _tabPane.getTabCount() > 0 ) + paintTabArea( g, _tabPane.getTabPlacement(), _tabPane.getSelectedIndex(), c ); + } + + @Override + protected void paintTabBackground( Graphics g, int tabPlacement, int tabIndex, + int x, int y, int w, int h, boolean isSelected ) + { + // paint tab background + boolean enabled = _tabPane.isEnabled(); + g.setColor( enabled && _tabPane.isEnabledAt( tabIndex ) && _indexMouseOver == tabIndex + ? hoverColor + : (enabled && isSelected && _tabPane.hasFocus() + ? focusColor + : _tabPane.getBackgroundAt( tabIndex )) ); + g.fillRect( x, y, w, h ); + } + + @Override + protected void paintTabBorder( Graphics g, int tabPlacement, int tabIndex, int x, int y, int w, int h, + boolean isSelected ) + { + if( isSelected ) + paintTabSelection( g, tabPlacement, x, y, w, h ); + } + + protected void paintTabSelection( Graphics g, int tabPlacement, int x, int y, int w, int h ) { + // increase clip bounds in scroll-tab-layout to paint over the separator line + Rectangle clipBounds = scrollableTabLayoutEnabled() ? g.getClipBounds() : null; + if( clipBounds != null ) { + Rectangle newClipBounds = new Rectangle( clipBounds ); + int contentSeparatorHeight = scale( this.contentSeparatorHeight ); + switch( tabPlacement ) { + case TOP: + default: + newClipBounds.height += contentSeparatorHeight; + break; + + case BOTTOM: + newClipBounds.y -= contentSeparatorHeight; + newClipBounds.height += contentSeparatorHeight; + break; + + case LEFT: + newClipBounds.width += contentSeparatorHeight; + break; + + case RIGHT: + newClipBounds.x -= contentSeparatorHeight; + newClipBounds.width += contentSeparatorHeight; + break; + } + g.setClip( newClipBounds ); + } + + g.setColor( _tabPane.isEnabled() ? underlineColor : disabledUnderlineColor ); + + Insets contentInsets = getContentBorderInsets0( tabPlacement ); + + // paint underline selection + switch( tabPlacement ) { + case TOP: + default: + int sy = y + h + contentInsets.top - tabSelectionHeight; + g.fillRect( x, sy, w, tabSelectionHeight ); + break; + + case BOTTOM: + g.fillRect( x, y - contentInsets.bottom, w, tabSelectionHeight ); + break; + + case LEFT: + int sx = x + w + contentInsets.left - tabSelectionHeight; + g.fillRect( sx, y, tabSelectionHeight, h ); + break; + + case RIGHT: + g.fillRect( x - contentInsets.right, y, tabSelectionHeight, h ); + break; + } + + if( clipBounds != null ) + g.setClip( clipBounds ); + } + + /** + * Actually does the nearly the same as super.paintContentBorder() but + * - not invoking paintContentBorder*Edge() methods + * - repaint selection + */ + @Override + protected void paintContentBorder( Graphics g, int tabPlacement, int selectedIndex ) { + if( _tabPane.getTabCount() <= 0 ) + return; + + Insets insets = _tabPane.getInsets(); + Insets tabAreaInsets = getTabAreaInsets( tabPlacement ); + + int x = insets.left; + int y = insets.top; + int w = _tabPane.getWidth() - insets.right - insets.left; + int h = _tabPane.getHeight() - insets.top - insets.bottom; + + Dimension lsize = isTabLeadingComponentVisible() ? _tabLeadingComponent.getPreferredSize() : new Dimension(); + Dimension tsize = isTabTrailingComponentVisible() ? _tabTrailingComponent.getPreferredSize() : new Dimension(); + + // remove tabs from bounds + switch( tabPlacement ) { + case LEFT: + x += Math.max( calculateTabAreaWidth( tabPlacement, _runCount, _maxTabWidth ), + Math.max( lsize.width, tsize.width ) ); + if( tabsOverlapBorder ) + x -= tabAreaInsets.right; + w -= (x - insets.left); + break; + case RIGHT: + w -= calculateTabAreaWidth( tabPlacement, _runCount, _maxTabWidth ); + if( tabsOverlapBorder ) + w += tabAreaInsets.left; + break; + case BOTTOM: + h -= calculateTabAreaHeight( tabPlacement, _runCount, _maxTabHeight ); + if( tabsOverlapBorder ) + h += tabAreaInsets.top; + break; + case TOP: + default: + y += Math.max( calculateTabAreaHeight( tabPlacement, _runCount, _maxTabHeight ), + Math.max( lsize.height, tsize.height ) ); + if( tabsOverlapBorder ) + y -= tabAreaInsets.bottom; + h -= (y - insets.top); + } + + // compute insets for separator or full border + boolean hasFullBorder = this.hasFullBorder || clientPropertyEquals( _tabPane, TABBED_PANE_HAS_FULL_BORDER, true ); + int sh = scale( contentSeparatorHeight * 100 ); // multiply by 100 because rotateInsets() does not use floats + Insets ci = new Insets( 0, 0, 0, 0 ); + rotateInsets( hasFullBorder ? new Insets( sh, sh, sh, sh ) : new Insets( sh, 0, 0, 0 ), ci, tabPlacement ); + + // paint content area + g.setColor( contentAreaColor ); + Path2D path = new Path2D.Float( Path2D.WIND_EVEN_ODD ); + path.append( new Rectangle2D.Float( x, y, w, h ), false ); + path.append( new Rectangle2D.Float( x + (ci.left / 100f), y + (ci.top / 100f), + w - (ci.left / 100f) - (ci.right / 100f), h - (ci.top / 100f) - (ci.bottom / 100f) ), false ); + ((Graphics2D)g).fill( path ); + + // repaint selection in scroll-tab-layout because it may be painted before + // the content border was painted (from BasicTabbedPaneUI$ScrollableTabPanel) + if( scrollableTabLayoutEnabled() && selectedIndex >= 0 && _tabScroller != null && _tabScroller.viewport != null ) { + Rectangle tabRect = getTabBounds( _tabPane, selectedIndex ); + + Shape oldClip = g.getClip(); + g.setClip( _tabScroller.viewport.getBounds() ); + paintTabSelection( g, tabPlacement, tabRect.x, tabRect.y, tabRect.width, tabRect.height ); + g.setClip( oldClip ); + } + } + + @Override + protected void paintFocusIndicator( Graphics g, int tabPlacement, Rectangle[] rects, int tabIndex, + Rectangle iconRect, Rectangle textRect, boolean isSelected ) + { + } +} diff --git a/flatlaf-jide-oss/src/main/resources/com/formdev/flatlaf/jideoss/FlatLaf.properties b/flatlaf-jide-oss/src/main/resources/com/formdev/flatlaf/jideoss/FlatLaf.properties new file mode 100644 index 00000000..2313450d --- /dev/null +++ b/flatlaf-jide-oss/src/main/resources/com/formdev/flatlaf/jideoss/FlatLaf.properties @@ -0,0 +1,32 @@ +# +# Copyright 2019 FormDev Software GmbH +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#---- UI delegates ---- + +JideTabbedPaneUI=com.formdev.flatlaf.jideoss.ui.FlatJideTabbedPaneUI + + +#---- JideTabbedPane ---- + +JideTabbedPane.background=@background +JideTabbedPane.foreground=@foreground +JideTabbedPane.tabAreaBackground=@background + +JideTabbedPane.tabInsets=@@TabbedPane.tabInsets +JideTabbedPane.tabAreaInsets=@@TabbedPane.tabAreaInsets +JideTabbedPane.contentBorderInsets=0,0,0,0 +JideTabbedPane.tabRunOverlay=@@TabbedPane.tabRunOverlay +JideTabbedPane.shadow=@@TabbedPane.shadow diff --git a/flatlaf-testing/build.gradle.kts b/flatlaf-testing/build.gradle.kts index 0ad46588..d81729d8 100644 --- a/flatlaf-testing/build.gradle.kts +++ b/flatlaf-testing/build.gradle.kts @@ -24,6 +24,7 @@ dependencies { implementation( project( ":flatlaf-core" ) ) implementation( project( ":flatlaf-extras" ) ) implementation( project( ":flatlaf-swingx" ) ) + implementation( project( ":flatlaf-jide-oss" ) ) implementation( "com.miglayout:miglayout-swing:5.2" ) implementation( "com.jgoodies:jgoodies-forms:1.9.0" ) diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/jideoss/FlatJideOssTest.java b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/jideoss/FlatJideOssTest.java new file mode 100644 index 00000000..dfbab877 --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/jideoss/FlatJideOssTest.java @@ -0,0 +1,294 @@ +/* + * Copyright 2019 FormDev Software GmbH + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.formdev.flatlaf.testing.jideoss; + +import static com.formdev.flatlaf.FlatClientProperties.TABBED_PANE_HAS_FULL_BORDER; +import java.awt.*; +import javax.swing.*; +import javax.swing.border.*; +import com.formdev.flatlaf.testing.*; +import com.formdev.flatlaf.testing.FlatTestFrame; +import com.jgoodies.forms.layout.*; +import com.jidesoft.plaf.LookAndFeelFactory; +import com.jidesoft.swing.*; +import net.miginfocom.swing.*; + +/** + * @author Karl Tauber + */ +public class FlatJideOssTest + extends FlatTestPanel +{ + public static void main( String[] args ) { + SwingUtilities.invokeLater( () -> { + FlatTestFrame frame = FlatTestFrame.create( args, "FlatJideOssTest" ); + LookAndFeelFactory.installJideExtension(); + frame.showFrame( FlatJideOssTest::new ); + + UIManager.addPropertyChangeListener( e -> { + if( "lookAndFeel".equals( e.getPropertyName() ) ) { + LookAndFeelFactory.installJideExtension(); + } + } ); + } ); + } + + FlatJideOssTest() { + initComponents(); + } + + private void tabScrollChanged() { + int tabLayoutPolicy = tabScrollCheckBox.isSelected() ? JTabbedPane.SCROLL_TAB_LAYOUT : JTabbedPane.WRAP_TAB_LAYOUT; + tabbedPane1.setTabLayoutPolicy( tabLayoutPolicy ); + tabbedPane2.setTabLayoutPolicy( tabLayoutPolicy ); + tabbedPane3.setTabLayoutPolicy( tabLayoutPolicy ); + tabbedPane4.setTabLayoutPolicy( tabLayoutPolicy ); + } + + private void hasFullBorderChanged() { + Boolean hasFullBorder = hasFullBorderCheckBox.isSelected() ? true : null; + tabbedPane1.putClientProperty( TABBED_PANE_HAS_FULL_BORDER, hasFullBorder ); + tabbedPane2.putClientProperty( TABBED_PANE_HAS_FULL_BORDER, hasFullBorder ); + tabbedPane3.putClientProperty( TABBED_PANE_HAS_FULL_BORDER, hasFullBorder ); + tabbedPane4.putClientProperty( TABBED_PANE_HAS_FULL_BORDER, hasFullBorder ); + } + + private void moreTabsChanged() { + boolean moreTabs = moreTabsCheckBox.isSelected(); + addRemoveMoreTabs( tabbedPane1, moreTabs ); + addRemoveMoreTabs( tabbedPane2, moreTabs ); + addRemoveMoreTabs( tabbedPane3, moreTabs ); + addRemoveMoreTabs( tabbedPane4, moreTabs ); + } + + private void addRemoveMoreTabs( JTabbedPane tabbedPane, boolean add ) { + if( add ) { + tabbedPane.addTab( "Tab 4", new JLabel( "tab 4" ) ); + tabbedPane.addTab( "Tab 5", new JLabel( "tab 5" ) ); + } else { + int tabCount = tabbedPane.getTabCount(); + if( tabCount > 3 ) { + for( int i = 0; i < 2; i++ ) + tabbedPane.removeTabAt( tabbedPane.getTabCount() - 1 ); + } + } + } + + private void initComponents() { + // JFormDesigner - Component initialization - DO NOT MODIFY //GEN-BEGIN:initComponents + JPanel panel9 = new JPanel(); + JLabel tabbedPaneLabel = new JLabel(); + tabbedPane1 = new JideTabbedPane(); + JPanel panel1 = new JPanel(); + JLabel label1 = new JLabel(); + JPanel panel2 = new JPanel(); + JLabel label2 = new JLabel(); + tabbedPane3 = new JideTabbedPane(); + JPanel panel5 = new JPanel(); + JLabel label5 = new JLabel(); + JPanel panel6 = new JPanel(); + JLabel label6 = new JLabel(); + tabbedPane2 = new JideTabbedPane(); + JPanel panel3 = new JPanel(); + JLabel label3 = new JLabel(); + JPanel panel4 = new JPanel(); + JLabel label4 = new JLabel(); + tabbedPane4 = new JideTabbedPane(); + JPanel panel7 = new JPanel(); + JLabel label7 = new JLabel(); + JPanel panel8 = new JPanel(); + JLabel label8 = new JLabel(); + JPanel panel14 = new JPanel(); + moreTabsCheckBox = new JCheckBox(); + tabScrollCheckBox = new JCheckBox(); + hasFullBorderCheckBox = new JCheckBox(); + CellConstraints cc = new CellConstraints(); + + //======== this ======== + setLayout(new MigLayout( + "insets dialog,hidemode 3", + // columns + "[grow,fill]", + // rows + "[grow,fill]")); + + //======== panel9 ======== + { + panel9.setOpaque(false); + panel9.setLayout(new FormLayout( + "70dlu:grow, $lcgap, 70dlu:grow", + "pref, 2*($lgap, fill:70dlu:grow), $lgap, pref")); + + //---- tabbedPaneLabel ---- + tabbedPaneLabel.setText("JideTabbedPane:"); + panel9.add(tabbedPaneLabel, cc.xy(1, 1)); + + //======== tabbedPane1 ======== + { + + //======== panel1 ======== + { + panel1.setLayout(new FlowLayout()); + + //---- label1 ---- + label1.setText("TOP"); + panel1.add(label1); + } + tabbedPane1.addTab("Tab 1", panel1); + + //======== panel2 ======== + { + panel2.setBorder(new LineBorder(Color.magenta)); + panel2.setLayout(new FlowLayout()); + } + tabbedPane1.addTab("Tab 2", panel2); + + //---- label2 ---- + label2.setText("text"); + tabbedPane1.addTab("Tab 3", label2); + } + panel9.add(tabbedPane1, cc.xy(1, 3)); + + //======== tabbedPane3 ======== + { + tabbedPane3.setTabPlacement(SwingConstants.LEFT); + + //======== panel5 ======== + { + panel5.setLayout(new FlowLayout()); + + //---- label5 ---- + label5.setText("LEFT"); + panel5.add(label5); + } + tabbedPane3.addTab("Tab 1", panel5); + + //======== panel6 ======== + { + panel6.setBorder(new LineBorder(Color.magenta)); + panel6.setLayout(new FlowLayout()); + } + tabbedPane3.addTab("Tab 2", panel6); + + //---- label6 ---- + label6.setText("text"); + tabbedPane3.addTab("Tab 3", label6); + } + panel9.add(tabbedPane3, cc.xy(3, 3)); + + //======== tabbedPane2 ======== + { + tabbedPane2.setTabPlacement(SwingConstants.BOTTOM); + + //======== panel3 ======== + { + panel3.setLayout(new FlowLayout()); + + //---- label3 ---- + label3.setText("BOTTOM"); + panel3.add(label3); + } + tabbedPane2.addTab("Tab 1", panel3); + + //======== panel4 ======== + { + panel4.setBorder(new LineBorder(Color.magenta)); + panel4.setLayout(new FlowLayout()); + } + tabbedPane2.addTab("Tab 2", panel4); + tabbedPane2.setEnabledAt(1, false); + + //---- label4 ---- + label4.setText("text"); + tabbedPane2.addTab("Tab 3", label4); + } + panel9.add(tabbedPane2, cc.xy(1, 5)); + + //======== tabbedPane4 ======== + { + tabbedPane4.setTabPlacement(SwingConstants.RIGHT); + + //======== panel7 ======== + { + panel7.setLayout(new FlowLayout()); + + //---- label7 ---- + label7.setText("RIGHT"); + panel7.add(label7); + } + tabbedPane4.addTab("Tab 1", panel7); + + //======== panel8 ======== + { + panel8.setBorder(new LineBorder(Color.magenta)); + panel8.setLayout(new FlowLayout()); + } + tabbedPane4.addTab("Tab 2", panel8); + + //---- label8 ---- + label8.setText("text"); + tabbedPane4.addTab("Tab 3", label8); + } + panel9.add(tabbedPane4, cc.xy(3, 5)); + + //======== panel14 ======== + { + panel14.setOpaque(false); + panel14.setLayout(new MigLayout( + "insets 0,hidemode 3", + // columns + "[]" + + "[]" + + "[]", + // rows + "[center]")); + + //---- moreTabsCheckBox ---- + moreTabsCheckBox.setText("more tabs"); + moreTabsCheckBox.setMnemonic('M'); + moreTabsCheckBox.addActionListener(e -> moreTabsChanged()); + panel14.add(moreTabsCheckBox, "cell 0 0"); + + //---- tabScrollCheckBox ---- + tabScrollCheckBox.setText("tabLayoutPolicy = SCROLL"); + tabScrollCheckBox.setMnemonic('S'); + tabScrollCheckBox.setSelected(true); + tabScrollCheckBox.addActionListener(e -> tabScrollChanged()); + panel14.add(tabScrollCheckBox, "cell 1 0,alignx left,growx 0"); + + //---- hasFullBorderCheckBox ---- + hasFullBorderCheckBox.setText("JTabbedPane.hasFullBorder"); + hasFullBorderCheckBox.setMnemonic('F'); + hasFullBorderCheckBox.addActionListener(e -> hasFullBorderChanged()); + panel14.add(hasFullBorderCheckBox, "cell 2 0,alignx left,growx 0"); + } + panel9.add(panel14, cc.xywh(1, 7, 3, 1)); + } + add(panel9, "cell 0 0"); + // JFormDesigner - End of component initialization //GEN-END:initComponents + } + + // JFormDesigner - Variables declaration - DO NOT MODIFY //GEN-BEGIN:variables + private JideTabbedPane tabbedPane1; + private JideTabbedPane tabbedPane3; + private JideTabbedPane tabbedPane2; + private JideTabbedPane tabbedPane4; + private JCheckBox moreTabsCheckBox; + private JCheckBox tabScrollCheckBox; + private JCheckBox hasFullBorderCheckBox; + // JFormDesigner - End of variables declaration //GEN-END:variables +} diff --git a/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/jideoss/FlatJideOssTest.jfd b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/jideoss/FlatJideOssTest.jfd new file mode 100644 index 00000000..d181cfdc --- /dev/null +++ b/flatlaf-testing/src/main/java/com/formdev/flatlaf/testing/jideoss/FlatJideOssTest.jfd @@ -0,0 +1,203 @@ +JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8" + +new FormModel { + contentType: "form/swing" + root: new FormRoot { + auxiliary() { + "JavaCodeGenerator.defaultVariableLocal": true + } + add( new FormContainer( "com.formdev.flatlaf.testing.FlatTestPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets dialog,hidemode 3" + "$columnConstraints": "[grow,fill]" + "$rowConstraints": "[grow,fill]" + } ) { + name: "this" + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class com.jgoodies.forms.layout.FormLayout ) { + "$columnSpecs": "70dlu:grow, labelcompgap, 70dlu:grow" + "$rowSpecs": "pref, linegap, fill:70dlu:grow, linegap, fill:70dlu:grow, linegap, pref" + } ) { + name: "panel9" + "opaque": false + add( new FormComponent( "javax.swing.JLabel" ) { + name: "tabbedPaneLabel" + "text": "JideTabbedPane:" + }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { + "gridX": 1 + } ) + add( new FormContainer( "com.jidesoft.swing.JideTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabbedPane1" + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel1" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label1" + "text": "TOP" + } ) + }, new FormLayoutConstraints( null ) { + "title": "Tab 1" + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel2" + "border": &LineBorder0 new javax.swing.border.LineBorder( sfield java.awt.Color magenta, 1, false ) + }, new FormLayoutConstraints( null ) { + "title": "Tab 2" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label2" + "text": "text" + }, new FormLayoutConstraints( null ) { + "title": "Tab 3" + } ) + }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { + "gridX": 1 + "gridY": 3 + } ) + add( new FormContainer( "com.jidesoft.swing.JideTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabbedPane3" + "tabPlacement": 2 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel5" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label5" + "text": "LEFT" + } ) + }, new FormLayoutConstraints( null ) { + "title": "Tab 1" + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel6" + "border": #LineBorder0 + }, new FormLayoutConstraints( null ) { + "title": "Tab 2" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label6" + "text": "text" + }, new FormLayoutConstraints( null ) { + "title": "Tab 3" + } ) + }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { + "gridX": 3 + "gridY": 3 + } ) + add( new FormContainer( "com.jidesoft.swing.JideTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabbedPane2" + "tabPlacement": 3 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel3" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label3" + "text": "BOTTOM" + } ) + }, new FormLayoutConstraints( null ) { + "title": "Tab 1" + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel4" + "border": #LineBorder0 + }, new FormLayoutConstraints( null ) { + "title": "Tab 2" + "enabled": false + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label4" + "text": "text" + }, new FormLayoutConstraints( null ) { + "title": "Tab 3" + } ) + }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { + "gridY": 5 + } ) + add( new FormContainer( "com.jidesoft.swing.JideTabbedPane", new FormLayoutManager( class javax.swing.JTabbedPane ) ) { + name: "tabbedPane4" + "tabPlacement": 4 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel7" + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label7" + "text": "RIGHT" + } ) + }, new FormLayoutConstraints( null ) { + "title": "Tab 1" + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) { + name: "panel8" + "border": #LineBorder0 + }, new FormLayoutConstraints( null ) { + "title": "Tab 2" + } ) + add( new FormComponent( "javax.swing.JLabel" ) { + name: "label8" + "text": "text" + }, new FormLayoutConstraints( null ) { + "title": "Tab 3" + } ) + }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { + "gridX": 3 + "gridY": 5 + } ) + add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class net.miginfocom.swing.MigLayout ) { + "$layoutConstraints": "insets 0,hidemode 3" + "$columnConstraints": "[][][]" + "$rowConstraints": "[center]" + } ) { + name: "panel14" + "opaque": false + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "moreTabsCheckBox" + "text": "more tabs" + "mnemonic": 77 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "moreTabsChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "tabScrollCheckBox" + "text": "tabLayoutPolicy = SCROLL" + "mnemonic": 83 + "selected": true + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "tabScrollChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 1 0,alignx left,growx 0" + } ) + add( new FormComponent( "javax.swing.JCheckBox" ) { + name: "hasFullBorderCheckBox" + "text": "JTabbedPane.hasFullBorder" + "mnemonic": 70 + auxiliary() { + "JavaCodeGenerator.variableLocal": false + } + addEvent( new FormEvent( "java.awt.event.ActionListener", "actionPerformed", "hasFullBorderChanged", false ) ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 2 0,alignx left,growx 0" + } ) + }, new FormLayoutConstraints( class com.jgoodies.forms.layout.CellConstraints ) { + "gridY": 7 + "gridWidth": 3 + } ) + }, new FormLayoutConstraints( class net.miginfocom.layout.CC ) { + "value": "cell 0 0" + } ) + }, new FormLayoutConstraints( null ) { + "location": new java.awt.Point( 0, 0 ) + "size": new java.awt.Dimension( 500, 500 ) + } ) + } +} diff --git a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties index ad511051..fb442327 100644 --- a/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties +++ b/flatlaf-testing/src/main/resources/com/formdev/flatlaf/testing/FlatTestLaf.properties @@ -17,6 +17,7 @@ #---- variables ---- @background=ccffcc +@foreground=ff0000 @selectionBackground=00aa00 @selectionInactiveBackground=888888 @selectionInactiveForeground=ffffff @@ -29,7 +30,7 @@ #---- globals ---- *.background=@background -*.foreground=ff0000 +*.foreground=@foreground *.textBackground=ccffcc *.textForeground=ff0000 *.caretForeground=0000ff