mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
TabbedPane: support Ctrl+TAB/Ctrl+Shift+TAB to switch to next/previous tab if a child of tabbedpane has focus
This commit is contained in:
@@ -4,6 +4,8 @@ FlatLaf Change Log
|
||||
## Unreleased
|
||||
|
||||
- PasswordField: Warn about enabled Caps Lock.
|
||||
- TabbedPane: Support <kbd>Ctrl+TAB</kbd> / <kbd>Ctrl+Shift+TAB</kbd> to switch
|
||||
to next / previous tab.
|
||||
- TextField, FormattedTextField and PasswordField: Support round borders (see UI
|
||||
default value `TextComponent.arc`). (issue #65)
|
||||
- IntelliJ Themes: Added Gradianto themes to demo.
|
||||
|
||||
@@ -69,7 +69,14 @@ class FlatInputMaps
|
||||
"ctrl PAGE_DOWN", "negativeBlockIncrement",
|
||||
"ctrl PAGE_UP", "positiveBlockIncrement"
|
||||
);
|
||||
}
|
||||
|
||||
modifyInputMap( defaults, "TabbedPane.ancestorInputMap",
|
||||
"ctrl TAB", "navigateNext",
|
||||
"shift ctrl TAB", "navigatePrevious"
|
||||
);
|
||||
|
||||
if( !SystemInfo.IS_MAC ) {
|
||||
modifyInputMap( defaults, "Tree.focusInputMap",
|
||||
"ADD", "expand",
|
||||
"SUBTRACT", "collapse"
|
||||
|
||||
@@ -26,15 +26,21 @@ import java.awt.FontMetrics;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Insets;
|
||||
import java.awt.KeyboardFocusManager;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.InputEvent;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.UIManager;
|
||||
import javax.swing.plaf.ComponentUI;
|
||||
import javax.swing.plaf.UIResource;
|
||||
@@ -90,6 +96,9 @@ import com.formdev.flatlaf.util.UIScale;
|
||||
public class FlatTabbedPaneUI
|
||||
extends BasicTabbedPaneUI
|
||||
{
|
||||
private static Set<KeyStroke> focusForwardTraversalKeys;
|
||||
private static Set<KeyStroke> focusBackwardTraversalKeys;
|
||||
|
||||
protected Color disabledForeground;
|
||||
protected Color selectedBackground;
|
||||
protected Color selectedForeground;
|
||||
@@ -142,11 +151,27 @@ public class FlatTabbedPaneUI
|
||||
tabHeight = scale( tabHeight );
|
||||
tabSelectionHeight = scale( tabSelectionHeight );
|
||||
|
||||
// replace focus forward/backward traversal keys with TAB/Shift+TAB because
|
||||
// the default also includes Ctrl+TAB/Ctrl+Shift+TAB, which we need to switch tabs
|
||||
if( focusForwardTraversalKeys == null ) {
|
||||
focusForwardTraversalKeys = Collections.singleton( KeyStroke.getKeyStroke( KeyEvent.VK_TAB, 0 ) );
|
||||
focusBackwardTraversalKeys = Collections.singleton( KeyStroke.getKeyStroke( KeyEvent.VK_TAB, InputEvent.SHIFT_MASK ) );
|
||||
}
|
||||
// Ideally we should use `LookAndFeel.installProperty( tabPane, "focusTraversalKeysForward", keys )` here
|
||||
// instead of `tabPane.setFocusTraversalKeys()`, but WindowsTabbedPaneUI also uses later method
|
||||
// and switching from Windows LaF to FlatLaf would not replace the keys and Ctrl+TAB would not work.
|
||||
tabPane.setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, focusForwardTraversalKeys );
|
||||
tabPane.setFocusTraversalKeys( KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, focusBackwardTraversalKeys );
|
||||
|
||||
MigLayoutVisualPadding.install( tabPane, null );
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void uninstallDefaults() {
|
||||
// restore focus forward/backward traversal keys
|
||||
tabPane.setFocusTraversalKeys( KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, null );
|
||||
tabPane.setFocusTraversalKeys( KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, null );
|
||||
|
||||
super.uninstallDefaults();
|
||||
|
||||
disabledForeground = null;
|
||||
|
||||
@@ -81,7 +81,11 @@ public class FlatContainerTest
|
||||
JSplitPane splitPane3 = new JSplitPane();
|
||||
JSplitPane splitPane1 = new JSplitPane();
|
||||
JPanel panel10 = new JPanel();
|
||||
JTextField textField2 = new JTextField();
|
||||
JButton button1 = new JButton();
|
||||
JPanel panel11 = new JPanel();
|
||||
JTextField textField3 = new JTextField();
|
||||
JButton button2 = new JButton();
|
||||
JSplitPane splitPane2 = new JSplitPane();
|
||||
JPanel panel12 = new JPanel();
|
||||
JPanel panel13 = new JPanel();
|
||||
@@ -89,7 +93,11 @@ public class FlatContainerTest
|
||||
tabbedPane1 = new JTabbedPane();
|
||||
JPanel panel1 = new JPanel();
|
||||
JLabel label1 = new JLabel();
|
||||
JTextField textField4 = new JTextField();
|
||||
JButton button3 = new JButton();
|
||||
JPanel panel2 = new JPanel();
|
||||
JTextField textField5 = new JTextField();
|
||||
JButton button4 = new JButton();
|
||||
JLabel label2 = new JLabel();
|
||||
tabbedPane3 = new JTabbedPane();
|
||||
JPanel panel5 = new JPanel();
|
||||
@@ -145,6 +153,14 @@ public class FlatContainerTest
|
||||
{
|
||||
panel10.setBackground(Color.orange);
|
||||
panel10.setLayout(new FlowLayout());
|
||||
|
||||
//---- textField2 ----
|
||||
textField2.setText("some text");
|
||||
panel10.add(textField2);
|
||||
|
||||
//---- button1 ----
|
||||
button1.setText("...");
|
||||
panel10.add(button1);
|
||||
}
|
||||
splitPane1.setLeftComponent(panel10);
|
||||
|
||||
@@ -152,6 +168,14 @@ public class FlatContainerTest
|
||||
{
|
||||
panel11.setBackground(Color.magenta);
|
||||
panel11.setLayout(new FlowLayout());
|
||||
|
||||
//---- textField3 ----
|
||||
textField3.setText("some text");
|
||||
panel11.add(textField3);
|
||||
|
||||
//---- button2 ----
|
||||
button2.setText("...");
|
||||
panel11.add(button2);
|
||||
}
|
||||
splitPane1.setRightComponent(panel11);
|
||||
}
|
||||
@@ -195,6 +219,14 @@ public class FlatContainerTest
|
||||
//---- label1 ----
|
||||
label1.setText("TOP");
|
||||
panel1.add(label1);
|
||||
|
||||
//---- textField4 ----
|
||||
textField4.setText("some text");
|
||||
panel1.add(textField4);
|
||||
|
||||
//---- button3 ----
|
||||
button3.setText("...");
|
||||
panel1.add(button3);
|
||||
}
|
||||
tabbedPane1.addTab("Tab 1", panel1);
|
||||
|
||||
@@ -202,6 +234,14 @@ public class FlatContainerTest
|
||||
{
|
||||
panel2.setBorder(new LineBorder(Color.magenta));
|
||||
panel2.setLayout(new FlowLayout());
|
||||
|
||||
//---- textField5 ----
|
||||
textField5.setText("some text");
|
||||
panel2.add(textField5);
|
||||
|
||||
//---- button4 ----
|
||||
button4.setText("...");
|
||||
panel2.add(button4);
|
||||
}
|
||||
tabbedPane1.addTab("Tab 2", panel2);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
JFDML JFormDesigner: "7.0.0.0.194" Java: "11.0.2" encoding: "UTF-8"
|
||||
JFDML JFormDesigner: "7.0.1.0.272" Java: "13.0.1" encoding: "UTF-8"
|
||||
|
||||
new FormModel {
|
||||
contentType: "form/swing"
|
||||
@@ -32,12 +32,28 @@ new FormModel {
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel10"
|
||||
"background": sfield java.awt.Color orange
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "textField2"
|
||||
"text": "some text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button1"
|
||||
"text": "..."
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "left"
|
||||
} )
|
||||
add( new FormContainer( "javax.swing.JPanel", new FormLayoutManager( class java.awt.FlowLayout ) ) {
|
||||
name: "panel11"
|
||||
"background": sfield java.awt.Color magenta
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "textField3"
|
||||
"text": "some text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button2"
|
||||
"text": "..."
|
||||
} )
|
||||
}, new FormLayoutConstraints( class java.lang.String ) {
|
||||
"value": "right"
|
||||
} )
|
||||
@@ -86,12 +102,28 @@ new FormModel {
|
||||
name: "label1"
|
||||
"text": "TOP"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "textField4"
|
||||
"text": "some text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button3"
|
||||
"text": "..."
|
||||
} )
|
||||
}, 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 )
|
||||
add( new FormComponent( "javax.swing.JTextField" ) {
|
||||
name: "textField5"
|
||||
"text": "some text"
|
||||
} )
|
||||
add( new FormComponent( "javax.swing.JButton" ) {
|
||||
name: "button4"
|
||||
"text": "..."
|
||||
} )
|
||||
}, new FormLayoutConstraints( null ) {
|
||||
"title": "Tab 2"
|
||||
} )
|
||||
|
||||
@@ -536,11 +536,13 @@ SplitPane.ancestorInputMap [lazy] 14 javax.swing.plaf.InputMapUIResource
|
||||
|
||||
#---- TabbedPane ----
|
||||
|
||||
TabbedPane.ancestorInputMap [lazy] 4 javax.swing.plaf.InputMapUIResource [UI]
|
||||
TabbedPane.ancestorInputMap [lazy] 6 javax.swing.plaf.InputMapUIResource [UI]
|
||||
ctrl KP_UP requestFocus
|
||||
ctrl PAGE_DOWN navigatePageDown
|
||||
ctrl PAGE_UP navigatePageUp
|
||||
ctrl TAB navigateNext
|
||||
ctrl UP requestFocus
|
||||
shift ctrl TAB navigatePrevious
|
||||
TabbedPane.focusInputMap [lazy] 10 javax.swing.plaf.InputMapUIResource [UI]
|
||||
ctrl DOWN requestFocusForVisibleComponent
|
||||
ctrl KP_DOWN requestFocusForVisibleComponent
|
||||
|
||||
@@ -475,11 +475,13 @@ SplitPane.ancestorInputMap [lazy] 14 javax.swing.plaf.InputMapUIResource
|
||||
|
||||
#---- TabbedPane ----
|
||||
|
||||
TabbedPane.ancestorInputMap [lazy] 4 javax.swing.plaf.InputMapUIResource [UI]
|
||||
TabbedPane.ancestorInputMap [lazy] 6 javax.swing.plaf.InputMapUIResource [UI]
|
||||
ctrl KP_UP requestFocus
|
||||
ctrl PAGE_DOWN navigatePageDown
|
||||
ctrl PAGE_UP navigatePageUp
|
||||
ctrl TAB navigateNext
|
||||
ctrl UP requestFocus
|
||||
shift ctrl TAB navigatePrevious
|
||||
TabbedPane.focusInputMap [lazy] 10 javax.swing.plaf.InputMapUIResource [UI]
|
||||
ctrl DOWN requestFocusForVisibleComponent
|
||||
ctrl KP_DOWN requestFocusForVisibleComponent
|
||||
|
||||
Reference in New Issue
Block a user