You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by aa...@apache.org on 2010/01/04 09:04:59 UTC

svn commit: r895574 [1/2] - in /cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler: dialog/ dialog/objentity/ dialog/validator/ editor/ editor/dbentity/ pref/ util/

Author: aadamchik
Date: Mon Jan  4 08:04:52 2010
New Revision: 895574

URL: http://svn.apache.org/viewvc?rev=895574&view=rev
Log:
CAY-1350 Implement memorized sorting of modeler columns

patch by Ksenia Khailenko. Works 99%, just a few small glitches remain

Added:
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BevelArrowIcon.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BlankIcon.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/SortButtonRenderer.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/TableHeaderSortingListener.java
Modified:
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbJoinTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialogView.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/OverrideEmbeddableAttributeTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/validator/DuplicatedAttributesDialog.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AbstractCallbackMethodsTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackDescriptorTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjAttributeTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityAttributeTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/TableColumnPreferences.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTable.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTableModel.java
    cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CellEditorForAttributeTable.java

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbJoinTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbJoinTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbJoinTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/DbJoinTableModel.java Mon Jan  4 08:04:52 2010
@@ -153,4 +153,21 @@
 
         return false;
     }
+
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return true;
+    }
+
+    @Override
+    public void sortByColumn(int sortCol, boolean isAscent) {
+        switch(sortCol){
+            case SOURCE:
+                sortByElementProperty("sourceName", isAscent);
+                break;
+            case TARGET:
+                sortByElementProperty("targetName", isAscent);
+                break;
+        }
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/ResolveDbRelationshipDialog.java Mon Jan  4 08:04:52 2010
@@ -47,6 +47,8 @@
 import org.apache.cayenne.map.event.MapEvent;
 import org.apache.cayenne.map.event.RelationshipEvent;
 import org.apache.cayenne.modeler.Application;
+import org.apache.cayenne.modeler.editor.ObjAttributeTableModel;
+import org.apache.cayenne.modeler.pref.TableColumnPreferences;
 import org.apache.cayenne.modeler.undo.RelationshipUndoableEdit;
 import org.apache.cayenne.modeler.util.CayenneDialog;
 import org.apache.cayenne.modeler.util.CayenneTable;
@@ -73,6 +75,7 @@
     protected JTextField name;
     protected JTextField reverseName;
     protected CayenneTable table;
+    protected TableColumnPreferences tablePreferences;
     protected JButton addButton;
     protected JButton removeButton;
     protected JButton saveButton;
@@ -124,8 +127,11 @@
         cancelButton.setEnabled(this.editable);
 
         table = new AttributeTable();
+        
+        
         table.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-
+        tablePreferences = new TableColumnPreferences(getClass(), "dbentity/dbjoinTable");
+        
         // assemble
         getContentPane().setLayout(new BorderLayout());
 
@@ -187,7 +193,6 @@
         table.setModel(new DbJoinTableModel(relationship, getMediator(), this, true));
         TableColumn sourceColumn = table.getColumnModel().getColumn(
                 DbJoinTableModel.SOURCE);
-        sourceColumn.setMinWidth(150);
         JComboBox comboBox = CayenneWidgetFactory.createComboBox(ModelerUtil
                 .getDbAttributeNames(getMediator(), (DbEntity) relationship
                         .getSourceEntity()), true);
@@ -197,7 +202,6 @@
 
         TableColumn targetColumn = table.getColumnModel().getColumn(
                 DbJoinTableModel.TARGET);
-        targetColumn.setMinWidth(150);
         comboBox = CayenneWidgetFactory.createComboBox(ModelerUtil.getDbAttributeNames(
                 getMediator(),
                 (DbEntity) relationship.getTargetEntity()), true);
@@ -210,6 +214,7 @@
         }
 
         name.setText(relationship.getName());
+        tablePreferences.bind(table, null, null, null, DbJoinTableModel.SOURCE, true);
     }
 
     private void initController() {

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialog.java Mon Jan  4 08:04:52 2010
@@ -326,30 +326,34 @@
                 .getOverrideAttributeTable()
                 .getColumnModel()
                 .getColumn(OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE);
-        nameColumn.setMinWidth(180);
         nameColumn.setCellRenderer(renderer);
 
         TableColumn typeColumn = view
                 .getOverrideAttributeTable()
                 .getColumnModel()
                 .getColumn(OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE_TYPE);
-        typeColumn.setMinWidth(200);
         typeColumn.setCellRenderer(renderer);
 
         TableColumn dbAttrColumn = view
                 .getOverrideAttributeTable()
                 .getColumnModel()
                 .getColumn(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE);
-        dbAttrColumn.setMinWidth(180);
         dbAttrColumn.setCellRenderer(renderer);
 
         TableColumn dbAttrTypeColumn = view
                 .getOverrideAttributeTable()
                 .getColumnModel()
                 .getColumn(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE_TYPE);
-        dbAttrTypeColumn.setMinWidth(180);
         dbAttrTypeColumn.setCellRenderer(renderer);
-
+        
+        view.getTablePreferences().bind(
+                view.getOverrideAttributeTable(),
+                null,
+                null,
+                null,
+                OverrideEmbeddableAttributeTableModel.OBJ_ATTRIBUTE,
+                true);
+        
         initComboBoxes();
 
     }
@@ -364,7 +368,8 @@
                 embeddableModel.setCellEditor(nameAttr, view.getOverrideAttributeTable());
                 embeddableModel.setComboBoxes(
                         nameAttr,
-                        OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE);
+                        view.getOverrideAttributeTable().
+                        convertColumnIndexToView(OverrideEmbeddableAttributeTableModel.DB_ATTRIBUTE));
             }
         }
     }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialogView.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialogView.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialogView.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/ObjAttributeInfoDialogView.java Mon Jan  4 08:04:52 2010
@@ -39,6 +39,8 @@
 
 import org.apache.cayenne.map.Embeddable;
 import org.apache.cayenne.modeler.ProjectController;
+import org.apache.cayenne.modeler.editor.dbentity.DbAttributeTableModel;
+import org.apache.cayenne.modeler.pref.TableColumnPreferences;
 import org.apache.cayenne.modeler.util.CayenneTable;
 import org.apache.cayenne.modeler.util.CayenneWidgetFactory;
 import org.apache.cayenne.modeler.util.ModelerUtil;
@@ -71,7 +73,8 @@
     protected JPanel typeManagerPane;
 
     protected CayenneTable overrideAttributeTable;
-
+    protected TableColumnPreferences tablePreferences;
+    
     ProjectController mediator;
 
     static final Dimension BROWSER_CELL_DIM = new Dimension(130, 200);
@@ -98,7 +101,8 @@
         type.getRenderer();
 
         overrideAttributeTable = new CayenneTable();
-
+        tablePreferences = new TableColumnPreferences(getClass(), "overrideAttributeTable");
+        
         saveButton.setEnabled(false);
         cancelButton.setEnabled(true);
         selectPathButton.setEnabled(false);
@@ -234,6 +238,10 @@
     public CayenneTable getOverrideAttributeTable() {
         return overrideAttributeTable;
     }
