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 aa66b4b58 Modeler: cleaning up DB Import panels
aa66b4b58 is described below

commit aa66b4b58d94903af7c57bea4f084558ab2da425
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sat Aug 29 20:14:35 2026 -0400

    Modeler: cleaning up DB Import panels
    
    * centering empty table messages
    * filter editor look aligned with regular text field
---
 .../editor/datadomain/DataDomainGeneratorsTab.java |  2 +-
 .../editor/datamap/dbimport/DBSchemaPanel.java     |  8 +-
 .../editor/datamap/dbimport/DbImportTree.java      | 24 ++++++
 .../datamap/dbimport/DbImportTreeCellEditor.java   | 17 ++++
 .../datamap/dbimport/DbImportTreeCellRenderer.java |  4 +-
 .../editor/datamap/dbimport/DbImportTreeModel.java | 12 +--
 .../editor/datamap/dbimport/DbImportTreeView.java  | 95 ++++++++++++++++++++++
 .../editor/datamap/dbimport/DbImportView.java      |  6 +-
 .../dbimport/ReverseEngineeringTreePanel.java      |  2 +-
 .../datamap/dbimport/tree/ColorTreeRenderer.java   |  4 +-
 .../editor/datamap/dbimport/tree/Status.java       | 19 +++--
 11 files changed, 167 insertions(+), 26 deletions(-)

diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datadomain/DataDomainGeneratorsTab.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datadomain/DataDomainGeneratorsTab.java
index 85ef542e6..7cf847df8 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datadomain/DataDomainGeneratorsTab.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datadomain/DataDomainGeneratorsTab.java
@@ -91,7 +91,7 @@ public abstract class DataDomainGeneratorsTab<T> extends 
ProjectPanel implements
         builder.setDefaultDialogBorder();
 
         if (generatorsPanels.isEmpty()) {
-            this.add(new JLabel("There are no datamaps.", 
SwingConstants.CENTER), BorderLayout.CENTER);
+            this.add(new JLabel("There are no DataMaps", 
SwingConstants.CENTER), BorderLayout.CENTER);
             return;
         }
 
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DBSchemaPanel.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DBSchemaPanel.java
index 969de1254..fa9f263e6 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DBSchemaPanel.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DBSchemaPanel.java
@@ -75,7 +75,7 @@ public class DBSchemaPanel extends JPanel {
 
     private final AppAction.CayenneToolbarButton moveButton;
     private final AppAction.CayenneToolbarButton moveInvertButton;
-    private final JScrollPane scrollPane;
+    private final DbImportTreeView sourceTreeView;
 
     private ImportSourceTree importSourceTree;
 
@@ -88,7 +88,7 @@ public class DBSchemaPanel extends JPanel {
         this.insertableLevels = new HashMap<>();
         this.moveButton = (AppAction.CayenneToolbarButton) 
actions.getMoveImportNodeAction().buildButton();
         this.moveInvertButton = (AppAction.CayenneToolbarButton) 
actions.getMoveInvertNodeAction().buildButton();
-        this.scrollPane = new JScrollPane(sourceTree);
+        this.sourceTreeView = new DbImportTreeView(sourceTree);
 
         initLayout();
         initBindings();
@@ -138,7 +138,7 @@ public class DBSchemaPanel extends JPanel {
         moveInvertButton.setText(MOVE_INV_BUTTON_LABEL);
 
         setLayout(new BorderLayout());
-        add(scrollPane, BorderLayout.CENTER);
+        add(sourceTreeView, BorderLayout.CENTER);
     }
 
     private void initBindings() {
@@ -175,7 +175,7 @@ public class DBSchemaPanel extends JPanel {
     }
 
     public void resetHorizontalScroll() {
-        scrollPane.getHorizontalScrollBar().setValue(0);
+        sourceTreeView.getScrollPane().getHorizontalScrollBar().setValue(0);
     }
 
     private boolean canBeMoved() {
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTree.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTree.java
index 92656c61f..5794fd189 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTree.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTree.java
@@ -40,6 +40,7 @@ import javax.swing.plaf.basic.BasicTreeUI;
 import javax.swing.tree.TreeNode;
 import javax.swing.tree.TreePath;
 import java.awt.Color;
+import java.awt.Dimension;
 import java.awt.Graphics;
 import java.awt.Insets;
 import java.awt.Rectangle;
@@ -56,6 +57,7 @@ public class DbImportTree extends JTree {
     private boolean isTransferable;
     private ReverseEngineering reverseEngineering;
     private LoadDbSchemaAction loadDbSchemaAction;
+    private String emptyText;
 
     public DbImportTree(TreeNode node) {
         super(node);
@@ -68,6 +70,28 @@ public class DbImportTree extends JTree {
         this.loadDbSchemaAction = loadDbSchemaAction;
     }
 
+    /**
+     * Sets a message shown in place of this tree while it is empty.
+     */
+    public void setEmptyText(String emptyText) {
+        this.emptyText = emptyText;
+    }
+
+    public String getEmptyText() {
+        return emptyText;
+    }
+
+    @Override
+    public Dimension getPreferredScrollableViewportSize() {
+        Dimension size = super.getPreferredScrollableViewportSize();
+        if (getRowCount() == 0) {
+            // an empty tree has no rows to measure, and JTree falls back to a 
16 px guess. Use our own row
+            // height instead, so that an empty tree takes as much space as a 
populated one
+            size.height = getVisibleRowCount() * 
DbImportTreeCellRenderer.MIN_ROW_HEIGHT;
+        }
+        return size;
+    }
+
     public void translateReverseEngineeringToTree(ReverseEngineering 
reverseEngineering, boolean isTransferable) {
         this.isTransferable = isTransferable;
         this.reverseEngineering = reverseEngineering;
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeCellEditor.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeCellEditor.java
index 1637f89dd..4fe6f5714 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeCellEditor.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeCellEditor.java
@@ -25,8 +25,11 @@ import 
org.apache.cayenne.modeler.ui.project.editor.datamap.dbimport.action.Edit
 import 
org.apache.cayenne.modeler.ui.project.editor.datamap.dbimport.tree.DbImportTreeNode;
 import org.apache.cayenne.util.Util;
 
+import javax.swing.DefaultCellEditor;
+import javax.swing.JTextField;
 import javax.swing.JTree;
 import javax.swing.UIManager;
+import javax.swing.border.Border;
 import javax.swing.event.CellEditorListener;
 import javax.swing.event.ChangeEvent;
 import javax.swing.tree.DefaultTreeCellEditor;
@@ -45,6 +48,7 @@ public class DbImportTreeCellEditor extends 
DefaultTreeCellEditor {
         super(tree, renderer);
         this.actions = actions;
         setFont(UIManager.getFont("Tree.font"));
+        initEditorFieldBorder();
         this.addCellEditorListener(new CellEditorListener() {
             @Override
             public void editingStopped(ChangeEvent e) {
@@ -59,6 +63,19 @@ public class DbImportTreeCellEditor extends 
DefaultTreeCellEditor {
 
     }
 
+    /**
+     * Replaces the default "Tree.editorBorder" - a black line with no padding 
- with the border used by the
+     * regular text fields, so that the editor gets the same padding and the 
same (focus-aware) border color.
+     */
+    private void initEditorFieldBorder() {
+        Border border = UIManager.getBorder("TextField.border");
+        if (border != null
+                && realEditor instanceof DefaultCellEditor cellEditor
+                && cellEditor.getComponent() instanceof JTextField textField) {
+            textField.setBorder(border);
+        }
+    }
+
     @Override
     public Object getCellEditorValue() {
         if (tree.getSelectionPath() == null) {
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeCellRenderer.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeCellRenderer.java
index 5a00cf3c4..9b6d5c877 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeCellRenderer.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeCellRenderer.java
@@ -44,6 +44,8 @@ import java.util.Map;
 
 public class DbImportTreeCellRenderer extends DefaultTreeCellRenderer {
 
+    static final int MIN_ROW_HEIGHT = 25;
+
     protected DbImportTreeNode node;
     private Map<Class<?>, String> icons;
     private Map<Class<?>, String> transferableTreeIcons;
@@ -110,7 +112,7 @@ public class DbImportTreeCellRenderer extends 
DefaultTreeCellRenderer {
     @Override
     public Dimension getPreferredSize() {
         Dimension size = super.getPreferredSize();
-        return new Dimension(size.width, Math.max(size.height, 25));
+        return new Dimension(size.width, Math.max(size.height, 
MIN_ROW_HEIGHT));
     }
 
     @Override
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeModel.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeModel.java
index 4bccebef5..a3a82bf46 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeModel.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeModel.java
@@ -28,12 +28,10 @@ import javax.swing.tree.TreeNode;
 public class DbImportTreeModel extends DefaultTreeModel {
 
     private final boolean canBeCleaned;
-    private final String emptyText;
 
-    DbImportTreeModel(TreeNode root, boolean canBeCleaned, String emptyText) {
+    DbImportTreeModel(TreeNode root, boolean canBeCleaned) {
         super(root);
         this.canBeCleaned = canBeCleaned;
-        this.emptyText = emptyText;
     }
 
     private void clearReverseEngineering(ReverseEngineering 
reverseEngineering) {
@@ -49,12 +47,8 @@ public class DbImportTreeModel extends DefaultTreeModel {
 
     private void preprocessTree() {
         DbImportTreeNode rootNode = (DbImportTreeNode) getRoot();
-        if (rootNode.getChildCount() == 0) {
-            ReverseEngineering reverseEngineering = ((ReverseEngineering) 
rootNode.getUserObject());
-            if (canBeCleaned) {
-                clearReverseEngineering(reverseEngineering);
-            }
-            rootNode.add(new DbImportTreeNode(emptyText));
+        if (rootNode.getChildCount() == 0 && canBeCleaned) {
+            clearReverseEngineering((ReverseEngineering) 
rootNode.getUserObject());
         }
     }
 
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeView.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeView.java
new file mode 100644
index 000000000..160cde532
--- /dev/null
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportTreeView.java
@@ -0,0 +1,95 @@
+/*****************************************************************
+ *   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.ui.project.editor.datamap.dbimport;
+
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.SwingConstants;
+import javax.swing.UIManager;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.tree.TreeNode;
+import java.awt.CardLayout;
+import java.awt.Color;
+
+/**
+ * A scrollable {@link DbImportTree} that is replaced with a centered message 
while the tree is empty.
+ */
+class DbImportTreeView extends JPanel {
+
+    private static final String TREE_CARD = "tree";
+    private static final String EMPTY_CARD = "empty";
+
+    private final DbImportTree tree;
+    private final JScrollPane scrollPane;
+    private final JLabel emptyLabel;
+    private final CardLayout cards;
+
+    DbImportTreeView(DbImportTree tree) {
+        this.tree = tree;
+        this.cards = new CardLayout();
+        this.scrollPane = new JScrollPane(tree);
+        this.emptyLabel = new JLabel("", SwingConstants.CENTER);
+
+        emptyLabel.setOpaque(true);
+        emptyLabel.setBackground(tree.getBackground());
+        Color disabled = UIManager.getColor("Label.disabledForeground");
+        emptyLabel.setForeground(disabled != null ? disabled : Color.GRAY);
+
+        setLayout(cards);
+        add(scrollPane, TREE_CARD);
+        add(emptyLabel, EMPTY_CARD);
+
+        tree.getModel().addTreeModelListener(new TreeModelListener() {
+
+            public void treeNodesChanged(TreeModelEvent e) {
+                showRelevantCard();
+            }
+
+            public void treeNodesInserted(TreeModelEvent e) {
+                showRelevantCard();
+            }
+
+            public void treeNodesRemoved(TreeModelEvent e) {
+                showRelevantCard();
+            }
+
+            public void treeStructureChanged(TreeModelEvent e) {
+                showRelevantCard();
+            }
+        });
+
+        showRelevantCard();
+    }
+
+    JScrollPane getScrollPane() {
+        return scrollPane;
+    }
+
+    private void showRelevantCard() {
+        if (((TreeNode) tree.getModel().getRoot()).getChildCount() == 0) {
+            emptyLabel.setText(tree.getEmptyText());
+            cards.show(this, EMPTY_CARD);
+        } else {
+            cards.show(this, TREE_CARD);
+        }
+    }
+}
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportView.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportView.java
index da2446795..b04fd8b33 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportView.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/DbImportView.java
@@ -58,14 +58,16 @@ public class DbImportView extends ProjectPanel {
 
         DbImportTreeNode configRoot = new DbImportTreeNode(new 
ReverseEngineering());
         DbImportTree configTree = new DbImportTree(configRoot);
-        DbImportTreeModel configModel = new DbImportTreeModel(configRoot, 
true, "Create DB Import Rules");
+        DbImportTreeModel configModel = new DbImportTreeModel(configRoot, 
true);
+        configTree.setEmptyText("Create DB Import rules");
         configTree.setRootVisible(false);
         configTree.setModel(configModel);
         configTree.setShowsRootHandles(true);
 
         DbImportTreeNode dbSchemaRootNode = new DbImportTreeNode(new 
ReverseEngineering());
         DbImportTree dbSchemaTree = new DbImportTree(new 
TransferableNode(dbSchemaRootNode));
-        DbImportTreeModel dbSchemaModel = new 
DbImportTreeModel(dbSchemaRootNode, false, "Click 'Refresh DB Schema' to load 
the schema.");
+        DbImportTreeModel dbSchemaModel = new 
DbImportTreeModel(dbSchemaRootNode, false);
+        dbSchemaTree.setEmptyText("Click 'Refresh DB Schema' to load the 
schema");
         dbSchemaTree.setRootVisible(false);
         dbSchemaTree.setShowsRootHandles(true);
         dbSchemaTree.setModel(dbSchemaModel);
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/ReverseEngineeringTreePanel.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/ReverseEngineeringTreePanel.java
index e47989086..977cb5622 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/ReverseEngineeringTreePanel.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/ReverseEngineeringTreePanel.java
@@ -92,7 +92,7 @@ class ReverseEngineeringTreePanel extends ProjectPanel {
         popups.put(ExcludeProcedure.class, new DefaultPopUpMenu(actions));
         changeIcons();
         setLayout(new BorderLayout());
-        add(new JScrollPane(reverseEngineeringTree), BorderLayout.CENTER);
+        add(new DbImportTreeView(reverseEngineeringTree), BorderLayout.CENTER);
     }
 
     private void initBindings() {
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/tree/ColorTreeRenderer.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/tree/ColorTreeRenderer.java
index 8311a54f9..8c63366c2 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/tree/ColorTreeRenderer.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/tree/ColorTreeRenderer.java
@@ -56,7 +56,7 @@ public class ColorTreeRenderer extends 
DbImportTreeCellRenderer {
                                                   boolean leaf, int row, 
boolean hasFocus) {
         super.getTreeCellRendererComponent(tree, value, selected, expanded, 
leaf, row, hasFocus);
 
-        if (this.node.isLabel() || selected) {
+        if (this.node.isLabel()) {
             return this;
         }
 
@@ -71,7 +71,7 @@ public class ColorTreeRenderer extends 
DbImportTreeCellRenderer {
             status = logicalTreeNode.getStatus(mask);
         }
 
-        setForeground(status.getColor());
+        setForeground(status.getColor(selected));
         return this;
     }
 
diff --git 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/tree/Status.java
 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/tree/Status.java
index 1c3cfe4e4..721375106 100644
--- 
a/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/tree/Status.java
+++ 
b/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/ui/project/editor/datamap/dbimport/tree/Status.java
@@ -22,17 +22,24 @@ package 
org.apache.cayenne.modeler.ui.project.editor.datamap.dbimport.tree;
 import java.awt.Color;
 
 enum Status {
-    INCLUDE             (new Color(60,179,113)),
-    EXCLUDE_EXPLICIT    (new Color(178, 0, 0)),
-    EXCLUDE_IMPLICIT    (Color.LIGHT_GRAY);
+
+    INCLUDE             (new Color(60,179,113), new Color(60,179,113)),
+    EXCLUDE_EXPLICIT    (Color.GRAY,            Color.WHITE),
+    EXCLUDE_IMPLICIT    (Color.BLACK,           Color.BLACK);
 
     private final Color color;
+    private final Color selectionColor;
 
-    Status(Color color) {
+    Status(Color color, Color selectionColor) {
         this.color = color;
+        this.selectionColor = selectionColor;
     }
 
-    public Color getColor() {
-        return color;
+    /**
+     * Returns the text color for this status. Selected rows keep their color, 
except for the grey of an
+     * explicit exclude, that is invisible against the selection background.
+     */
+    public Color getColor(boolean selected) {
+        return selected ? selectionColor : color;
     }
 }

Reply via email to