mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-11 06:27:13 -06:00
ComboBox on macOS: fixed keyboard navigation and show/hide popup
This commit is contained in:
@@ -10,6 +10,7 @@ FlatLaf Change Log
|
||||
longer `null`.
|
||||
- Tree on macOS: Fixed <kbd>Left</kbd> and <kbd>Right</kbd> keys to collapse or
|
||||
expand nodes.
|
||||
- ComboBox on macOS: Fixed keyboard navigation and show/hide popup.
|
||||
- Button and ToggleButton: Support per component minimum height (set client
|
||||
property `JComponent.minimumHeight` to an integer). (issue #44)
|
||||
- Button and ToggleButton: Do not apply minimum width if button border was
|
||||
|
||||
@@ -344,9 +344,26 @@ public abstract class FlatLaf
|
||||
private void initInputMaps( UIDefaults defaults ) {
|
||||
if( SystemInfo.IS_MAC ) {
|
||||
// AquaLookAndFeel (the base for UI defaults on macOS) uses special
|
||||
// action keys (e.g. "aquaExpandNode") for its macOS typical tree node
|
||||
// expanding/collapsing, which are not available in FlatLaf.
|
||||
// --> map the keys back to default Java actions
|
||||
// action keys (e.g. "aquaExpandNode") for some macOS specific behaviour.
|
||||
// Those action keys are not available in FlatLaf, which makes it
|
||||
// necessary to make some modifications.
|
||||
|
||||
// combobox
|
||||
defaults.put( "ComboBox.ancestorInputMap", new UIDefaults.LazyInputMap( new Object[] {
|
||||
"ESCAPE", "hidePopup",
|
||||
"PAGE_UP", "pageUpPassThrough",
|
||||
"PAGE_DOWN", "pageDownPassThrough",
|
||||
"HOME", "homePassThrough",
|
||||
"END", "endPassThrough",
|
||||
"DOWN", "selectNext",
|
||||
"KP_DOWN", "selectNext",
|
||||
"SPACE", "spacePopup",
|
||||
"ENTER", "enterPressed",
|
||||
"UP", "selectPrevious",
|
||||
"KP_UP", "selectPrevious"
|
||||
} ) );
|
||||
|
||||
// tree node expanding/collapsing
|
||||
modifyInputMap( defaults, "Tree.focusInputMap",
|
||||
"RIGHT", "selectChild",
|
||||
"KP_RIGHT", "selectChild",
|
||||
@@ -486,6 +503,9 @@ public abstract class FlatLaf
|
||||
|
||||
//---- class LazyModifyInputMap -------------------------------------------
|
||||
|
||||
/**
|
||||
* Takes a (lazy) base input map and lazily applies modifications to it specified in bindings.
|
||||
*/
|
||||
private static class LazyModifyInputMap
|
||||
implements LazyValue
|
||||
{
|
||||
@@ -515,6 +535,5 @@ public abstract class FlatLaf
|
||||
|
||||
return inputMap;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ import java.awt.Insets;
|
||||
import java.awt.LayoutManager;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Shape;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.FocusEvent;
|
||||
import java.awt.event.FocusListener;
|
||||
import java.awt.event.MouseListener;
|
||||
@@ -35,13 +37,16 @@ import java.awt.geom.Rectangle2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.lang.ref.WeakReference;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.DefaultListCellRenderer;
|
||||
import javax.swing.InputMap;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JComboBox;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.JList;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ListCellRenderer;
|
||||
import javax.swing.LookAndFeel;
|
||||
import javax.swing.SwingConstants;
|
||||
@@ -54,6 +59,7 @@ import javax.swing.plaf.basic.BasicComboPopup;
|
||||
import javax.swing.plaf.basic.ComboPopup;
|
||||
import javax.swing.text.JTextComponent;
|
||||
import com.formdev.flatlaf.FlatClientProperties;
|
||||
import com.formdev.flatlaf.util.SystemInfo;
|
||||
import com.formdev.flatlaf.util.UIScale;
|
||||
|
||||
/**
|
||||
@@ -271,6 +277,18 @@ public class FlatComboBoxUI
|
||||
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||
|
||||
updateEditorColors();
|
||||
|
||||
// macOS
|
||||
if( SystemInfo.IS_MAC && editor instanceof JTextComponent ) {
|
||||
// delegate actions from editor text field to combobox, which is necessary
|
||||
// because text field on macOS (based on Aqua LaF UI defaults)
|
||||
// already handle those keys
|
||||
InputMap inputMap = ((JTextComponent)editor).getInputMap();
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "UP" ) );
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "KP_UP" ) );
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "DOWN" ) );
|
||||
new EditorDelegateAction( inputMap, KeyStroke.getKeyStroke( "KP_DOWN" ) );
|
||||
}
|
||||
}
|
||||
|
||||
private void updateEditorColors() {
|
||||
@@ -608,4 +626,31 @@ public class FlatComboBoxUI
|
||||
rendererBorder.paintBorder( c, g, x, y, width, height );
|
||||
}
|
||||
}
|
||||
|
||||
//---- class EditorDelegateAction -----------------------------------------
|
||||
|
||||
/**
|
||||
* Delegates actions from editor text field to combobox.
|
||||
*/
|
||||
private class EditorDelegateAction
|
||||
extends AbstractAction
|
||||
{
|
||||
private final KeyStroke keyStroke;
|
||||
|
||||
EditorDelegateAction( InputMap inputMap, KeyStroke keyStroke ) {
|
||||
this.keyStroke = keyStroke;
|
||||
|
||||
// add to input map
|
||||
inputMap.put( keyStroke, this );
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionPerformed( ActionEvent e ) {
|
||||
ActionListener action = comboBox.getActionForKeyStroke( keyStroke );
|
||||
if( action != null ) {
|
||||
action.actionPerformed( new ActionEvent( comboBox, e.getID(),
|
||||
e.getActionCommand(), e.getWhen(), e.getModifiers() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user