You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2022/06/20 13:13:55 UTC

[groovy] branch GROOVY_4_0_X updated (8635ff87ea -> d82a46914e)

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

paulk pushed a change to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git


    from 8635ff87ea GROOVY-10436: STC: closure parameter as type witness for SAM-type target
     new 996ff1e3d7 GROOVY-10661: Support launching of ObjectExplore when property rows are double clicked. Also support Array tab aside from Collection and Map Tabs.
     new ed23c1b9a8 GROOVY-10661: Support column sorting by storing raw values in a hidden table column and other optimization.
     new d82a46914e GROOVY-10661: additional refactoring

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/main/java/groovy/inspect/Inspector.java        |  67 +++++++++++
 .../groovy/groovy/console/ui/ObjectBrowser.groovy  | 123 +++++++++++++++++----
 2 files changed, 170 insertions(+), 20 deletions(-)


[groovy] 03/03: GROOVY-10661: additional refactoring

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit d82a46914ebdd5f7f59e50f3f000fc6cdef9dad7
Author: Paul King <pa...@asert.com.au>
AuthorDate: Mon Jun 20 23:11:56 2022 +1000

    GROOVY-10661: additional refactoring
---
 .../groovy/groovy/console/ui/ObjectBrowser.groovy  | 100 ++++++++++-----------
 1 file changed, 49 insertions(+), 51 deletions(-)

diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
index 5726bedda9..198ac3eb35 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
@@ -22,10 +22,10 @@ import groovy.inspect.Inspector
 import groovy.swing.table.TableSorter
 import groovy.swing.SwingBuilder
 
-import javax.swing.ListSelectionModel
 import javax.swing.WindowConstants
 import java.awt.FlowLayout
-import java.awt.event.*
+import java.awt.event.MouseAdapter
+import java.awt.event.MouseEvent
 
 import static groovy.inspect.Inspector.MEMBER_DECLARER_IDX
 import static groovy.inspect.Inspector.MEMBER_EXCEPTIONS_IDX
