[Thinlet-development] thinlet/src/java/thinlet Thinlet.java,1.20,1.21
Brought to you by:
bajzat
From: Andrzej B. <ab...@us...> - 2005-01-18 12:00:27
|
Update of /cvsroot/thinlet/thinlet/src/java/thinlet In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv12851 Modified Files: Thinlet.java Log Message: Some JVMs don't tolerate deeply nested arrays, such as used in child lists of Thinlet widgets. This patch adds an alternative implementation based on Vectors. Note: this implementation has some limitations, such as the requirement that the list format should be selected BEFORE any Thinlets are instantiated, and may not be changed while there are any instances running. Proper solution to this would require significant changes in the way Thinlet framework uses the static method get(comp, key). Submitted by: Mike Hartshorn and Robert Piotrowski. Index: Thinlet.java =================================================================== RCS file: /cvsroot/thinlet/thinlet/src/java/thinlet/Thinlet.java,v retrieving revision 1.20 retrieving revision 1.21 diff -u -d -r1.20 -r1.21 --- Thinlet.java 11 Oct 2004 19:43:48 -0000 1.20 +++ Thinlet.java 18 Jan 2005 12:00:14 -0000 1.21 @@ -83,6 +83,8 @@ private static Method wheelrotation = null; private static int evm = 0; + private static boolean useVectors = true; + static { try { WHEEL_MASK = AWTEvent.class.getField("MOUSE_WHEEL_EVENT_MASK").getLong(null); @@ -5079,6 +5081,23 @@ return false; } + /** Select whether widget child lists should use Vectors or Object[]. Some JVMs don't + * tolerate deeply nested arrays. + * <p><b>WARNING: this value MUST NOT be changed while running instances + * of Thinlet exist. The proper way to call this method is in the main() + * method before any Thinlets are instantiated.</b></p> + */ + public static void setUseVectors(boolean b) { + useVectors = b; + } + + /** If true, then Thinlet will use Vectors instead of Object[] to + * keep the child lists. + */ + public static boolean getUseVectors() { + return useVectors; + } + /** * Get a specified sub-component or component part. Key is e.g. "header" * (table header), ":parent" (parent component), ":comp" (head of a @@ -5086,6 +5105,32 @@ * popupmenu, etc ... */ static Object get(Object component, Object key) { + if (useVectors) { + if (key == ":comp") { + try { + return ((Vector)get(component, ":children")).elementAt(0); + } catch (Exception e) { + return null; + } + } else if (key == ":next") { + // the desktop doesn't have a parent so you can get + // null's here if you remove the only component + // from a desktop + Integer slotInteger = (Integer)get(component, ":slot"); + if (slotInteger != null) { + int nextSlot = ((Integer)get(component, ":slot")).intValue() + 1; + Object parent = get(component, ":parent"); + try { + return ((Vector)get(parent, ":children")).elementAt(nextSlot); + } catch (Exception e) { + return null; + } + } else { + return null; + } + } + } + // possibly fall-through from above for (Object[] entry = (Object[]) component; entry != null; entry = (Object[]) entry[2]) { if (entry[0] == key) { return entry[1]; @@ -5217,6 +5262,9 @@ public void removeAll(Object component) { if (get(component, ":comp") != null) { set(component, ":comp", null); + if (useVectors) { + set(component, ":children", null); + } update(component, "validate"); } } @@ -5328,14 +5376,36 @@ * Referenced by DOM */ private void insertItem(Object parent, Object key, Object component, int index) { - Object item = parent, next = get(parent, key); - for (int i = 0;; i++) { - if ((i == index) || (next == null)) { - set(item, key, component); - set(component, ":next", next); - break; + if (useVectors && key.equals(":comp")) { + Vector v = (Vector)get(parent, ":children"); + if (v == null) { + // tune here + v = new Vector(4, 4); + set(parent, ":children", v); + } + + if (index == -1) { + set(component, ":slot", new Integer(v.size())); + v.addElement(component); + } else { + set(component, ":slot", new Integer(index)); + v.insertElementAt(component, index); + int len = v.size(); + for (int i = 0; i < len; i++) { + Object child = v.elementAt(i); + set(child, ":slot", new Integer(i)); + } + } + } else { + Object item = parent, next = get(parent, key); + for (int i = 0;; i++) { + if ((i == index) || (next == null)) { + set(item, key, component); + set(component, ":next", next); + break; + } + next = get(item = next, key = ":next"); } - next = get(item = next, key = ":next"); } } @@ -5371,17 +5441,31 @@ * @param component */ private void removeItemImpl(Object parent, Object component) { - Object previous = null; // the widget before the given component - for (Object comp = get(parent, ":comp"); comp != null;) { - Object next = get(comp, ":next"); - if (next == component) { - previous = comp; - break; + if (useVectors) { + Vector v = (Vector)get(parent, ":children"); + if (v != null) { + v.removeElement(component); + int len = v.size(); + // rebuld slot list, should only do it from position + // where component was removed + for (int i = 0; i < len; i++) { + Object child = v.elementAt(i); + set(child, ":slot", new Integer(i)); + } } - comp = next; + } else { + Object previous = null; // the widget before the given component + for (Object comp = get(parent, ":comp"); comp != null;) { + Object next = get(comp, ":next"); + if (next == component) { + previous = comp; + break; + } + comp = next; + } + set((previous != null) ? previous : parent, (previous != null) ? ":next" : ":comp", get(component, ":next")); + set(component, ":next", null); } - set((previous != null) ? previous : parent, (previous != null) ? ":next" : ":comp", get(component, ":next")); - set(component, ":next", null); set(component, ":parent", null); // not required } |