+    
+    public TableColumnPreferences getTablePreferences() {
+        return tablePreferences;
+    }
 
     public JComboBox getType() {
         return type;

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/OverrideEmbeddableAttributeTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/OverrideEmbeddableAttributeTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/OverrideEmbeddableAttributeTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/objentity/OverrideEmbeddableAttributeTableModel.java Mon Jan  4 08:04:52 2010
@@ -22,6 +22,8 @@
 import java.awt.Component;
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -185,17 +187,7 @@
             }
             else if (column == DB_ATTRIBUTE_TYPE) {
 
-                DbEntity currentEnt = ((ObjEntity) attr.getEntity()).getDbEntity();
-                if (currentEnt != null
-                        && currentEnt.getAttributes() != null
-                        && dbAttributeName != null) {
-                    DbAttribute dbAttr = (DbAttribute) currentEnt
-                            .getAttribute(dbAttributeName);
-                    if (dbAttr != null) {
-                        return TypesMapping.getSqlNameByType(dbAttr.getType());
-                    }
-                }
-                return null;
+                return getDBAttrType(dbAttributeName);
             }
             else {
                 return null;
@@ -203,6 +195,20 @@
         }
     }
 
+    private String getDBAttrType(String dbAttributeName) {
+        DbEntity currentEnt = ((ObjEntity) attr.getEntity()).getDbEntity();
+        if (currentEnt != null
+                && currentEnt.getAttributes() != null
+                && dbAttributeName != null) {
+            DbAttribute dbAttr = (DbAttribute) currentEnt
+                    .getAttribute(dbAttributeName);
+            if (dbAttr != null) {
+                return TypesMapping.getSqlNameByType(dbAttr.getType());
+            }
+        }
+        return null;
+    }
+
     public String getColumnName(int column) {
         switch (column) {
             case OBJ_ATTRIBUTE:
@@ -248,6 +254,67 @@
         return attr;
     }
 
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return true;
+    }
+
+    @Override
+    public void sortByColumn(final int sortCol, boolean isAscent) {
+        Collections.sort(embeddableList, new Comparator<EmbeddableAttribute>(){
+
+                    public int compare(EmbeddableAttribute o1, EmbeddableAttribute o2) {
+                        Integer compareObjAttributesVal = compareObjAttributes(o1, o2);
+                        if(compareObjAttributesVal!=null){
+                            return compareObjAttributesVal;
+                        }
+                        String valueToCompare1 = "";
+                        String valueToCompare2 = ""; 
+                        switch(sortCol){
+                            case OBJ_ATTRIBUTE:
+                                valueToCompare1=o1.getName();
+                                valueToCompare2=o2.getName();
+                                break;
+                            case OBJ_ATTRIBUTE_TYPE:
+                                valueToCompare1=o1.getType();
+                                valueToCompare2=o2.getType();
+                                break;
+                            case DB_ATTRIBUTE:
+                                valueToCompare1=o1.getDbAttributeName();
+                                valueToCompare2=o2.getDbAttributeName();
+                                break;
+                            case DB_ATTRIBUTE_TYPE:
+                                valueToCompare1=getDBAttrType(o1.getDbAttributeName());
+                                valueToCompare2=getDBAttrType(o2.getDbAttributeName());
+                                break;
+                        }
+                        
+                        return (valueToCompare1 == null) ? -1 : (valueToCompare2 == null)? 1 : valueToCompare1.compareTo(valueToCompare2);
+                    }
+                    
+                });
+        
+        if(!isAscent){
+            Collections.reverse(embeddableList);
+        }
+        
+            
+        
+    }
+    
+    private Integer compareObjAttributes(EmbeddableAttribute o1, EmbeddableAttribute o2) {
+        if ((o1 == null && o2 == null) || o1 == o2) {
+            return 0;
+        }
+        else if (o1 == null && o2 != null) {
+            return -1;
+        }
+        else if (o1 != null && o2 == null) {
+            return 1;
+        }
+        return null;
+    }
+
 }
 
 class BoxCellRenderer implements ListCellRenderer {
@@ -283,4 +350,5 @@
     public void setNotActiveColumn(int notActiveColumn) {
         this.notActiveColumn = notActiveColumn;
     }
+   
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/validator/DuplicatedAttributesDialog.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/validator/DuplicatedAttributesDialog.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/validator/DuplicatedAttributesDialog.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/dialog/validator/DuplicatedAttributesDialog.java Mon Jan  4 08:04:52 2010
@@ -262,6 +262,15 @@
         public Class getColumnClass(int column) {
           return String.class;
         }
+
+        @Override
+        public boolean isColumnSortable(int sortCol) {
+            return false;
+        }
+
+        @Override
+        public void sortByColumn(int sortCol, boolean isAscent) {
+        }
     }
 
     public class DuplicatedAttributeInfo {

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AbstractCallbackMethodsTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AbstractCallbackMethodsTab.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AbstractCallbackMethodsTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/AbstractCallbackMethodsTab.java Mon Jan  4 08:04:52 2010
@@ -36,7 +36,6 @@
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
 import javax.swing.table.DefaultTableCellRenderer;
-import javax.swing.table.TableColumn;
 
 import org.apache.cayenne.map.CallbackDescriptor;
 import org.apache.cayenne.map.CallbackMap;
@@ -168,10 +167,10 @@
 
         table = new CayenneTable();
         table.setDefaultRenderer(String.class, new StringRenderer());
-        table.getTableHeader().setReorderingAllowed(false);
-
+        
         // drag-and-drop initialization
         table.setDragEnabled(true);
+        
         table.setTransferHandler(new StringTransferHandler() {
 
             @Override
@@ -181,9 +180,9 @@
 
                 String result = null;
                 if (rowIndex >= 0 && rowIndex < table.getModel().getRowCount()) {
-                    result = String.valueOf(table.getModel().getValueAt(rowIndex, 0));
+                    result = String.valueOf(table.getModel().getValueAt(rowIndex, CallbackDescriptorTableModel.METHOD_NAME));
                 }
-
+                
                 return result;
             }
 
@@ -206,6 +205,7 @@
             protected void cleanup(JComponent c, boolean remove) {
             }
         });
+        
 
         initTablePreferences();
         
@@ -244,7 +244,7 @@
                     updateCallbackTypeCounters();
                     rebuildTable();
                     
-                    if (table.editCellAt(table.getRowCount() - 1, 0)
+                    if (table.editCellAt(table.getRowCount() - 1, CallbackDescriptorTableModel.METHOD_NAME)
                             && table.getEditorComponent() != null) {
                         table.getEditorComponent().requestFocus();
                     }
@@ -282,7 +282,7 @@
                         methods = new String[sel.length];
                         
                         for (int i = 0; i < sel.length; i++) {
-                            methods[i] = (String) table.getValueAt(sel[i], 0);
+                            methods[i] = (String) table.getValueAt(sel[i], table.convertColumnIndexToView(CallbackDescriptorTableModel.METHOD_NAME));
                         }
                     }
                         
@@ -338,10 +338,10 @@
         table.setModel(model);
         table.setRowHeight(25);
         table.setRowMargin(3);
-
+        
         mediator.setCurrentCallbackMethods(new String[0]);
         
