mirror of
https://github.com/JFormDesigner/FlatLaf.git
synced 2026-02-12 23:07:15 -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`.
|
longer `null`.
|
||||||
- Tree on macOS: Fixed <kbd>Left</kbd> and <kbd>Right</kbd> keys to collapse or
|
- Tree on macOS: Fixed <kbd>Left</kbd> and <kbd>Right</kbd> keys to collapse or
|
||||||
expand nodes.
|
expand nodes.
|
||||||
|
- ComboBox on macOS: Fixed keyboard navigation and show/hide popup.
|
||||||
- Button and ToggleButton: Support per component minimum height (set client
|
- Button and ToggleButton: Support per component minimum height (set client
|
||||||
property `JComponent.minimumHeight` to an integer). (issue #44)
|
property `JComponent.minimumHeight` to an integer). (issue #44)
|
||||||
- Button and ToggleButton: Do not apply minimum width if button border was
|
- 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 ) {
|
private void initInputMaps( UIDefaults defaults ) {
|
||||||
if( SystemInfo.IS_MAC ) {
|
if( SystemInfo.IS_MAC ) {
|
||||||
// AquaLookAndFeel (the base for UI defaults on macOS) uses special
|
// AquaLookAndFeel (the base for UI defaults on macOS) uses special
|
||||||
// action keys (e.g. "aquaExpandNode") for its macOS typical tree node
|
// action keys (e.g. "aquaExpandNode") for some macOS specific behaviour.
|
||||||
// expanding/collapsing, which are not available in FlatLaf.
|
// Those action keys are not available in FlatLaf, which makes it
|
||||||
// --> map the keys back to default Java actions
|
// 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",
|
modifyInputMap( defaults, "Tree.focusInputMap",
|
||||||
"RIGHT", "selectChild",
|
"RIGHT", "selectChild",
|
||||||
"KP_RIGHT", "selectChild",
|
"KP_RIGHT", "selectChild",
|
||||||
@@ -486,6 +503,9 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
//---- class LazyModifyInputMap -------------------------------------------
|
//---- class LazyModifyInputMap -------------------------------------------
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes a (lazy) base input map and lazily applies modifications to it specified in bindings.
|
||||||
|
*/
|
||||||
private static class LazyModifyInputMap
|
private static class LazyModifyInputMap
|
||||||
implements LazyValue
|
implements LazyValue
|
||||||
{
|
{
|
||||||
@@ -515,6 +535,5 @@ public abstract class FlatLaf
|
|||||||
|
|
||||||
return inputMap;
|
return inputMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ import java.awt.Insets;
|
|||||||
import java.awt.LayoutManager;
|
import java.awt.LayoutManager;
|
||||||
import java.awt.Rectangle;
|
import java.awt.Rectangle;
|
||||||
import java.awt.Shape;
|
import java.awt.Shape;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
import java.awt.event.FocusEvent;
|
import java.awt.event.FocusEvent;
|
||||||
import java.awt.event.FocusListener;
|
import java.awt.event.FocusListener;
|
||||||
import java.awt.event.MouseListener;
|
import java.awt.event.MouseListener;
|
||||||
@@ -35,13 +37,16 @@ import java.awt.geom.Rectangle2D;
|
|||||||
import java.beans.PropertyChangeEvent;
|
import java.beans.PropertyChangeEvent;
|
||||||
import java.beans.PropertyChangeListener;
|
import java.beans.PropertyChangeListener;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
import javax.swing.DefaultListCellRenderer;
|
import javax.swing.DefaultListCellRenderer;
|
||||||
|
import javax.swing.InputMap;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JComboBox;
|
import javax.swing.JComboBox;
|
||||||
import javax.swing.JComponent;
|
import javax.swing.JComponent;
|
||||||
import javax.swing.JList;
|
import javax.swing.JList;
|
||||||
import javax.swing.JPanel;
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.KeyStroke;
|
||||||
import javax.swing.ListCellRenderer;
|
import javax.swing.ListCellRenderer;
|
||||||
import javax.swing.LookAndFeel;
|
import javax.swing.LookAndFeel;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
@@ -54,6 +59,7 @@ import javax.swing.plaf.basic.BasicComboPopup;
|
|||||||
import javax.swing.plaf.basic.ComboPopup;
|
import javax.swing.plaf.basic.ComboPopup;
|
||||||
import javax.swing.text.JTextComponent;
|
import javax.swing.text.JTextComponent;
|
||||||
import com.formdev.flatlaf.FlatClientProperties;
|
import com.formdev.flatlaf.FlatClientProperties;
|
||||||
|
import com.formdev.flatlaf.util.SystemInfo;
|
||||||
import com.formdev.flatlaf.util.UIScale;
|
import com.formdev.flatlaf.util.UIScale;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -271,6 +277,18 @@ public class FlatComboBoxUI
|
|||||||
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
|
editor.applyComponentOrientation( comboBox.getComponentOrientation() );
|
||||||
|
|
||||||
updateEditorColors();
|
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() {
|
private void updateEditorColors() {
|
||||||
@@ -608,4 +626,31 @@ public class FlatComboBoxUI
|
|||||||
rendererBorder.paintBorder( c, g, x, y, width, height );
|
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