From 6a2813f43d9fb4b1e3eb614ba56ab36244f51223 Mon Sep 17 00:00:00 2001 From: willemc Date: Mon, 26 Nov 2007 00:01:25 +0100 Subject: [PATCH] [svn r297] some hack work to enable some features and removed all compiler warnings --- lib/idcanet-x4o-bin.jar | Bin 65538 -> 76629 bytes .../annotations/VascAnnotationParser.java | 29 +- .../vasc/annotations/VascDefaultValue.java | 2 +- .../vasc/annotations/VascModelReference.java | 2 +- .../idcanet/vasc/core/VascEventListener.java | 2 +- .../idcanet/vasc/core/VascRecordCreator.java | 2 +- .../vasc/core/VascTableController.java | 2 + .../vasc/core/ui/VascColorChooser.java | 61 +++ .../vasc/impl/BeanVascRecordCreator.java | 11 +- .../vasc/impl/DefaultVascTableController.java | 18 + .../vasc/impl/actions/AddRowAction.java | 2 +- .../serv5/Serv5HibernateVascDataSource.java | 5 +- .../impl/swing/SwingVascViewRenderer.java | 55 +- .../idcanet/vasc/impl/swing/TableSorter.java | 492 ++++++++++++++++++ .../vasc/impl/swing/ui/SwingColorChooser.java | 125 +++++ .../vasc/impl/swt/SwtVascViewRenderer.java | 9 +- tests/META-INF/vasc-lang.eld | 27 + tests/META-INF/vasc-namespaces.xml | 8 + tests/com/idcanet/vasc/TestTable.java | 16 +- tests/com/idcanet/vasc/models/TestModel.java | 18 +- 20 files changed, 829 insertions(+), 57 deletions(-) create mode 100644 src/com/idcanet/vasc/core/ui/VascColorChooser.java create mode 100644 src/com/idcanet/vasc/impl/swing/TableSorter.java create mode 100644 src/com/idcanet/vasc/impl/swing/ui/SwingColorChooser.java create mode 100644 tests/META-INF/vasc-lang.eld create mode 100644 tests/META-INF/vasc-namespaces.xml diff --git a/lib/idcanet-x4o-bin.jar b/lib/idcanet-x4o-bin.jar index 5fd57486cc59485cc9d18a2eefb2fc0987142f9c..a3f65090202c66638674989997c42aa02efb929c 100644 GIT binary patch delta 40647 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%0AfB$Vaklvz}75TC-AE%OPB!4*+_hZ17CGhKl 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 DFw-r` delta 30254 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 beanClass,String property) { return (String)getValue(beanClass,VascToolTip.class,property); } - public String getVascToolTipKey(Class beanClass) { + public String getVascToolTipKey(Class beanClass) { return (String)getValue(beanClass,VascToolTip.class,null); } @@ -76,44 +76,44 @@ public class VascAnnotationParser { * @param property The property for the Labe * @return The i18n key for an Label */ - public String getVascNameKey(Class beanClass,String property) { + public String getVascNameKey(Class beanClass,String property) { return (String)getValue(beanClass,VascName.class,property); } - public String getVascNameKey(Class beanClass) { + public String getVascNameKey(Class beanClass) { return (String)getValue(beanClass,VascName.class,null); } - public Object getVascColumnWidth(Class beanClass,String property) { + public Object getVascColumnWidth(Class beanClass,String property) { return getValue(beanClass,VascColumnWidth.class,property); } - public Object getVascColumnWidth(Class beanClass) { + public Object getVascColumnWidth(Class beanClass) { return getValue(beanClass,VascColumnWidth.class,null); } - public String getVascHelpId(Class beanClass,String property) { + public String getVascHelpId(Class beanClass,String property) { return (String)getValue(beanClass,VascHelpId.class,property); } - public String getVascHelpId(Class beanClass) { + public String getVascHelpId(Class beanClass) { return (String)getValue(beanClass,VascHelpId.class,null); } - public Object getVascDefaultValue(Class beanClass,String property) { + public Object getVascDefaultValue(Class beanClass,String property) { return getValue(beanClass,VascDefaultValue.class,property); } - public Object getVascDefaultValue(Class beanClass) { + public Object getVascDefaultValue(Class beanClass) { return getValue(beanClass,VascDefaultValue.class,null); } - public String getVascImage(Class beanClass,String property) { + public String getVascImage(Class beanClass,String property) { return (String)getValue(beanClass,VascImage.class,property); } - public String getVascImage(Class beanClass) { + public String getVascImage(Class beanClass) { return (String)getValue(beanClass,VascImage.class,null); } @@ -127,7 +127,8 @@ public class VascAnnotationParser { * @param annotationType * @return */ - private Object getValue(Class beanClass,Class annotationType,String property) { + @SuppressWarnings("unchecked") + private Object getValue(Class beanClass,Class annotationType,String property) { if(beanClass==null) { throw new NullPointerException("beanClass may not be null"); } if(annotationType==null){ throw new NullPointerException("annotationType may not be null"); } @@ -202,7 +203,7 @@ public class VascAnnotationParser { return null; } - Class a = b.annotationType(); + Class a = b.annotationType(); if (a.equals(VascName.class)) { VascName l = (VascName)b; if("".equals(l.key()) | "null".equals(l.key())) { diff --git a/src/com/idcanet/vasc/annotations/VascDefaultValue.java b/src/com/idcanet/vasc/annotations/VascDefaultValue.java index ab49bea..bccde37 100644 --- a/src/com/idcanet/vasc/annotations/VascDefaultValue.java +++ b/src/com/idcanet/vasc/annotations/VascDefaultValue.java @@ -45,7 +45,7 @@ public @interface VascDefaultValue { /** * The defaultValue of the method */ - Class defaultValueClass() default Object.class; + Class defaultValueClass() default Object.class; String defaultValue() default "null"; } \ No newline at end of file diff --git a/src/com/idcanet/vasc/annotations/VascModelReference.java b/src/com/idcanet/vasc/annotations/VascModelReference.java index c707ba1..fe7cbc9 100644 --- a/src/com/idcanet/vasc/annotations/VascModelReference.java +++ b/src/com/idcanet/vasc/annotations/VascModelReference.java @@ -42,5 +42,5 @@ import java.lang.annotation.Target; @Target(ElementType.METHOD) public @interface VascModelReference { - Class type() default Object.class; + Class type() default Object.class; } \ No newline at end of file diff --git a/src/com/idcanet/vasc/core/VascEventListener.java b/src/com/idcanet/vasc/core/VascEventListener.java index da24029..db8c40c 100644 --- a/src/com/idcanet/vasc/core/VascEventListener.java +++ b/src/com/idcanet/vasc/core/VascEventListener.java @@ -34,7 +34,7 @@ package com.idcanet.vasc.core; */ public interface VascEventListener { - public enum VascEventType { DATA_UPDATE,OPTION_UPDATE,CLOSE_WINDOW } + public enum VascEventType { DATA_UPDATE,OPTION_UPDATE,CLOSE_WINDOW,BEAN_MERGE,BEAN_INIT } public void vascEvent(VascEventType e,Object o); diff --git a/src/com/idcanet/vasc/core/VascRecordCreator.java b/src/com/idcanet/vasc/core/VascRecordCreator.java index 62c2f44..afb8083 100644 --- a/src/com/idcanet/vasc/core/VascRecordCreator.java +++ b/src/com/idcanet/vasc/core/VascRecordCreator.java @@ -36,5 +36,5 @@ public interface VascRecordCreator { public Object newRecord(VascTable table) throws Exception; - public Class getObjectClass(); + public Class getObjectClass(); } \ No newline at end of file diff --git a/src/com/idcanet/vasc/core/VascTableController.java b/src/com/idcanet/vasc/core/VascTableController.java index 8c5b228..0e5c576 100644 --- a/src/com/idcanet/vasc/core/VascTableController.java +++ b/src/com/idcanet/vasc/core/VascTableController.java @@ -60,4 +60,6 @@ public interface VascTableController { public void addExceptionListener(VascExceptionListener listener); public void removeExceptionListener(VascExceptionListener listener); + + public Object mergeObject(VascTable table,Object object); } \ No newline at end of file diff --git a/src/com/idcanet/vasc/core/ui/VascColorChooser.java b/src/com/idcanet/vasc/core/ui/VascColorChooser.java new file mode 100644 index 0000000..9952245 --- /dev/null +++ b/src/com/idcanet/vasc/core/ui/VascColorChooser.java @@ -0,0 +1,61 @@ +/* + * Copyright 2004-2007 IDCA. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and + * the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY IDCA AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IDCA OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the authors and + * should not be interpreted as representing official policies, either expressed or implied, of IDCA. + */ + +package com.idcanet.vasc.core.ui; + +import com.idcanet.vasc.core.VascTable; + + +/** + * + * @author Willem Cazander + * @version 1.0 Nov 25, 2007 + */ +public class VascColorChooser extends VascUIComponentImplLoader { + + // TODO: remove this hack with converters + boolean hexSwingEncoding = false; + + public Object createComponent(VascTable table,VascValueModel model,Object gui) throws Exception { + return loadAndCreateComponent(this, table, model, gui); + } + + /** + * @return the hexSwingEncoding + */ + public boolean getHexSwingEncoding() { + return hexSwingEncoding; + } + + /** + * @param hexSwingEncoding the hexSwingEncoding to set + */ + public void setHexSwingEncoding(boolean hexSwingEncoding) { + this.hexSwingEncoding = hexSwingEncoding; + } + + +} \ No newline at end of file diff --git a/src/com/idcanet/vasc/impl/BeanVascRecordCreator.java b/src/com/idcanet/vasc/impl/BeanVascRecordCreator.java index dafcd8b..2a23dde 100644 --- a/src/com/idcanet/vasc/impl/BeanVascRecordCreator.java +++ b/src/com/idcanet/vasc/impl/BeanVascRecordCreator.java @@ -36,13 +36,12 @@ import com.idcanet.vasc.core.VascTable; */ public class BeanVascRecordCreator implements VascRecordCreator { - private Class objectClass = null; - + private Class objectClass = null; public BeanVascRecordCreator() { - } - public BeanVascRecordCreator(Class objectClass) { + + public BeanVascRecordCreator(Class objectClass) { setObjectClass(objectClass); } @@ -50,10 +49,10 @@ public class BeanVascRecordCreator implements VascRecordCreator { return objectClass.newInstance(); } - public Class getObjectClass() { + public Class getObjectClass() { return objectClass; } - public void setObjectClass(Class objectClass) { + public void setObjectClass(Class objectClass) { this.objectClass=objectClass; } } \ No newline at end of file diff --git a/src/com/idcanet/vasc/impl/DefaultVascTableController.java b/src/com/idcanet/vasc/impl/DefaultVascTableController.java index 006a7b3..f72ed71 100644 --- a/src/com/idcanet/vasc/impl/DefaultVascTableController.java +++ b/src/com/idcanet/vasc/impl/DefaultVascTableController.java @@ -147,6 +147,7 @@ public class DefaultVascTableController implements VascTableController { return object; } object = table.getVascRecordCreator().newRecord(table); + fireVascEvent(VascEventListener.VascEventType.BEAN_INIT, object); return object; } @@ -245,4 +246,21 @@ public class DefaultVascTableController implements VascTableController { public void removeExceptionListener(VascExceptionListener listener) { exceptionListeners.remove(listener); } + + public Object mergeObject(VascTable table,Object object) { + Object result = null; + try { + object = table.getVascDataSource().merge(object); + fireVascEvent(VascEventListener.VascEventType.BEAN_MERGE,object); + // todo: make faster + // add to table at position old old object + // then remove old object + // send refresh + + table.getVascTableController().refreshData(table); + } catch (Exception e) { + handleException(e, table); + } + return result; + } } \ No newline at end of file diff --git a/src/com/idcanet/vasc/impl/actions/AddRowAction.java b/src/com/idcanet/vasc/impl/actions/AddRowAction.java index 4b9b4be..5db3ed7 100644 --- a/src/com/idcanet/vasc/impl/actions/AddRowAction.java +++ b/src/com/idcanet/vasc/impl/actions/AddRowAction.java @@ -44,6 +44,6 @@ public class AddRowAction extends AbstractVascAction implements RowVascAction { } public void doRowAction(VascTable table,Object rowObject) throws Exception { - table.getVascViewRenderer().renderEdit(table.getVascRecordCreator().newRecord(table)); + table.getVascViewRenderer().renderEdit(null); } } \ No newline at end of file diff --git a/src/com/idcanet/vasc/impl/serv5/Serv5HibernateVascDataSource.java b/src/com/idcanet/vasc/impl/serv5/Serv5HibernateVascDataSource.java index 142bb42..9b40b3f 100644 --- a/src/com/idcanet/vasc/impl/serv5/Serv5HibernateVascDataSource.java +++ b/src/com/idcanet/vasc/impl/serv5/Serv5HibernateVascDataSource.java @@ -27,13 +27,11 @@ package com.idcanet.vasc.impl.serv5; import java.util.List; -import java.util.logging.Level; import org.hibernate.Query; import com.idcanet.serv5.services.hibernate3.Hibernate3Factory; import com.idcanet.vasc.core.AbstractVascDataSource; -import com.idcanet.vasc.core.VascDataSource; import com.idcanet.xtes.xpql.query.QueryParameterValue; /** @@ -55,6 +53,7 @@ public class Serv5HibernateVascDataSource extends AbstractVascDataSource { setQuery(query); } + @SuppressWarnings("unchecked") public List execute() throws Exception { try { Query q = Hibernate3Factory.getSession(getSession()).createQuery(query.toPreparedSQL(query)); @@ -66,7 +65,7 @@ public class Serv5HibernateVascDataSource extends AbstractVascDataSource { q.setParameter(i,value.getValue()); i++; } - List data = q.list(); + List data = q.list(); //logger.fine("Query returned: "+data.size()+" of: "+crudTable.getQueryName()); return data; } finally { diff --git a/src/com/idcanet/vasc/impl/swing/SwingVascViewRenderer.java b/src/com/idcanet/vasc/impl/swing/SwingVascViewRenderer.java index 68ee086..5aa51b2 100644 --- a/src/com/idcanet/vasc/impl/swing/SwingVascViewRenderer.java +++ b/src/com/idcanet/vasc/impl/swing/SwingVascViewRenderer.java @@ -35,6 +35,8 @@ import java.awt.Image; import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.io.FileOutputStream; import java.io.OutputStream; import java.util.ArrayList; @@ -73,6 +75,7 @@ import com.idcanet.vasc.core.VascViewRenderer; import com.idcanet.vasc.core.actions.GlobalVascAction; import com.idcanet.vasc.core.actions.RowVascAction; import com.idcanet.vasc.core.column.VascTableColumn; +import com.idcanet.vasc.core.ui.VascColorChooser; import com.idcanet.vasc.core.ui.VascColumnValueModelListener; import com.idcanet.vasc.core.ui.VascDate; import com.idcanet.vasc.core.ui.VascList; @@ -80,6 +83,7 @@ import com.idcanet.vasc.core.ui.VascTextField; import com.idcanet.vasc.core.ui.VascToggle; import com.idcanet.vasc.core.ui.VascUIComponent; import com.idcanet.vasc.core.ui.VascValueModel; +import com.idcanet.vasc.impl.swing.ui.SwingColorChooser; import com.idcanet.vasc.impl.swing.ui.SwingDate; import com.idcanet.vasc.impl.swing.ui.SwingList; import com.idcanet.vasc.impl.swing.ui.SwingTextField; @@ -117,6 +121,7 @@ public class SwingVascViewRenderer implements VascViewRenderer { table.putUIComponent(VascList.class, SwingList.class); table.putUIComponent(VascToggle.class, SwingToggle.class); table.putUIComponent(VascDate.class, SwingDate.class); + table.putUIComponent(VascColorChooser.class, SwingColorChooser.class); this.table=table; } @@ -141,7 +146,7 @@ public class SwingVascViewRenderer implements VascViewRenderer { */ public void renderEdit(Object rowBean) throws Exception { logger.fine("Rending Edit View"); - table.getVascTableController().initEditObject(table, rowBean); + rowBean = table.getVascTableController().initEditObject(table, rowBean); String beanValue = rowBean.toString(); if (table.getUIIdentifierVascTableColomn()!=null) { Object vv = table.getUIIdentifierVascTableColomn().getVascColumnValue().getValue(table.getUIIdentifierVascTableColomn(), rowBean); @@ -160,16 +165,7 @@ public class SwingVascViewRenderer implements VascViewRenderer { if(result==null) { return; } - try { - result = table.getVascDataSource().merge(rowBean); - } finally { - // todo: make faster - // add to table at position old old object - // then remove old object - // send refresh - - table.getVascTableController().refreshData(table); - } + table.getVascTableController().mergeObject(table, result); } public void renderDelete(Object rowBean) throws Exception { @@ -455,8 +451,17 @@ public class SwingVascViewRenderer implements VascViewRenderer { VascColumnModel model = new VascColumnModel(); table.getVascTableController().addEventListener(model); - JTable jTable = new JTable(model); - + JTable jTable = new JTable(); + //TODO: remove this extra model for sorting, AND fixup a real sorting stuff + TableSorter tableSorter = new TableSorter(); + // this regs the listeners for the sorting + tableSorter.setTableHeader(jTable.getTableHeader()); + tableSorter.setTableModel(model); + + + jTable.setModel(tableSorter); + jTable.getTableHeader().setReorderingAllowed(false); + // remove auto columns :( int cols = jTable.getColumnModel().getColumnCount(); for (int i=0;i list = new ArrayList(); for(VascTableColumn c:table.getTableColumns()) { if (c.isListDisplay()==false) { diff --git a/src/com/idcanet/vasc/impl/swing/TableSorter.java b/src/com/idcanet/vasc/impl/swing/TableSorter.java new file mode 100644 index 0000000..c671c96 --- /dev/null +++ b/src/com/idcanet/vasc/impl/swing/TableSorter.java @@ -0,0 +1,492 @@ +/* + * + * + * THIS FILE IS FROM: + * http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#sorting + */ + +package com.idcanet.vasc.impl.swing; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.util.List; + +import javax.swing.*; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.*; + +/** + * TableSorter is a decorator for TableModels; adding sorting + * functionality to a supplied TableModel. TableSorter does + * not store or copy the data in its TableModel; instead it maintains + * a map from the row indexes of the view to the row indexes of the + * model. As requests are made of the sorter (like getValueAt(row, col)) + * they are passed to the underlying model after the row numbers + * have been translated via the internal mapping array. This way, + * the TableSorter appears to hold another copy of the table + * with the rows in a different order. + *

+ * TableSorter registers itself as a listener to the underlying model, + * just as the JTable itself would. Events recieved from the model + * are examined, sometimes manipulated (typically widened), and then + * passed on to the TableSorter's listeners (typically the JTable). + * If a change to the model has invalidated the order of TableSorter's + * rows, a note of this is made and the sorter will resort the + * rows the next time a value is requested. + *

+ * When the tableHeader property is set, either by using the + * setTableHeader() method or the two argument constructor, the + * table header may be used as a complete UI for TableSorter. + * The default renderer of the tableHeader is decorated with a renderer + * that indicates the sorting status of each column. In addition, + * a mouse listener is installed with the following behavior: + *

    + *
  • + * Mouse-click: Clears the sorting status of all other columns + * and advances the sorting status of that column through three + * values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to + * NOT_SORTED again). + *
  • + * SHIFT-mouse-click: Clears the sorting status of all other columns + * and cycles the sorting status of the column through the same + * three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}. + *
  • + * CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except + * that the changes to the column do not cancel the statuses of columns + * that are already sorting - giving a way to initiate a compound + * sort. + *
+ *

+ * This is a long overdue rewrite of a class of the same name that + * first appeared in the swing table demos in 1997. + * + * @author Philip Milne + * @author Brendon McLean + * @author Dan van Enckevort + * @author Parwinder Sekhon + * @version 2.0 02/27/04 + */ +@SuppressWarnings("unchecked") +public class TableSorter extends AbstractTableModel { + + private static final long serialVersionUID = 10L; + protected TableModel tableModel; + + public static final int DESCENDING = -1; + public static final int NOT_SORTED = 0; + public static final int ASCENDING = 1; + + private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED); + + public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() { + public int compare(Object o1, Object o2) { + return ((Comparable) o1).compareTo(o2); + } + }; + public static final Comparator LEXICAL_COMPARATOR = new Comparator() { + public int compare(Object o1, Object o2) { + return o1.toString().compareTo(o2.toString()); + } + }; + + private Row[] viewToModel; + private int[] modelToView; + + private JTableHeader tableHeader; + private MouseListener mouseListener; + private TableModelListener tableModelListener; + private Map columnComparators = new HashMap(); + private List sortingColumns = new ArrayList(); + + public TableSorter() { + this.mouseListener = new MouseHandler(); + this.tableModelListener = new TableModelHandler(); + } + + public TableSorter(TableModel tableModel) { + this(); + setTableModel(tableModel); + } + + public TableSorter(TableModel tableModel, JTableHeader tableHeader) { + this(); + setTableHeader(tableHeader); + setTableModel(tableModel); + } + + private void clearSortingState() { + viewToModel = null; + modelToView = null; + } + + public TableModel getTableModel() { + return tableModel; + } + + public void setTableModel(TableModel tableModel) { + if (this.tableModel != null) { + this.tableModel.removeTableModelListener(tableModelListener); + } + + this.tableModel = tableModel; + if (this.tableModel != null) { + this.tableModel.addTableModelListener(tableModelListener); + } + + clearSortingState(); + fireTableStructureChanged(); + } + + public JTableHeader getTableHeader() { + return tableHeader; + } + + public void setTableHeader(JTableHeader tableHeader) { + if (this.tableHeader != null) { + this.tableHeader.removeMouseListener(mouseListener); + TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer(); + if (defaultRenderer instanceof SortableHeaderRenderer) { + this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer); + } + } + this.tableHeader = tableHeader; + if (this.tableHeader != null) { + this.tableHeader.addMouseListener(mouseListener); + this.tableHeader.setDefaultRenderer( + new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer())); + } + } + + public boolean isSorting() { + return sortingColumns.size() != 0; + } + + private Directive getDirective(int column) { + for (int i = 0; i < sortingColumns.size(); i++) { + Directive directive = (Directive)sortingColumns.get(i); + if (directive.column == column) { + return directive; + } + } + return EMPTY_DIRECTIVE; + } + + public int getSortingStatus(int column) { + return getDirective(column).direction; + } + + private void sortingStatusChanged() { + clearSortingState(); + fireTableDataChanged(); + if (tableHeader != null) { + tableHeader.repaint(); + } + } + + public void setSortingStatus(int column, int status) { + Directive directive = getDirective(column); + if (directive != EMPTY_DIRECTIVE) { + sortingColumns.remove(directive); + } + if (status != NOT_SORTED) { + sortingColumns.add(new Directive(column, status)); + } + sortingStatusChanged(); + } + + protected Icon getHeaderRendererIcon(int column, int size) { + Directive directive = getDirective(column); + if (directive == EMPTY_DIRECTIVE) { + return null; + } + return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive)); + } + + private void cancelSorting() { + sortingColumns.clear(); + sortingStatusChanged(); + } + + public void setColumnComparator(Class type, Comparator comparator) { + if (comparator == null) { + columnComparators.remove(type); + } else { + columnComparators.put(type, comparator); + } + } + + protected Comparator getComparator(int column) { + Class columnType = tableModel.getColumnClass(column); + Comparator comparator = (Comparator) columnComparators.get(columnType); + if (comparator != null) { + return comparator; + } + if (Comparable.class.isAssignableFrom(columnType)) { + return COMPARABLE_COMAPRATOR; + } + return LEXICAL_COMPARATOR; + } + + private Row[] getViewToModel() { + if (viewToModel == null) { + int tableModelRowCount = tableModel.getRowCount(); + viewToModel = new Row[tableModelRowCount]; + for (int row = 0; row < tableModelRowCount; row++) { + viewToModel[row] = new Row(row); + } + + if (isSorting()) { + Arrays.sort(viewToModel); + } + } + return viewToModel; + } + + public int modelIndex(int viewIndex) { + return getViewToModel()[viewIndex].modelIndex; + } + + private int[] getModelToView() { + if (modelToView == null) { + int n = getViewToModel().length; + modelToView = new int[n]; + for (int i = 0; i < n; i++) { + modelToView[modelIndex(i)] = i; + } + } + return modelToView; + } + + // TableModel interface methods + + public int getRowCount() { + return (tableModel == null) ? 0 : tableModel.getRowCount(); + } + + public int getColumnCount() { + return (tableModel == null) ? 0 : tableModel.getColumnCount(); + } + + public String getColumnName(int column) { + return tableModel.getColumnName(column); + } + + public Class getColumnClass(int column) { + return tableModel.getColumnClass(column); + } + + public boolean isCellEditable(int row, int column) { + return tableModel.isCellEditable(modelIndex(row), column); + } + + public Object getValueAt(int row, int column) { + return tableModel.getValueAt(modelIndex(row), column); + } + + public void setValueAt(Object aValue, int row, int column) { + tableModel.setValueAt(aValue, modelIndex(row), column); + } + + // Helper classes + + private class Row implements Comparable { + private int modelIndex; + + public Row(int index) { + this.modelIndex = index; + } + + public int compareTo(Object o) { + int row1 = modelIndex; + int row2 = ((Row) o).modelIndex; + + for (Iterator it = sortingColumns.iterator(); it.hasNext();) { + Directive directive = (Directive) it.next(); + int column = directive.column; + Object o1 = tableModel.getValueAt(row1, column); + Object o2 = tableModel.getValueAt(row2, column); + + int comparison = 0; + // Define null less than everything, except null. + if (o1 == null && o2 == null) { + comparison = 0; + } else if (o1 == null) { + comparison = -1; + } else if (o2 == null) { + comparison = 1; + } else { + comparison = getComparator(column).compare(o1, o2); + } + if (comparison != 0) { + return directive.direction == DESCENDING ? -comparison : comparison; + } + } + return 0; + } + } + + private class TableModelHandler implements TableModelListener { + public void tableChanged(TableModelEvent e) { + // If we're not sorting by anything, just pass the event along. + if (!isSorting()) { + clearSortingState(); + fireTableChanged(e); + return; + } + + // If the table structure has changed, cancel the sorting; the + // sorting columns may have been either moved or deleted from + // the model. + if (e.getFirstRow() == TableModelEvent.HEADER_ROW) { + cancelSorting(); + fireTableChanged(e); + return; + } + + // We can map a cell event through to the view without widening + // when the following conditions apply: + // + // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, + // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and, + // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and, + // d) a reverse lookup will not trigger a sort (modelToView != null) + // + // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS. + // + // The last check, for (modelToView != null) is to see if modelToView + // is already allocated. If we don't do this check; sorting can become + // a performance bottleneck for applications where cells + // change rapidly in different parts of the table. If cells + // change alternately in the sorting column and then outside of + // it this class can end up re-sorting on alternate cell updates - + // which can be a performance problem for large tables. The last + // clause avoids this problem. + int column = e.getColumn(); + if (e.getFirstRow() == e.getLastRow() + && column != TableModelEvent.ALL_COLUMNS + && getSortingStatus(column) == NOT_SORTED + && modelToView != null) { + int viewIndex = getModelToView()[e.getFirstRow()]; + fireTableChanged(new TableModelEvent(TableSorter.this, + viewIndex, viewIndex, + column, e.getType())); + return; + } + + // Something has happened to the data that may have invalidated the row order. + clearSortingState(); + fireTableDataChanged(); + return; + } + } + + private class MouseHandler extends MouseAdapter { + public void mouseClicked(MouseEvent e) { + JTableHeader h = (JTableHeader) e.getSource(); + TableColumnModel columnModel = h.getColumnModel(); + int viewColumn = columnModel.getColumnIndexAtX(e.getX()); + int column = columnModel.getColumn(viewColumn).getModelIndex(); + if (column != -1) { + int status = getSortingStatus(column); + if (!e.isControlDown()) { + cancelSorting(); + } + // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or + // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed. + status = status + (e.isShiftDown() ? -1 : 1); + status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1} + setSortingStatus(column, status); + } + } + } + + private static class Arrow implements Icon { + private boolean descending; + private int size; + private int priority; + + public Arrow(boolean descending, int size, int priority) { + this.descending = descending; + this.size = size; + this.priority = priority; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Color color = c == null ? Color.GRAY : c.getBackground(); + // In a compound sort, make each succesive triangle 20% + // smaller than the previous one. + int dx = (int)(size/2*Math.pow(0.8, priority)); + int dy = descending ? dx : -dx; + // Align icon (roughly) with font baseline. + y = y + 5*size/6 + (descending ? -dy : 0); + int shift = descending ? 1 : -1; + g.translate(x, y); + + // Right diagonal. + g.setColor(color.darker()); + g.drawLine(dx / 2, dy, 0, 0); + g.drawLine(dx / 2, dy + shift, 0, shift); + + // Left diagonal. + g.setColor(color.brighter()); + g.drawLine(dx / 2, dy, dx, 0); + g.drawLine(dx / 2, dy + shift, dx, shift); + + // Horizontal line. + if (descending) { + g.setColor(color.darker().darker()); + } else { + g.setColor(color.brighter().brighter()); + } + g.drawLine(dx, 0, 0, 0); + + g.setColor(color); + g.translate(-x, -y); + } + + public int getIconWidth() { + return size; + } + + public int getIconHeight() { + return size; + } + } + + private class SortableHeaderRenderer implements TableCellRenderer { + private TableCellRenderer tableCellRenderer; + + public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) { + this.tableCellRenderer = tableCellRenderer; + } + + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + Component c = tableCellRenderer.getTableCellRendererComponent(table, + value, isSelected, hasFocus, row, column); + if (c instanceof JLabel) { + JLabel l = (JLabel) c; + l.setHorizontalTextPosition(JLabel.LEFT); + int modelColumn = table.convertColumnIndexToModel(column); + l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize())); + } + return c; + } + } + + private static class Directive { + private int column; + private int direction; + + public Directive(int column, int direction) { + this.column = column; + this.direction = direction; + } + } +} diff --git a/src/com/idcanet/vasc/impl/swing/ui/SwingColorChooser.java b/src/com/idcanet/vasc/impl/swing/ui/SwingColorChooser.java new file mode 100644 index 0000000..39722b9 --- /dev/null +++ b/src/com/idcanet/vasc/impl/swing/ui/SwingColorChooser.java @@ -0,0 +1,125 @@ +/* + * Copyright 2004-2007 IDCA. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the + * following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and + * the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions + * and the following disclaimer in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY IDCA AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL IDCA OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR + * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * The views and conclusions contained in the software and documentation are those of the authors and + * should not be interpreted as representing official policies, either expressed or implied, of IDCA. + */ + +package com.idcanet.vasc.impl.swing.ui; + +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.JComponent; + +import com.idcanet.vasc.core.VascTable; +import com.idcanet.vasc.core.ui.AbstractVascUIComponent; +import com.idcanet.vasc.core.ui.VascColorChooser; +import com.idcanet.vasc.core.ui.VascValueModel; + +/** + * + * + * @author Willem Cazander + * @version 1.0 Nov 25, 2007 + */ +public class SwingColorChooser extends AbstractVascUIComponent { + + private JButton colorButton = null; + private Color orgBackgroundColor = null; + + public Object createComponent(VascTable table,VascValueModel model,Object gui) throws Exception { + + + VascColorChooser org = (VascColorChooser)getWrapper(); + + JButton colorButton = new JButton("Color"); + orgBackgroundColor = colorButton.getBackground(); + ((JComponent)gui).add(colorButton); + colorButton.addActionListener(new SelectActionListener3(model,org.getHexSwingEncoding())); + return colorButton; + } + + /** + * @see com.idcanet.vasc.core.ui.VascUIComponent#getErrorText() + */ + public String getErrorText() { + if (colorButton==null) { + return null; + } + return colorButton.getToolTipText(); + } + + /** + * @see com.idcanet.vasc.core.ui.VascUIComponent#setErrorText(java.lang.String) + */ + public void setErrorText(String text) { + if (colorButton==null) { + return; + } + colorButton.setToolTipText(text); + if (text==null) { + colorButton.setBackground(orgBackgroundColor); + } else { + colorButton.setBackground(Color.RED); + } + } +} +class SelectActionListener3 implements ActionListener { + + private VascValueModel model; + private boolean hexEncoding = false; + public SelectActionListener3(VascValueModel model,boolean hexEncoding) { + this.model=model; + this.hexEncoding=hexEncoding; + } + + /** + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + public void actionPerformed(ActionEvent e) { + if (hexEncoding==false) { + Color cur = (Color)model.getValue(); + if (cur==null) { + cur = Color.YELLOW; + } + Color newColor = JColorChooser.showDialog(null,"Choose a color...",cur); + model.setValue(newColor); + } else { + String cur = (String)model.getValue(); + Color c = Color.YELLOW; + try { + if (cur!=null) { + c = Color.decode(cur); + } + Color newColor = JColorChooser.showDialog(null,"Choose a color...",c); + String newColorString = "#"+Integer.toHexString( newColor.getRGB() & 0x00ffffff ); + model.setValue(newColorString); + } catch (Exception ee) { + + } + } + } +} \ No newline at end of file diff --git a/src/com/idcanet/vasc/impl/swt/SwtVascViewRenderer.java b/src/com/idcanet/vasc/impl/swt/SwtVascViewRenderer.java index 66f2b98..a9fd355 100644 --- a/src/com/idcanet/vasc/impl/swt/SwtVascViewRenderer.java +++ b/src/com/idcanet/vasc/impl/swt/SwtVascViewRenderer.java @@ -66,7 +66,6 @@ import org.eclipse.swt.widgets.ToolItem; import com.idcanet.fff.SwingImageHelper; import com.idcanet.vasc.core.VascDataExporter; import com.idcanet.vasc.core.VascTable; -import com.idcanet.vasc.core.VascUserOption; import com.idcanet.vasc.core.VascViewRenderer; import com.idcanet.vasc.core.actions.GlobalVascAction; import com.idcanet.vasc.core.actions.RowVascAction; @@ -189,14 +188,14 @@ public class SwtVascViewRenderer implements VascViewRenderer { public class SwtVascEditDialog extends Dialog { private Shell shell = null; - private String headerText = null; + //private String headerText = null; private String title = null; private Object result = null; private Object bean = null; public SwtVascEditDialog (Shell parent,VascTable table,Object bean,String title,String headerText) { super (parent, 0); - this.headerText = headerText; + ///this.headerText = headerText; this.title = title; this.bean = bean; } @@ -445,7 +444,7 @@ public class SwtVascViewRenderer implements VascViewRenderer { } // create options - for(VascUserOption option:table.getUserOptions()) { + //for(VascUserOption option:table.getUserOptions()) { /* if(option.getLabelText()!=null) { @@ -461,7 +460,7 @@ public class SwtVascViewRenderer implements VascViewRenderer { cpo.getValueHolder().addPropertyChangeListener(this); */ - } + //} } class GlobalActionListener extends SelectionAdapter { diff --git a/tests/META-INF/vasc-lang.eld b/tests/META-INF/vasc-lang.eld new file mode 100644 index 0000000..c19c954 --- /dev/null +++ b/tests/META-INF/vasc-lang.eld @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/tests/META-INF/vasc-namespaces.xml b/tests/META-INF/vasc-namespaces.xml new file mode 100644 index 0000000..01ac3aa --- /dev/null +++ b/tests/META-INF/vasc-namespaces.xml @@ -0,0 +1,8 @@ + + + + + Vasc namespace for x4o vasc state/table/column language + + META-INF/vasc-lang.eld + \ No newline at end of file diff --git a/tests/com/idcanet/vasc/TestTable.java b/tests/com/idcanet/vasc/TestTable.java index 30b3012..e6f0971 100644 --- a/tests/com/idcanet/vasc/TestTable.java +++ b/tests/com/idcanet/vasc/TestTable.java @@ -31,11 +31,11 @@ import java.util.Date; import com.idcanet.vasc.core.VascTable; import com.idcanet.vasc.core.column.VascAnnotationTableColumn; import com.idcanet.vasc.core.column.VascTableColumn; +import com.idcanet.vasc.core.ui.VascColorChooser; import com.idcanet.vasc.core.ui.VascList; import com.idcanet.vasc.core.ui.VascTextField; import com.idcanet.vasc.impl.BeanVascRecordCreator; import com.idcanet.vasc.impl.DefaultVascTableController; -import com.idcanet.vasc.impl.DefaultVascTextValue; import com.idcanet.vasc.impl.actions.AddRowAction; import com.idcanet.vasc.impl.actions.CSVExportGlobalAction; import com.idcanet.vasc.impl.actions.DeleteRowAction; @@ -44,9 +44,6 @@ import com.idcanet.vasc.impl.actions.RefreshDataGlobalAction; import com.idcanet.vasc.impl.actions.XMLExportGlobalAction; import com.idcanet.vasc.impl.column.BeanPropertyVascColumnValue; import com.idcanet.vasc.models.TestModel; -import com.idcanet.xtes.core.TemplateStore; -import com.idcanet.xtes.core.XTESParser; -import com.idcanet.xtes.xpql.query.Query; /** @@ -122,9 +119,16 @@ public class TestTable { VascList list = new VascList(); list.setVascSelectItemModel(data); column.setVascUIComponent(list); - - table.addTableColumns(column); + + + column = new VascAnnotationTableColumn("hexColor"); + column.setDefaultValue("#FF3355"); + VascColorChooser ui = new VascColorChooser(); + ui.setHexSwingEncoding(true); + column.setVascUIComponent(ui); + table.addTableColumns(column); + return table; } diff --git a/tests/com/idcanet/vasc/models/TestModel.java b/tests/com/idcanet/vasc/models/TestModel.java index 2a4341a..8640982 100644 --- a/tests/com/idcanet/vasc/models/TestModel.java +++ b/tests/com/idcanet/vasc/models/TestModel.java @@ -56,6 +56,7 @@ public class TestModel { private Boolean active = null; private Date date = null; private TestModel testModel = null; + private String hexColor = null; /** * @return the date @@ -146,7 +147,18 @@ public class TestModel { public void setActive(Boolean active) { this.active = active; } - - - + + /** + * @return the hexColor + */ + public String getHexColor() { + return hexColor; + } + + /** + * @param hexColor the hexColor to set + */ + public void setHexColor(String hexColor) { + this.hexColor = hexColor; + } } \ No newline at end of file