This is an automated email from the ASF dual-hosted git repository.

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/master by this push:
     new 2b35e20b0 CayenneModeler .. Messy combo box sizing for editable popups
2b35e20b0 is described below

commit 2b35e20b0b485c38fc6d9612f95823eac65aba15
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sat May 23 08:39:51 2026 -0400

    CayenneModeler .. Messy combo box sizing for editable popups
    
    vibecoding vs Swing :-/
---
 .../toolkit/table/CMComboBoxCellEditor.java        | 47 +++++++++++-----------
 1 file changed, 24 insertions(+), 23 deletions(-)

diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMComboBoxCellEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMComboBoxCellEditor.java
index d0e207a77..c6e7d6e97 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMComboBoxCellEditor.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMComboBoxCellEditor.java
@@ -62,21 +62,10 @@ public class CMComboBoxCellEditor extends AbstractCellEditor
         comboBox.addPopupMenuListener(new PopupMenuListener() {
             @Override
             public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
-                // First call: sets popup.preferredSize so the popup *window* 
is created at the
-                // correct width (window size is determined from 
popup.preferredSize before show()).
-                adjustPopupWidth();
-                // Second call via invokeLater: BasicComboPopup.show() calls 
getPopupLocation()
-                // *after* firing this listener, which re-constrains 
scroller.maxSize back to the
-                // column width. Running again on the next EDT cycle fixes the 
scroller, then
-                // revalidate/repaint forces the layout to update inside the 
already-wide window.
-                SwingUtilities.invokeLater(() -> {
-                    adjustPopupWidth();
-                    Object child = 
comboBox.getUI().getAccessibleChild(comboBox, 0);
-                    if (child instanceof JPopupMenu popup) {
-                        popup.revalidate();
-                        popup.repaint();
-                    }
-                });
+                // BasicComboPopup.show() calls getPopupLocation() after this 
listener fires,
+                // constraining the popup to the column width. Adjust on the 
next EDT cycle —
+                // invokeLater lands ahead of the first WM_PAINT, so no flash 
occurs.
+                SwingUtilities.invokeLater(() -> adjustPopupWidth());
             }
             @Override public void popupMenuWillBecomeInvisible(PopupMenuEvent 
e) {}
             @Override public void popupMenuCanceled(PopupMenuEvent e) {}
@@ -97,19 +86,20 @@ public class CMComboBoxCellEditor extends AbstractCellEditor
 
     private void adjustPopupWidth() {
         Object child = comboBox.getUI().getAccessibleChild(comboBox, 0);
-        if (!(child instanceof JPopupMenu)) {
+        if (!(child instanceof JPopupMenu popup)) {
             return;
         }
-        JPopupMenu popup = (JPopupMenu) child;
         JScrollPane scrollPane = findScrollPane(popup);
         if (scrollPane == null) {
             return;
         }
+        Window window = SwingUtilities.getWindowAncestor(popup);
+        if (window == null) {
+            return;
+        }
 
-        // BasicComboPopup.show() constrains the scroll pane's preferredSize 
and maximumSize
-        // to the column width before firing this listener. Reset them so the 
scroll pane
-        // reports its natural content-based width — which already 
incorporates item metrics,
-        // list insets, scrollbar width, and scroll pane borders — no manual 
overhead needed.
+        // Clear sizes set by BasicComboPopup.getPopupLocation() so the scroll 
pane
+        // reports its natural content-based width.
         scrollPane.setPreferredSize(null);
         scrollPane.setMaximumSize(null);
         popup.setPreferredSize(null);
@@ -117,10 +107,21 @@ public class CMComboBoxCellEditor extends 
AbstractCellEditor
         int naturalWidth = scrollPane.getPreferredSize().width;
         int targetWidth = Math.min(Math.max(naturalWidth, 
comboBox.getWidth()), ComboBoxPopup.MAX_WIDTH);
 
-        Dimension scrollSize = new Dimension(targetWidth, 
scrollPane.getPreferredSize().height);
+        // Use the window's actual height — correctly determined by 
BasicComboPopup based on row count.
+        // Setting scroller maxSize to windowHeight lets BoxLayout fill all 
available vertical space.
+        int windowHeight = window.getHeight();
+        Dimension scrollSize = new Dimension(targetWidth, windowHeight);
         scrollPane.setPreferredSize(scrollSize);
         scrollPane.setMaximumSize(scrollSize);
-        popup.setPreferredSize(new Dimension(targetWidth, 
popup.getPreferredSize().height));
+        popup.setPreferredSize(new Dimension(targetWidth, windowHeight));
+
+        // Widen the popup window; the height was already set correctly by 
BasicComboPopup.
+        Point loc = window.getLocation();
+        window.setSize(targetWidth, windowHeight);
+        window.setLocation(loc);
+
+        popup.revalidate();
+        popup.repaint();
     }
 
     private static JScrollPane findScrollPane(Container container) {

Reply via email to