diff --git a/CHANGELOG.md b/CHANGELOG.md index 14d45a01..e6b08448 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ FlatLaf Change Log - Extras: Class `FlatSVGIcon` now uses [JSVG](https://github.com/weisJ/jsvg) library (instead of svgSalamander) for rendering. JSVG provides improved SVG rendering and uses less memory compared to svgSalamander. (PR #684) +- ComboBox: Improved location of selected item in popup if list is large and + scrollable. - Added system property `flatlaf.useNativeLibrary` to allow disabling loading of FlatLaf native library. (issue #674) diff --git a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java index 4dc256f3..f24bb543 100644 --- a/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java +++ b/flatlaf-core/src/main/java/com/formdev/flatlaf/ui/FlatComboBoxUI.java @@ -986,6 +986,29 @@ public class FlatComboBoxUI } } + // improve location of selected item in popup if list is large and scrollable + if( list.getHeight() == 0 ) { + // If popup is shown for the first time (or after a laf switch) and is scrollable, + // then BasicComboPopup scrolls the selected item to the top of the visible area. + // But for usability it would be better to have selected item somewhere + // in the middle of the visible area so that the user can see items above + // the selected item, which are usually more "important". + + int selectedIndex = list.getSelectedIndex(); + if( selectedIndex >= 1 ) { + int maximumRowCount = comboBox.getMaximumRowCount(); + if( selectedIndex < maximumRowCount ) { + // selected item is in the first visible items --> scroll to top + list.scrollRectToVisible( new Rectangle() ); + } else { + // scroll the selected item to the middle of the visible area + int firstVisibleIndex = Math.max( selectedIndex - (maximumRowCount / 2), 0 ); + if( firstVisibleIndex > 0 ) + list.ensureIndexIsVisible( firstVisibleIndex ); + } + } + } + super.show( invoker, x, y ); }