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

commit 23e72ed19cbd8e026386878bcf08d070d15a373d
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sat May 23 10:11:14 2026 -0400

    CMComboBoxCellEditor refactoring
---
 .../toolkit/combobox/CMComboBoxCellEditor.java     | 100 +++++++++++++++++++++
 .../CMComboBoxPopupResizer.java}                   |  90 +++----------------
 .../ui/dbrelationship/DbRelationshipDialog.java    |   2 +-
 .../dbentity/properties/DbAttributePanel.java      |   2 +-
 .../dbentity/properties/DbRelationshipPanel.java   |   2 +-
 .../attributes/EmbeddableAttributesView.java       |   2 +-
 .../duplicates/DuplicatedAttributesDialog.java     |   2 +-
 .../objentity/properties/ObjAttributePanel.java    |   2 +-
 .../objentity/properties/ObjRelationshipPanel.java |   2 +-
 .../editor/procedure/ProcedureParameterTab.java    |   2 +-
 10 files changed, 122 insertions(+), 84 deletions(-)

diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/combobox/CMComboBoxCellEditor.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/combobox/CMComboBoxCellEditor.java
new file mode 100644
index 000000000..ecc06b238
--- /dev/null
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/combobox/CMComboBoxCellEditor.java
@@ -0,0 +1,100 @@
+/*****************************************************************
+ *   Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    https://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ ****************************************************************/
+
+package org.apache.cayenne.modeler.toolkit.combobox;
+
+import javax.swing.*;
+import javax.swing.table.TableCellEditor;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseEvent;
+import java.io.Serializable;
+import java.util.EventObject;
+
+/**
+ * Combo box cell editor for the modeler. Handles both auto-completion-aware
+ * and plain combos uniformly. Editing is suppressed for ctrl/shift-clicks so
+ * the user can extend a multi-row selection without opening the editor.
+ */
+public class CMComboBoxCellEditor extends AbstractCellEditor implements 
TableCellEditor, ActionListener, Serializable {
+
+    // Auto-complete combos collide with DefaultCellEditor's stop-editing flow,
+    // so they need a custom action-listener-based path. This client property
+    // is read by Swing's combo UI to keep the popup behavior table-friendly.
+    static final String IS_TABLE_CELL_EDITOR_PROPERTY = 
"JComboBox.isTableCellEditor";
+
+    private final JComboBox<?> comboBox;
+    private final boolean autocomplete;
+
+    public CMComboBoxCellEditor(JComboBox<?> comboBox) {
+        this.comboBox = comboBox;
+        this.autocomplete = Boolean.TRUE.equals(
+                
comboBox.getClientProperty(AutoCompletion.AUTOCOMPLETION_PROPERTY));
+
+        if (autocomplete) {
+            comboBox.putClientProperty(IS_TABLE_CELL_EDITOR_PROPERTY, 
Boolean.TRUE);
+            comboBox.addActionListener(this);
+        }
+
+        comboBox.addPopupMenuListener(new CMComboBoxPopupResizer(comboBox));
+    }
+
+    @Override
+    public Object getCellEditorValue() {
+        return comboBox.getSelectedItem();
+    }
+
+    @Override
+    public Component getTableCellEditorComponent(
+            JTable table, Object value, boolean isSelected, int row, int 
column) {
+        comboBox.setSelectedItem(value);
+        return comboBox;
+    }
+
+    @Override
+    public boolean stopCellEditing() {
+        if (autocomplete && comboBox.isEditable()) {
+            // Notify the combo box that editing has stopped (e.g. user 
pressed F2).
+            comboBox.actionPerformed(new ActionEvent(this, 0, ""));
+        }
+        fireEditingStopped();
+        return true;
+    }
+
+    @Override
+    public boolean isCellEditable(EventObject e) {
+        if (e instanceof MouseEvent) {
+            MouseEvent me = (MouseEvent) e;
+            if (me.isControlDown() || me.isShiftDown()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    @Override
+    public void actionPerformed(ActionEvent e) {
+        // Selecting an item produces "comboBoxChanged" — ignore.
+        // Hitting enter produces "comboBoxEdited" — stop editing.
+        if (autocomplete && "comboBoxEdited".equals(e.getActionCommand())) {
+            stopCellEditing();
+        }
+    }
+}
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/combobox/CMComboBoxPopupResizer.java
similarity index 54%
rename from 
modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/table/CMComboBoxCellEditor.java
rename to 
modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/toolkit/combobox/CMComboBoxPopupResizer.java
index e7961afd4..6a8dce424 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/combobox/CMComboBoxPopupResizer.java
@@ -17,71 +17,39 @@
  *  under the License.
  ****************************************************************/
 
-package org.apache.cayenne.modeler.toolkit.table;
-
-import org.apache.cayenne.modeler.toolkit.combobox.AutoCompletion;
-import org.apache.cayenne.modeler.toolkit.combobox.ComboBoxPopup;
+package org.apache.cayenne.modeler.toolkit.combobox;
 
 import javax.swing.*;
 import javax.swing.event.PopupMenuEvent;
 import javax.swing.event.PopupMenuListener;
-import javax.swing.table.TableCellEditor;
 import java.awt.*;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseEvent;
-import java.io.Serializable;
-import java.util.EventObject;
 
 /**
- * Combo box cell editor for the modeler. Handles both auto-completion-aware
- * and plain combos uniformly. Editing is suppressed for ctrl/shift-clicks so
- * the user can extend a multi-row selection without opening the editor.
+ * Widens a combo box drop-down to fit its content, up to {@link 
ComboBoxPopup#MAX_WIDTH}.
+ * Handles both heavyweight (own Window) and lightweight (embedded) popups 
correctly.
  */
-public class CMComboBoxCellEditor extends AbstractCellEditor
-        implements TableCellEditor, ActionListener, Serializable {
-
-    // Auto-complete combos collide with DefaultCellEditor's stop-editing flow,
-    // so they need a custom action-listener-based path. This client property
-    // is read by Swing's combo UI to keep the popup behavior table-friendly.
-    static final String IS_TABLE_CELL_EDITOR_PROPERTY = 
"JComboBox.isTableCellEditor";
+public class CMComboBoxPopupResizer implements PopupMenuListener {
 
     private final JComboBox<?> comboBox;
-    private final boolean autocomplete;
 
-    public CMComboBoxCellEditor(JComboBox<?> comboBox) {
+    public CMComboBoxPopupResizer(JComboBox<?> comboBox) {
         this.comboBox = comboBox;
-        this.autocomplete = Boolean.TRUE.equals(
-                
comboBox.getClientProperty(AutoCompletion.AUTOCOMPLETION_PROPERTY));
-
-        if (autocomplete) {
-            comboBox.putClientProperty(IS_TABLE_CELL_EDITOR_PROPERTY, 
Boolean.TRUE);
-            comboBox.addActionListener(this);
-        }
+    }
 
-        comboBox.addPopupMenuListener(new PopupMenuListener() {
-            @Override
-            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
-                // 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) {}
-        });
+    @Override
+    public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
+        // 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(this::adjustPopupWidth);
     }
 
     @Override
-    public Object getCellEditorValue() {
-        return comboBox.getSelectedItem();
+    public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
     }
 
     @Override
-    public Component getTableCellEditorComponent(JTable table, Object value,
-                                                 boolean isSelected, int row, 
int column) {
-        comboBox.setSelectedItem(value);
-        return comboBox;
+    public void popupMenuCanceled(PopupMenuEvent e) {
     }
 
     private void adjustPopupWidth() {
@@ -145,34 +113,4 @@ public class CMComboBoxCellEditor extends 
AbstractCellEditor
         }
         return null;
     }
-
-    @Override
-    public boolean stopCellEditing() {
-        if (autocomplete && comboBox.isEditable()) {
-            // Notify the combo box that editing has stopped (e.g. user 
pressed F2).
-            comboBox.actionPerformed(new ActionEvent(this, 0, ""));
-        }
-        fireEditingStopped();
-        return true;
-    }
-
-    @Override
-    public boolean isCellEditable(EventObject e) {
-        if (e instanceof MouseEvent) {
-            MouseEvent me = (MouseEvent) e;
-            if (me.isControlDown() || me.isShiftDown()) {
-                return false;
-            }
-        }
-        return true;
-    }
-
-    @Override
-    public void actionPerformed(ActionEvent e) {
-        // Selecting an item produces "comboBoxChanged" — ignore.
-        // Hitting enter produces "comboBoxEdited" — stop editing.
-        if (autocomplete && "comboBoxEdited".equals(e.getActionCommand())) {
-            stopCellEditing();
-        }
-    }
 }
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
index ddb77346d..3fb61a545 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/dbrelationship/DbRelationshipDialog.java
@@ -36,7 +36,7 @@ import org.apache.cayenne.modeler.project.DbRelationshipOps;
 import org.apache.cayenne.modeler.toolkit.buttons.CMButtonPanel;
 import org.apache.cayenne.modeler.toolkit.combobox.AutoCompletion;
 import org.apache.cayenne.modeler.toolkit.combobox.CMComboBox;
-import org.apache.cayenne.modeler.toolkit.table.CMComboBoxCellEditor;
+import org.apache.cayenne.modeler.toolkit.combobox.CMComboBoxCellEditor;
 import org.apache.cayenne.modeler.toolkit.table.CMTable;
 import org.apache.cayenne.modeler.pref.adapters.CMTablePrefs;
 import org.apache.cayenne.modeler.toolkit.ProjectDialog;
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbAttributePanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbAttributePanel.java
index 0e6d80dd5..35b9459c1 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbAttributePanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbAttributePanel.java
@@ -33,7 +33,7 @@ import org.apache.cayenne.modeler.toolkit.ProjectPanel;
 import org.apache.cayenne.modeler.toolkit.combobox.AutoCompletion;
 import org.apache.cayenne.modeler.toolkit.combobox.CMComboBox;
 import org.apache.cayenne.modeler.toolkit.table.BoardTableCellRenderer;
-import org.apache.cayenne.modeler.toolkit.table.CMComboBoxCellEditor;
+import org.apache.cayenne.modeler.toolkit.combobox.CMComboBoxCellEditor;
 import org.apache.cayenne.modeler.toolkit.table.CMTable;
 import org.apache.cayenne.modeler.toolkit.table.CMTablePanel;
 import org.apache.cayenne.modeler.pref.adapters.CMTablePrefs;
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbRelationshipPanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbRelationshipPanel.java
index c28b7e093..42b6136ba 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbRelationshipPanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/dbentity/properties/DbRelationshipPanel.java
@@ -45,7 +45,7 @@ import org.apache.cayenne.modeler.toolkit.table.CMTablePanel;
 import org.apache.cayenne.modeler.toolkit.Renderers;
 import org.apache.cayenne.modeler.toolkit.combobox.AutoCompletion;
 import org.apache.cayenne.modeler.toolkit.combobox.CMComboBox;
-import org.apache.cayenne.modeler.toolkit.table.CMComboBoxCellEditor;
+import org.apache.cayenne.modeler.toolkit.combobox.CMComboBoxCellEditor;
 
 import javax.swing.*;
 import javax.swing.event.ListSelectionEvent;
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/embeddable/attributes/EmbeddableAttributesView.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/embeddable/attributes/EmbeddableAttributesView.java
index e3ca0b3e3..a122547a0 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/embeddable/attributes/EmbeddableAttributesView.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/embeddable/attributes/EmbeddableAttributesView.java
@@ -34,7 +34,7 @@ import 
org.apache.cayenne.modeler.service.action.GlobalActions;
 import org.apache.cayenne.modeler.toolkit.valuetype.ValueTypes;
 import org.apache.cayenne.modeler.toolkit.combobox.AutoCompletion;
 import org.apache.cayenne.modeler.toolkit.combobox.CMComboBox;
-import org.apache.cayenne.modeler.toolkit.table.CMComboBoxCellEditor;
+import org.apache.cayenne.modeler.toolkit.combobox.CMComboBoxCellEditor;
 import org.apache.cayenne.modeler.toolkit.table.CMTable;
 import org.apache.cayenne.modeler.toolkit.table.CMTablePanel;
 import org.apache.cayenne.modeler.pref.adapters.CMTablePrefs;
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/duplicates/DuplicatedAttributesDialog.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/duplicates/DuplicatedAttributesDialog.java
index b4375d8bc..4287871e5 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/duplicates/DuplicatedAttributesDialog.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/duplicates/DuplicatedAttributesDialog.java
@@ -25,7 +25,7 @@ import org.apache.cayenne.map.ObjAttribute;
 import org.apache.cayenne.map.ObjEntity;
 import org.apache.cayenne.modeler.Application;
 import org.apache.cayenne.modeler.toolkit.combobox.CMComboBox;
-import org.apache.cayenne.modeler.toolkit.table.CMComboBoxCellEditor;
+import org.apache.cayenne.modeler.toolkit.combobox.CMComboBoxCellEditor;
 import org.apache.cayenne.modeler.toolkit.AppDialog;
 import org.apache.cayenne.modeler.project.ProjectSession;
 import org.apache.cayenne.modeler.toolkit.table.CMTableModel;
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjAttributePanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjAttributePanel.java
index da3b6fca6..0dcfce0cb 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjAttributePanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjAttributePanel.java
@@ -39,7 +39,7 @@ import org.apache.cayenne.modeler.project.ObjEntityOps;
 import org.apache.cayenne.modeler.service.action.GlobalActions;
 import org.apache.cayenne.modeler.toolkit.combobox.AutoCompletion;
 import org.apache.cayenne.modeler.toolkit.combobox.CMComboBox;
-import org.apache.cayenne.modeler.toolkit.table.CMComboBoxCellEditor;
+import org.apache.cayenne.modeler.toolkit.combobox.CMComboBoxCellEditor;
 import org.apache.cayenne.modeler.toolkit.icon.IconFactory;
 import org.apache.cayenne.modeler.toolkit.table.CMTable;
 import org.apache.cayenne.modeler.toolkit.table.CMTableModel;
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
index bc62df29f..368379df2 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/objentity/properties/ObjRelationshipPanel.java
@@ -27,7 +27,7 @@ import 
org.apache.cayenne.modeler.event.model.ObjEntityListener;
 import org.apache.cayenne.modeler.event.model.ObjRelationshipListener;
 import org.apache.cayenne.modeler.toolkit.ProjectPanel;
 import org.apache.cayenne.modeler.toolkit.combobox.CMComboBox;
-import org.apache.cayenne.modeler.toolkit.table.CMComboBoxCellEditor;
+import org.apache.cayenne.modeler.toolkit.combobox.CMComboBoxCellEditor;
 import org.apache.cayenne.modeler.toolkit.icon.IconFactory;
 import org.apache.cayenne.modeler.project.ProjectSession;
 import org.apache.cayenne.modeler.service.action.GlobalActions;
diff --git 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureParameterTab.java
 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureParameterTab.java
index f071f1f44..1ecbd0c31 100644
--- 
a/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureParameterTab.java
+++ 
b/modeler/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/procedure/ProcedureParameterTab.java
@@ -37,7 +37,7 @@ import org.apache.cayenne.modeler.toolkit.ProjectPanel;
 import org.apache.cayenne.modeler.toolkit.combobox.AutoCompletion;
 import org.apache.cayenne.modeler.toolkit.combobox.CMComboBox;
 import org.apache.cayenne.modeler.toolkit.icon.IconFactory;
-import org.apache.cayenne.modeler.toolkit.table.CMComboBoxCellEditor;
+import org.apache.cayenne.modeler.toolkit.combobox.CMComboBoxCellEditor;
 import org.apache.cayenne.modeler.toolkit.table.CMTable;
 import org.apache.cayenne.modeler.toolkit.table.CMTablePanel;
 import org.apache.cayenne.modeler.pref.adapters.CMTablePrefs;

Reply via email to