-        tablePreferences.bind(table, null, null);
+        tablePreferences.bind(table, null, null, null);
     }
 
     /**

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackDescriptorTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackDescriptorTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackDescriptorTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/CallbackDescriptorTableModel.java Mon Jan  4 08:04:52 2010
@@ -34,8 +34,9 @@
  * @version 1.0 Oct 23, 2007
  */
 public class CallbackDescriptorTableModel extends CayenneTableModel {
-    private static final int COLUMN_COUNT = 1;
-    public static final int METHOD_NAME = 0;
+    private static final int COLUMN_COUNT = 2;
+    public static final int METHOD_NUMBER = 0;
+    public static final int METHOD_NAME = 1;
     protected ObjEntity entity;
     protected CallbackDescriptor callbackDescriptor;
 
@@ -104,6 +105,8 @@
      */
     public Object getValueAt(int rowIndex, int columnIndex) {
         switch (columnIndex) {
+            case METHOD_NUMBER:
+                return rowIndex+1;
             case METHOD_NAME:
                 return getCallbackMethod(rowIndex);
         }
@@ -124,6 +127,8 @@
      */
     public String getColumnName(int column) {
         switch (column) {
+            case METHOD_NUMBER:
+                return "No.";
             case METHOD_NAME:
                 return "Method";
         }
@@ -144,36 +149,37 @@
 
     /**
      * stores edited value
-     *
+     * 
      * @param newVal new value
      * @param row row
      * @param col column
      */
     public void setValueAt(Object newVal, int row, int col) {
-        String method = (String) newVal;
-        if (method != null) {
-            method = method.trim();
-        }
-        String prevMethod = (String) getObjectList().get(row);
+        if (col != METHOD_NUMBER) {
+            String method = (String) newVal;
+            if (method != null) {
+                method = method.trim();
+            }
+            String prevMethod = (String) getObjectList().get(row);
 
-        if (method != null && method.length() > 0) {
-            //check that method changed and name is not duplicate
-            if (!method.equals(prevMethod) &&
-                !getCallbackDescriptor().getCallbackMethods().contains(method)) {
-                //update model
-                getObjectList().set(row, method);
-
-                //update entity
-                getCallbackDescriptor().setCallbackMethodAt(row, method);
-
-                fireTableRowsUpdated(row, row);
-
-                mediator.fireCallbackMethodEvent(new CallbackMethodEvent(
-                        eventSource,
-                        prevMethod,
-                        method,
-                        MapEvent.CHANGE
-                ));
+            if (method != null && method.length() > 0) {
+                // check that method changed and name is not duplicate
+                if (!method.equals(prevMethod)
+                        && !getCallbackDescriptor().getCallbackMethods().contains(method)) {
+                    // update model
+                    getObjectList().set(row, method);
+
+                    // update entity
+                    getCallbackDescriptor().setCallbackMethodAt(row, method);
+
+                    fireTableRowsUpdated(row, row);
+
+                    mediator.fireCallbackMethodEvent(new CallbackMethodEvent(
+                            eventSource,
+                            prevMethod,
+                            method,
+                            MapEvent.CHANGE));
+                }
             }
         }
     }
@@ -184,5 +190,14 @@
     public CallbackDescriptor getCallbackDescriptor() {
         return callbackDescriptor;
     }
+
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return false;
+    }
+
+    @Override
+    public void sortByColumn(int sortCol, boolean isAscent) {
+    }
 }
 

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTab.java Mon Jan  4 08:04:52 2010
@@ -183,7 +183,7 @@
         AutoCompletion.enable(javaTypesCombo, false, true);
         typeColumn.setCellEditor(CayenneWidgetFactory.createCellEditor(javaTypesCombo));
 
-        tablePreferences.bind(table, null, null);
+        tablePreferences.bind(table, null, null, null, EmbeddableAttributeTableModel.OBJ_ATTRIBUTE, true);
 
     }
 

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/EmbeddableAttributeTableModel.java Mon Jan  4 08:04:52 2010
@@ -20,7 +20,6 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Comparator;
 
 import org.apache.cayenne.map.Embeddable;
@@ -52,7 +51,7 @@
         this.embeddable = embeddable;
 
         // order using local comparator
-        Collections.sort(objectList, new EmbeddableAttributeComparator());
+       // Collections.sort(objectList, new EmbeddableAttributeComparator());
     }
 
     public EmbeddableAttribute getEmbeddableAttribute(int row) {
@@ -157,4 +156,24 @@
             return a.getEmbeddable() == embeddable ? 1 : -1;
         }
     }
