TabbedPane: support rotated/vertical tabs (issue #633)

This commit is contained in:
Karl Tauber
2023-11-04 18:57:40 +01:00
parent 61ba011c3b
commit 2ef5270095
19 changed files with 1458 additions and 913 deletions

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -32,6 +32,7 @@ import com.formdev.flatlaf.extras.components.FlatTabbedPane.*;
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 class 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 class 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 @@ public class FlatContainerTest
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 @@ public class FlatContainerTest
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 @@ public class FlatContainerTest
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 @@ public class FlatContainerTest
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 @@ public class FlatContainerTest
//---- 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 @@ public class FlatContainerTest
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 @@ public class FlatContainerTest
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 @@ public class FlatContainerTest
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 @@ public class FlatContainerTest
}
// 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 @@ public class FlatContainerTest
private JCheckBox customTabsCheckBox;
private JCheckBox htmlTabsCheckBox;
private JCheckBox multiLineTabsCheckBox;
private FlatTestEnumSelector<TabsPopupPolicy> tabsPopupPolicyField;
private FlatTestEnumSelector<TabPlacement> tabPlacementField;
private JCheckBox tabBackForegroundCheckBox;
private FlatTestEnumSelector<ScrollButtonsPolicy> scrollButtonsPolicyField;
private FlatTestEnumSelector<TabsPopupPolicy> tabsPopupPolicyField;
private JCheckBox tabIconsCheckBox;
private JSpinner tabIconSizeSpinner;
private FlatTestEnumSelector<TabIconPlacement> iconPlacementField;
private FlatTestEnumSelector<ScrollButtonsPlacement> scrollButtonsPlacementField;
private FlatTestEnumSelector<ScrollButtonsPolicy> scrollButtonsPolicyField;
private JCheckBox tabsClosableCheckBox;
private FlatTestEnumSelector<TabPlacement> tabPlacementField;
private FlatTestEnumSelector<ScrollButtonsPlacement> scrollButtonsPlacementField;
private FlatTriStateCheckBox secondTabClosableCheckBox;
private FlatTestEnumSelector<TabAreaAlignment> tabAreaAlignmentField;
private FlatTestEnumSelector<TabWidthMode> tabWidthModeField;
private FlatTestEnumSelector<TabAlignment> tabAlignmentField;
private FlatTestEnumSelector<TabRotation> tabRotationField;
private FlatTestEnumSelector<TabType> tabTypeComboBox;
private JCheckBox leadingComponentCheckBox;
private JCheckBox customBorderCheckBox;

View File

@@ -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:"