@@ -87,24 +87,23 @@ class ObjectBrowser {
                     if (inspector.object?.class?.array) {
                         scrollPane(name: ' Array data ') {
                             arrayTable = table {
-                                int i = 0
-                                def list = Arrays.asList(inspector.object)
-                                def data = list.collect { val -> [i++, val] }
-                                tableModel(list: data) {
-                                    closureColumn(header: 'Index', read: { it[0] })
-                                    closureColumn(header: 'Value', read: { it[1] })
-                                    closureColumn(header: 'Raw Value', read: { it[1] }) // to support sorting
+                                tableModel(list: inspector.object.toList().withIndex()) {
+                                    closureColumn(header: 'Index', read: { it[1] })
+                                    closureColumn(header: 'Value', read: { it[0] })
+                                    closureColumn(header: 'Raw Value', read: { it[0] }) // to support sorting
                                 }
                             }
-                            arrayTable.getColumnModel().getColumn(2).setMinWidth(0);
-                            arrayTable.getColumnModel().getColumn(2).setMaxWidth(0);
-                            arrayTable.getColumnModel().getColumn(2).setWidth(0);
+                            arrayTable.columnModel.getColumn(2).with {
+                                minWidth = 0
+                                maxWidth = 0
+                                width = 0
+                            }
                             arrayTable.addMouseListener(new MouseAdapter() {
-                                public void mouseClicked(MouseEvent e) {
-                                    if (e.getClickCount() == 2) {
+                                void mouseClicked(MouseEvent e) {
+                                    if (e.clickCount == 2) {
                                         def selectedRow = arrayTable.selectedRow
                                         if (selectedRow != -1) {
-                                            def value = arrayTable.getModel().getValueAt(selectedRow, 2)
+                                            def value = arrayTable.model.getValueAt(selectedRow, 2)
                                             if (value != null) {
                                                 ObjectBrowser.inspect(value)
                                             }
@@ -113,27 +112,26 @@ class ObjectBrowser {
                                 }
                             })
                         }
-                    }
-                    if (inspector.object instanceof Collection) {
+                    } else if (inspector.object instanceof Collection) {
                         scrollPane(name: ' Collection data ') {
                             collectionTable = table {
-                                int i = 0
-                                def data = inspector.object.collect { val -> [i++, val] }
-                                tableModel(list: data) {
-                                    closureColumn(header: 'Index', read: { it[0] })
-                                    closureColumn(header: 'Value', read: { it[1] })
-                                    closureColumn(header: 'Raw Value', read: { it[1] }) // to support sorting
+                                tableModel(list: inspector.object.withIndex()) {
+                                    closureColumn(header: 'Index', read: { it[1] })
+                                    closureColumn(header: 'Value', read: { it[0] })
+                                    closureColumn(header: 'Raw Value', read: { it[0] }) // to support sorting
                                 }
                             }
-                            collectionTable.getColumnModel().getColumn(2).setMinWidth(0);
-                            collectionTable.getColumnModel().getColumn(2).setMaxWidth(0);
-                            collectionTable.getColumnModel().getColumn(2).setWidth(0);
+                            collectionTable.columnModel.getColumn(2).with {
+                                minWidth = 0
+                                maxWidth = 0
+                                width = 0
+                            }
                             collectionTable.addMouseListener(new MouseAdapter() {
-                                public void mouseClicked(MouseEvent e) {
-                                    if (e.getClickCount() == 2) {
+                                void mouseClicked(MouseEvent e) {
+                                    if (e.clickCount == 2) {
                                         def selectedRow = collectionTable.selectedRow
                                         if (selectedRow != -1) {
-                                            def value = collectionTable.getModel().getValueAt(selectedRow, 2)
+                                            def value = collectionTable.model.getValueAt(selectedRow, 2)
                                             if (value != null) {
                                                 ObjectBrowser.inspect(value)
                                             }
@@ -142,28 +140,27 @@ class ObjectBrowser {
                                 }
                             })
                         }
-                    }
-                    if (inspector.object instanceof Map) {
+                    } else if (inspector.object instanceof Map) {
                         scrollPane(name: ' Map data ') {
                             mapTable = table {
-                                int i = 0
-                                def data = inspector.object.collect { key, val -> [i++, key, val] }
-                                tableModel(list: data) {
-                                    closureColumn(header: 'Index', read: { it[0] })
-                                    closureColumn(header: 'Key', read: { it[1] })
-                                    closureColumn(header: 'Value', read: { it[2] })
-                                    closureColumn(header: 'Raw Value', read: { it[2] }) // to support sorting
+                                tableModel(list: inspector.object.entrySet().withIndex()) {
+                                    closureColumn(header: 'Index', read: { it[1] })
+                                    closureColumn(header: 'Key', read: { it[0].key })
+                                    closureColumn(header: 'Value', read: { it[0].value })
+                                    closureColumn(header: 'Raw Value', read: { it[0].value }) // to support sorting
                                 }
                             }
-                            mapTable.getColumnModel().getColumn(3).setMinWidth(0);
-                            mapTable.getColumnModel().getColumn(3).setMaxWidth(0);
-                            mapTable.getColumnModel().getColumn(3).setWidth(0);
+                            mapTable.columnModel.getColumn(3).with {
+                                minWidth = 0
+                                maxWidth = 0
+                                width = 0
+                            }
                             mapTable.addMouseListener(new MouseAdapter() {
-                                public void mouseClicked(MouseEvent e) {
-                                    if (e.getClickCount() == 2) {
+                                void mouseClicked(MouseEvent e) {
+                                    if (e.clickCount == 2) {
                                         def selectedRow = mapTable.selectedRow
                                         if (selectedRow != -1) {
-                                            def value = mapTable.getModel().getValueAt(selectedRow, 2)
+                                            def value = mapTable.model.getValueAt(selectedRow, 2)
                                             if (value != null) {
                                                 ObjectBrowser.inspect(value)
                                             }
@@ -186,16 +183,17 @@ class ObjectBrowser {
                                 closureColumn(header: 'Raw Value', read: { it[MEMBER_RAW_VALUE_IDX] }) // to support sorting
                             }
                         }
-                        fieldTable.getColumnModel().getColumn(6).setMinWidth(0);
-                        fieldTable.getColumnModel().getColumn(6).setMaxWidth(0);
-                        fieldTable.getColumnModel().getColumn(6).setWidth(0);
+                        fieldTable.columnModel.getColumn(6).with {
+                            minWidth = 0
+                            maxWidth = 0
+                            width = 0
+                        }
                         fieldTable.addMouseListener(new MouseAdapter() {
-                            public void mouseClicked(MouseEvent e) {
-                                if (e.getClickCount() == 2) {
+                            void mouseClicked(MouseEvent e) {
+                                if (e.clickCount == 2) {
                                     def selectedRow = fieldTable.selectedRow
                                     if (selectedRow != -1) {
-                                        def value = fieldTable.getModel().getValueAt(selectedRow, MEMBER_RAW_VALUE_IDX)
-                                        println value
+                                        def value = fieldTable.model.getValueAt(selectedRow, MEMBER_RAW_VALUE_IDX)
                                         if (value != null) {
                                             ObjectBrowser.inspect(value)
                                         }


[groovy] 01/03: GROOVY-10661: Support launching of ObjectExplore when property rows are double clicked. Also support Array tab aside from Collection and Map Tabs.

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit 996ff1e3d7819c6e9b700dca2a4d3dd82b6c10dd
Author: Sandip Chitale <sa...@gmail.com>
AuthorDate: Thu Jun 16 14:53:36 2022 -0700

    GROOVY-10661: Support launching of ObjectExplore when property rows are double clicked. Also support Array tab aside from Collection and Map Tabs.
---
 src/main/java/groovy/inspect/Inspector.java        | 67 ++++++++++++++++++
 .../groovy/groovy/console/ui/ObjectBrowser.groovy  | 82 +++++++++++++++++++++-
 2 files changed, 147 insertions(+), 2 deletions(-)

diff --git a/src/main/java/groovy/inspect/Inspector.java b/src/main/java/groovy/inspect/Inspector.java
index 6f5304cd90..8833027d4a 100644
--- a/src/main/java/groovy/inspect/Inspector.java
+++ b/src/main/java/groovy/inspect/Inspector.java
@@ -60,6 +60,7 @@ public class Inspector {
     public static final int MEMBER_PARAMS_IDX = 5;
     public static final int MEMBER_VALUE_IDX = 5;
     public static final int MEMBER_EXCEPTIONS_IDX = 6;
+    public static final int MEMBER_RAW_VALUE_IDX = 6;
 
     public static final String NOT_APPLICABLE = "n/a";
     public static final String GROOVY = "GROOVY";
@@ -210,6 +211,36 @@ public class Inspector {
         return withoutNulls(result);
     }
 
+    public Object[] getPropertyInfoWithRawValue() {
+        List props = DefaultGroovyMethods.getMetaPropertyValues(objectUnderInspection);
+        Object[] result = new Object[props.size()];
+        int i = 0;
+        for (Iterator iter = props.iterator(); iter.hasNext(); i++) {
+            PropertyValue pv = (PropertyValue) iter.next();
+            result[i] = fieldInfoWithRawValue(pv);
+        }
+        return result;
+    }
+
+    protected Object[] fieldInfoWithRawValue(PropertyValue pv) {
+        Object[] result = new Object[MEMBER_VALUE_IDX + 2];
+        result[MEMBER_ORIGIN_IDX] = GROOVY;
+        result[MEMBER_MODIFIER_IDX] = "public";
+        result[MEMBER_DECLARER_IDX] = NOT_APPLICABLE;
+        result[MEMBER_TYPE_IDX] = shortName(pv.getType());
+        result[MEMBER_NAME_IDX] = pv.getName();
+        Object rawValue = null;
+        try {
+            result[MEMBER_VALUE_IDX] = FormatHelper.inspect(pv.getValue());
+            rawValue = pv.getValue();
+        } catch (Exception e) {
+            result[MEMBER_VALUE_IDX] = NOT_APPLICABLE;
+        }
+        result = withoutNullsWithRawValue(result);
+        result[MEMBER_RAW_VALUE_IDX] = rawValue;
+        return result;
+    }
+
     protected Class getClassUnderInspection() {
         return objectUnderInspection.getClass();
     }
@@ -290,6 +321,15 @@ public class Inspector {
         return toNormalize;
     }
 
+    protected Object[] withoutNullsWithRawValue(Object[] toNormalize) {
+        for (int i = 0; i < toNormalize.length; i++) {
+            if (toNormalize[i] == null) {
+                toNormalize[i] = NOT_APPLICABLE;
+            }
+        }
+        return toNormalize;
+    }
+
     public static void print(Object[] memberInfo) {
         print(System.out, memberInfo);
     }
@@ -331,4 +371,31 @@ public class Inspector {
             return result;
         }
     }
+
+    public static Collection sortWithRawValue(List<Object> memberInfo) {
+        memberInfo.sort(new MemberComparatorWithRawValue());
+        return memberInfo;
+    }
+
+    public static class MemberComparatorWithRawValue implements Comparator<Object>, Serializable {
+        private static final long serialVersionUID = -7691851726606749542L;
+
+        @Override
+        public int compare(Object a, Object b) {
+            Object[] aStr = (Object[]) a;
+            Object[] bStr = (Object[]) b;
+            int result = ((String) aStr[Inspector.MEMBER_NAME_IDX]).compareTo((String) bStr[Inspector.MEMBER_NAME_IDX]);
+            if (0 != result) return result;
+            result = ((String) aStr[Inspector.MEMBER_TYPE_IDX]).compareTo((String) bStr[Inspector.MEMBER_TYPE_IDX]);
+            if (0 != result) return result;
+            result = ((String)aStr[Inspector.MEMBER_PARAMS_IDX]).compareTo((String) bStr[Inspector.MEMBER_PARAMS_IDX]);
+            if (0 != result) return result;
+            result =((String) aStr[Inspector.MEMBER_DECLARER_IDX]).compareTo((String) bStr[Inspector.MEMBER_DECLARER_IDX]);
+            if (0 != result) return result;
+            result = ((String)aStr[Inspector.MEMBER_MODIFIER_IDX]).compareTo((String) bStr[Inspector.MEMBER_MODIFIER_IDX]);
+            if (0 != result) return result;
+            result = ((String) aStr[Inspector.MEMBER_ORIGIN_IDX]).compareTo((String) bStr[Inspector.MEMBER_ORIGIN_IDX]);
+            return result;
+        }
+    }
 }
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
index 845d4ead94..8382ea18e6 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
@@ -22,8 +22,10 @@ import groovy.inspect.Inspector
 import groovy.swing.table.TableSorter
 import groovy.swing.SwingBuilder
 
+import javax.swing.ListSelectionModel
 import javax.swing.WindowConstants
 import java.awt.FlowLayout
+import java.awt.event.*
 
 import static groovy.inspect.Inspector.MEMBER_DECLARER_IDX
 import static groovy.inspect.Inspector.MEMBER_EXCEPTIONS_IDX
@@ -33,6 +35,7 @@ import static groovy.inspect.Inspector.MEMBER_ORIGIN_IDX
 import static groovy.inspect.Inspector.MEMBER_PARAMS_IDX
 import static groovy.inspect.Inspector.MEMBER_TYPE_IDX
 import static groovy.inspect.Inspector.MEMBER_VALUE_IDX
+import static groovy.inspect.Inspector.MEMBER_RAW_VALUE_IDX
 
 /**
  * A little GUI to show some of the Inspector capabilities.
@@ -81,22 +84,67 @@ class ObjectBrowser {
                     label(classLabel)
                 }
                 tabbedPane(constraints: CENTER) {
+                    if (inspector.object?.class?.array) {
+                        scrollPane(name: ' Array data ') {
+                            def values
+                            itemTable = table {
+                                def list = Arrays.asList(inspector.object)
+                                int i = 0
+                                values = list
+                                def data = list.collect { val -> [i++, val] }
+                                tableModel(list: data) {
+                                    closureColumn(header: 'Index', read: { it[0] })
+                                    closureColumn(header: 'Value', read: { it[1] })
+                                }
+                            }
+                            itemTable.addMouseListener(new MouseAdapter() {
+                                public void mouseClicked(MouseEvent e) {
+                                    if (e.getClickCount() == 2) {
+                                        def selectedRow = itemTable.selectedRow
+                                        if (selectedRow != -1) {
+                                            def value = values[selectedRow]
+                                            if (value != null) {
+                                                ObjectBrowser.inspect(value)
+                                            }
+                                        }
+                                    }
+                                }
+                            })
+                        }
+                    }
                     if (inspector.object instanceof Collection) {
                         scrollPane(name: ' Collection data ') {
+                            def values
                             itemTable = table {
                                 int i = 0
+                                values = inspector.object.collect { val -> val }
                                 def data = inspector.object.collect { val -> [i++, val] }
                                 tableModel(list: data) {
                                     closureColumn(header: 'Index', read: { it[0] })
                                     closureColumn(header: 'Value', read: { it[1] })
                                 }
                             }
+                            itemTable.addMouseListener(new MouseAdapter() {
+                                public void mouseClicked(MouseEvent e) {
+                                    if (e.getClickCount() == 2) {
+                                        def selectedRow = itemTable.selectedRow
+                                        if (selectedRow != -1) {
+                                            def value = values[selectedRow]
+                                            if (value != null) {
+                                                ObjectBrowser.inspect(value)
+                                            }
+                                        }
+                                    }
+                                }
+                            })
                         }
                     }
                     if (inspector.object instanceof Map) {
                         scrollPane(name: ' Map data ') {
+                            def values
                             itemTable = table {
                                 int i = 0
+                                values = inspector.object.collect { key, val -> val }
                                 def data = inspector.object.collect { key, val -> [i++, key, val] }
                                 tableModel(list: data) {
                                     closureColumn(header: 'Index', read: { it[0] })
@@ -104,11 +152,24 @@ class ObjectBrowser {
                                     closureColumn(header: 'Value', read: { it[2] })
                                 }
                             }
+                            itemTable.addMouseListener(new MouseAdapter() {
+                                public void mouseClicked(MouseEvent e) {
+                                    if (e.getClickCount() == 2) {
+                                        def selectedRow = itemTable.selectedRow
+                                        if (selectedRow != -1) {
+                                            def value = values[selectedRow]
+                                            if (value != null) {
+                                                ObjectBrowser.inspect(value)
+                                            }
+                                        }
+                                    }
+                                }
+                            })
                         }
                     }
                     scrollPane(name: ' Properties (includes public fields) ') {
+                        def data = Inspector.sortWithRawValue(inspector.propertyInfoWithRawValue.toList())
                         fieldTable = table {
-                            def data = Inspector.sort(inspector.propertyInfo.toList())
                             tableModel(list: data) {
                                 closureColumn(header: 'Name', read: { it[MEMBER_NAME_IDX] })
                                 closureColumn(header: 'Value', read: { it[MEMBER_VALUE_IDX] })
@@ -116,14 +177,31 @@ class ObjectBrowser {
                                 closureColumn(header: 'Origin', read: { it[MEMBER_ORIGIN_IDX] })
                                 closureColumn(header: 'Modifier', read: { it[MEMBER_MODIFIER_IDX] })
                                 closureColumn(header: 'Declarer', read: { it[MEMBER_DECLARER_IDX] })
+                                closureColumn(header: 'Raw Value', read: { it[MEMBER_RAW_VALUE_IDX] })
                             }
                         }
+                        fieldTable.getColumnModel().getColumn(6).setMinWidth(0);
+                        fieldTable.getColumnModel().getColumn(6).setMaxWidth(0);
+                        fieldTable.getColumnModel().getColumn(6).setWidth(0);
+                        fieldTable.addMouseListener(new MouseAdapter() {
+                            public void mouseClicked(MouseEvent e) {
+                                if (e.getClickCount() == 2) {
+                                    def selectedRow = fieldTable.selectedRow
+                                    if (selectedRow != -1) {
+                                        def value = fieldTable.getModel().getValueAt(selectedRow, MEMBER_RAW_VALUE_IDX)
+                                        println value
+                                        if (value != null) {
+                                            ObjectBrowser.inspect(value)
+                                        }
+                                    }
+                                }
+                            }
+                        })
                     }
                     scrollPane(name: ' (Meta) Methods ') {
                         methodTable = table {
                             def data = Inspector.sort(inspector.methods.toList())
                             data.addAll(Inspector.sort(inspector.metaMethods.toList()))
-
                             tableModel(list: data) {
                                 closureColumn(header: 'Name', read: { it[MEMBER_NAME_IDX] })
                                 closureColumn(header: 'Params', read: { it[MEMBER_PARAMS_IDX] })


[groovy] 02/03: GROOVY-10661: Support column sorting by storing raw values in a hidden table column and other optimization.

Posted by pa...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

paulk pushed a commit to branch GROOVY_4_0_X
in repository https://gitbox.apache.org/repos/asf/groovy.git

commit ed23c1b9a8ffc816c9728f797603642780da3879
Author: Sandip Chitale <sa...@gmail.com>
AuthorDate: Fri Jun 17 16:50:27 2022 -0700

    GROOVY-10661: Support column sorting by storing raw values in a hidden table column and other optimization.
---
 .../groovy/groovy/console/ui/ObjectBrowser.groovy  | 51 ++++++++++++----------
 1 file changed, 29 insertions(+), 22 deletions(-)

diff --git a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
index 8382ea18e6..5726bedda9 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/console/ui/ObjectBrowser.groovy
@@ -48,7 +48,7 @@ import static groovy.inspect.Inspector.MEMBER_RAW_VALUE_IDX
 class ObjectBrowser {
 
     def inspector
-    def swing, frame, fieldTable, methodTable, itemTable, mapTable
+    def swing, frame, fieldTable, methodTable, arrayTable, collectionTable, mapTable
 
     static void main(args) {
         inspect('some String')
@@ -86,23 +86,25 @@ class ObjectBrowser {
                 tabbedPane(constraints: CENTER) {
                     if (inspector.object?.class?.array) {
                         scrollPane(name: ' Array data ') {
-                            def values
-                            itemTable = table {
-                                def list = Arrays.asList(inspector.object)
+                            arrayTable = table {
                                 int i = 0
-                                values = list
+                                def list = Arrays.asList(inspector.object)
                                 def data = list.collect { val -> [i++, val] }
                                 tableModel(list: data) {
                                     closureColumn(header: 'Index', read: { it[0] })
                                     closureColumn(header: 'Value', read: { it[1] })
+                                    closureColumn(header: 'Raw Value', read: { it[1] }) // to support sorting
                                 }
                             }
-                            itemTable.addMouseListener(new MouseAdapter() {
+                            arrayTable.getColumnModel().getColumn(2).setMinWidth(0);
+                            arrayTable.getColumnModel().getColumn(2).setMaxWidth(0);
+                            arrayTable.getColumnModel().getColumn(2).setWidth(0);
+                            arrayTable.addMouseListener(new MouseAdapter() {
                                 public void mouseClicked(MouseEvent e) {
                                     if (e.getClickCount() == 2) {
-                                        def selectedRow = itemTable.selectedRow
+                                        def selectedRow = arrayTable.selectedRow
                                         if (selectedRow != -1) {
-                                            def value = values[selectedRow]
+                                            def value = arrayTable.getModel().getValueAt(selectedRow, 2)
                                             if (value != null) {
                                                 ObjectBrowser.inspect(value)
                                             }
@@ -114,22 +116,24 @@ class ObjectBrowser {
                     }
                     if (inspector.object instanceof Collection) {
                         scrollPane(name: ' Collection data ') {
-                            def values
-                            itemTable = table {
+                            collectionTable = table {
                                 int i = 0
-                                values = inspector.object.collect { val -> val }
                                 def data = inspector.object.collect { val -> [i++, val] }
                                 tableModel(list: data) {
                                     closureColumn(header: 'Index', read: { it[0] })
                                     closureColumn(header: 'Value', read: { it[1] })
+                                    closureColumn(header: 'Raw Value', read: { it[1] }) // to support sorting
                                 }
                             }
-                            itemTable.addMouseListener(new MouseAdapter() {
+                            collectionTable.getColumnModel().getColumn(2).setMinWidth(0);
+                            collectionTable.getColumnModel().getColumn(2).setMaxWidth(0);
+                            collectionTable.getColumnModel().getColumn(2).setWidth(0);
+                            collectionTable.addMouseListener(new MouseAdapter() {
                                 public void mouseClicked(MouseEvent e) {
                                     if (e.getClickCount() == 2) {
-                                        def selectedRow = itemTable.selectedRow
+                                        def selectedRow = collectionTable.selectedRow
                                         if (selectedRow != -1) {
-                                            def value = values[selectedRow]
+                                            def value = collectionTable.getModel().getValueAt(selectedRow, 2)
                                             if (value != null) {
                                                 ObjectBrowser.inspect(value)
                                             }
@@ -141,23 +145,25 @@ class ObjectBrowser {
                     }
                     if (inspector.object instanceof Map) {
                         scrollPane(name: ' Map data ') {
-                            def values
-                            itemTable = table {
+                            mapTable = table {
                                 int i = 0
-                                values = inspector.object.collect { key, val -> val }
                                 def data = inspector.object.collect { key, val -> [i++, key, val] }
                                 tableModel(list: data) {
                                     closureColumn(header: 'Index', read: { it[0] })
                                     closureColumn(header: 'Key', read: { it[1] })
                                     closureColumn(header: 'Value', read: { it[2] })
+                                    closureColumn(header: 'Raw Value', read: { it[2] }) // to support sorting
                                 }
                             }
-                            itemTable.addMouseListener(new MouseAdapter() {
+                            mapTable.getColumnModel().getColumn(3).setMinWidth(0);
+                            mapTable.getColumnModel().getColumn(3).setMaxWidth(0);
+                            mapTable.getColumnModel().getColumn(3).setWidth(0);
+                            mapTable.addMouseListener(new MouseAdapter() {
                                 public void mouseClicked(MouseEvent e) {
                                     if (e.getClickCount() == 2) {
-                                        def selectedRow = itemTable.selectedRow
+                                        def selectedRow = mapTable.selectedRow
                                         if (selectedRow != -1) {
-                                            def value = values[selectedRow]
+                                            def value = mapTable.getModel().getValueAt(selectedRow, 2)
                                             if (value != null) {
                                                 ObjectBrowser.inspect(value)
                                             }
@@ -177,7 +183,7 @@ class ObjectBrowser {
                                 closureColumn(header: 'Origin', read: { it[MEMBER_ORIGIN_IDX] })
                                 closureColumn(header: 'Modifier', read: { it[MEMBER_MODIFIER_IDX] })
                                 closureColumn(header: 'Declarer', read: { it[MEMBER_DECLARER_IDX] })
-                                closureColumn(header: 'Raw Value', read: { it[MEMBER_RAW_VALUE_IDX] })
+                                closureColumn(header: 'Raw Value', read: { it[MEMBER_RAW_VALUE_IDX] }) // to support sorting
                             }
                         }
                         fieldTable.getColumnModel().getColumn(6).setMinWidth(0);
@@ -218,7 +224,8 @@ class ObjectBrowser {
         }
 
         // Add a bit of formatting
-        addSorter(itemTable)
+        addSorter(arrayTable)
+        addSorter(collectionTable)
         addSorter(mapTable)
         addSorter(fieldTable)
         addSorter(methodTable)