+
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return true;
+    }
+
+    @Override
+    public void sortByColumn(int sortCol, boolean isAscent) {
+        switch(sortCol){
+            case OBJ_ATTRIBUTE:
+                sortByElementProperty("name", isAscent);
+                break;
+            case OBJ_ATTRIBUTE_TYPE:
+                sortByElementProperty("type", isAscent);
+                break;
+            case DB_ATTRIBUTE:
+                sortByElementProperty("dbAttributeName", isAscent);
+                break;
+        }
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjAttributeTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjAttributeTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjAttributeTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjAttributeTableModel.java Mon Jan  4 08:04:52 2010
@@ -87,8 +87,7 @@
     protected void orderList() {
         // NOOP
     }
-    
-    
+
     public CayenneTable getTable() {
         return table;
     }
@@ -182,57 +181,64 @@
         else {
             DbAttribute dbAttribute = attribute.getDbAttribute();
             if (column == DB_ATTRIBUTE) {
-
-                if (dbAttribute == null) {
-                    if (!attribute.isInherited()
-                            && ((ObjEntity) attribute.getEntity()).isAbstract()) {
-                        return attribute.getDbAttributePath();
-                    }
-                    else {
-                        return null;
-                    }
-                }
-                else if (attribute.getDbAttributePath() != null
-                        && attribute.getDbAttributePath().contains(".")) {
-                    return attribute.getDbAttributePath();
-                }
-                return dbAttribute.getName();
+                return getDBAttribute(attribute, dbAttribute);
             }
             else if (column == DB_ATTRIBUTE_TYPE) {
-                int type;
-                if (dbAttribute == null) {
-                    if (!(attribute instanceof EmbeddedAttribute)) {
-                        try {
-                            type = TypesMapping.getSqlTypeByJava(getAttribute(row)
-                                    .getJavaClass());
-                            // have to catch the exception here to make sure that
-                            // exceptional situations
-                            // (class doesn't exist, for example) don't prevent the gui
-                            // from properly updating.
-                        }
-                        catch (CayenneRuntimeException cre) {
-                            return null;
-                        }
-                    }
-                    else {
-                        return null;
-                    }
+                return getDBAttributeType(attribute, dbAttribute);
+            }
+            else {
+                return null;
+            }
+        }
+    }
+
+    private String getDBAttribute(ObjAttribute attribute, DbAttribute dbAttribute) {
+        if (dbAttribute == null) {
+            if (!attribute.isInherited()
+                    && ((ObjEntity) attribute.getEntity()).isAbstract()) {
+                return attribute.getDbAttributePath();
+            }
+            else {
+                return null;
+            }
+        }
+        else if (attribute.getDbAttributePath() != null
+                && attribute.getDbAttributePath().contains(".")) {
+            return attribute.getDbAttributePath();
+        }
+        return dbAttribute.getName();
+    }
+
+    private String getDBAttributeType(ObjAttribute attribute, DbAttribute dbAttribute) {
+        int type;
+        if (dbAttribute == null) {
+            if (!(attribute instanceof EmbeddedAttribute)) {
+                try {
+                    type = TypesMapping.getSqlTypeByJava(attribute.getJavaClass());
+                    // have to catch the exception here to make sure that
+                    // exceptional situations
+                    // (class doesn't exist, for example) don't prevent the gui
+                    // from properly updating.
                 }
-                else {
-                    type = dbAttribute.getType();
+                catch (CayenneRuntimeException cre) {
+                    return null;
                 }
-                return TypesMapping.getSqlNameByType(type);
             }
             else {
                 return null;
             }
         }
+        else {
+            type = dbAttribute.getType();
+        }
+        return TypesMapping.getSqlNameByType(type);
     }
 
-    public CellEditorForAttributeTable setCellEditor(Collection<String> nameAttr, CayenneTable table) {
-        this.cellEditor = new CellEditorForAttributeTable(table, CayenneWidgetFactory.createComboBox(
-                nameAttr,
-                true));
+    public CellEditorForAttributeTable setCellEditor(
+            Collection<String> nameAttr,
+            CayenneTable table) {
+        this.cellEditor = new CellEditorForAttributeTable(table, CayenneWidgetFactory
+                .createComboBox(nameAttr, true));
         this.table = table;
         return cellEditor;
     }
@@ -260,24 +266,30 @@
             attribute.setType(value != null ? value.toString() : null);
             String newType = attribute.getType();
             String[] registeredTypes = ModelerUtil.getRegisteredTypeNames();
-            Collection<String> registeredTypesList =  Arrays.asList(registeredTypes); ;
-            if(oldType!=null && newType!=null && ! (registeredTypesList.contains(oldType) == registeredTypesList.contains(newType))){
+            Collection<String> registeredTypesList = Arrays.asList(registeredTypes);
+            ;
+            if (oldType != null
+                    && newType != null
+                    && !(registeredTypesList.contains(oldType) == registeredTypesList
+                            .contains(newType))) {
                 ObjAttribute attributeNew;
-                
-                ArrayList<Embeddable> embs = mediator.getEmbeddableNamesInCurRentDataDomain();
+
+                ArrayList<Embeddable> embs = mediator
+                        .getEmbeddableNamesInCurRentDataDomain();
                 ArrayList<String> embNames = new ArrayList<String>();
                 Iterator<Embeddable> it = embs.iterator();
                 while (it.hasNext()) {
                     embNames.add(it.next().getClassName());
                 }
-                
-                if(registeredTypesList.contains(newType) || !embNames.contains(newType)){
+
+                if (registeredTypesList.contains(newType) || !embNames.contains(newType)) {
                     attributeNew = new ObjAttribute();
-                } else {
+                }
+                else {
                     attributeNew = new EmbeddedAttribute();
                     attribute.setDbAttributePath(null);
                 }
-                
+
                 attributeNew.setDbAttributePath(attribute.getDbAttributePath());
                 attributeNew.setName(attribute.getName());
                 attributeNew.setEntity(attribute.getEntity());
@@ -287,11 +299,8 @@
                 Entity ent = attribute.getEntity();
                 ent.removeAttribute(attribute.getName());
                 ent.addAttribute(attributeNew);
-                
-                mediator.fireObjEntityEvent(new EntityEvent(
-                        this,
-                        ent,
-                        MapEvent.CHANGE));
+
+                mediator.fireObjEntityEvent(new EntityEvent(this, ent, MapEvent.CHANGE));
 
                 EntityDisplayEvent ev = new EntityDisplayEvent(this, mediator
                         .getCurrentObjEntity(), mediator.getCurrentDataMap(), mediator
@@ -299,7 +308,11 @@
 
                 mediator.fireObjEntityDisplayEvent(ev);
 
-                mediator.fireObjAttributeEvent(new AttributeEvent(this, attributeNew, ent, MapEvent.CHANGE));
+                mediator.fireObjAttributeEvent(new AttributeEvent(
+                        this,
+                        attributeNew,
+                        ent,
+                        MapEvent.CHANGE));
 
                 AttributeDisplayEvent eventAttr = new AttributeDisplayEvent(
                         this,
@@ -310,7 +323,7 @@
 
                 mediator.fireObjAttributeDisplayEvent(eventAttr);
             }
-            
+
             fireTableCellUpdated(row, column);
         }
         else if (column == LOCKING) {
@@ -386,7 +399,7 @@
                 }
 
                 // If path is flattened attribute, update the JComboBox
-                if (path != null && path.split("\\.").length > 1 && dbEntity!=null) {
+                if (path != null && path.split("\\.").length > 1 && dbEntity != null) {
                     setComboBoxes(nameAttr, column);
                 }
             }
@@ -394,7 +407,7 @@
         }
         mediator.fireObjAttributeEvent(event);
     }
-    
+
     public void setComboBoxes(Collection<String> nameAttr, int column) {
         int count = getRowCount();
         for (int i = 0; i < count; i++) {
@@ -402,18 +415,17 @@
                     && getAttribute(i).getDbAttributePath().contains(".")) {
                 Collection<String> attributeComboForRow = new ArrayList<String>();
                 attributeComboForRow.addAll(nameAttr);
-                attributeComboForRow
-                        .add(getAttribute(i).getDbAttributePath());
-                JComboBox comboBoxForRow = CayenneWidgetFactory
-                        .createComboBox(attributeComboForRow, true);
+                attributeComboForRow.add(getAttribute(i).getDbAttributePath());
+                JComboBox comboBoxForRow = CayenneWidgetFactory.createComboBox(
+                        attributeComboForRow,
+                        true);
 
                 cellEditor.setEditorAt(new Integer(i), new DefaultCellEditor(
                         comboBoxForRow));
-                
+
             }
         }
-        table.getColumnModel().getColumn(column).setCellEditor(
-                cellEditor);
+        table.getColumnModel().getColumn(column).setCellEditor(cellEditor);
     }
 
     public boolean isCellEditable(int row, int col) {
@@ -446,4 +458,75 @@
         }
     }
 
+    @Override
+    public void sortByColumn(final int sortCol, boolean isAscent) {
+        switch (sortCol) {
+            case INHERITED:
+                sortByElementProperty("inherited", isAscent);
+                break;
+            case OBJ_ATTRIBUTE:
+                sortByElementProperty("name", isAscent);
+                break;
+            case OBJ_ATTRIBUTE_TYPE:
+                sortByElementProperty("type", isAscent);
+                break;
+            case LOCKING:
+                sortByElementProperty("usedForLocking", isAscent);
+                break;
+            case DB_ATTRIBUTE:
+            case DB_ATTRIBUTE_TYPE:
+                Collections.sort(objectList, new Comparator<ObjAttribute>() {
+
+                    public int compare(ObjAttribute o1, ObjAttribute o2) {
+                        Integer compareObjAttributesVal = compareObjAttributes(o1, o2);
+                        if (compareObjAttributesVal != null) {
+                            return compareObjAttributesVal;
+                        }
+
+                        String valToCompare1 = getDBAttribute(o1, o1.getDbAttribute());
+                        String valToCompare2 = getDBAttribute(o2, o2.getDbAttribute());
+                        switch (sortCol) {
+                            case DB_ATTRIBUTE:
+                                valToCompare1 = getDBAttribute(o1, o1.getDbAttribute());
+                                valToCompare2 = getDBAttribute(o2, o2.getDbAttribute());
+                                break;
+                            case DB_ATTRIBUTE_TYPE:
+                                valToCompare1 = getDBAttributeType(o1, o1
+                                        .getDbAttribute());
+                                valToCompare2 = getDBAttributeType(o2, o2
+                                        .getDbAttribute());
+                                break;
+                        }
+                        return (valToCompare1 == null) ? -1 : (valToCompare2 == null)
+                                ? 1
+                                : valToCompare1.compareTo(valToCompare2);
+                    }
+
+                });
+                if (!isAscent) {
+                    Collections.reverse(objectList);
+                }
+                break;
+
+        }
+    }
+
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return true;
+    }
+
+    private Integer compareObjAttributes(ObjAttribute o1, ObjAttribute o2) {
+        if ((o1 == null && o2 == null) || o1 == o2) {
+            return 0;
+        }
+        else if (o1 == null && o2 != null) {
+            return -1;
+        }
+        else if (o1 != null && o2 == null) {
+            return 1;
+        }
+        return null;
+    }
+
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityAttributeTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityAttributeTab.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityAttributeTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityAttributeTab.java Mon Jan  4 08:04:52 2010
@@ -330,7 +330,7 @@
 
     protected void setUpTableStructure(ObjAttributeTableModel model) {
        
-        int inheritanceColumnWidth = 20;
+        int inheritanceColumnWidth = 30;
                
         Map<Integer, Integer> minSizes = new HashMap<Integer, Integer>();
         Map<Integer, Integer> maxSizes = new HashMap<Integer, Integer>();
@@ -340,7 +340,7 @@
         
         initComboBoxes(model);
 
-        tablePreferences.bind(table, minSizes, maxSizes);
+        tablePreferences.bind(table, minSizes, maxSizes, null, ObjAttributeTableModel.OBJ_ATTRIBUTE, true);
     }
 
     /**

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjEntityRelationshipTab.java Mon Jan  4 08:04:52 2010
@@ -26,9 +26,7 @@
 import java.awt.event.ActionListener;
 import java.util.Collection;
 import java.util.EventObject;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.swing.DefaultCellEditor;
 import javax.swing.DefaultComboBoxModel;
@@ -415,7 +413,7 @@
         deleteRulesCombo.setSelectedIndex(0); // Default to the first value
         col.setCellEditor(CayenneWidgetFactory.createCellEditor(deleteRulesCombo));
         
-        tablePreferences.bind(table, null, null);
+        tablePreferences.bind(table, null, null, null, ObjRelationshipTableModel.REL_NAME, true);
     }
 
     class EntityRenderer extends StringRenderer {

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ObjRelationshipTableModel.java Mon Jan  4 08:04:52 2010
@@ -124,25 +124,7 @@
             return relationship.isUsedForLocking() ? Boolean.TRUE : Boolean.FALSE;
         }
         else if (column == REL_SEMANTICS) {
-            String semantics = relationship.isToMany() ? "to many" : "to one";
-            if (relationship.isReadOnly()) {
-                semantics += ", read-only";
-            }
-
-            if (relationship.isToMany()) {
-                String collection = "list";
-                if (relationship.getCollectionType() != null) {
-                    int dot = relationship.getCollectionType().lastIndexOf('.');
-                    collection = relationship
-                            .getCollectionType()
-                            .substring(dot + 1)
-                            .toLowerCase();
-                }
-
-                semantics += ", " + collection;
-            }
-
-            return semantics;
+            return getSemantics(relationship);
         }
         else if (column == REL_DELETERULE) {
             return DeleteRule.deleteRuleName(relationship.getDeleteRule());
@@ -152,6 +134,28 @@
         }
     }
 
+    private String getSemantics(ObjRelationship relationship) {
+        String semantics = relationship.isToMany() ? "to many" : "to one";
+        if (relationship.isReadOnly()) {
+            semantics += ", read-only";
+        }
+
+        if (relationship.isToMany()) {
+            String collection = "list";
+            if (relationship.getCollectionType() != null) {
+                int dot = relationship.getCollectionType().lastIndexOf('.');
+                collection = relationship
+                        .getCollectionType()
+                        .substring(dot + 1)
+                        .toLowerCase();
+            }
+
+            semantics += ", " + collection;
+        }
+
+        return semantics;
+    }
+
     @Override
     public void setUpdatedValueAt(Object value, int row, int column) {
         ObjRelationship relationship = getRelationship(row);
@@ -238,4 +242,64 @@
             return r.getSourceEntity() == entity ? 1 : -1;
         }
     }
+
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return true;
+    }
+
+    @Override
+    public void sortByColumn(final int sortCol, boolean isAscent) {
+        switch (sortCol) {
+            case REL_NAME:
+                sortByElementProperty("name", isAscent);
+                break;
+            case REL_TARGET:
+                sortByElementProperty("targetEntityName", isAscent);
+                break;
+            case REL_LOCKING:
+                sortByElementProperty("usedForLocking", isAscent);
+                break;
+            case REL_SEMANTICS:
+            case REL_DELETERULE:
+                Collections.sort(objectList, new Comparator<ObjRelationship>() {
+
+                    public int compare(ObjRelationship o1, ObjRelationship o2) {
+                        if ((o1 == null && o2 == null) || o1 == o2) {
+                            return 0;
+                        }
+                        else if (o1 == null && o2 != null) {
+                            return -1;
+                        }
+                        else if (o1 != null && o2 == null) {
+                            return 1;
+                        }
+                        
+                        String valueToCompare1 = "";
+                        String valueToCompare2 = "";
+                        switch(sortCol){
+                            case REL_SEMANTICS:
+                                valueToCompare1 = getSemantics(o1);
+                                valueToCompare2 = getSemantics(o2);
+                                break;
+                            case REL_DELETERULE:
+                                valueToCompare1 = DeleteRule.deleteRuleName(o1.getDeleteRule());
+                                valueToCompare2 = DeleteRule.deleteRuleName(o2.getDeleteRule());
+                                
+                                break;
+                        }
+                        return (valueToCompare1 == null) ? -1 : (valueToCompare2 == null)
+                                ? 1
+                                : valueToCompare1.compareTo(valueToCompare2);
+                    }
+
+                });
+                if (!isAscent) {
+                    Collections.reverse(objectList);
+                }
+                break;
+            
+        }
+
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTab.java Mon Jan  4 08:04:52 2010
@@ -307,7 +307,7 @@
         moveUp.setEnabled(false);
         moveDown.setEnabled(false);
         
-        tablePreferences.bind(table, null, null);
+        tablePreferences.bind(table, null, null, null);
     }
 
     public void procedureParameterAdded(ProcedureParameterEvent e) {

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/ProcedureParameterTableModel.java Mon Jan  4 08:04:52 2010
@@ -272,4 +272,13 @@
     public boolean isCellEditable(int row, int col) {
         return col != PARAMETER_NUMBER;
     }
+
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return false;
+    }
+
+    @Override
+    public void sortByColumn(int sortCol, boolean isAscent) {
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbAttributeTableModel.java Mon Jan  4 08:04:52 2010
@@ -21,6 +21,8 @@
 
 import java.util.ArrayList;
 import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
 
@@ -331,4 +333,57 @@
         }
         return true;
     }
+
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return true;
+    }
+
+    @Override
+    public void sortByColumn(int sortCol, boolean isAscent) {
+        switch(sortCol){
+            case DB_ATTRIBUTE_NAME:
+                sortByElementProperty("name", isAscent);
+                break;
+            case DB_ATTRIBUTE_TYPE:
+                Collections.sort(objectList, new Comparator<DbAttribute>() {
+
+                    public int compare(DbAttribute o1, DbAttribute o2) {
+                        if ((o1 == null && o2 == null) || o1 == o2) {
+                            return 0;
+                        }
+                        else if (o1 == null && o2 != null) {
+                            return -1;
+                        }
+                        else if (o1 != null && o2 == null) {
+                            return 1;
+                        }
+                        
+                        String attrType1 = getAttributeType(o1);
+                        String attrType2 = getAttributeType(o2);
+                        
+                        return (attrType1 == null) ? -1 : (attrType2 == null)
+                                ? 1
+                                : attrType1.compareTo(attrType2);
+                    }
+
+                });
+                if (!isAscent) {
+                    Collections.reverse(objectList);
+                }
+                break;
+            case DB_ATTRIBUTE_PRIMARY_KEY:
+                sortByElementProperty("primaryKey", isAscent);
+                break;
+            case DB_ATTRIBUTE_SCALE:
+                sortByElementProperty("scale", isAscent);
+                break;
+            case DB_ATTRIBUTE_MANDATORY:
+                sortByElementProperty("mandatory", isAscent);
+                break;
+            case DB_ATTRIBUTE_MAX:
+                sortByElementProperty("maxLength", isAscent);
+                break;
+        }
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityAttributeTab.java Mon Jan  4 08:04:52 2010
@@ -32,7 +32,9 @@
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.ListSelectionEvent;
 import javax.swing.event.ListSelectionListener;
+import javax.swing.table.JTableHeader;
 import javax.swing.table.TableColumn;
+import javax.swing.table.TableColumnModel;
 
 import org.apache.cayenne.dba.TypesMapping;
 import org.apache.cayenne.map.DbAttribute;
@@ -230,6 +232,6 @@
 
         table.getSelectionModel().addListSelectionListener(this);
         
-        tablePreferences.bind(table, null, null);
+        tablePreferences.bind(table, null, null, null, model.nameColumnInd(), true);
     }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbEntityRelationshipTab.java Mon Jan  4 08:04:52 2010
@@ -23,9 +23,7 @@
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
 import java.util.EventObject;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 import javax.swing.ComboBoxModel;
 import javax.swing.DefaultComboBoxModel;
@@ -302,7 +300,7 @@
         col.setCellEditor(CayenneWidgetFactory.createCellEditor(targetCombo));
         table.getSelectionModel().addListSelectionListener(this);
         
-        tablePreferences.bind(table, null, null);
+        tablePreferences.bind(table, null, null, null, DbRelationshipTableModel.NAME, true);
     }
 
     public void dbEntityChanged(EntityEvent e) {

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/editor/dbentity/DbRelationshipTableModel.java Mon Jan  4 08:04:52 2010
@@ -216,4 +216,27 @@
         }
         return true;
     }
+
+    @Override
+    public boolean isColumnSortable(int sortCol) {
+        return true;
+    }
+
+    @Override
+    public void sortByColumn(int sortCol, boolean isAscent) {
+        switch (sortCol) {
+            case NAME:
+                sortByElementProperty("name", isAscent);
+                break;
+            case TARGET:
+                sortByElementProperty("targetEntityName", isAscent);
+                break;
+            case TO_DEPENDENT_KEY:
+                sortByElementProperty("toDependentPK", isAscent);
+                break;
+            case CARDINALITY:
+                sortByElementProperty("toMany", isAscent);
+                break;
+        }
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/TableColumnPreferences.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/TableColumnPreferences.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/TableColumnPreferences.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/pref/TableColumnPreferences.java Mon Jan  4 08:04:52 2010
@@ -30,15 +30,19 @@
 import javax.swing.table.TableColumnModel;
 import javax.swing.table.TableModel;
 
+import org.apache.cayenne.modeler.util.CayenneTable;
 import org.apache.cayenne.pref.CayennePreference;
 
 public class TableColumnPreferences extends CayennePreference {
 
+    private static final String SORT_COLUMN_KEY = "sort_column";
+    private static final String SORT_ORDER_KEY = "sort_order";
     private static final String WIDTH_KEY = "width_";
     public static final String TABLE_COLUMN_PREF_KEY = "table_column";
     private static final String ORDER_KEY = "order_";
     private JTable table;
     private int columnCount;
+    
     private TableColumnModelListener listener = new TableColumnModelListener() {
 
         public void columnAdded(TableColumnModelEvent e) {
@@ -66,7 +70,6 @@
         public void columnSelectionChanged(ListSelectionEvent e) {
         }
     };
-    
 
     public TableColumnPreferences(Class className, String path) {
         setCurrentNodeForPreference(className, path);
@@ -81,30 +84,62 @@
 
     /**
      * Binds this preference object to synchronize its state with a given table component,
-     * allowing to specify an initial offset compared to the stored position.
+     * allowing to specify an initial offset compared to the stored position. Allow to specify
+     * initial sorting.
+     * 
+     * @param table
+     * @param minSizes
+     * @param maxSizes
+     * @param defaultSizes
+     * @param defaultSortColumn
+     * @param defaultSortOrder
+     */
+    public void bind(
+            final JTable table,
+            Map<Integer, Integer> minSizes,
+            Map<Integer, Integer> maxSizes,
+            Map<Integer, Integer> defaultSizes,
+            int defaultSortColumn,
+            boolean defaultSortOrder) {
+        bind(table, minSizes, maxSizes, defaultSizes);
+        ((CayenneTable) table).setSortPreferenceSaver(this);
+        updateSort(defaultSortColumn, defaultSortOrder);
+    }
+
+    /**
+     * Binds this preference object to synchronize its state with a given table component,
+     * allowing to specify an initial offset compared to the stored position. 
      * 
+     * @param table
      * @param minSizes
-     * @param maxSizes 
+     * @param maxSizes
+     * @param defaultSizes
      */
-    public void bind(final JTable table, Map<Integer, Integer> minSizes, Map<Integer, Integer> maxSizes) {
+    public void bind(
+            final JTable table,
+            Map<Integer, Integer> minSizes,
+            Map<Integer, Integer> maxSizes,
+            Map<Integer, Integer> defaultSizes) {
 
         this.table = table;
-        this.columnCount=table.getColumnCount();
+       
+        this.columnCount = table.getColumnCount();
         table.getColumnModel().removeColumnModelListener(listener);
-        updateTable(minSizes, maxSizes);
+        updateTable(minSizes, maxSizes, defaultSizes);
         table.getColumnModel().addColumnModelListener(listener);
-       
+
     }
 
-    private void updateTable(Map<Integer, Integer> minSizes, Map<Integer, Integer> maxSizes) {
-        updateWidths(minSizes, maxSizes);
+    private void updateTable(
+            Map<Integer, Integer> minSizes,
+            Map<Integer, Integer> maxSizes, Map<Integer, Integer> defaultSizes) {
+        updateWidths(minSizes, maxSizes, defaultSizes);
         updateOrder();
     }
 
-    
     private void updateWidths(
             Map<Integer, Integer> minSizes,
-            Map<Integer, Integer> maxSizes) {
+            Map<Integer, Integer> maxSizes, Map<Integer, Integer> defaultSizes) {
         TableColumn column = null;
         TableColumnModel columnModel = table.getColumnModel();
         for (int i = 0; i < columnCount; i++) {
@@ -113,32 +148,35 @@
 
             int defaultWidth;
             if (minSizes != null && minSizes.containsKey(modelIndex)) {
-                Integer minWidth = minSizes.get(modelIndex);
-                column.setMinWidth(minWidth);
-                defaultWidth = minWidth;
-            } else {
-                defaultWidth = column.getPreferredWidth();
+                column.setMinWidth(minSizes.get(modelIndex));
+                
             }
 
             if (maxSizes != null && maxSizes.containsKey(modelIndex)) {
                 column.setMaxWidth(maxSizes.get(modelIndex));
             }
 
+            if(defaultSizes!=null && defaultSizes.containsKey(modelIndex)){
+                defaultWidth=defaultSizes.get(modelIndex);
+            } else {
+                defaultWidth = column.getPreferredWidth();
+            }
+            
             int width = getWidth(modelIndex, defaultWidth);
             if (column.getPreferredWidth() != width) {
                 column.setPreferredWidth(width);
             }
         }
     }
-    
+
     private void updateOrder() {
-        TableColumn column=null;
+        TableColumn column = null;
         TableColumnModel columnModel = table.getColumnModel();
         TableModel model = table.getModel();
         String columnName = "";
         for (int i = 0; i < columnCount; i++) {
             columnName = model.getColumnName(i);
-            column=table.getColumn(columnName);
+            column = table.getColumn(columnName);
             int modelIndex = column.getModelIndex();
             int orderIndex = getOrderIndex(modelIndex, modelIndex);
             if (i != orderIndex) {
@@ -147,21 +185,46 @@
         }
     }
 
+    private void updateSort(int defaultSortColumn, boolean defaultSortOrder) {
+        ((CayenneTable) table).sort(
+                getSortColumn(SORT_COLUMN_KEY, defaultSortColumn),
+                getSortOrder(SORT_ORDER_KEY, defaultSortOrder));
+    }
+
     private int getWidth(int index, int defaultWidth) {
-        return getPreference().getInt(WIDTH_KEY+Integer.toString(index), defaultWidth);
+        return getPreference().getInt(WIDTH_KEY + Integer.toString(index), defaultWidth);
     }
 
     private void setWidth(int index, int width) {
-        getPreference().putInt(WIDTH_KEY+Integer.toString(index), width);
+        getPreference().putInt(WIDTH_KEY + Integer.toString(index), width);
     }
 
     private int getOrderIndex(int columnIndex, int defaultOrderIndex) {
-        return getPreference().getInt(ORDER_KEY+Integer.toString(columnIndex), defaultOrderIndex);
+        return getPreference().getInt(
+                ORDER_KEY + Integer.toString(columnIndex),
+                defaultOrderIndex);
     }
 
     private void setOrderIndex(int columnIndex, int defaultOrderIndex) {
-        getPreference().putInt(ORDER_KEY+Integer.toString(columnIndex), defaultOrderIndex);
+        getPreference().putInt(
+                ORDER_KEY + Integer.toString(columnIndex),
+                defaultOrderIndex);
+    }
+
+    private boolean getSortOrder(String sortOrderKey, boolean defaultSortOrder) {
+        return getPreference().getBoolean(SORT_ORDER_KEY, defaultSortOrder);
+    }
+
+    public void setSortOrder(boolean isAscent) {
+        getPreference().putBoolean(SORT_ORDER_KEY, isAscent);
+    }
+
+    private int getSortColumn(String sortColumnKey, int defaultSortColumn) {
+        return getPreference().getInt(SORT_COLUMN_KEY, defaultSortColumn);
+    }
+
+    public void setSortColumn(int sortCol) {
+        getPreference().putInt(SORT_COLUMN_KEY, sortCol);
     }
 
-    
 }

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BevelArrowIcon.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BevelArrowIcon.java?rev=895574&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BevelArrowIcon.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BevelArrowIcon.java Mon Jan  4 08:04:52 2010
@@ -0,0 +1,166 @@
+/*****************************************************************
+ *   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
+ *
+ *    http://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.util;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+
+import javax.swing.Icon;
+import javax.swing.UIManager;
+
+public class BevelArrowIcon implements Icon {
+
+    public static final int UP = 0; // direction
+    public static final int DOWN = 1;
+
+    private static final int DEFAULT_SIZE = 11;
+
+    private Color edge1;
+    private Color edge2;
+    private Color fill;
+    private int size;
+    private int direction;
+
+    public BevelArrowIcon(int direction, boolean isRaisedView, boolean isPressedView) {
+        if (isRaisedView) {
+            if (isPressedView) {
+                init(
+                        UIManager.getColor("controlLtHighlight"),
+                        UIManager.getColor("controlDkShadow"),
+                        UIManager.getColor("controlShadow"),
+                        DEFAULT_SIZE,
+                        direction);
+            }
+            else {
+                init(
+                        UIManager.getColor("controlHighlight"),
+                        UIManager.getColor("controlShadow"),
+                        UIManager.getColor("control"),
+                        DEFAULT_SIZE,
+                        direction);
+            }
+        }
+        else {
+            if (isPressedView) {
+                init(UIManager.getColor("controlDkShadow"), UIManager
+                        .getColor("controlLtHighlight"), UIManager
+                        .getColor("controlShadow"), DEFAULT_SIZE, direction);
+            }
+            else {
+                init(
+                        UIManager.getColor("controlShadow"),
+                        UIManager.getColor("controlHighlight"),
+                        UIManager.getColor("control"),
+                        DEFAULT_SIZE,
+                        direction);
+            }
+        }
+    }
+
+    public BevelArrowIcon(Color edge1, Color edge2, Color fill, int size, int direction) {
+        init(edge1, edge2, fill, size, direction);
+    }
+
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+        switch (direction) {
+            case DOWN:
+                drawDownArrow(g, x, y);
+                break;
+            case UP:
+                drawUpArrow(g, x, y);
+                break;
+        }
+    }
+
+    public int getIconWidth() {
+        return size;
+    }
+
+    public int getIconHeight() {
+        return size;
+    }
+
+    private void init(Color edge1, Color edge2, Color fill, int size, int direction) {
+        this.edge1 = edge1;
+        this.edge2 = edge2;
+        this.fill = fill;
+        this.size = size;
+        this.direction = direction;
+    }
+
+    private void drawDownArrow(Graphics g, int xo, int yo) {
+        g.setColor(edge1);
+        g.drawLine(xo, yo, xo + size - 1, yo);
+        g.drawLine(xo, yo + 1, xo + size - 3, yo + 1);
+        g.setColor(edge2);
+        g.drawLine(xo + size - 2, yo + 1, xo + size - 1, yo + 1);
+        int x = xo + 1;
+        int y = yo + 2;
+        int dx = size - 6;
+        while (y + 1 < yo + size) {
+            g.setColor(edge1);
+            g.drawLine(x, y, x + 1, y);
+            g.drawLine(x, y + 1, x + 1, y + 1);
+            if (0 < dx) {
+                g.setColor(fill);
+                g.drawLine(x + 2, y, x + 1 + dx, y);
+                g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
+            }
+            g.setColor(edge2);
+            g.drawLine(x + dx + 2, y, x + dx + 3, y);
+            g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
+            x += 1;
+            y += 2;
+            dx -= 2;
+        }
+        g.setColor(edge1);
+        g.drawLine(xo + (size / 2), yo + size - 1, xo + (size / 2), yo + size - 1);
+    }
+
+    private void drawUpArrow(Graphics g, int xo, int yo) {
+        g.setColor(edge1);
+        int x = xo + (size / 2);
+        g.drawLine(x, yo, x, yo);
+        x--;
+        int y = yo + 1;
+        int dx = 0;
+        while (y + 3 < yo + size) {
+            g.setColor(edge1);
+            g.drawLine(x, y, x + 1, y);
+            g.drawLine(x, y + 1, x + 1, y + 1);
+            if (0 < dx) {
+                g.setColor(fill);
+                g.drawLine(x + 2, y, x + 1 + dx, y);
+                g.drawLine(x + 2, y + 1, x + 1 + dx, y + 1);
+            }
+            g.setColor(edge2);
+            g.drawLine(x + dx + 2, y, x + dx + 3, y);
+            g.drawLine(x + dx + 2, y + 1, x + dx + 3, y + 1);
+            x -= 1;
+            y += 2;
+            dx += 2;
+        }
+        g.setColor(edge1);
+        g.drawLine(xo, yo + size - 3, xo + 1, yo + size - 3);
+        g.setColor(edge2);
+        g.drawLine(xo + 2, yo + size - 2, xo + size - 1, yo + size - 2);
+        g.drawLine(xo, yo + size - 1, xo + size, yo + size - 1);
+    }
+}

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BlankIcon.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BlankIcon.java?rev=895574&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BlankIcon.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/BlankIcon.java Mon Jan  4 08:04:52 2010
@@ -0,0 +1,56 @@
+/*****************************************************************
+ *   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
+ *
+ *    http://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.util;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics;
+
+import javax.swing.Icon;
+
+public class BlankIcon implements Icon {
+
+    private static final int DEFAULT_BUTTON_SIZE = 18;
+    private Color fillColor;
+    private int size;
+
+    public BlankIcon(Color color, int size) {
+        fillColor = color;
+        this.size = size;
+    }
+
+    public BlankIcon() {
+        this(null, DEFAULT_BUTTON_SIZE);
+    }
+
+    public void paintIcon(Component c, Graphics g, int x, int y) {
+        if (fillColor != null) {
+            g.setColor(fillColor);
+            g.drawRect(x, y, size - 1, size - 1);
+        }
+    }
+
+    public int getIconWidth() {
+        return size;
+    }
+
+    public int getIconHeight() {
+        return size;
+    }
+}

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTable.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTable.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTable.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTable.java Mon Jan  4 08:04:52 2010
@@ -20,6 +20,7 @@
 package org.apache.cayenne.modeler.util;
 
 import java.awt.Component;
+import java.awt.event.MouseListener;
 
 import javax.swing.DefaultCellEditor;
 import javax.swing.DefaultListSelectionModel;
@@ -27,25 +28,51 @@
 import javax.swing.JTextField;
 import javax.swing.event.ChangeEvent;
 import javax.swing.event.TableModelEvent;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.table.JTableHeader;
 import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableColumnModel;
+import javax.swing.table.TableModel;
 import javax.swing.text.JTextComponent;
 
+import org.apache.cayenne.modeler.pref.TableColumnPreferences;
+
 /**
  * Common superclass of tables used in Cayenne. Contains some common configuration
  * settings and utility methods.
  * 
  */
 public class CayenneTable extends JTable {
-
+    
+    private SortButtonRenderer renderer = new SortButtonRenderer();
+    protected TableHeaderSortingListener tableHeaderListener;
+    
     public CayenneTable() {
         super();
         this.setRowHeight(25);
         this.setRowMargin(3);
-        
+        JTableHeader header = getTableHeader();
+        tableHeaderListener = new TableHeaderSortingListener(header,renderer);
+        header.addMouseListener(tableHeaderListener);
         setSelectionModel(new CayenneListSelectionModel());
     }
 
     @Override
+    public void setModel(TableModel dataModel) {
+
+        super.setModel(dataModel);
+        if (!(dataModel instanceof DefaultTableModel)) {
+            TableColumnModel model = getColumnModel();
+
+            for (int i = 0; i < getColumnCount(); i++) {
+                model.getColumn(i).setHeaderRenderer(renderer);
+
+            }
+
+        }
+    }
+
+    @Override
     protected void createDefaultEditors() {
         super.createDefaultEditors();
 
@@ -192,4 +219,12 @@
             }
         }
     }
+
+    public void sort(int column, boolean isAscend) {
+        tableHeaderListener.sortByDefinedColumn(convertColumnIndexToView(column), column, isAscend);
+    }
+
+    public void setSortPreferenceSaver(TableColumnPreferences tableColumnPreferences) {
+        tableHeaderListener.setPreferences(tableColumnPreferences);
+    }
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTableModel.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTableModel.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTableModel.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CayenneTableModel.java Mon Jan  4 08:04:52 2010
@@ -62,7 +62,7 @@
         this.mediator = mediator;
         this.objectList = objectList;
 
-        orderList();
+        //orderList();
     }
 
     public void setValueAt(Object newVal, int row, int col) {
@@ -206,7 +206,7 @@
         fireTableDataChanged();
     }
 
-    class PropertyComparator implements Comparator {
+    protected class PropertyComparator implements Comparator {
 
         Method getter;
 
@@ -248,12 +248,26 @@
             try {
                 Comparable p1 = (Comparable) getter.invoke(o1);
                 Comparable p2 = (Comparable) getter.invoke(o2);
-
-                return (p1 == null) ? -1 : p1.compareTo(p2);
+                
+                return (p1 == null) ? -1 : (p2 == null)? 1 : p1.compareTo(p2);
             }
             catch (Exception ex) {
                 throw new CayenneRuntimeException("Error reading property.", ex);
             }
         }
     }
+
+    public abstract void sortByColumn(int sortCol, boolean isAscent);
+    
+    public abstract boolean isColumnSortable(int sortCol);
+    
+    public void sortByElementProperty(String string, boolean isAscent) {
+        Collections.sort(objectList, new PropertyComparator(
+                string,
+                getElementsClass()));
+        if(!isAscent){
+            Collections.reverse(objectList);
+        }
+    }
+    
 }

