### Eclipse Workspace Patch 1.0 #P org.eclipse.swt.nebula.widgets Index: src/org/eclipse/swt/nebula/widgets/compositetable/CompositeTable.java =================================================================== RCS file: /cvsroot/technology/org.eclipse.swt.nebula/org.eclipse.swt.nebula.widgets/src/org/eclipse/swt/nebula/widgets/compositetable/CompositeTable.java,v retrieving revision 1.3 diff -u -r1.3 CompositeTable.java --- src/org/eclipse/swt/nebula/widgets/compositetable/CompositeTable.java 6 Feb 2007 03:46:42 -0000 1.3 +++ src/org/eclipse/swt/nebula/widgets/compositetable/CompositeTable.java 18 Feb 2007 21:03:03 -0000 @@ -13,6 +13,7 @@ package org.eclipse.swt.nebula.widgets.compositetable; import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; @@ -140,10 +141,14 @@ // Private fields here private Constructor headerConstructor = null; + private Method headerFactoryMethod = null; + private Control headerControl = null; private Constructor rowConstructor = null; + private Method rowFactoryMethod = null; + private Control rowControl = null; // TODO: on public API methods that reference contentPane, make sure it's @@ -337,27 +342,45 @@ private void findPrototypeConstructors(Control[] finalChildren) { // Get a constructor for the header and/or the row prototype if (finalChildren.length == 1) { + rowControl = finalChildren[0]; + } else { + rowControl = finalChildren[1]; + + headerControl = finalChildren[0]; try { - rowControl = (Composite) finalChildren[0]; - rowConstructor = finalChildren[0].getClass().getConstructor( + headerConstructor = headerControl.getClass().getConstructor( new Class[] { Composite.class, Integer.TYPE }); } catch (Exception e) { - throw new RuntimeException( - "Unable to get constructor object for header or row", e); + headerConstructor = null; } - } else { try { - headerConstructor = finalChildren[0].getClass().getConstructor( - new Class[] { Composite.class, Integer.TYPE }); - headerControl = finalChildren[0]; - rowConstructor = finalChildren[1].getClass().getConstructor( - new Class[] { Composite.class, Integer.TYPE }); - rowControl = finalChildren[1]; + headerFactoryMethod = headerControl.getClass().getMethod("createHeader", + new Class[] { Composite.class }); } catch (Exception e) { + headerFactoryMethod = null; + } + if (headerConstructor == null && headerFactoryMethod == null) { throw new RuntimeException( - "Unable to get constructor object for header or row", e); + "Unable to get either constructor object or the createHeader method for header"); } } + + try { + rowConstructor = rowControl.getClass().getConstructor( + new Class[] { Composite.class, Integer.TYPE }); + } catch (Exception e) { + rowConstructor = null; + } + try { + rowFactoryMethod = rowControl.getClass().getMethod("createRow", + new Class[] { Composite.class }); + } catch (Exception e) { + rowFactoryMethod = null; + } + if (rowConstructor == null && rowFactoryMethod == null) { + throw new RuntimeException( + "Unable to get either constructor object or the createRow method for row"); + } } private void resizePrototypeObjects(Control[] finalChildren) { @@ -845,6 +868,27 @@ } /** + * (non-API) Method getHeaderFactoryMethod. Returns the method in the header + * object used internally to construct the table's header, or null if there + * is none + * + * @return the header's constructor. + */ + public Method getHeaderFactoryMethod() { + return headerFactoryMethod; + } + + /** + * (non-API) Method getRowFactoryMethod. Returns a method in the the object + * used internally to construct each row object + * + * @return the rows' constructor + */ + public Method getRowFactoryMethod() { + return rowFactoryMethod; + } + + /** * (non-API) Method getHeaderControl. Returns the prototype header control. * * @return the prototype header control. Index: src/org/eclipse/swt/nebula/widgets/compositetable/InternalCompositeTable.java =================================================================== RCS file: /cvsroot/technology/org.eclipse.swt.nebula/org.eclipse.swt.nebula.widgets/src/org/eclipse/swt/nebula/widgets/compositetable/InternalCompositeTable.java,v retrieving revision 1.14 diff -u -r1.14 InternalCompositeTable.java --- src/org/eclipse/swt/nebula/widgets/compositetable/InternalCompositeTable.java 9 Feb 2007 03:36:47 -0000 1.14 +++ src/org/eclipse/swt/nebula/widgets/compositetable/InternalCompositeTable.java 18 Feb 2007 21:03:04 -0000 @@ -12,6 +12,7 @@ package org.eclipse.swt.nebula.widgets.compositetable; import java.lang.reflect.Constructor; +import java.lang.reflect.Method; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; @@ -84,6 +85,10 @@ // them private Constructor headerConstructor; private Constructor rowConstructor; + + private Method headerFactoryMethod; + private Method rowFactoryMethod; + private Control headerControl; private Control myHeader = null; private Control rowControl; @@ -112,6 +117,10 @@ headerConstructor = parent.getHeaderConstructor(); rowConstructor = parent.getRowConstructor(); + + headerFactoryMethod = parent.getHeaderFactoryMethod(); + rowFactoryMethod = parent.getRowFactoryMethod(); + headerControl = parent.getHeaderControl(); rowControl = parent.getRowControl(); @@ -432,21 +441,38 @@ * Construct a header or row object on demand. Logs an error and returns * null on failure. * + * At least one of constructor and factoryMethod + * must be non-null. If both are non-null then factoryMethod + * is used. + * * @param parent * The SWT parent. * @param constructor * The header or row object's constructor. + * @param factoryMethod + * A method in the header or row object that creates another + * copy of the header or row * @return The constructed control or null if none could be constructed. */ private Control createInternalControl(Composite parent, - Constructor constructor) { + Control originalControl, + Constructor constructor, Method factoryMethod) { Control result = null; + try { - if (!constructor.isAccessible()) { - constructor.setAccessible(true); + if (factoryMethod != null) { + if (!factoryMethod.isAccessible()) { + factoryMethod.setAccessible(true); + } + result = (Control) factoryMethod.invoke(originalControl, new Object [] { + parent }); + } else { + if (!constructor.isAccessible()) { + constructor.setAccessible(true); + } + result = (Control) constructor.newInstance(new Object[] { parent, + Integer.valueOf(originalControl.getStyle()) }); } - result = (Control) constructor.newInstance(new Object[] { parent, - new Integer(SWT.NULL) }); } catch (Exception e) { throw new IllegalArgumentException("Unable to construct control"); //$NON-NLS-1$ } @@ -463,8 +489,11 @@ * If the header control hasn't been created yet, create and show it. */ private void showHeader() { - if (myHeader == null && headerConstructor != null) { - myHeader = createInternalControl(controlHolder, headerConstructor); + if (myHeader == null && (headerConstructor != null || headerFactoryMethod != null)) { + myHeader = createInternalControl(controlHolder, + headerControl, + headerConstructor, + headerFactoryMethod); fireHeaderConstructionEvent(myHeader); if (myHeader instanceof Composite) { Composite headerComp = (Composite) myHeader; @@ -771,7 +800,9 @@ return recycledRow; } Control newControl = createInternalControl(controlHolder, - rowConstructor); + rowControl, + rowConstructor, + rowFactoryMethod); if (menu != null) { newControl.setMenu(menu); }