Modified: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CellEditorForAttributeTable.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CellEditorForAttributeTable.java?rev=895574&r1=895573&r2=895574&view=diff
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CellEditorForAttributeTable.java (original)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/CellEditorForAttributeTable.java Mon Jan  4 08:04:52 2010
@@ -57,7 +57,7 @@
                 boolean isSelected,
                 int row,
                 int column) {
-
+            column = table.convertColumnIndexToView(column);
             return editor.getTableCellEditorComponent(
                     table,
                     value,

Added: cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/SortButtonRenderer.java
URL: http://svn.apache.org/viewvc/cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/SortButtonRenderer.java?rev=895574&view=auto
==============================================================================
--- cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/SortButtonRenderer.java (added)
+++ cayenne/main/trunk/framework/cayenne-modeler/src/main/java/org/apache/cayenne/modeler/util/SortButtonRenderer.java Mon Jan  4 08:04:52 2010
@@ -0,0 +1,126 @@
+/*****************************************************************
+ *   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
+ *
+ *    http://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.util;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Insets;
+import java.util.Hashtable;
+
+import javax.swing.BorderFactory;
+import javax.swing.JButton;
+import javax.swing.JTable;
+import javax.swing.border.MatteBorder;
+import javax.swing.table.TableCellRenderer;
+
+public class SortButtonRenderer extends JButton implements TableCellRenderer {
+
+    public static final int NONE = 0;
+    public static final int DOWN = 1;
+    public static final int UP = 2;
+
+    private int pushedColumn;
+    private Hashtable state;
+    private JButton downButton, upButton;
+
+    public SortButtonRenderer() {
+        MatteBorder matteBorder = BorderFactory.createMatteBorder(0, 0, 1, 1, Color.gray);
+        setBorder(matteBorder);
+
+        pushedColumn = -1;
+        state = new Hashtable();
+
+        setMargin(new Insets(0, 0, 0, 0));
+        setHorizontalTextPosition(CENTER);
+        setIcon(new BlankIcon());
+
+        downButton = new JButton();
+
+        downButton.setBorder(matteBorder);
+        downButton.setMargin(new Insets(0, 0, 0, 0));
+        downButton.setHorizontalTextPosition(LEFT);
+        downButton.setIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, false));
+        downButton.setPressedIcon(new BevelArrowIcon(BevelArrowIcon.DOWN, false, true));
+
+        upButton = new JButton();
+        upButton.setBorder(matteBorder);
+        upButton.setMargin(new Insets(0, 0, 0, 0));
+        upButton.setHorizontalTextPosition(LEFT);
+        upButton.setIcon(new BevelArrowIcon(BevelArrowIcon.UP, false, false));
+    }
+
+    public Component getTableCellRendererComponent(
+            JTable table,
+            Object value,
+            boolean isSelected,
+            boolean hasFocus,
+            int row,
+            int column) {
+        JButton button = this;
+        Object obj = state.get(new Integer(column));
+
+        if (obj != null) {
+            if (((Integer) obj).intValue() == DOWN) {
+                button = downButton;
+            }
+            else {
+                button = upButton;
+            }
+        }
+        button.setText((value == null) ? "" : value.toString());
+        return button;
+    }
+
+    public void setPressedColumn(int col) {
+        pushedColumn = col;
+    }
+
+    public void setSelectedColumn(int col, boolean isAscOrder) {
+        if (col < 0)
+            return;
+        Integer value = null;
+        //shows the direction of ordering
+        if (isAscOrder) {
+            value = new Integer(DOWN);
+        }
+        else {
+            value = new Integer(UP);
+        }
+
+        state.clear();
+        state.put(new Integer(col), value);
+    }
+
+    public int getState(int col) {
+        int retValue;
+        Object obj = state.get(new Integer(col));
+        if (obj == null) {
+            retValue = NONE;
+        }
+        else {
+            if (((Integer) obj).intValue() == DOWN) {
+                retValue = DOWN;
+            }
+            else {
+                retValue = UP;
+            }
+        }
+        return retValue;
+    }
+}
\ No newline at end of file