Jaxx-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
April 2009
- 3 participants
- 92 discussions
[Buix-commits] r1294 - jaxx/trunk/jaxx-example/src/main/java/jaxx/demo
by tchemit@users.labs.libre-entreprise.org 04 Apr '09
by tchemit@users.labs.libre-entreprise.org 04 Apr '09
04 Apr '09
Author: tchemit
Date: 2009-04-04 17:19:47 +0000 (Sat, 04 Apr 2009)
New Revision: 1294
Modified:
jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx
jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx
Log:
revert modification gwt package does not exist :)
Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx
===================================================================
--- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-04-04 17:09:45 UTC (rev 1293)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-04-04 17:19:47 UTC (rev 1294)
@@ -12,22 +12,24 @@
<Identity id='identity'/>
<!-- errors model -->
- <jaxx.runtime.validator.gwt.GWTValidatorMessageListModel id='errors'
- onContentsChanged='ok.setEnabled(errors.isEmpty())'/>
+ <!-- Not existing :) -->
+ <!--jaxx.runtime.validator.gwt.GWTValidatorMessageListModel id='errors'-->
+ <jaxx.runtime.validator.swing.SwingValidatorMessageListModel id='errors'
+ onContentsChanged='ok.setEnabled(errors.isEmpty())'/>
<!-- validators -->
- <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.gwt.ui.ImageValidationUI">
+ <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.swing.ui.ImageValidationUI">
<field name="text"/>
<field name="text2"/>
<field name="ratio"/>
</BeanValidator>
- <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.gwt.ui.IconValidationUI">
+ <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.swing.ui.IconValidationUI">
<field name="text" component="_text"/>
<field name="text2" component="_text2"/>
<field name="ratio" component="_ratio"/>
</BeanValidator>
<BeanValidator id='validator3' autoField='true' bean='identity'
- uiClass="jaxx.runtime.validator.gwt.ui.TranslucentValidationUI">
+ uiClass="jaxx.runtime.validator.swing.ui.TranslucentValidationUI">
<field name="email" component="email2"/>
</BeanValidator>
@@ -320,4 +322,4 @@
</row>
</Table>
-</DemoPanel>
+</DemoPanel>
Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx
===================================================================
--- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-04-04 17:09:45 UTC (rev 1293)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-04-04 17:19:47 UTC (rev 1294)
@@ -7,22 +7,24 @@
<Identity id='identity'/>
<!-- errors model -->
- <jaxx.runtime.validator.gwt.GWTValidatorMessageTableModel id='errors2'
- onTableChanged='ok.setEnabled(errors2.getRowCount()==0)'/>
+ <!-- Not existing :) -->
+ <!--jaxx.runtime.validator.gwt.GWTValidatorMessageTableModel id='errors2'/-->
+ <jaxx.runtime.validator.swing.SwingValidatorMessageTableModel id='errors2'
+ onTableChanged='ok.setEnabled(errors2.getRowCount()==0)'/>
<!-- validators -->
- <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.gwt.ui.ImageValidationUI">
+ <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.swing.ui.ImageValidationUI">
<field name="text"/>
<field name="text2"/>
<field name="ratio"/>
</BeanValidator>
- <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.gwt.ui.IconValidationUI">
+ <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.swing.ui.IconValidationUI">
<field name="text" component="_text"/>
<field name="text2" component="_text2"/>
<field name="ratio" component="_ratio"/>
</BeanValidator>
<BeanValidator id='validator3' autoField='true' bean='identity'
- uiClass="jaxx.runtime.validator.gwt.ui.TranslucentValidationUI">
+ uiClass="jaxx.runtime.validator.swing.ui.TranslucentValidationUI">
<field name="email" component="email2"/>
</BeanValidator>
1
0
[Buix-commits] r1293 - jaxx/trunk/jaxx-example/src/main/java/jaxx/demo
by tchemit@users.labs.libre-entreprise.org 04 Apr '09
by tchemit@users.labs.libre-entreprise.org 04 Apr '09
04 Apr '09
Author: tchemit
Date: 2009-04-04 17:09:45 +0000 (Sat, 04 Apr 2009)
New Revision: 1293
Modified:
jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx
Log:
little works :) see in changelog ...
Modified: jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx
===================================================================
--- jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-04-04 17:08:37 UTC (rev 1292)
+++ jaxx/trunk/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-04-04 17:09:45 UTC (rev 1293)
@@ -31,10 +31,7 @@
import jaxx.runtime.SwingUtil;
void $afterCompleteSetup() {
- errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.gwt.SwingValidatorMessageTableRenderer());
- errorTable.getRowSorter().setSortKeys(java.util.Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
- SwingUtil.setI18nTableHeaderRenderer(errorTable, n_("validator.scope"), n_("validator.scope.tip"), n_("validator.field"), n_("validator.field.tip"), n_("validator.message"), n_("validator.message.tip"));
- SwingUtil.fixTableColumnWidth(errorTable, 0, 25);
+ jaxx.runtime.SwingValidatorUtil.installUI(errorTable, new jaxx.runtime.validator.swing.SwingValidatorMessageTableRenderer());
}
]]></script>
@@ -329,4 +326,4 @@
</row>
</Table>
-</DemoPanel>
+</DemoPanel>
1
0
[Buix-commits] r1292 - in jaxx/trunk: . jaxx-example/src/main/resources/i18n jaxx-runtime-swing jaxx-runtime-swing/src/main/java/jaxx/runtime jaxx-runtime-swing/src/main/java/jaxx/runtime/swing jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation
by tchemit@users.labs.libre-entreprise.org 04 Apr '09
by tchemit@users.labs.libre-entreprise.org 04 Apr '09
04 Apr '09
Author: tchemit
Date: 2009-04-04 17:08:37 +0000 (Sat, 04 Apr 2009)
New Revision: 1292
Added:
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandler.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandlerWithCardLayout.java
Modified:
jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties
jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties
jaxx/trunk/jaxx-runtime-swing/changelog.txt
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JaxxHelpBroker.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java
jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java
jaxx/trunk/pom.xml
Log:
little works :) see in changelog ...
Modified: jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties 2009-04-04 17:05:55 UTC (rev 1291)
+++ jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-en_GB.properties 2009-04-04 17:08:37 UTC (rev 1292)
@@ -108,10 +108,13 @@
no\ layer=
valid=
validator.field=Champ
+validator.field.header.tip=
validator.field.tip=
validator.message=Message
+validator.message.header.tip=
validator.message.tip=
validator.scope=...
+validator.scope.header.tip=
validator.scope.tip=
with\ layer=
x=
Modified: jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties
===================================================================
--- jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties 2009-04-04 17:05:55 UTC (rev 1291)
+++ jaxx/trunk/jaxx-example/src/main/resources/i18n/jaxx-example-fr_FR.properties 2009-04-04 17:08:37 UTC (rev 1292)
@@ -107,11 +107,11 @@
form2.text2=Form2 \: text2
no\ layer=
valid=
-validator.field=Champ
-validator.field.tip=
-validator.message=Message
-validator.message.tip=
-validator.scope=...
-validator.scope.tip=
+validator.field=
+validator.field.header.tip=
+validator.message=
+validator.message.header.tip=
+validator.scope=
+validator.scope.header.tip=
with\ layer=
x=
Modified: jaxx/trunk/jaxx-runtime-swing/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-04-04 17:05:55 UTC (rev 1291)
+++ jaxx/trunk/jaxx-runtime-swing/changelog.txt 2009-04-04 17:08:37 UTC (rev 1292)
@@ -1,4 +1,5 @@
1.3 chemit 20090321
+ * 20090404 [chemit] - introduce dimension factory in SwingUtil for min and max dimensions
* 20090327 [chemit] - add javax help mecanism
* 20090318 [chemit] - introduce the BlockingLayerUI2 class (should be merge with BlockingLayerUI)
* 20090318 [chemit] - introduce the CardLayout2Ext class
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java 2009-04-04 17:05:55 UTC (rev 1291)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/SwingUtil.java 2009-04-04 17:08:37 UTC (rev 1292)
@@ -3,6 +3,7 @@
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
+import java.awt.Dimension;
import java.awt.Rectangle;
import java.beans.BeanInfo;
import java.beans.IntrospectionException;
@@ -35,6 +36,8 @@
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
+import javax.swing.JLayeredPane;
+import javax.swing.JRootPane;
import javax.swing.JTabbedPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
@@ -62,6 +65,22 @@
public static final String ICON_PREFIX = "icon.";
public static final String COLOR_PREFIX = "color.";
+ public static Dimension newMinDimension() {
+ return new Dimension(0, 0);
+ }
+
+ public static Dimension newMaxXDimension() {
+ return new Dimension(Short.MAX_VALUE, 0);
+ }
+
+ public static Dimension newMaxYDimension() {
+ return new Dimension(0, Short.MAX_VALUE);
+ }
+
+ public static Dimension newMaxXYDimension() {
+ return new Dimension(Short.MAX_VALUE, Short.MAX_VALUE);
+ }
+
public static void setText(final JTextComponent c, final String text) {
try {
// AbstractDocument deadlocks if we try to acquire a write lock while a read lock is held by the current thread
@@ -205,6 +224,7 @@
return result;
}
+ @SuppressWarnings("unchecked")
public static JXLayer<JComponent> getLayer(JComponent comp) {
if (!isLayered(comp)) {
return null;
@@ -470,7 +490,7 @@
icon = (Icon) iconKey;
} else if (iconKey instanceof String) {
icon = jaxx.runtime.Util.getUIManagerActionIcon((String) iconKey);
- }
+ }
JLabel result;
if (icon == null) {
result = new JLabel(text, aligment);
@@ -479,4 +499,97 @@
}
return result;
}
+
+ /**
+ * Gets the higest visible component in a ancestor hierarchy at
+ * specific x,y coordinates
+ * @param parent
+ * @param x
+ * @param y
+ * @return
+ */
+ public static Component getDeepestObjectAt(Component parent, int x, int y) {
+
+ if (parent instanceof Container) {
+ Container cont = (Container) parent;
+ // use a copy of 1.3 Container.findComponentAt
+ Component child = findComponentAt(cont, cont.getWidth(), cont.getHeight(), x, y);
+ if (child != null && child != cont) {
+ //log.info("child find : " + child.getName());
+ if (child instanceof JRootPane) {
+ JLayeredPane lp = ((JRootPane) child).getLayeredPane();
+ Rectangle b = lp.getBounds();
+ child = getDeepestObjectAt(lp, x - b.x, y - b.y);
+ }
+ if (child != null) {
+ return child;
+ }
+ }
+ }
+ // if the parent is not a Container then it might be a MenuItem.
+ // But even if it isn't a MenuItem just return the parent because
+ // that's a close as we can come.
+ return parent;
+ }
+
+ public static Component findComponentAt(Container cont, int width, int height, int x, int y) {
+ //log.info("container : " + cont.getName());
+ synchronized (cont.getTreeLock()) {
+
+ if (!((x >= 0) && (x < width) && (y >= 0) && (y < height) && cont.isVisible() && cont.isEnabled())) {
+ return null;
+ }
+
+ Component[] component = cont.getComponents();
+ int ncomponents = cont.getComponentCount();
+
+ // Two passes: see comment in sun.awt.SunGraphicsCallback
+ for (int i = 0; i < ncomponents; i++) {
+ Component comp = component[i];
+ Rectangle rect = null;
+
+ if (comp != null && !comp.isLightweight()) {
+ if (rect == null || rect.width == 0 || rect.height == 0) {
+ rect = comp.getBounds();
+ }
+ if (comp instanceof JXLayer) {
+ JXLayer layer = (JXLayer) comp;
+ comp = layer.getView();
+ }
+ if (comp instanceof Container) {
+ comp = findComponentAt((Container) comp, rect.width, rect.height, x - rect.x, y - rect.y);
+ } else {
+ comp = comp.getComponentAt(x - rect.x, y - rect.y);
+ }
+ if (comp != null && comp.isVisible() && comp.isEnabled()) {
+ return comp;
+ }
+ }
+ }
+
+ for (int i = 0; i < ncomponents; i++) {
+ Component comp = component[i];
+ Rectangle rect = null;
+
+ if (comp != null && comp.isLightweight()) {
+ if (rect == null || rect.width == 0 || rect.height == 0) {
+ rect = comp.getBounds();
+ }
+ if (comp instanceof JXLayer) {
+ JXLayer layer = (JXLayer) comp;
+ comp = layer.getView();
+ }
+ if (comp instanceof Container) {
+ comp = findComponentAt((Container) comp, rect.width, rect.height, x - rect.x, y - rect.y);
+ } else {
+ comp = comp.getComponentAt(x - rect.x, y - rect.y);
+ }
+ if (comp != null && comp.isVisible() && comp.isEnabled()) {
+ return comp;
+ }
+ }
+ }
+ return cont;
+ }
+ }
}
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JaxxHelpBroker.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JaxxHelpBroker.java 2009-04-04 17:05:55 UTC (rev 1291)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JaxxHelpBroker.java 2009-04-04 17:08:37 UTC (rev 1292)
@@ -2,6 +2,7 @@
import java.applet.Applet;
import java.awt.*;
+import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
@@ -9,19 +10,16 @@
import java.net.URL;
import java.util.Enumeration;
import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
import java.util.Vector;
import javax.help.CSH;
-import javax.help.CSH.DisplayHelpFromSource;
import javax.help.HelpBroker;
import javax.help.HelpSet;
import javax.swing.AbstractButton;
-import javax.swing.JComponent;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import jaxx.runtime.JAXXContext;
import jaxx.runtime.JAXXObject;
+import jaxx.runtime.SwingUtil;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -43,7 +41,6 @@
// Main HelpSet & Broker
protected final HelpSet helpset;
protected final HelpBroker helpBroker;
- protected ActionListener showHelpAction;
protected Hashtable<Component, Cursor> cursors;
protected Cursor onItemCursor;
@@ -64,40 +61,34 @@
}
}
- public AbstractButton getShowHelperButton(JAXXObject c) {
- return (AbstractButton) c.getObjectById("showHelp");
- }
-
public void prepareUI(JAXXObject c) {
if (c == null) {
throw new NullPointerException("parameter c can not be null!");
}
// l'ui doit avoir un boutton showHelp
- AbstractButton help = getShowHelperButton(c);
+ AbstractButton help = getShowHelpButton(c);
if (help == null) {
- log.warn("no showButton detected for " + c.getClass());
+ if (log.isDebugEnabled()) {
+ log.debug("no showButton detected for " + c.getClass());
+ }
} else {
- boolean needListener = true;
- for (ActionListener a : help.getActionListeners()) {
- if (a instanceof DisplayHelpFromSource) {
- needListener = false;
- break;
- }
+
+ // attach context to button
+ help.putClientProperty(JAXX_CONTEXT_ENTRY, c.getDelegateContext());
+
+ // add tracking action
+ ActionListener listener = getShowHelpAction();
+ if (log.isDebugEnabled()) {
+ log.debug("adding tracking action " + listener);
}
- if (needListener) {
- // attach context to button
- help.putClientProperty(JAXX_CONTEXT_ENTRY, c.getDelegateContext());
- help.addActionListener(getShowHelpAction(c));
- }
+ help.addActionListener(listener);
}
if (log.isDebugEnabled()) {
- log.debug("for " + c);
+ log.debug("done for " + c);
}
-
- //installUI(c, new java.util.ArrayList<String>());
}
public HelpBroker getHelpBroker() {
@@ -132,141 +123,72 @@
CSH.setHelpIDString(comp, helpId);
}
- protected void installUI(Object comp, List<String> scanned) {
- //log.info(comp);
- if (comp instanceof JComponent) {
- JComponent c = (JComponent) comp;
- if (scanned.contains(c.getName())) {
- return;
- } else {
- scanned.add(c.getName());
- }
- Object id = c.getClientProperty(helpKey);
- if (id != null && id instanceof String) {
- String helpId = (String) id;
+ public class ShowHelpForTrackedComponentAction implements ActionListener {
- CSH.setHelpIDString(c, helpId);
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ AbstractButton source = (AbstractButton) e.getSource();
- log.info(c.getName() + " : " + helpId);
+ JAXXContext context = (JAXXContext) source.getClientProperty(JAXX_CONTEXT_ENTRY);
- if (log.isDebugEnabled()) {
- log.debug(c.getName() + " : " + helpId);
+ // prepare cursor
+ onItemCursor = (Cursor) UIManager.get("HelpOnItemCursor");
+ Vector topComponents = null;
+ cursors = null;
+ if (onItemCursor != null) {
+ cursors = new Hashtable<Component, Cursor>();
+ topComponents = getTopContainers(source);
+ Enumeration enums = topComponents.elements();
+ while (enums.hasMoreElements()) {
+ setAndStoreCursors((Container) enums.nextElement(), onItemCursor);
}
}
- }
- if (comp instanceof JAXXObject) {
- JAXXObject jo = (JAXXObject) comp;
-
-
- Map<String, Object> $objectMap = jo.get$objectMap();
- for (String key : $objectMap.keySet()) {
-
- if (scanned.contains(key)) {
- continue;
+ // get the tracked component
+ Component comp = null;
+ try {
+ MouseEvent event = getMouseEvent();
+ if (event == null) {
+ // tracking canceled
+ return;
}
-
- Object o = $objectMap.get(key);
-
- if (o == comp) {
- continue;
+ comp = (Component) event.getSource();
+ if (log.isDebugEnabled()) {
+ log.debug("component traking " + comp.getName() + " : " + comp.getClass().getName());
}
-
- if (o instanceof JAXXObject) {
- installUI(o, scanned);
- scanned.add(key);
- continue;
+ comp = SwingUtil.getDeepestObjectAt(comp, event.getX(), event.getY());
+ if (log.isDebugEnabled()) {
+ log.debug("deepest component " + comp.getName() + " : " + comp.getClass().getName());
}
- if (o instanceof JComponent) {
- installUI(o, scanned);
- continue;
+ } finally {
+ // restore the old cursors
+ if (topComponents != null) {
+ Enumeration containers = topComponents.elements();
+ while (containers.hasMoreElements()) {
+ resetAndRestoreCursors((Container) containers.nextElement());
+ }
}
+ cursors = null;
}
- }
- }
- protected ActionListener getShowHelpAction(JAXXContext context) {
- if (showHelpAction == null) {
- showHelpAction = addShowHelpAction(context);
+ String helpID = CSH.getHelpIDString(comp);
+
+ showHelp(context, helpID);
}
- return showHelpAction;
}
- protected ActionListener addShowHelpAction(JAXXContext context) {
- return new CSH.DisplayHelpAfterTracking(helpBroker);
+ protected AbstractButton getShowHelpButton(JAXXObject c) {
+ return (AbstractButton) c.getObjectById("showHelp");
}
- protected String getHelpID(Component source) {
- String helpID = null;
-
- // It is necessery for UIManager.get("HelpOnItemCursor");
-
- // Get the onItemCursor
- onItemCursor = (Cursor) UIManager.get("HelpOnItemCursor");
- if (onItemCursor == null) {
- return null;
- }
-
- // change all the cursors on all windows
- Vector topComponents = null;
- cursors = null;
-
- if (onItemCursor != null) {
- cursors = new Hashtable<Component, Cursor>();
- topComponents = getTopContainers(source);
- Enumeration enums = topComponents.elements();
- while (enums.hasMoreElements()) {
- setAndStoreCursors((Container) enums.nextElement(), onItemCursor);
- }
- }
- /*MouseEvent event = getMouseEvent();
-
- if (event != null) {
- Component comp = (Component)event.getSource();
- log.info("component traking!!!!!!!! " + comp.getName()+" : "+comp.getClass().getName());
- }*/
-
-
- Object o = CSH.trackCSEvents();
-
- if (o instanceof Component) {
-
- helpID = CSH.getHelpIDString((Component) o);
-
- log.info("component traking " + ((Component) o).getName() + " : " + helpID);
-
- if (log.isDebugEnabled()) {
- log.debug("component traking " + ((Component) o).getName() + " : " + helpID);
- }
- }
-
- /*HelpSet objHS = getHelpset();
- try {
- ID id = ID.create(helpID, objHS);
- if (id == null) {
- id = objHS.getHomeID();
- }
-
- } catch (Exception e2) {
- e2.printStackTrace();
- }
- if (helpID == null) {
- helpID = getDefaultID();
- }*/
-
- // restore the old cursors
- if (topComponents != null) {
- Enumeration containers = topComponents.elements();
- while (containers.hasMoreElements()) {
- resetAndRestoreCursors((Container) containers.nextElement());
- }
- }
- cursors = null;
-
- return helpID;
+ protected ActionListener getShowHelpAction() {
+ return new ShowHelpForTrackedComponentAction();
}
+ //-------------------------------------------------------------------------
+ //--- Copy CSH code but with accessible modifiers and little improvments
+ //-------------------------------------------------------------------------
/*
* Get all top level containers to change it's cursors
*/
@@ -332,7 +254,6 @@
return null;
}
-
/*
* Set the cursor for a component and its children.
* Store the old cursors for future resetting
@@ -432,7 +353,9 @@
// can't call eq.dispatchEvent
// so I pasted it's body here
- // debug(event);
+ if (log.isDebugEnabled()) {
+ log.debug(event);
+ }
// Not sure if I should suppress ActiveEvents or not
// Modal dialogs do. For now we will not suppress the
@@ -460,9 +383,22 @@
} else if (event instanceof MouseEvent) {
MouseEvent e = (MouseEvent) event;
int eID = e.getID();
+
if ((eID == MouseEvent.MOUSE_CLICKED ||
eID == MouseEvent.MOUSE_PRESSED ||
eID == MouseEvent.MOUSE_RELEASED) &&
+ SwingUtilities.isRightMouseButton(e)) {
+ // cancel tracking
+ e.consume();
+ if (log.isDebugEnabled()) {
+ log.debug("tracking canceled!!!");
+ }
+ return null;
+ }
+
+ if ((eID == MouseEvent.MOUSE_CLICKED ||
+ eID == MouseEvent.MOUSE_PRESSED ||
+ eID == MouseEvent.MOUSE_RELEASED) &&
SwingUtilities.isLeftMouseButton(e)) {
if (eID == MouseEvent.MOUSE_CLICKED) {
if (eventNumber == 0) {
@@ -483,14 +419,18 @@
((InputEvent) event).consume();
}
} else {
- System.err.println("unable to dispatch event: " + event);
+ log.error("unable to dispatch event: " + event);
}
}
}
} catch (InterruptedException e) {
- log.debug(e);
+ if (log.isDebugEnabled()) {
+ log.debug(e);
+ }
}
- log.debug("Fall Through code");
+ if (log.isDebugEnabled()) {
+ log.debug("Fall Through code");
+ }
return null;
}
@@ -504,7 +444,7 @@
} else if (src instanceof MenuComponent) {
((MenuComponent) src).dispatchEvent(event);
} else {
- System.err.println("unable to dispatch event: " + event);
+ log.error("unable to dispatch event: " + event);
}
}
}
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandler.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandler.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandler.java 2009-04-04 17:08:37 UTC (rev 1292)
@@ -0,0 +1,249 @@
+package jaxx.runtime.swing.navigation;
+
+import java.awt.Component;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultTreeSelectionModel;
+import javax.swing.tree.TreePath;
+import jaxx.runtime.JAXXAction;
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.JAXXContextEntryDef;
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The handler of a navigation tree.
+ *
+ * This is also the selection model to use, since we must check before moving
+ * from a node we can not just listen selection model changed, we must control
+ * it.
+ *
+ *
+ * @author tony
+ * @since 1.3
+ */
+public abstract class NavigationTreeHandler extends DefaultTreeSelectionModel {
+
+ private static final long serialVersionUID = 1L;
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(NavigationTreeHandler.class);
+ static public final String NAVIGATION_SELECTED_BEAN = "navigation-selected-bean";
+ static public final JAXXContextEntryDef<String> NAVIGATION_SELECTED_PATH_ENTRY_DEF = JAXXContextEntryDef.newDef("navigation-selected-path", String.class);
+ static public final JAXXContextEntryDef<NavigationTreeNode> NAVIGATION_SELECTED_NODE_ENTRY_DEF = JAXXContextEntryDef.newDef("navigation-selected-node", NavigationTreeNode.class);
+
+ /** defined the stategy of instanciation of ui */
+ public enum Strategy {
+
+ /** instanciate a ui for a node */
+ PER_NODE,
+ /** instanciate only one a ui for a type,nodes will share the instanciation */
+ PER_UI_TYPE
+ }
+ /** la classe d'ui par defaut, associé à un noeud de l'arbe */
+ protected Class<? extends JAXXObject> defaultUIClass;
+ protected Class<? extends JAXXAction> defaultUIHandlerClass;
+ /** l'ui contenant l'arbre de navigation */
+ protected JAXXObject context;
+ protected Strategy strategy;
+
+ protected NavigationTreeHandler(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context, Strategy strategy) {
+ this.defaultUIClass = defaultUIClass;
+ this.defaultUIHandlerClass = defaultUIHandlerClass;
+ this.context = context;
+ this.strategy = strategy;
+ addTreeSelectionListener(new TreeSelectionListener() {
+
+ @Override
+ public void valueChanged(TreeSelectionEvent event) {
+ if (event.getOldLeadSelectionPath() != null && event.getOldLeadSelectionPath().equals(event.getPath())) {
+ // do not treate this if no path changed
+ return;
+ }
+ NavigationTreeNode node = (NavigationTreeNode) event.getPath().getLastPathComponent();
+ selectNodeUI(node);
+ }
+ });
+ }
+
+ protected abstract NavigationTreeModel getNavigationTreeModel();
+
+ /**
+ * @return le composent actuellement visible associé au noeud courant ou au noeud précédent
+ * lors d'un changement de noeud.
+ */
+ protected abstract Component getCurrentUI();
+
+ /**
+ * @param node le noeud associé à l'ui à retrouver
+ * @return l'ui associé au novueau noeud sélectionné
+ */
+ protected abstract Component getUI(NavigationTreeNode node);
+
+ /**
+ * @param component le composent actuellement visible
+ * @return <code>true</code> si le composent a bien été fermé, <code>false</code> sinon
+ * @throws Exception if any
+ */
+ protected abstract boolean closeUI(Component component) throws Exception;
+
+ /**
+ * Instancie une nouvelle ui associé à un noeud de l'arbre de navigation
+ *
+ * @param node le noeud associé à l'ui à créer
+ * @return la nouvelle ui associée au noeud
+ * @throws Exception if any
+ */
+ protected abstract Component createUI(NavigationTreeNode node) throws Exception;
+
+ protected abstract JAXXContext createUIContext(NavigationTreeNode node) throws Exception;
+
+ /**
+ * Ouvre l'ui associée au noeud sélectionné dans l'arbre de navigation.
+ *
+ * @param newUI l'ui associé au noeud sélectionné à ouvrir
+ * @param node le node de l'ui a ouvrir
+ * @throws Exception if any
+ */
+ protected abstract void openUI(Component newUI, NavigationTreeNode node) throws Exception;
+
+ /**
+ * Traitement des exceptions.
+ *
+ * @param e l'erreur recontrée (ou null si pas d"erreur)
+ */
+ protected abstract void treateError(Exception e);
+
+ /**
+ * Prepare le nouveau noeud sélectionné.
+ *
+ * @param node le noeud a preparer
+ * @return le noeud selectionné et preparé
+ */
+ protected NavigationTreeNode prepareNode(NavigationTreeNode node) {
+
+ if (node.getJaxxClass() == null) {
+ // no ui is associated with this node, display a empty content
+ node.setJaxxClass(defaultUIClass);
+ }
+
+ if (node.getJaxxActionClass() == null) {
+ node.setJaxxActionClass(defaultUIHandlerClass);
+ }
+ return node;
+ }
+
+ @Override
+ public void setSelectionPath(TreePath path) {
+ if (path.equals(getSelectionPath())) {
+ // stay on same node, can skip
+ if (log.isDebugEnabled()) {
+ log.debug("skip stay on path " + path);
+ }
+ return;
+ }
+ Component component = getCurrentUI();
+
+ try {
+ if (!closeUI(component)) {
+ if (log.isDebugEnabled()) {
+ log.debug("changing node canceled!");
+ }
+ // can not changed current node
+ return;
+ }
+ } catch (Exception ex) {
+ treateError(ex);
+ return;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("will select path " + path);
+ }
+ // ok can safely select the new path
+ super.setSelectionPath(path);
+ }
+
+ public void selectNodeUI(NavigationTreeNode node) {
+
+ try {
+
+ node = prepareNode(node);
+
+ String path = node.getContextPath();
+
+ if (log.isTraceEnabled()) {
+ log.trace(path);
+ }
+
+ Component newUI = getUI(node);
+
+ // now, we are free to open the ui associated with the selected node in navigation
+
+ // always clean cache on the node before all
+ node.cachedBean = null;
+ if (node.renderer != null) {
+ node.renderer.setRendererCachedValue(null);
+ }
+ // before all, attach bean in context associated with the selected node in navigation tree
+ Object data = getNavigationTreeModel().getJAXXContextValue(context, path);
+
+ addSelectedBeanInContext(node, data);
+
+ if (newUI == null) {
+ // instanciate a new ui associated with the selected node
+ newUI = createUI(node);
+ }
+
+ // save in context current node context path
+ NAVIGATION_SELECTED_PATH_ENTRY_DEF.setContextValue(context, node.getContextPath());
+
+ // save in context current node
+ NAVIGATION_SELECTED_NODE_ENTRY_DEF.setContextValue(context, node);
+
+ // really open the ui associated with the selected node
+ openUI(newUI, node);
+
+ } catch (Exception e) {
+ // remove data from context
+
+ // if any error, go back to previvous node
+ treateError(e);
+ }
+ }
+
+ protected void addSelectedBeanInContext(NavigationTreeNode node, Object data) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("find data for contextPath <" + node.getContextPath() + "> : " + (data == null ? null : data.getClass()));
+ }
+
+ context.removeContextValue(Object.class, NAVIGATION_SELECTED_BEAN);
+
+ if (data != null) {
+ context.setContextValue(data, NAVIGATION_SELECTED_BEAN);
+ //todo should we not use this to avoid conflict in context ?
+ context.setContextValue(data);
+ }
+ }
+
+ protected String getNodeConstraints(NavigationTreeNode node) {
+ String constraints;
+ switch (strategy) {
+ case PER_NODE:
+ constraints = node.getContextPath();
+ break;
+ case PER_UI_TYPE:
+ constraints = node.getJaxxClass().getName();
+ break;
+ default:
+ throw new IllegalArgumentException("could not find constraint for node : " + node);
+ }
+ return constraints;
+ }
+
+ protected JAXXAction getJAXXAction(Class<? extends JAXXAction> jaxxActionClass) throws Exception {
+ JAXXAction action = jaxxActionClass.newInstance();
+ return action;
+ }
+}
Added: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandlerWithCardLayout.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandlerWithCardLayout.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeHandlerWithCardLayout.java 2009-04-04 17:08:37 UTC (rev 1292)
@@ -0,0 +1,119 @@
+package jaxx.runtime.swing.navigation;
+
+import jaxx.runtime.JAXXAction;
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.JAXXInitialContext;
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.swing.CardLayout2;
+import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JPanel;
+import java.awt.Component;
+
+/**
+ * Simple {@link NavigationTreeSelectionAdapter} implementation with a {@link jaxx.runtime.swing.CardLayout2} to manage components to
+ * associated with tree's nodes.
+ * <p/>
+ * For each node, the ui associated has a constraints in a cardlayout which is the node context path.
+ * <p/>
+ * A single container managed by the cardlayout is used to display the components associated with tree's nodes.
+ *
+ * @author chemit
+ */
+public abstract class NavigationTreeHandlerWithCardLayout extends NavigationTreeHandler {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(NavigationTreeHandlerWithCardLayout.class);
+
+ /**
+ * All components associated with a tree's node is displayed in a single container.
+ *
+ * @return the containter of components
+ */
+ protected abstract JPanel getContentContainer();
+
+ /**
+ * the cardlayout managing components associated with tree node. The constraints
+ * of each component is the node contextPath.
+ *
+ * @return the layout used to display components associated with tree's nodes.
+ */
+ protected abstract CardLayout2 getContentLayout();
+
+ public NavigationTreeHandlerWithCardLayout(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context, Strategy strategy) {
+ super(defaultUIClass, defaultUIHandlerClass, context, strategy);
+
+ if (getContentContainer() == null) {
+ throw new IllegalArgumentException("could not have a null 'contentContainer' in ui " + context);
+ }
+ if (getContentLayout() == null) {
+ throw new IllegalArgumentException("could not have a null 'contentLayout' in ui " + context);
+ }
+ }
+
+ @Override
+ protected Component getCurrentUI() {
+ CardLayout2 layout = getContentLayout();
+ JPanel container = getContentContainer();
+ return layout.getVisibleComponent(container);
+ }
+
+ @Override
+ protected Component getUI(NavigationTreeNode node) {
+ CardLayout2 layout = getContentLayout();
+ JPanel container = getContentContainer();
+ String path = getNodeConstraints(node);
+ return layout.contains(path) ? layout.getComponent(container, path) : null;
+ }
+
+ @Override
+ protected void openUI(Component newUI, NavigationTreeNode node) throws Exception {
+
+ CardLayout2 layout = getContentLayout();
+ JPanel container = getContentContainer();
+ // switch layout
+ layout.show(container, getNodeConstraints(node));
+ }
+
+ @Override
+ protected boolean closeUI(Component component) throws Exception {
+ // by default, we says that component was succesfull closed
+ return true;
+ }
+
+ @Override
+ protected JAXXContext createUIContext(NavigationTreeNode node) throws Exception {
+
+ if (node.getJaxxActionClass() == null) {
+ if (log.isWarnEnabled()) {
+ log.warn("no action associated with ui " + node.getJaxxClass());
+ }
+ // no action associated, just
+ return context;
+ }
+
+ JAXXAction action = getJAXXAction(node.getJaxxActionClass());
+
+ // init context with
+ JAXXInitialContext uiContext = action.init(this.context);
+ return uiContext;
+ }
+
+ @Override
+ protected Component createUI(NavigationTreeNode node) throws Exception {
+
+ JAXXContext uiContext = createUIContext(node);
+
+ JAXXObject newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(uiContext);
+
+ if (log.isDebugEnabled()) {
+ log.debug("instanciate new ui " + newUI);
+ }
+
+ getContentContainer().add((Component) newUI, getNodeConstraints(node));
+ return (Component) newUI;
+ }
+}
+
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java 2009-04-04 17:05:55 UTC (rev 1291)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java 2009-04-04 17:08:37 UTC (rev 1292)
@@ -126,6 +126,7 @@
return node;
}
+ @Override
public void valueChanged(TreeSelectionEvent event) {
if (event.getOldLeadSelectionPath() != null && event.getOldLeadSelectionPath().equals(event.getPath())) {
// do not treate this if no path changed
Modified: jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java 2009-04-04 17:05:55 UTC (rev 1291)
+++ jaxx/trunk/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java 2009-04-04 17:08:37 UTC (rev 1292)
@@ -149,6 +149,11 @@
log.debug(rendererCachedValue);
}
}
+
+ public String getRendererCachedValue() {
+ return rendererCachedValue;
+ }
+
}
}
Modified: jaxx/trunk/pom.xml
===================================================================
--- jaxx/trunk/pom.xml 2009-04-04 17:05:55 UTC (rev 1291)
+++ jaxx/trunk/pom.xml 2009-04-04 17:08:37 UTC (rev 1292)
@@ -108,7 +108,8 @@
<dependency>
<groupId>com.opensymphony</groupId>
<artifactId>xwork</artifactId>
- <version>2.1.1-cl_20090130</version>
+ <version>2.1.1-cl_20081015</version>
+ <!--version>2.1.1-cl_20090130</version-->
<!--version>2.1.1</version-->
</dependency>
1
0
04 Apr '09
Author: tchemit
Date: 2009-04-04 17:05:55 +0000 (Sat, 04 Apr 2009)
New Revision: 1291
Added:
jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DataContext.java
jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DecoratorUtils.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/
jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/jaxx-runtime-validator-swing-en_GB.properties
jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/jaxx-runtime-validator-swing-fr_FR.properties
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/FieldExpressionWithParamsValidator.java
jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/
jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/jaxx-runtime-validator-en_GB.properties
jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/jaxx-runtime-validator-fr_FR.properties
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractValidatorBeanFieldValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/FieldExpressionBean.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/FieldExpressionWithParamsValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ValidatorBean.java
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/FieldExpressionBean-error-validation.xml
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/ValidatorBean-error-validation.xml
Removed:
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/ValidatorBean.java
jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml
Modified:
jaxx/trunk/jaxx-runtime-api/changelog.txt
jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/Decorator.java
jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DefaultJAXXContext.java
jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/JXPathDecorator.java
jaxx/trunk/jaxx-runtime-validator-swing/pom.xml
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/SwingValidatorUtil.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java
jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java
jaxx/trunk/jaxx-runtime-validator/changelog.txt
jaxx/trunk/jaxx-runtime-validator/pom.xml
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/BeanValidatorUtil.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java
jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidator.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/CollectionUniqueKeyValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ExistingFileFieldValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/NotExistingFileFieldValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/RequiredFileFieldValidatorTest.java
jaxx/trunk/jaxx-runtime-validator/src/test/resources/log4j.properties
jaxx/trunk/jaxx-runtime-validator/src/test/resources/validators.xml
Log:
little works :) see in changelog ...
Modified: jaxx/trunk/jaxx-runtime-api/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-api/changelog.txt 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-api/changelog.txt 2009-04-04 17:05:55 UTC (rev 1291)
@@ -1,4 +1,6 @@
1.3 chemit 20090320
+ * 20090404 [chemit] - introduce DataContext class
+ * 20090331 [chemit] - introduce DecoratorUtils class
* 20090302 [chemit] - add pcs in ApplicationContext
- add method in Util to filter JAXX property changed listeners
Added: jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DataContext.java
===================================================================
--- jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DataContext.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DataContext.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,355 @@
+package jaxx.runtime;
+
+import java.awt.Container;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.regex.Pattern;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Un contexte de données qui permet l'utilisation des bindings sur les
+ * entrées du contexte.
+ *
+ * TODO javadoc
+ *
+ * @author tony
+ * @since 1.3
+ */
+public abstract class DataContext {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(DataContext.class);
+ /** le context qui contient les données */
+ protected final DefaultJAXXContext delegate;
+ /** la definition de l'entree actuallement selectionnee */
+ protected DataContextEntry<?> currentEntry;
+ /** to manage properties modifications */
+ protected final PropertyChangeSupport pcs;
+ protected DataContextEntry<?>[] entries;
+ protected final String[] DEFAULT_JAXX_PCS;
+
+ public abstract String getContextPath(Object e);
+
+ public DataContext(String[] DEFAULT_JAXX_PCS, DataContextEntry<?>[] entries) {
+ this.DEFAULT_JAXX_PCS = DEFAULT_JAXX_PCS;
+ this.entries = entries;
+ delegate = new DefaultJAXXContext() {
+
+ @Override
+ protected void setUi(JAXXObject ui) {
+ throw new IllegalStateException("can not use this method for this type of context");
+ }
+
+ @Override
+ public <O extends Container> O getParentContainer(Class<O> clazz) {
+ throw new IllegalStateException("can not use this method for this type of context");
+ }
+
+ @Override
+ public <O extends Container> O getParentContainer(Object top, Class<O> clazz) {
+ throw new IllegalStateException("can not use this method for this type of context");
+ }
+
+ @Override
+ protected JAXXObject getUi() {
+ throw new IllegalStateException("can not use this method for this type of context");
+ }
+
+ @Override
+ protected void setParentContext(JAXXContext parentContext) {
+ throw new IllegalStateException("can not use this method for this type of context");
+ }
+
+ @Override
+ protected JAXXContext getParentContext() {
+ return null;
+ }
+ };
+ pcs = new PropertyChangeSupport(this);
+ }
+
+ public DefaultJAXXContext getDelegate() {
+ return delegate;
+ }
+
+ public Iterable<? extends DataContextEntry<?>> iterateOnAll() {
+ return new Iterable<DataContextEntry<?>>() {
+
+ @Override
+ public Iterator<DataContextEntry<?>> iterator() {
+ return new DataContextEntryIterator(entries);
+ }
+ };
+ }
+
+ public Iterable<? extends DataContextEntry<?>> iterateToLevel(final int level) {
+ return new Iterable<DataContextEntry<?>>() {
+
+ @Override
+ public Iterator<DataContextEntry<?>> iterator() {
+ return new DataContextEntryIterator(entries, level);
+ }
+ };
+ }
+
+ public Iterable<? extends DataContextEntry<?>> reverseIterateOnAll() {
+
+ return new Iterable<DataContextEntry<?>>() {
+
+ @Override
+ public Iterator<DataContextEntry<?>> iterator() {
+ return new DataContextEntryIterator(entries, true);
+ }
+ };
+ }
+
+ public DataContextEntry<?> getCurrentEntry() {
+ return currentEntry;
+ }
+
+ public DataContextEntry<?> getEntry(String path) {
+ for (DataContextEntry<?> scope : reverseIterateOnAll()) {
+ if (scope.acceptPath(path)) {
+ return scope;
+ }
+ }
+ return null;
+ }
+
+ public DataContextEntry<?> getEntry(Class<?> type) {
+ for (DataContextEntry<?> scope : iterateOnAll()) {
+ if (scope.acceptType(type)) {
+ return scope;
+ }
+ }
+ return null;
+ }
+
+ public void updateSelectedData(String path, Object data, UpdateDataContext updator) {
+
+ if (currentEntry != null) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("remove from old entry " + currentEntry);
+ }
+ for (DataContextEntry<?> s : currentEntry) {
+ if (log.isTraceEnabled()) {
+ log.trace("remove entry " + s);
+ }
+ updator.onRemovingData(delegate, s);
+ }
+ }
+
+ currentEntry = getEntry(path);
+
+ if (log.isDebugEnabled()) {
+ log.debug("new entry " + currentEntry + " for path " + path);
+ }
+
+ if (currentEntry != null) {
+
+ for (DataContextEntry<?> s : iterateToLevel(currentEntry.getLevel())) {
+
+ updator.onAddingData(delegate, s, path);
+ }
+ }
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+
+ public synchronized boolean hasListeners(String propertyName) {
+ return pcs.hasListeners(propertyName);
+ }
+
+ public synchronized PropertyChangeListener[] getPropertyChangeListeners(String propertyName) {
+ return pcs.getPropertyChangeListeners(propertyName);
+ }
+
+ public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
+ return pcs.getPropertyChangeListeners();
+ }
+
+ public void removeJaxxPropertyChangeListener() {
+ PropertyChangeListener[] toRemove = Util.findJaxxPropertyChangeListener(DEFAULT_JAXX_PCS, getPropertyChangeListeners());
+ if (toRemove == null || toRemove.length == 0) {
+ return;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("before remove : " + getPropertyChangeListeners().length);
+ log.debug("toRemove : " + toRemove.length);
+ }
+ for (PropertyChangeListener listener : toRemove) {
+ removePropertyChangeListener(listener);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("after remove : " + getPropertyChangeListeners().length);
+ }
+ }
+
+ protected void firePropertyChange(String name, Object oldValue, Object newValue) {
+ pcs.firePropertyChange(name, oldValue, newValue);
+ }
+
+ public void close() throws Exception {
+ delegate.clear();
+ }
+
+ public void clear() {
+ delegate.clear();
+ }
+
+ public static abstract class DataContextEntry<E> implements Iterable<DataContextEntry<?>> {
+
+ private final int level;
+ private final DataContextEntry<?> previous;
+ private final DataContextEntry[] parents;
+ private Class<E> klass;
+
+ public DataContextEntry(Class<E> klass, DataContextEntry<?> previous) {
+ this.previous = previous;
+ this.level = previous.level + 1;
+ this.klass = klass;
+ this.parents = new DataContextEntry[level];
+ int i = level;
+ while (i > 0) {
+ parents[--i] = previous;
+ previous = previous.previous;
+ }
+ }
+
+ public DataContextEntry(Class<E> klass) {
+ this.level = 0;
+ this.klass = klass;
+ this.previous = null;
+ this.parents = new DataContextEntry[0];
+ }
+
+ public Class<E> getKlass() {
+ return klass;
+ }
+
+ public int getLevel() {
+ return level;
+ }
+
+ public DataContextEntry[] getParents() {
+ return parents;
+ }
+
+ public abstract Pattern getPattern();
+
+ public abstract String getContextPath(Object... args);
+
+ public E getData(JAXXContext c) {
+ return c.getContextValue(klass, null);
+ }
+
+ public E getData(JAXXContext c, String context) {
+ return c.getContextValue(klass, context);
+ }
+
+ public boolean acceptPath(String path) {
+ return getPattern().matcher(path).matches();
+ }
+
+ public boolean acceptType(Class<?> type) {
+ return klass.isAssignableFrom(type);
+ }
+
+ @Override
+ public Iterator<DataContextEntry<?>> iterator() {
+ int length = parents.length;
+ DataContextEntry[] t = new DataContextEntry[length + 1];
+ System.arraycopy(parents, 0, t, 0, length);
+ t[length] = this;
+ return new DataContextEntryIterator(t, true);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "<type: " + klass.getSimpleName() + ">";
+ }
+ }
+
+ public static interface UpdateDataContext {
+
+ void onRemovingData(JAXXContext context, DataContextEntry entry);
+
+ void onAddingData(JAXXContext context, DataContextEntry entry, String path);
+ }
+
+ public static class DataContextEntryIterator implements Iterator<DataContextEntry<?>> {
+
+ protected final DataContextEntry[] datas;
+ protected final boolean reverse;
+ protected final int level;
+ protected int index;
+
+ public DataContextEntryIterator(DataContextEntry[] datas) {
+ this(datas, false, -1);
+ }
+
+ public DataContextEntryIterator(DataContextEntry[] datas, int level) {
+ this(datas, false, level);
+ }
+
+ public DataContextEntryIterator(DataContextEntry[] datas, boolean reverse) {
+ this(datas, reverse, -1);
+ }
+
+ DataContextEntryIterator(DataContextEntry[] datas, boolean reverse, int level) {
+ this.datas = datas;
+ this.reverse = reverse;
+ if (reverse) {
+ index = datas.length;
+ } else {
+ index = -1;
+ }
+ this.level = level;
+ }
+
+ @Override
+ public boolean hasNext() {
+ if (reverse) {
+ return index > 0;
+ } else {
+ return index + 1 < datas.length && (level == -1 || datas[index + 1].getLevel() <= level);
+ }
+ }
+
+ @Override
+ public DataContextEntry<?> next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ if (reverse) {
+ index--;
+ } else {
+ index++;
+ }
+ return datas[index];
+ }
+
+ @Override
+ public void remove() {
+ throw new UnsupportedOperationException("Not supported yet.");
+ }
+ }
+}
Modified: jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/Decorator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/Decorator.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/Decorator.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -3,6 +3,7 @@
/**
* A simple contract to define a String decorator on any java objet.
*
+ * @param <O> the type of decorated object
* @author chemit
*/
public abstract class Decorator<O> implements java.io.Serializable {
Added: jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DecoratorUtils.java
===================================================================
--- jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DecoratorUtils.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DecoratorUtils.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,111 @@
+package jaxx.runtime;
+
+import java.util.List;
+
+/**
+ *
+ * Some usefull methods on {@link Decorator} to store and obtain decorators.
+ *
+ * Use the method {@link #registerDecorator(String, Decorator)} to register a new
+ * decorator.
+ *
+ * Use the method {@link #getDecorator(String)} to obtain a registred
+ * decorator based on his registred name.
+ *
+ * Use the method {@link #getDecorator(Class, tring)} to obtain a registred
+ * decorator based on the type of decorator and the registred name.
+ *
+ * @author tony
+ * @since 1.3
+ */
+public class DecoratorUtils {
+
+ protected static List<DecoratorContext<?>> cache;
+
+ public static <T> void registerDecorator(String context, Decorator<T> decorator) {
+ DecoratorContext<T> result = getDecoratorContext(decorator.getInternalClass(), context);
+
+ if (result != null) {
+ throw new IllegalArgumentException("there is an already register decorator " + result);
+ }
+
+ if (cache == null) {
+ cache = new java.util.ArrayList<DecoratorContext<?>>();
+ }
+ cache.add(new DecoratorContext<T>(context, decorator));
+ }
+
+ public static <T> Decorator<T> getDecorator(String context) {
+ Decorator<T> result = getDecorator(null, context);
+ return result;
+ }
+
+ public static <T> Decorator<T> getDecorator(Class<T> type, String context) {
+ DecoratorContext<T> decoratorContext = getDecoratorContext(type, context);
+ Decorator<T> result = decoratorContext == null ? null : decoratorContext.getDecorator();
+ return result;
+ }
+
+ public static void clear() {
+ if (cache != null) {
+ cache.clear();
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ protected static <T> DecoratorContext<T> getDecoratorContext(Class<T> type, String context) {
+ DecoratorContext<T> result = null;
+ if (cache != null) {
+ for (DecoratorContext<?> d : cache) {
+ if (type == null) {
+ if (d.accept(context)) {
+ result = (DecoratorContext<T>) d;
+ break;
+ }
+ continue;
+ }
+ if (d.accept(type, context)) {
+ result = (DecoratorContext<T>) d;
+ break;
+ }
+ }
+ }
+ return result;
+ }
+
+ public static class DecoratorContext<T> {
+
+ final String context;
+ final Decorator<T> decorator;
+
+ public DecoratorContext(String context, Decorator<T> decorator) {
+ this.context = context;
+ this.decorator = decorator;
+ }
+
+ public String getContext() {
+ return context;
+ }
+
+ public Decorator<T> getDecorator() {
+ return decorator;
+ }
+
+ public Class<T> getType() {
+ return decorator.getInternalClass();
+ }
+
+ public boolean accept(Class<?> type, String context) {
+ return getType().isAssignableFrom(type) && accept(context);
+ }
+
+ public boolean accept(String context) {
+ return ((this.context == null && context == null) || (this.context != null && this.context.equals(context)));
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "<type: " + getType().getName() + ", context :" + context + ">";
+ }
+ }
+}
Modified: jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DefaultJAXXContext.java
===================================================================
--- jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DefaultJAXXContext.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/DefaultJAXXContext.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -6,6 +6,7 @@
import java.awt.Container;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
@@ -23,16 +24,12 @@
public class DefaultJAXXContext implements JAXXContext {
protected static final JAXXContextEntryDef<JAXXContext> PARENT_CONTEXT_ENTRY = newDef(JAXXContext.class);
-
/** to use log facility, just put in your code: log.info(\"...\"); */
static private final Log log = LogFactory.getLog(DefaultJAXXContext.class);
-
/** l'ui auquel est rattache le context */
protected JAXXObject ui;
-
/** le context parent */
protected JAXXContext parentContext;
-
/** les données contenues dans le context */
protected final Map<JAXXContextEntryDef, Object> data;
@@ -45,10 +42,12 @@
this.ui = ui;
}
+ @Override
public <T> void setContextValue(T o) {
setContextValue(o, null);
}
+ @Override
public <T> void setContextValue(T o, String name) {
if (name == null && PARENT_CONTEXT_ENTRY.accept2(o.getClass(), null)) {
setParentContext((JAXXContext) o);
@@ -66,11 +65,13 @@
data.put(entry, o);
}
+ @Override
public <T> T getContextValue(Class<T> clazz) {
return getContextValue(clazz, null);
}
@SuppressWarnings({"unchecked"})
+ @Override
public <T> T getContextValue(Class<T> clazz, String name) {
if (PARENT_CONTEXT_ENTRY.accept(clazz, name)) {
return (T) getParentContext();
@@ -87,28 +88,32 @@
return null;
}
- JAXXContext parentContext = getParentContext();
- if (parentContext == null) {
+ JAXXContext parent = getParentContext();
+ if (parent == null) {
// no parent context, so no value find
return null;
}
// seek in parent context
- return parentContext.getContextValue(clazz, name);
+ return parent.getContextValue(clazz, name);
}
+ @Override
public <T> void removeContextValue(Class<T> klazz) {
removeContextValue(klazz, null);
}
+ @Override
public <T> void removeContextValue(Class<T> klazz, String name) {
remove0(klazz, name);
}
+ @Override
public <O extends Container> O getParentContainer(Class<O> clazz) {
return this.getParentContainer(ui, clazz);
}
@SuppressWarnings({"unchecked"})
+ @Override
public <O extends Container> O getParentContainer(Object top, Class<O> clazz) {
if (ui == null) {
throw new IllegalStateException("no ui attached to this context");
@@ -126,6 +131,28 @@
return (O) parent;
}
+ /**
+ * Obtain all the keys of data for a given type.
+ *
+ * @param klass the type of searched keys
+ * @return the array of all names of keys for the given type of data
+ * @since 1.3
+ */
+ public String[] getKeys(Class<?> klass) {
+ List<String> keys = new java.util.ArrayList<String>();
+ for (JAXXContextEntryDef key : data.keySet()) {
+ if (key.getKlass() == klass) {
+ keys.add(key.getName());
+ }
+ }
+ return keys.toArray(new String[keys.size()]);
+
+ }
+
+ public void clear() {
+ data.clear();
+ }
+
protected JAXXObject getUi() {
return ui;
}
@@ -160,14 +187,14 @@
return null;
}
// try in parentContext
- JAXXContext parentContext = getParentContext();
+ JAXXContext parent = getParentContext();
- if (parentContext == null) {
+ if (parent == null) {
return null;
}
- if (parentContext instanceof DefaultJAXXContext) {
- return ((DefaultJAXXContext) parentContext).remove0(klazz, name);
+ if (parent instanceof DefaultJAXXContext) {
+ return ((DefaultJAXXContext) parent).remove0(klazz, name);
}
return null;
Modified: jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/JXPathDecorator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/JXPathDecorator.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-api/src/main/java/jaxx/runtime/JXPathDecorator.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -35,7 +35,6 @@
/** to use log facility, just put in your code: log.info(\"...\"); */
private static final Log log = LogFactory.getLog(JXPathDecorator.class);
-
private static final long serialVersionUID = 1L;
/**
@@ -83,7 +82,6 @@
public static class JXPathComparator<O> implements Comparator<O> {
protected Map<O, Comparable<Comparable>> valueCache;
-
private final String expression;
public JXPathComparator(String expression) {
@@ -119,12 +117,9 @@
* using using the jxpath tokens.
*/
protected String expression;
-
/** list of jxpath tokens to apply on expression */
protected String[] tokens;
-
protected transient Comparator<O> comparator;
-
private static final long serialVersionUID = 1L;
public Context(String expression, String[] tokens) {
@@ -152,25 +147,30 @@
return "<expression:" + expression + ", tokens:" + Arrays.toString(tokens) + ">";
}
}
-
/** the computed context of the decorator */
protected Context<O> context;
-
/** nb jxpath tokens to compute */
protected int nbToken;
-
/** the initial expression used to compute the decorator context. */
protected String initialExpression;
+ @Override
public String toString(Object bean) {
if (bean == null) {
return null;
}
JXPathContext jxcontext = JXPathContext.newContext(bean);
Object[] args = new Object[nbToken];
+
for (int i = 0; i < nbToken; i++) {
- args[i] = getTokenValue(jxcontext, context.tokens[i]);
+ try {
+ args[i] = getTokenValue(jxcontext, context.tokens[i]);
+ } catch (Exception e) {
+ log.error("can not obtain token " + context.tokens[i] + "on object " + bean + " for reason " + e.getMessage(), e);
+
+ }
}
+
return String.format(context.expression, args);
}
Modified: jaxx/trunk/jaxx-runtime-validator/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/changelog.txt 2009-04-04 17:05:55 UTC (rev 1291)
@@ -1,4 +1,9 @@
1.3 chemit 20090321
+ * 20090404 [chemit] - can now use a shared instance of ValueStack (in BeanValidatorUtil)
+ * 20090401 [chemit] - introduce a extended fieldexpression validator where we can push extra parameters
+ - improve tests
+ - add useSensitiveContext in CollectionFieldExpressionValidator.
+
* 20090320 [chemit] - rename and move ValidationUtil to jaxx.runtime.BeanValidatorUtil
* 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design
Modified: jaxx/trunk/jaxx-runtime-validator/pom.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/pom.xml 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/pom.xml 2009-04-04 17:05:55 UTC (rev 1291)
@@ -47,6 +47,23 @@
<!-- ************************************************************* -->
<packaging>jar</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codelutin</groupId>
+ <artifactId>maven-i18n-plugin</artifactId>
+ <version>${i18n.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>parserJava</goal>
+ <goal>gen</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
<!-- ************************************************************* -->
<!-- *** Build Environment ************************************** -->
<!-- ************************************************************* -->
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/BeanValidatorUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/BeanValidatorUtil.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/BeanValidatorUtil.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -1,5 +1,9 @@
package jaxx.runtime;
+import com.opensymphony.xwork2.config.Configuration;
+import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.util.ValueStackFactory;
import jaxx.runtime.validator.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -22,7 +26,27 @@
/** to use log facility, just put in your code: log.info(\"...\"); */
static private final Log log = LogFactory.getLog(BeanValidatorUtil.class);
+ /**
+ * a shared value stack to allow external operations on it (for example
+ * add some datas in stack to be usedby validators
+ */
+ static private ValueStack sharedValueStack;
+ public static synchronized ValueStack getSharedValueStack() {
+ if (sharedValueStack == null) {
+
+ // init context
+ ConfigurationManager confManager = new ConfigurationManager();
+ Configuration conf = confManager.getConfiguration();
+
+ sharedValueStack = conf.getContainer().getInstance(ValueStackFactory.class).createValueStack();
+ if (log.isDebugEnabled()) {
+ log.debug("init shared value stack " + sharedValueStack);
+ }
+ }
+ return sharedValueStack;
+ }
+
protected BeanValidatorUtil() {
// no instance
}
@@ -148,5 +172,4 @@
throw new IllegalStateException("could not acquire PropertyChangeListener bean info for " + beanClass + " for reason " + ex.getMessage(), ex);
}
}
-
}
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -107,7 +107,7 @@
}
public Set<BeanValidatorScope> getScopes() {
- return new java.util.HashSet< BeanValidatorScope>(validators.keySet());
+ return new java.util.HashSet<BeanValidatorScope>(validators.keySet());
}
/**
@@ -342,6 +342,9 @@
errors.add(conversionError);
} else {
errors = java.util.Collections.singletonList(conversionError);
+ if (newMessages == XWorkBeanValidator.EMPTY_RESULT) {
+ newMessages = new java.util.HashMap<String, List<String>>();
+ }
// add the concrete conversion error
newMessages.put(entry.getKey(), errors);
}
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorScope.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -1,5 +1,7 @@
package jaxx.runtime.validator;
+import static org.codelutin.i18n.I18n.n_;
+
/**
* The differents levels of messages in validation process.
* <p/>
@@ -10,25 +12,35 @@
* @author chemit
*/
public enum BeanValidatorScope {
+
/**
* the error scope level.
*
* When a message of a such scope is found on a validator, then the validator
* is invalid and modified.
*/
- ERROR,
+ ERROR(n_("validator.scope.error.label")),
/**
* the warning scope level.
*
* When a message of a such scope is found on a validator, then the validator
* is still valid but modified.
*/
- WARNING,
+ WARNING(n_("validator.scope.warning.label")),
/**
* the information scope level.
*
* When a message of a sucg scope is found on a validator, then the
* validator is still valid and not modified.
*/
- INFO
+ INFO(n_("validator.scope.info.label"));
+ private final String label;
+
+ private BeanValidatorScope(String label) {
+ this.label = label;
+ }
+
+ public String getLabel() {
+ return label;
+ }
}
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/XWorkBeanValidator.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -20,6 +20,7 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
+import jaxx.runtime.BeanValidatorUtil;
/**
*
@@ -37,7 +38,7 @@
/** to use log facility, just put in your code: log.info(\"...\"); */
private static final Log log = LogFactory.getLog(XWorkBeanValidator.class);
- private final static Map<String, List<String>> EMPTY_RESULT = Collections.unmodifiableMap(new HashMap<String, List<String>>());
+ protected final static Map<String, List<String>> EMPTY_RESULT = Collections.unmodifiableMap(new HashMap<String, List<String>>());
/** the type of bean to validate */
protected final Class<B> beanClass;
/** the validation named context (can be null) */
@@ -55,26 +56,43 @@
protected ActionContext context;
public XWorkBeanValidator(Class<B> beanClass, String contextName) {
- this(beanClass, contextName, true);
+ this(beanClass, contextName, true, BeanValidatorUtil.getSharedValueStack());
}
+ public XWorkBeanValidator(Class<B> beanClass, String contextName, ValueStack vs) {
+ this(beanClass, contextName, true, vs);
+ }
+
public XWorkBeanValidator(Class<B> beanClass, String contextName, boolean includeDefaultContext) {
+ this(beanClass, contextName, includeDefaultContext, BeanValidatorUtil.getSharedValueStack());
+ }
+ public XWorkBeanValidator(Class<B> beanClass, String contextName, boolean includeDefaultContext, ValueStack vs) {
+
this.beanClass = beanClass;
this.includeDefaultContext = includeDefaultContext;
validationSupport = new ValidationAwareSupport();
validationContext = new DelegatingValidatorContext(validationSupport);
- // init context
- ConfigurationManager confManager = new ConfigurationManager();
- Configuration conf = confManager.getConfiguration();
+ if (vs == null) {
+ // create a standalone value stack
+ ConfigurationManager confManager = new ConfigurationManager();
+ Configuration conf = confManager.getConfiguration();
+ vs = conf.getContainer().getInstance(ValueStackFactory.class).createValueStack();
+ if (log.isDebugEnabled()) {
+ log.info("create a standalone value stack " + vs);
+ }
+ } else {
+ if (log.isDebugEnabled()) {
+ log.debug("use given value stack " + vs);
+ }
+ }
- ValueStack vs = conf.getContainer().getInstance(ValueStackFactory.class).createValueStack();
context = new ActionContext(vs.getContext());
ActionContext.setContext(context);
// init validator
- validator = conf.getContainer().getInstance(ActionValidatorManager.class, "no-annotations");
+ validator = context.getContainer().getInstance(ActionValidatorManager.class, "no-annotations");
// init context
setContextName(contextName);
Modified: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidator.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidator.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -25,6 +25,30 @@
}
/** le mode de validation sur la liste */
protected Mode mode;
+ /**
+ * drapeau pour utiliser le contexte de parcours pour valider
+ * l'expression, on dispose donc alors des variables previous, current,
+ * index, size et empty dans l'expression.
+ *
+ * Sinon l'expression s'applique directement sur l'entrée courant dans le
+ * parcours sans préfixe.
+ */
+ protected boolean useSensitiveContext;
+ /**
+ * expression a valider sur la premiètre entrée de la collection.
+ *
+ * Note : Pour le moment, on autorise uniquement cela en mode ALL.
+ */
+ protected String expressionForFirst;
+ /**
+ * expression a valider sur la dernière entrée de la collection.
+ *
+ * Note : Pour le moment, on autorise uniquement cela en mode ALL.
+ */
+ protected String expressionForLast;
+ /** le context de parcours */
+ protected WalkerContext c;
+ private boolean useFirst, useLast;
public Mode getMode() {
return mode;
@@ -34,16 +58,53 @@
this.mode = mode;
}
+ public boolean isUseSensitiveContext() {
+ return useSensitiveContext;
+ }
+
+ public void setUseSensitiveContext(boolean useSensitiveContext) {
+ this.useSensitiveContext = useSensitiveContext;
+ }
+
+ public String getExpressionForFirst() {
+ return expressionForFirst;
+ }
+
+ public void setExpressionForFirst(String expressionForFirst) {
+ this.expressionForFirst = expressionForFirst;
+ }
+
+ public String getExpressionForLast() {
+ return expressionForLast;
+ }
+
+ public void setExpressionForLast(String expressionForLast) {
+ this.expressionForLast = expressionForLast;
+ }
+
@Override
public void validate(Object object) throws ValidationException {
if (mode == null) {
- throw new ValidationException("no mode defined");
+ throw new ValidationException("no mode defined!");
}
+ useFirst = expressionForFirst != null && !expressionForFirst.trim().isEmpty();
+ useLast = expressionForLast != null && !expressionForLast.trim().isEmpty();
+ if (useFirst && mode != Mode.ALL) {
+ throw new ValidationException("can only use expressionForFirst in mode ALL but was " + mode);
+ }
+ if (useLast && mode != Mode.ALL) {
+ throw new ValidationException("can only use expressionForLast in mode ALL but was " + mode);
+ }
+
String fieldName = getFieldName();
Collection<?> col = getCollection(object);
+ if (useSensitiveContext) {
+ c = new WalkerContext(col.size());
+ }
+
boolean answer;
switch (mode) {
@@ -129,10 +190,36 @@
}
protected boolean validateOneEntry(Object object) throws ValidationException {
- // obtain the validation of one entry of the collection
+
+ Boolean answer = Boolean.FALSE;
+
+ boolean extraExpression = false;
+
+ if (useSensitiveContext) {
+ c.addCurrent(object);
+ object = c;
+
+ if (c.isFirst() && useFirst) {
+ // on valide l'expression sur la premiètre entrée
+ answer = evaluateExpression(expressionForFirst, object);
+ extraExpression = true;
+ }
+ if (c.isLast() && useLast) {
+ // on valide l'expression sur la dernière entrée
+ answer = (!extraExpression || answer) && evaluateExpression(expressionForLast, object);
+ extraExpression = true;
+ }
+ }
+
+ answer = (!extraExpression || answer) && evaluateExpression(getExpression(), object);
+
+ return answer;
+ }
+
+ protected boolean evaluateExpression(String expression, Object object) throws ValidationException {
Object obj = null;
try {
- obj = getFieldValue(getExpression(), object);
+ obj = getFieldValue(expression, object);
} catch (ValidationException e) {
throw e;
} catch (Exception e) {
@@ -144,7 +231,7 @@
if (obj != null && obj instanceof Boolean) {
answer = (Boolean) obj;
} else {
- log.warn("Got result of " + obj + " when trying to get Boolean.");
+ log.warn("Got result of " + obj + " when trying to get Boolean for expression " + expression);
}
return answer;
}
@@ -183,4 +270,50 @@
public String getValidatorType() {
return "collectionFieldExpression";
}
+
+ public class WalkerContext {
+
+ protected final int size;
+
+ public WalkerContext(int size) {
+ this.size = size;
+ }
+ protected int index = -1;
+ protected Object current;
+ protected Object previous;
+
+ public void addCurrent(Object current) {
+ index++;
+ previous = this.current;
+ this.current = current;
+ }
+
+ public Object getCurrent() {
+ return current;
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ public Object getPrevious() {
+ return previous;
+ }
+
+ public int getSize() {
+ return size;
+ }
+
+ public boolean isEmpty() {
+ return size == 0;
+ }
+
+ public boolean isFirst() {
+ return index == 0;
+ }
+
+ public boolean isLast() {
+ return index == size - 1;
+ }
+ }
}
Added: jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/FieldExpressionWithParamsValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/FieldExpressionWithParamsValidator.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/FieldExpressionWithParamsValidator.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,175 @@
+package jaxx.runtime.validator.field;
+
+import com.opensymphony.xwork2.util.ValueStack;
+import com.opensymphony.xwork2.validator.ValidationException;
+import com.opensymphony.xwork2.validator.validators.FieldExpressionValidator;
+import java.util.Map;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.codelutin.util.ConverterUtil;
+
+/**
+ * Extends {@link FieldExpressionValidator} to add some extra parameters available
+ * in the {@link #getExpression()}
+ *
+ * @author tony
+ * @since 1.3
+ */
+public class FieldExpressionWithParamsValidator extends FieldExpressionValidator {
+
+ protected static final Pattern EXTRA_BOOLEAN_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(false|true)");
+ protected static final Pattern EXTRA_SHORT_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(\\d+)");
+ protected static final Pattern EXTRA_INT_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(\\d+)");
+ protected static final Pattern EXTRA_LONG_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(\\d+)");
+ protected static final Pattern EXTRA_DOUBLE_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(\\d+\\.\\d+)");
+ protected static final Pattern EXTRA_STRING_PARAM_ENTRY_PATTERN = Pattern.compile("(\\w+)\\:(.+)");
+ protected ValueStack stack;
+ protected String booleanParams;
+ protected String shortParams;
+ protected String intParams;
+ protected String longParams;
+ protected String doubleParams;
+ protected String stringParams;
+ protected Map<String, Boolean> booleans;
+ protected Map<String, Short> shorts;
+ protected Map<String, Integer> ints;
+ protected Map<String, Long> longs;
+ protected Map<String, Double> doubles;
+ protected Map<String, String> strings;
+
+ public String getBooleanParams() {
+ return booleanParams;
+ }
+
+ public void setBooleanParams(String booleanParams) {
+ this.booleanParams = booleanParams;
+ }
+
+ public String getDoubleParams() {
+ return doubleParams;
+ }
+
+ public void setDoubleParams(String doubleParams) {
+ this.doubleParams = doubleParams;
+ }
+
+ public String getIntParams() {
+ return intParams;
+ }
+
+ public void setIntParams(String intParams) {
+ this.intParams = intParams;
+ }
+
+ public String getLongParams() {
+ return longParams;
+ }
+
+ public void setLongParams(String longParams) {
+ this.longParams = longParams;
+ }
+
+ public String getShortParams() {
+ return shortParams;
+ }
+
+ public void setShortParams(String shortParams) {
+ this.shortParams = shortParams;
+ }
+
+ public String getStringParams() {
+ return stringParams;
+ }
+
+ public void setStringParams(String stringParams) {
+ this.stringParams = stringParams;
+ }
+
+ public Map<String, Boolean> getBooleans() {
+ return booleans;
+ }
+
+ public Map<String, Double> getDoubles() {
+ return doubles;
+ }
+
+ public Map<String, Integer> getInts() {
+ return ints;
+ }
+
+ public Map<String, Long> getLongs() {
+ return longs;
+ }
+
+ public Map<String, Short> getShorts() {
+ return shorts;
+ }
+
+ public Map<String, String> getStrings() {
+ return strings;
+ }
+
+ @Override
+ public String getValidatorType() {
+ return "fieldexpressionwithparams";
+ }
+
+ @Override
+ public void setValueStack(ValueStack stack) {
+ super.setValueStack(stack);
+ this.stack = stack;
+ }
+
+ @Override
+ public void validate(Object object) throws ValidationException {
+
+ booleans = initParams(Boolean.class, booleanParams, EXTRA_BOOLEAN_PARAM_ENTRY_PATTERN);
+ shorts = initParams(Short.class, shortParams, EXTRA_SHORT_PARAM_ENTRY_PATTERN);
+ ints = initParams(Integer.class, intParams, EXTRA_INT_PARAM_ENTRY_PATTERN);
+ longs = initParams(Long.class, longParams, EXTRA_LONG_PARAM_ENTRY_PATTERN);
+ doubles = initParams(Double.class, doubleParams, EXTRA_DOUBLE_PARAM_ENTRY_PATTERN);
+ strings = initParams(String.class, stringParams, EXTRA_STRING_PARAM_ENTRY_PATTERN);
+
+ boolean pop = false;
+ if (!stack.getRoot().contains(this)) {
+ stack.push(this);
+ pop = true;
+ }
+
+ try {
+ super.validate(object);
+ } finally {
+ if (pop) {
+ stack.pop();
+ }
+ }
+
+ }
+
+ protected <T> Map<String, T> initParams(Class<T> klass, String extraParams, Pattern pattern) throws ValidationException {
+
+ if (extraParams == null || extraParams.isEmpty()) {
+ // not using
+ return null;
+ }
+
+ StringTokenizer stk = new StringTokenizer(extraParams, "|");
+ Map<String, T> result = new java.util.TreeMap<String, T>();
+ while (stk.hasMoreTokens()) {
+ String entry = stk.nextToken();
+ Matcher matcher = pattern.matcher(entry);
+ if (!matcher.matches()) {
+ throw new ValidationException("could not parse for extra params " + extraParams + " for type " + klass.getName());
+ }
+ String paramName = matcher.group(1);
+ String paramValueStr = matcher.group(2);
+ T paramValue = ConverterUtil.convert(klass, paramValueStr);
+ if (log.isDebugEnabled()) {
+ log.debug("detected extra param : <type:" + klass + ", name:" + paramName + ", value:" + paramValue + ">");
+ }
+ result.put(paramName, paramValue);
+ }
+ return result;
+ }
+}
Added: jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/jaxx-runtime-validator-en_GB.properties
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/jaxx-runtime-validator-en_GB.properties (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/jaxx-runtime-validator-en_GB.properties 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,3 @@
+validator.scope.error.label=Error
+validator.scope.info.label=Information
+validator.scope.warning.label=Warning
Added: jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/jaxx-runtime-validator-fr_FR.properties
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/jaxx-runtime-validator-fr_FR.properties (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/main/resources/i18n/jaxx-runtime-validator-fr_FR.properties 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,3 @@
+validator.scope.error.label=Erreur
+validator.scope.info.label=Information
+validator.scope.warning.label=Avertissement
Deleted: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/ValidatorBean.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/ValidatorBean.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/ValidatorBean.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -1,158 +0,0 @@
-package jaxx.runtime.validator;
-
-import java.beans.PropertyChangeListener;
-import java.beans.PropertyChangeSupport;
-import java.io.File;
-import java.util.Collection;
-
-public class ValidatorBean {
-
- public static class ValidatorBeanEntry {
-
- protected int intValue;
- protected String stringValue;
- protected String stringValue2;
-
- public ValidatorBeanEntry(int intValue, String stringValue) {
- this.intValue = intValue;
- this.stringValue = stringValue;
- }
-
- public ValidatorBeanEntry(int intValue, String stringValue, String stringValue2) {
- this.intValue = intValue;
- this.stringValue = stringValue;
- this.stringValue2 = stringValue2;
- }
-
- public int getIntValue() {
- return intValue;
- }
-
- public void setIntValue(int intValue) {
- this.intValue = intValue;
- }
-
- public String getStringValue() {
- return stringValue;
- }
-
- public void setStringValue(String stringValue) {
- this.stringValue = stringValue;
- }
-
- public String getStringValue2() {
- return stringValue2;
- }
-
- public void setStringValue2(String stringValue2) {
- this.stringValue2 = stringValue2;
- }
- }
-
- protected File existingFile;
- protected File notExistingFile;
-
- protected File existingDirectory;
- protected File notExistingDirectory;
-
- protected Collection<ValidatorBeanEntry> entries;
-
- protected String stringValue;
-
- protected ValidatorBeanEntry entry;
-
- PropertyChangeSupport p;
-
- public ValidatorBean() {
- p = new PropertyChangeSupport(this);
- }
-
- public void addPropertyChangeListener(PropertyChangeListener listener) {
- p.addPropertyChangeListener(listener);
- }
-
- public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- p.addPropertyChangeListener(propertyName, listener);
- }
-
- public void removePropertyChangeListener(PropertyChangeListener listener) {
- p.removePropertyChangeListener(listener);
- }
-
- public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
- p.removePropertyChangeListener(propertyName, listener);
- }
-
- public String getStringValue() {
- return stringValue;
- }
-
- public File getExistingFile() {
- return existingFile;
- }
-
- public File getNotExistingFile() {
- return notExistingFile;
- }
-
- public File getExistingDirectory() {
- return existingDirectory;
- }
-
- public File getNotExistingDirectory() {
- return notExistingDirectory;
- }
-
- public ValidatorBeanEntry getEntry() {
- return entry;
- }
-
- public Collection<ValidatorBeanEntry> getEntries() {
- return entries;
- }
-
- public void setStringValue(String stringValue) {
- String old = this.stringValue;
- this.stringValue = stringValue;
- p.firePropertyChange("stringValue", old, existingFile);
- }
-
- public void setExistingFile(File existingFile) {
- File old = this.existingFile;
- this.existingFile = existingFile;
- p.firePropertyChange("existingFile", old, existingFile);
- }
-
- public void setNotExistingFile(File notExistingFile) {
- File old = this.notExistingFile;
- this.notExistingFile = notExistingFile;
- p.firePropertyChange("notExistingFile", old, notExistingFile);
- }
-
- public void setExistingDirectory(File existingDirectory) {
- File old = this.existingDirectory;
- this.existingDirectory = existingDirectory;
- p.firePropertyChange("existingDirectory", old, existingDirectory);
- }
-
- public void setNotExistingDirectory(File notExistingDirectory) {
- File old = this.notExistingDirectory;
- this.notExistingDirectory = notExistingDirectory;
- p.firePropertyChange("notExistingDirectory", old, notExistingDirectory);
- }
-
- public void setEntries(Collection<ValidatorBeanEntry> entries) {
- this.entries = entries;
- // set null oldValue to always fire event
- // otherwise it could been not sent...
- p.firePropertyChange("entries", null, entries);
- }
-
- public void setEntry(ValidatorBeanEntry entry) {
- this.entry = entry;
- p.firePropertyChange("entry", null, entry);
- }
-
-
-
-}
\ No newline at end of file
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractFieldValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -3,10 +3,10 @@
import java.io.File;
import jaxx.runtime.validator.BeanValidator;
import jaxx.runtime.validator.BeanValidatorField;
-import jaxx.runtime.validator.ValidatorBean;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.After;
+import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -17,34 +17,59 @@
* To implements a test on a new validator, just extends this class
* and implements the method {@link #testValidator()}.
*
+ * @param <B> the type of bean to validate.
+ *
* @author chemit
*/
-public abstract class AbstractFieldValidatorTest extends Assert {
+public abstract class AbstractFieldValidatorTest<B> extends Assert {
/** to use log facility, just put in your code: log.info(\"...\"); */
static private final Log log = LogFactory.getLog(AbstractFieldValidatorTest.class);
- static protected BeanValidator<ValidatorBean> validator;
- static protected File basedir;
- protected ValidatorBean bean;
+ protected static BeanValidator cacheValidator;
+ protected static File basedir;
+ protected final Class<B> type;
+ protected BeanValidator<B> validator;
+ protected B bean;
+ public AbstractFieldValidatorTest(Class<B> type) {
+ this.type = type;
+ }
+
/**
- * the moethod to implements testing the given validator on the given bean.
+ * the method to test the given validator on the given bean.
*
+ * When coming here a validator and bean were instanciated and the bean was
+ * setted into validator via setBean method.
+ *
* @throws Exception if any error ?
*/
public abstract void testValidator() throws Exception;
@Before
+ @SuppressWarnings("unchecked")
public void setUp() throws Exception {
log.debug("start test " + getClass().getSimpleName());
- validator.setBean(bean = new ValidatorBean());
+ bean = type.newInstance();
+ if (cacheValidator == null) {
+ validator = validator = new BeanValidator<B>(type, null);
+ cacheValidator = validator;
+ } else {
+ validator = cacheValidator;
+ }
+ validator.setBean(bean);
}
@After
+ @SuppressWarnings("unchecked")
public void tearDown() {
validator.setBean(null);
}
+ @AfterClass
+ public static void afterclass() throws Exception {
+ cacheValidator = null;
+ }
+
@BeforeClass
public static void initValidator() throws Exception {
@@ -53,20 +78,20 @@
b = new File("").getAbsolutePath();
}
basedir = new File(b);
- validator = new BeanValidator<ValidatorBean>(ValidatorBean.class, null);
}
+ @SuppressWarnings("unchecked")
protected void assertFieldInError(String fieldName, String error, boolean required) {
- BeanValidatorField<ValidatorBean> field = validator.getField(fieldName);
- if (field !=null && field.getErrors() != null) {
+ BeanValidatorField<B> field = validator.getField(fieldName);
+ if (field != null && field.getErrors() != null) {
for (String o : field.getErrors()) {
if (o.equals(error)) {
- assertTrue(required);
+ assertTrue("error " + error + " should not exist but was found.", required);
return;
}
}
}
// error was not found
- assertFalse(required);
+ assertFalse("error " + error + " should exist but was not found.", required);
}
}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractValidatorBeanFieldValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractValidatorBeanFieldValidatorTest.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/AbstractValidatorBeanFieldValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,14 @@
+package jaxx.runtime.validator.field;
+
+/**
+ * Abstract class to test a specific validator for the {@link Validatorbean}.
+ *
+ * @author chemit
+ * @since 1.3
+ */
+public abstract class AbstractValidatorBeanFieldValidatorTest extends AbstractFieldValidatorTest<ValidatorBean> {
+
+ public AbstractValidatorBeanFieldValidatorTest() {
+ super(ValidatorBean.class);
+ }
+}
\ No newline at end of file
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidatorTest.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/CollectionFieldExpressionValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -1,14 +1,18 @@
package jaxx.runtime.validator.field;
-import jaxx.runtime.validator.ValidatorBean.ValidatorBeanEntry;
+import jaxx.runtime.validator.field.ValidatorBean.ValidatorBeanEntry;
import java.util.Arrays;
/** @author chemit */
-public class CollectionFieldExpressionValidatorTest extends AbstractFieldValidatorTest {
+public class CollectionFieldExpressionValidatorTest extends AbstractValidatorBeanFieldValidatorTest {
- static protected ValidatorBeanEntry beanEntry = new ValidatorBeanEntry(0, "stringValue");
- static protected ValidatorBeanEntry beanEntry2 = new ValidatorBeanEntry(0, "fake");
+ protected static final String PROPERTY = "entries";
+ static protected ValidatorBeanEntry beanEntry0 = new ValidatorBeanEntry(0, "stringValue");
+ static protected ValidatorBeanEntry beanEntry0Bis = new ValidatorBeanEntry(0, "fake");
+ static protected ValidatorBeanEntry beanEntry1 = new ValidatorBeanEntry(1, "fake");
+ static protected ValidatorBeanEntry beanEntry3 = new ValidatorBeanEntry(3, "fake");
+ static protected ValidatorBeanEntry beanEntry5 = new ValidatorBeanEntry(5, "fake");
@org.junit.Test
@Override
@@ -16,41 +20,215 @@
assertNull(bean.getEntries());
// no entry
- assertFieldInError("entries", "collectionFieldExpression.atLeastOne", true);
- assertFieldInError("entries", "collectionFieldExpression.exactlyOne", true);
- assertFieldInError("entries", "collectionFieldExpression.all", false);
- assertFieldInError("entries", "collectionFieldExpression.none", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none", false);
+
// add a matching etry
- bean.setEntries(Arrays.asList(beanEntry));
+ bean.setEntries(Arrays.asList(beanEntry0));
- assertFieldInError("entries", "collectionFieldExpression.atLeastOne", false);
- assertFieldInError("entries", "collectionFieldExpression.exactlyOne", false);
- assertFieldInError("entries", "collectionFieldExpression.all", false);
- assertFieldInError("entries", "collectionFieldExpression.none", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none", true);
// two matching etries
- bean.setEntries(Arrays.asList(beanEntry, beanEntry));
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry0));
- assertFieldInError("entries", "collectionFieldExpression.atLeastOne", false);
- assertFieldInError("entries", "collectionFieldExpression.exactlyOne", true);
- assertFieldInError("entries", "collectionFieldExpression.all", false);
- assertFieldInError("entries", "collectionFieldExpression.none", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none", true);
// add a none matching etry
- bean.setEntries(Arrays.asList(beanEntry2));
+ bean.setEntries(Arrays.asList(beanEntry0Bis));
- assertFieldInError("entries", "collectionFieldExpression.atLeastOne", true);
- assertFieldInError("entries", "collectionFieldExpression.exactlyOne", true);
- assertFieldInError("entries", "collectionFieldExpression.all", true);
- assertFieldInError("entries", "collectionFieldExpression.none", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none", false);
// add a none matching etry and a matching entry
- bean.setEntries(Arrays.asList(beanEntry2, beanEntry));
+ bean.setEntries(Arrays.asList(beanEntry0Bis, beanEntry0));
- assertFieldInError("entries", "collectionFieldExpression.atLeastOne", false);
- assertFieldInError("entries", "collectionFieldExpression.exactlyOne", false);
- assertFieldInError("entries", "collectionFieldExpression.all", true);
- assertFieldInError("entries", "collectionFieldExpression.none", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none", true);
}
+
+ @org.junit.Test
+ public void testValidatorWithContext() throws Exception {
+ assertNull(bean.getEntries());
+
+ // no entry
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false);
+
+ // add a matching etry
+ bean.setEntries(Arrays.asList(beanEntry0));
+
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false);
+
+ // add a none matching etry
+ bean.setEntries(Arrays.asList(beanEntry0Bis));
+
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false);
+
+ // add a none matching etry and a matching entry
+ bean.setEntries(Arrays.asList(beanEntry0Bis, beanEntry0));
+
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1));
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false);
+
+ bean.setEntries(Arrays.asList(beanEntry1, beanEntry0));
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3));
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", true);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3, beanEntry5));
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", true);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry3, beanEntry1));
+ assertFieldInError(PROPERTY, "collectionFieldExpression.atLeastOne.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.all.useSensitiveContext", true);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.exactlyOne.useSensitiveContext", false);
+ assertFieldInError(PROPERTY, "collectionFieldExpression.none.useSensitiveContext", false);
+ }
+
+ @org.junit.Test
+ public void testValidatorWithContextAndFirst() throws Exception {
+ assertNull(bean.getEntries());
+ String message = "collectionFieldExpression.all.useFirst";
+
+ // no entry
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0));
+ assertFieldInError(PROPERTY, message, false);
+
+
+ bean.setEntries(Arrays.asList(beanEntry0Bis));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry1));
+ assertFieldInError(PROPERTY, message, true);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry1, beanEntry0));
+ assertFieldInError(PROPERTY, message, true);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3, beanEntry5));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry3, beanEntry1));
+ assertFieldInError(PROPERTY, message, true);
+ }
+
+ @org.junit.Test
+ public void testValidatorWithContextAndLast() throws Exception {
+ assertNull(bean.getEntries());
+ String message = "collectionFieldExpression.all.useLast";
+
+ // no entry
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0));
+ assertFieldInError(PROPERTY, message, true);
+
+
+ bean.setEntries(Arrays.asList(beanEntry0Bis));
+ assertFieldInError(PROPERTY, message, true);
+
+ bean.setEntries(Arrays.asList(beanEntry1));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry1, beanEntry0));
+ assertFieldInError(PROPERTY, message, true);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry1, beanEntry3));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3, beanEntry5));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry3, beanEntry1));
+ assertFieldInError(PROPERTY, message, true);
+ }
+
+ @org.junit.Test
+ public void testValidatorWithContextAndFirstAndLast() throws Exception {
+ assertNull(bean.getEntries());
+
+ String message = "collectionFieldExpression.all.useFirstAndLast";
+ // no entry
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0));
+ assertFieldInError(PROPERTY, message, true);
+
+
+ bean.setEntries(Arrays.asList(beanEntry0Bis));
+ assertFieldInError(PROPERTY, message, true);
+
+ bean.setEntries(Arrays.asList(beanEntry1));
+ assertFieldInError(PROPERTY, message, true);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry1, beanEntry0));
+ assertFieldInError(PROPERTY, message, true);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry1, beanEntry3));
+ assertFieldInError(PROPERTY, message, true);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry1, beanEntry3, beanEntry5));
+ assertFieldInError(PROPERTY, message, false);
+
+ bean.setEntries(Arrays.asList(beanEntry0, beanEntry3, beanEntry1));
+ assertFieldInError(PROPERTY, message, true);
+ }
}
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/CollectionUniqueKeyValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/CollectionUniqueKeyValidatorTest.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/CollectionUniqueKeyValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -1,11 +1,11 @@
package jaxx.runtime.validator.field;
-import jaxx.runtime.validator.ValidatorBean.ValidatorBeanEntry;
+import jaxx.runtime.validator.field.ValidatorBean.ValidatorBeanEntry;
import java.util.Arrays;
/** @author chemit */
-public class CollectionUniqueKeyValidatorTest extends AbstractFieldValidatorTest {
+public class CollectionUniqueKeyValidatorTest extends AbstractValidatorBeanFieldValidatorTest {
static protected ValidatorBeanEntry beanEntry = new ValidatorBeanEntry(0, "stringValue");
static protected ValidatorBeanEntry beanEntry2 = new ValidatorBeanEntry(0, "fake");
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidatorTest.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -3,7 +3,7 @@
import java.io.File;
/** @author chemit */
-public class ExistingDirectoryFieldValidatorTest extends AbstractFieldValidatorTest {
+public class ExistingDirectoryFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest {
@org.junit.Test
@Override
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ExistingFileFieldValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ExistingFileFieldValidatorTest.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ExistingFileFieldValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -3,7 +3,7 @@
import java.io.File;
/** @author chemit */
-public class ExistingFileFieldValidatorTest extends AbstractFieldValidatorTest {
+public class ExistingFileFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest {
@org.junit.Test
@Override
Added: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/FieldExpressionBean.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/FieldExpressionBean.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/FieldExpressionBean.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,103 @@
+package jaxx.runtime.validator.field;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+/**
+ *
+ * @author tony
+ */
+public class FieldExpressionBean {
+
+ protected final PropertyChangeSupport p;
+ protected boolean booleanValue;
+ protected short shortValue;
+ protected int intValue;
+ protected long longValue;
+ protected double doubleValue;
+ protected String stringValue;
+
+ public FieldExpressionBean() {
+ p = new PropertyChangeSupport(this);
+ }
+
+ public boolean isBooleanValue() {
+ return booleanValue;
+ }
+
+ public double getDoubleValue() {
+ return doubleValue;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public long getLongValue() {
+ return longValue;
+ }
+
+ public short getShortValue() {
+ return shortValue;
+ }
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setBooleanValue(boolean newValue) {
+ Object oldValue = this.booleanValue;
+ this.booleanValue = newValue;
+ firePropertyChange("booleanValue", oldValue, newValue);
+ }
+
+ public void setDoubleValue(double newValue) {
+ Object oldValue = this.doubleValue;
+ this.doubleValue = newValue;
+ firePropertyChange("doubleValue", oldValue, newValue);
+ }
+
+ public void setIntValue(int newValue) {
+ Object oldValue = this.stringValue;
+ this.intValue = newValue;
+ firePropertyChange("intValue", oldValue, newValue);
+ }
+
+ public void setLongValue(long newValue) {
+ Object oldValue = this.longValue;
+ this.longValue = newValue;
+ firePropertyChange("longValue", oldValue, newValue);
+ }
+
+ public void setShortValue(short newValue) {
+ Object oldValue = this.shortValue;
+ this.shortValue = newValue;
+ firePropertyChange("shortValue", oldValue, newValue);
+ }
+
+ public void setStringValue(String newValue) {
+ Object oldValue = this.stringValue;
+ this.stringValue = newValue;
+ firePropertyChange("stringValue", oldValue, newValue);
+ }
+
+ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+ p.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ p.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ p.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ p.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ p.removePropertyChangeListener(propertyName, listener);
+ }
+}
Added: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/FieldExpressionWithParamsValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/FieldExpressionWithParamsValidatorTest.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/FieldExpressionWithParamsValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,116 @@
+package jaxx.runtime.validator.field;
+
+/** @author chemit */
+public class FieldExpressionWithParamsValidatorTest extends AbstractFieldValidatorTest<FieldExpressionBean> {
+
+ public static final String MESSAGE = "expression.too.big##100";
+ public static final String MESSAGE2 = "expression.too.big##100##2000";
+
+ public FieldExpressionWithParamsValidatorTest() {
+ super(FieldExpressionBean.class);
+ }
+
+ @org.junit.Test
+ @Override
+ public void testValidator() throws Exception {
+
+ testBooleanType();
+ testShortType();
+ testIntType();
+ testLongType();
+ testDoubleType();
+ testStringType();
+
+
+ }
+
+ protected void testBooleanType() {
+
+ assertEquals(false, bean.isBooleanValue());
+ assertFieldInError("booleanValue", "expression.boolean.not.equals##true", true);
+ assertFieldInError("booleanValue", "expression.boolean.not.equals##false", false);
+
+ bean.setBooleanValue(true);
+ assertFieldInError("booleanValue", "expression.boolean.not.equals##true", false);
+ assertFieldInError("booleanValue", "expression.boolean.not.equals##false", true);
+ }
+
+ protected void testShortType() {
+ assertEquals(0, bean.getShortValue());
+ assertFieldInError("shortValue", MESSAGE, false);
+ assertFieldInError("shortValue", MESSAGE2, false);
+ bean.setShortValue((short) 10);
+ assertFieldInError("shortValue", MESSAGE, false);
+ assertFieldInError("shortValue", MESSAGE2, false);
+ bean.setShortValue((short) 1000);
+ assertFieldInError("shortValue", MESSAGE, true);
+ assertFieldInError("shortValue", MESSAGE2, false);
+ bean.setShortValue((short) 3000);
+ assertFieldInError("shortValue", MESSAGE, true);
+ assertFieldInError("shortValue", MESSAGE2, true);
+ }
+
+ protected void testIntType() {
+ assertEquals(0, bean.getIntValue());
+ assertFieldInError("intValue", MESSAGE, false);
+ assertFieldInError("intValue", MESSAGE2, false);
+ bean.setIntValue(10);
+ assertFieldInError("intValue", MESSAGE, false);
+ assertFieldInError("intValue", MESSAGE2, false);
+ bean.setIntValue(1000);
+ assertFieldInError("intValue", MESSAGE, true);
+ assertFieldInError("intValue", MESSAGE2, false);
+ bean.setIntValue(3000);
+ assertFieldInError("intValue", MESSAGE, true);
+ assertFieldInError("intValue", MESSAGE2, true);
+ }
+
+ protected void testLongType() {
+ assertEquals(0, bean.getLongValue());
+ assertFieldInError("longValue", MESSAGE, false);
+ assertFieldInError("longValue", MESSAGE2, false);
+ bean.setLongValue(10);
+ assertFieldInError("longValue", MESSAGE, false);
+ assertFieldInError("longValue", MESSAGE2, false);
+ bean.setLongValue(1000);
+ assertFieldInError("longValue", MESSAGE, true);
+ assertFieldInError("longValue", MESSAGE2, false);
+ bean.setLongValue(3000);
+ assertFieldInError("longValue", MESSAGE, true);
+ assertFieldInError("longValue", MESSAGE2, true);
+ }
+
+ protected void testDoubleType() {
+ assertEquals(0.0, bean.getDoubleValue(), 0);
+ assertFieldInError("doubleValue", MESSAGE + ".0", false);
+ assertFieldInError("doubleValue", "expression.too.big##100.0##2000.0", false);
+ bean.setDoubleValue(10);
+ assertFieldInError("doubleValue", MESSAGE + ".0", false);
+ assertFieldInError("doubleValue", "expression.too.big##100.0##2000.0", false);
+ bean.setDoubleValue(1000);
+ assertFieldInError("doubleValue", MESSAGE + ".0", true);
+ assertFieldInError("doubleValue", "expression.too.big##100.0##2000.0", false);
+ bean.setDoubleValue(3000);
+ assertFieldInError("doubleValue", MESSAGE + ".0", true);
+ assertFieldInError("doubleValue", "expression.too.big##100.0##2000.0", true);
+ }
+
+ protected void testStringType() {
+ assertEquals(null, bean.getStringValue());
+
+ assertFieldInError("stringValue", "expression.stringNotValue##1000", true);
+ assertFieldInError("stringValue", "expression.stringNotValue##1000##3000", true);
+ bean.setStringValue("100");
+
+ assertFieldInError("stringValue", "expression.stringNotValue##1000", true);
+ assertFieldInError("stringValue", "expression.stringNotValue##1000##3000", true);
+
+ bean.setStringValue("1000");
+ assertFieldInError("stringValue", "expression.stringNotValue##1000", false);
+ assertFieldInError("stringValue", "expression.stringNotValue##1000##3000", false);
+
+ bean.setStringValue("3000");
+ assertFieldInError("stringValue", "expression.stringNotValue##1000", true);
+ assertFieldInError("stringValue", "expression.stringNotValue##1000##3000", false);
+ }
+}
\ No newline at end of file
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidatorTest.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -3,7 +3,7 @@
import java.io.File;
/** @author chemit */
-public class NotExistingDirectoryFieldValidatorTest extends AbstractFieldValidatorTest {
+public class NotExistingDirectoryFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest {
@org.junit.Test
@Override
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/NotExistingFileFieldValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/NotExistingFileFieldValidatorTest.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/NotExistingFileFieldValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -3,7 +3,7 @@
import java.io.File;
/** @author chemit */
-public class NotExistingFileFieldValidatorTest extends AbstractFieldValidatorTest {
+public class NotExistingFileFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest {
@org.junit.Test
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/RequiredFileFieldValidatorTest.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/RequiredFileFieldValidatorTest.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/RequiredFileFieldValidatorTest.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -3,7 +3,7 @@
import java.io.File;
/** @author chemit */
-public class RequiredFileFieldValidatorTest extends AbstractFieldValidatorTest {
+public class RequiredFileFieldValidatorTest extends AbstractValidatorBeanFieldValidatorTest {
@org.junit.Test
@Override
Copied: jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ValidatorBean.java (from rev 1273, jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/ValidatorBean.java)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ValidatorBean.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/java/jaxx/runtime/validator/field/ValidatorBean.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,149 @@
+package jaxx.runtime.validator.field;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.io.File;
+import java.util.Collection;
+
+public class ValidatorBean {
+
+ public static class ValidatorBeanEntry {
+
+ protected int intValue;
+ protected String stringValue;
+ protected String stringValue2;
+
+ public ValidatorBeanEntry(int intValue, String stringValue) {
+ this.intValue = intValue;
+ this.stringValue = stringValue;
+ }
+
+ public ValidatorBeanEntry(int intValue, String stringValue, String stringValue2) {
+ this.intValue = intValue;
+ this.stringValue = stringValue;
+ this.stringValue2 = stringValue2;
+ }
+
+ public int getIntValue() {
+ return intValue;
+ }
+
+ public void setIntValue(int intValue) {
+ this.intValue = intValue;
+ }
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public void setStringValue(String stringValue) {
+ this.stringValue = stringValue;
+ }
+
+ public String getStringValue2() {
+ return stringValue2;
+ }
+
+ public void setStringValue2(String stringValue2) {
+ this.stringValue2 = stringValue2;
+ }
+ }
+ protected File existingFile;
+ protected File notExistingFile;
+ protected File existingDirectory;
+ protected File notExistingDirectory;
+ protected Collection<ValidatorBeanEntry> entries;
+ protected String stringValue;
+ protected ValidatorBeanEntry entry;
+ PropertyChangeSupport p;
+
+ public ValidatorBean() {
+ p = new PropertyChangeSupport(this);
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ p.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ p.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ p.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ p.removePropertyChangeListener(propertyName, listener);
+ }
+
+ public String getStringValue() {
+ return stringValue;
+ }
+
+ public File getExistingFile() {
+ return existingFile;
+ }
+
+ public File getNotExistingFile() {
+ return notExistingFile;
+ }
+
+ public File getExistingDirectory() {
+ return existingDirectory;
+ }
+
+ public File getNotExistingDirectory() {
+ return notExistingDirectory;
+ }
+
+ public ValidatorBeanEntry getEntry() {
+ return entry;
+ }
+
+ public Collection<ValidatorBeanEntry> getEntries() {
+ return entries;
+ }
+
+ public void setStringValue(String stringValue) {
+ String old = this.stringValue;
+ this.stringValue = stringValue;
+ p.firePropertyChange("stringValue", old, existingFile);
+ }
+
+ public void setExistingFile(File existingFile) {
+ File old = this.existingFile;
+ this.existingFile = existingFile;
+ p.firePropertyChange("existingFile", old, existingFile);
+ }
+
+ public void setNotExistingFile(File notExistingFile) {
+ File old = this.notExistingFile;
+ this.notExistingFile = notExistingFile;
+ p.firePropertyChange("notExistingFile", old, notExistingFile);
+ }
+
+ public void setExistingDirectory(File existingDirectory) {
+ File old = this.existingDirectory;
+ this.existingDirectory = existingDirectory;
+ p.firePropertyChange("existingDirectory", old, existingDirectory);
+ }
+
+ public void setNotExistingDirectory(File notExistingDirectory) {
+ File old = this.notExistingDirectory;
+ this.notExistingDirectory = notExistingDirectory;
+ p.firePropertyChange("notExistingDirectory", old, notExistingDirectory);
+ }
+
+ public void setEntries(Collection<ValidatorBeanEntry> entries) {
+ this.entries = entries;
+ // set null oldValue to always fire event
+ // otherwise it could been not sent...
+ p.firePropertyChange("entries", null, entries);
+ }
+
+ public void setEntry(ValidatorBeanEntry entry) {
+ this.entry = entry;
+ p.firePropertyChange("entry", null, entry);
+ }
+}
\ No newline at end of file
Deleted: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml 2009-04-04 17:05:55 UTC (rev 1291)
@@ -1,95 +0,0 @@
-<!DOCTYPE validators PUBLIC
- "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
- "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
-<validators>
-
- <field name="stringValue">
- <field-validator type="requiredstring" short-circuit="true">
- <message>stringValue.required</message>
- </field-validator>
- </field>
-
- <field name="existingFile">
- <field-validator type="requiredFile" short-circuit="true">
- <message>existingFile.required</message>
- </field-validator>
- <field-validator type="existingFile" short-circuit="true">
- <message>existingFile.not.exist</message>
- </field-validator>
- </field>
-
- <field name="notExistingFile">
- <field-validator type="requiredFile" short-circuit="true">
- <message>notExistingFile.required</message>
- </field-validator>
- <field-validator type="notExistingFile" short-circuit="true">
- <message>notExistingFile.exist</message>
- </field-validator>
- </field>
-
- <field name="existingDirectory">
- <field-validator type="requiredFile" short-circuit="true">
- <message>existingDirectory.required</message>
- </field-validator>
-
- <field-validator type="existingDirectory" short-circuit="true">
- <message>existingDirectory.not.exist</message>
- </field-validator>
- </field>
-
- <field name="notExistingDirectory">
- <field-validator type="requiredFile" short-circuit="true">
- <message>notExistingDirectory.required</message>
- </field-validator>
-
- <field-validator type="notExistingDirectory" short-circuit="true">
- <message>notExistingDirectory.exist</message>
- </field-validator>
- </field>
-
- <field name="entries">
- <field-validator type="collectionFieldExpression">
- <param name="mode">AT_LEAST_ONE</param>
- <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
- <message>collectionFieldExpression.atLeastOne</message>
- </field-validator>
- <field-validator type="collectionFieldExpression">
- <param name="mode">EXACTLY_ONE</param>
- <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
- <message>collectionFieldExpression.exactlyOne</message>
- </field-validator>
- <field-validator type="collectionFieldExpression">
- <param name="mode">ALL</param>
- <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
- <message>collectionFieldExpression.all</message>
- </field-validator>
- <field-validator type="collectionFieldExpression">
- <param name="mode">NONE</param>
- <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]></param>
- <message>collectionFieldExpression.none</message>
- </field-validator>
-
- <field-validator type="collectionUniqueKey">
- <param name="keys">intValue</param>
- <message>collectionUniqueKey.one.failed</message>
- </field-validator>
- <field-validator type="collectionUniqueKey">
- <param name="keys">stringValue</param>
- <message>collectionUniqueKey.two.failed</message>
- </field-validator>
- <field-validator type="collectionUniqueKey">
- <param name="keys">intValue,stringValue</param>
- <message>collectionUniqueKey.three.failed</message>
- </field-validator>
- <field-validator type="collectionUniqueKey">
- <param name="keys">intValue,stringValue,stringValue2</param>
- <message>collectionUniqueKey.four.failed</message>
- </field-validator>
- <field-validator type="collectionUniqueKey">
- <param name="keys">stringValue</param>
- <param name="againstProperty">entry</param>
- <message>collectionUniqueKey.five.failed</message>
- </field-validator>
- </field>
-
-</validators>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/FieldExpressionBean-error-validation.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/FieldExpressionBean-error-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/FieldExpressionBean-error-validation.xml 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,99 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+
+<field name="booleanValue">
+ <field-validator type="fieldexpressionwithparams">
+ <param name="booleanParams">boolean:true</param>
+ <param name="expression"><![CDATA[ booleanValue == booleans.boolean]]>
+ </param>
+ <message>expression.boolean.not.equals##${booleans.boolean}</message>
+ </field-validator>
+ <field-validator type="fieldexpressionwithparams">
+ <param name="booleanParams">boolean:false</param>
+ <param name="expression"><![CDATA[ booleanValue == booleans.boolean]]>
+ </param>
+ <message>expression.boolean.not.equals##${booleans.boolean}</message>
+ </field-validator>
+ </field>
+
+ <field name="shortValue">
+ <field-validator type="fieldexpressionwithparams">
+ <param name="shortParams">short:100</param>
+ <param name="expression"><![CDATA[ shortValue < shorts.short]]>
+ </param>
+ <message>expression.too.big##${shorts.short}</message>
+ </field-validator>
+ <field-validator type="fieldexpressionwithparams">
+ <param name="shortParams">short:100|short2:2000</param>
+ <param name="expression"><![CDATA[ shortValue < shorts.short || shortValue < shorts.short2]]>
+ </param>
+ <message>expression.too.big##${shorts.short}##${shorts.short2}</message>
+ </field-validator>
+ </field>
+
+ <field name="intValue">
+ <field-validator type="fieldexpressionwithparams">
+ <param name="intParams">int:100</param>
+ <param name="expression"><![CDATA[ intValue < ints.int]]>
+ </param>
+ <message>expression.too.big##${ints.int}</message>
+ </field-validator>
+ <field-validator type="fieldexpressionwithparams">
+ <param name="intParams">int:100|int2:2000</param>
+ <param name="expression"><![CDATA[ intValue < ints.int || intValue < ints.int2]]>
+ </param>
+ <message>expression.too.big##${ints.int}##${ints.int2}</message>
+ </field-validator>
+ </field>
+
+ <field name="longValue">
+ <field-validator type="fieldexpressionwithparams">
+ <param name="longParams">long:100</param>
+ <param name="expression"><![CDATA[ longValue < longs.long]]>
+ </param>
+ <message>expression.too.big##${longs.long}</message>
+ </field-validator>
+ <field-validator type="fieldexpressionwithparams">
+ <param name="longParams">long:100|long2:2000</param>
+ <param name="expression"><![CDATA[ longValue < longs.long || longValue < longs.long2]]>
+ </param>
+ <message>expression.too.big##${longs.long}##${longs.long2}</message>
+ </field-validator>
+ </field>
+
+ <field name="doubleValue">
+ <field-validator type="fieldexpressionwithparams">
+ <param name="doubleParams">double:100.0</param>
+ <param name="expression"><![CDATA[ doubleValue < doubles.double]]>
+ </param>
+ <message>expression.too.big##${doubles.double}</message>
+ </field-validator>
+ <field-validator type="fieldexpressionwithparams">
+ <param name="doubleParams">double:100.0|double2:2000.0</param>
+ <param name="expression"><![CDATA[ doubleValue < doubles.double || doubleValue < doubles.double2]]>
+ </param>
+ <message>expression.too.big##${doubles.double}##${doubles.double2}</message>
+ </field-validator>
+ </field>
+
+ <field name="stringValue">
+ <field-validator type="fieldexpressionwithparams">
+ <param name="stringParams">string:1000</param>
+ <param name="expression"><![CDATA[ stringValue.equals(strings.string)]]>
+ </param>
+ <message>expression.stringNotValue##${strings.string}</message>
+ </field-validator>
+ <field-validator type="fieldexpressionwithparams">
+ <param name="stringParams">string:1000|string2:3000</param>
+ <param name="expression"><![CDATA[ stringValue.equals(strings.string) || stringValue.equals(strings.string2)]]>
+ </param>
+ <message>expression.stringNotValue##${strings.string}##${strings.string2}</message>
+ </field-validator>
+ </field>
+
+
+
+
+</validators>
\ No newline at end of file
Copied: jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/ValidatorBean-error-validation.xml (from rev 1274, jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/ValidatorBean-error-validation.xml)
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/ValidatorBean-error-validation.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/jaxx/runtime/validator/field/ValidatorBean-error-validation.xml 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,155 @@
+<!DOCTYPE validators PUBLIC
+ "-//OpenSymphony Group//XWork Validator 1.0.2//EN"
+ "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd">
+<validators>
+
+ <field name="stringValue">
+ <field-validator type="requiredstring" short-circuit="true">
+ <message>stringValue.required</message>
+ </field-validator>
+ </field>
+
+ <field name="existingFile">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>existingFile.required</message>
+ </field-validator>
+ <field-validator type="existingFile" short-circuit="true">
+ <message>existingFile.not.exist</message>
+ </field-validator>
+ </field>
+
+ <field name="notExistingFile">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>notExistingFile.required</message>
+ </field-validator>
+ <field-validator type="notExistingFile" short-circuit="true">
+ <message>notExistingFile.exist</message>
+ </field-validator>
+ </field>
+
+ <field name="existingDirectory">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>existingDirectory.required</message>
+ </field-validator>
+
+ <field-validator type="existingDirectory" short-circuit="true">
+ <message>existingDirectory.not.exist</message>
+ </field-validator>
+ </field>
+
+ <field name="notExistingDirectory">
+ <field-validator type="requiredFile" short-circuit="true">
+ <message>notExistingDirectory.required</message>
+ </field-validator>
+
+ <field-validator type="notExistingDirectory" short-circuit="true">
+ <message>notExistingDirectory.exist</message>
+ </field-validator>
+ </field>
+
+ <field name="entries">
+
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">intValue</param>
+ <message>collectionUniqueKey.one.failed</message>
+ </field-validator>
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">stringValue</param>
+ <message>collectionUniqueKey.two.failed</message>
+ </field-validator>
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">intValue,stringValue</param>
+ <message>collectionUniqueKey.three.failed</message>
+ </field-validator>
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">intValue,stringValue,stringValue2</param>
+ <message>collectionUniqueKey.four.failed</message>
+ </field-validator>
+ <field-validator type="collectionUniqueKey">
+ <param name="keys">stringValue</param>
+ <param name="againstProperty">entry</param>
+ <message>collectionUniqueKey.five.failed</message>
+ </field-validator>
+
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">AT_LEAST_ONE</param>
+ <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]>
+ </param>
+ <message>collectionFieldExpression.atLeastOne</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">EXACTLY_ONE</param>
+ <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]>
+ </param>
+ <message>collectionFieldExpression.exactlyOne</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">ALL</param>
+ <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]>
+ </param>
+ <message>collectionFieldExpression.all</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">NONE</param>
+ <param name="expression"><![CDATA[ intValue == 0 && stringValue == "stringValue" ]]>
+ </param>
+ <message>collectionFieldExpression.none</message>
+ </field-validator>
+
+ <!-- useContext -->
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">AT_LEAST_ONE</param>
+ <param name="useSensitiveContext">true</param>
+ <param name="expression"><![CDATA[ size > 1 && previous != null && previous.intValue < current.intValue]]></param>
+ <message>collectionFieldExpression.atLeastOne.useSensitiveContext</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">EXACTLY_ONE</param>
+ <param name="useSensitiveContext">true</param>
+ <param name="expression"><![CDATA[ size > 1 && previous != null && ( previous.intValue == 2 + current.intValue || current.intValue == 2 + previous.intValue) ]]></param>
+ <message>collectionFieldExpression.exactlyOne.useSensitiveContext</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">ALL</param>
+ <param name="useSensitiveContext">true</param>
+ <param name="expression"><![CDATA[ size > 1 && (previous == null || previous.intValue < current.intValue)]]></param>
+ <message>collectionFieldExpression.all.useSensitiveContext</message>
+ </field-validator>
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">NONE</param>
+ <param name="useSensitiveContext">true</param>
+ <param name="expression"><![CDATA[ size > 1 && previous != null && ( current.intValue == 2 + previous.intValue)]]></param>
+ <message>collectionFieldExpression.none.useSensitiveContext</message>
+ </field-validator>
+
+ <!-- useFirst -->
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">ALL</param>
+ <param name="useSensitiveContext">true</param>
+ <param name="expressionForFirst"><![CDATA[ current.intValue == 0]]></param>
+ <param name="expression"><![CDATA[ previous == null || previous.intValue < current.intValue]]></param>
+ <message>collectionFieldExpression.all.useFirst</message>
+ </field-validator>
+
+ <!-- useLast -->
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">ALL</param>
+ <param name="useSensitiveContext">true</param>
+ <param name="expressionForLast"><![CDATA[ current.intValue > 0]]></param>
+ <param name="expression"><![CDATA[ previous == null || previous.intValue < current.intValue]]></param>
+ <message>collectionFieldExpression.all.useLast</message>
+ </field-validator>
+
+ <!-- useFirstAndLast -->
+ <field-validator type="collectionFieldExpression">
+ <param name="mode">ALL</param>
+ <param name="useSensitiveContext">true</param>
+ <param name="expressionForFirst"><![CDATA[ current.intValue == 0]]></param>
+ <param name="expressionForLast"><![CDATA[ current.intValue > 0]]></param>
+ <param name="expression"><![CDATA[ previous == null || previous.intValue < current.intValue]]></param>
+ <message>collectionFieldExpression.all.useFirstAndLast</message>
+ </field-validator>
+
+ </field>
+
+</validators>
\ No newline at end of file
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/resources/log4j.properties
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/log4j.properties 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/log4j.properties 2009-04-04 17:05:55 UTC (rev 1291)
@@ -6,3 +6,4 @@
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n
log4j.logger.jaxx=INFO
+log4j.logger.jaxx.runtime.validator.field=DEBUG
Modified: jaxx/trunk/jaxx-runtime-validator/src/test/resources/validators.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator/src/test/resources/validators.xml 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator/src/test/resources/validators.xml 2009-04-04 17:05:55 UTC (rev 1291)
@@ -31,5 +31,6 @@
<validator name="notExistingFile" class="jaxx.runtime.validator.field.NotExistingFileFieldValidator"/>
<validator name="existingDirectory" class="jaxx.runtime.validator.field.ExistingDirectoryFieldValidator"/>
<validator name="notExistingDirectory" class="jaxx.runtime.validator.field.NotExistingDirectoryFieldValidator"/>
+ <validator name="fieldexpressionwithparams" class="jaxx.runtime.validator.field.FieldExpressionWithParamsValidator"/>
</validators>
\ No newline at end of file
Modified: jaxx/trunk/jaxx-runtime-validator-swing/pom.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/pom.xml 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator-swing/pom.xml 2009-04-04 17:05:55 UTC (rev 1291)
@@ -45,6 +45,23 @@
<!-- ************************************************************* -->
<packaging>jar</packaging>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.codelutin</groupId>
+ <artifactId>maven-i18n-plugin</artifactId>
+ <version>${i18n.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>parserJava</goal>
+ <goal>gen</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
<!-- ************************************************************* -->
<!-- *** Build Environment ************************************** -->
<!-- ************************************************************* -->
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/SwingValidatorUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/SwingValidatorUtil.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/SwingValidatorUtil.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -9,10 +9,13 @@
import java.awt.event.MouseListener;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
+import javax.swing.RowSorter;
+import javax.swing.SortOrder;
import jaxx.runtime.validator.swing.SwingValidatorMessageTableMouseListener;
import jaxx.runtime.validator.swing.SwingValidatorMessageListMouseListener;
import jaxx.runtime.validator.swing.SwingValidatorMessage;
-import org.codelutin.i18n.I18n;
+import jaxx.runtime.validator.swing.SwingValidatorMessageTableRenderer;
+import static org.codelutin.i18n.I18n.n_;
/**
* The helper class for validation module.
@@ -53,6 +56,26 @@
}
/**
+ * Prepare the ui where to display the validators messages.
+ *
+ * @param errorTable the table where to display validators messages
+ */
+ public static void installUI(JTable errorTable, SwingValidatorMessageTableRenderer render) {
+ errorTable.setDefaultRenderer(Object.class, render);
+ errorTable.getRowSorter().setSortKeys(java.util.Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
+ SwingUtil.setI18nTableHeaderRenderer(errorTable,
+ n_("validator.scope.header"),
+ n_("validator.scope.header.tip"),
+ n_("validator.field.header"),
+ n_("validator.field.header.tip"),
+ n_("validator.message.header"),
+ n_("validator.message.header.tip"));
+ // register a single 'goto widget error' mouse listener on errorTable
+ registerErrorTableMouseListener(errorTable);
+ SwingUtil.fixTableColumnWidth(errorTable, 0, 25);
+ }
+
+ /**
* Register for a given validator list ui a validator mouse listener.
*
* Note: there is only one listener registred for a given list model, so
@@ -145,11 +168,11 @@
JComponent editor = model.getEditor();
if (editor != null) {
text = (String) editor.getClientProperty("validatorLabel");
- /*if (l != null) {
- text = I18n._(l);
- } else {
- // TODO should try the text
- }*/
+ /*if (l != null) {
+ text = I18n._(l);
+ } else {
+ // TODO should try the text
+ }*/
}
if (text == null) {
text = value;
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageListRenderer.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -7,6 +7,7 @@
import javax.swing.DefaultListCellRenderer;
import jaxx.runtime.validator.BeanValidatorScope;
import jaxx.runtime.SwingValidatorUtil;
+import static org.codelutin.i18n.I18n._;
/**
* A simple render of a table of validator's messages, says a table that use
@@ -20,6 +21,7 @@
private static final long serialVersionUID = 1L;
protected String format = "%1$-20s - %2$s";
+ protected String formatTip = "%1$-20s - %2$-20s : %3$s";
public SwingValidatorMessageListRenderer() {
}
@@ -42,7 +44,7 @@
JLabel rendererComponent = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
SwingValidatorMessage model = (SwingValidatorMessage) value;
-
+
// scope
ImageIcon icon = SwingValidatorUtil.getIcon(model.getScope());
@@ -55,7 +57,15 @@
// text to display
String text = String.format(format, fieldName, message);
+ String label = _(model.getScope().getLabel());
+ String tmp = _("validator.scope.tip", label);
+ String tmp2 = _("validator.field.tip", fieldName);
+
+ String tooltTipText = String.format(formatTip, tmp, tmp2, message);
+
+
rendererComponent.setText(text);
+ rendererComponent.setToolTipText(tooltTipText);
rendererComponent.setIcon(icon);
return rendererComponent;
Modified: jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java 2009-04-03 10:36:56 UTC (rev 1290)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/java/jaxx/runtime/validator/swing/SwingValidatorMessageTableRenderer.java 2009-04-04 17:05:55 UTC (rev 1291)
@@ -7,6 +7,7 @@
import java.awt.Component;
import jaxx.runtime.validator.BeanValidatorScope;
import jaxx.runtime.SwingValidatorUtil;
+import static org.codelutin.i18n.I18n._;
/**
* A simple render of a table of validator's messages, says a table that use
@@ -26,30 +27,38 @@
ImageIcon icon = null;
String text = null;
+ String toolTipText = null;
column = table.convertColumnIndexToModel(column);
if (table.getRowSorter() != null) {
row = table.getRowSorter().convertRowIndexToModel(row);
}
+
switch (column) {
case 0:
- // scope
- icon = SwingValidatorUtil.getIcon((BeanValidatorScope) value);
+ // scope
+ BeanValidatorScope scope = (BeanValidatorScope) value;
+ icon = SwingValidatorUtil.getIcon(scope);
+ String label = _(scope.getLabel());
+ toolTipText = _("validator.scope.tip", label);
break;
case 1:
// field name
text = getFieldName(table, (String) value, row);
+ toolTipText = _("validator.field.tip", text);
break;
case 2:
// message
text = getMessage(table, (String) value, row);
+ toolTipText = _("validator.message.tip", text);
break;
}
rendererComponent.setText(text);
+ rendererComponent.setToolTipText(toolTipText);
rendererComponent.setIcon(icon);
return rendererComponent;
}
Added: jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/jaxx-runtime-validator-swing-en_GB.properties
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/jaxx-runtime-validator-swing-en_GB.properties (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/jaxx-runtime-validator-swing-en_GB.properties 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,9 @@
+validator.field.header=Property
+validator.field.header.tip=Property on which message occurs
+validator.field.tip=Property '%1$s'
+validator.message.header=Message
+validator.message.header.tip=The message text
+validator.message.tip=Message \: %1$s
+validator.scope.header=...
+validator.scope.header.tip=The message scope
+validator.scope.tip=Message scope \: '%1$s'
Added: jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/jaxx-runtime-validator-swing-fr_FR.properties
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/jaxx-runtime-validator-swing-fr_FR.properties (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-swing/src/main/resources/i18n/jaxx-runtime-validator-swing-fr_FR.properties 2009-04-04 17:05:55 UTC (rev 1291)
@@ -0,0 +1,9 @@
+validator.field.header=Champ
+validator.field.header.tip=Le champ surquel intervient le message
+validator.field.tip=Propri\u00E9t\u00E9 '%1$s'
+validator.message.header=Message
+validator.message.header.tip=Le texte du message
+validator.message.tip=Message \: %1$s
+validator.scope.header=...
+validator.scope.header.tip=Le de type de message
+validator.scope.tip=Type de message \: '%1$s'
1
0
[Buix-commits] r1290 - jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler
by kmorin@users.labs.libre-entreprise.org 03 Apr '09
by kmorin@users.labs.libre-entreprise.org 03 Apr '09
03 Apr '09
Author: kmorin
Date: 2009-04-03 10:36:56 +0000 (Fri, 03 Apr 2009)
New Revision: 1290
Added:
jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingBoxedCompiledObjectDecorator.java
jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingHelpRootCompiledObjectDecorator.java
Removed:
jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/BoxedCompiledObjectDecorator.java
jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/HelpRootCompiledObjectDecorator.java
Log:
Diff?\195?\169rentiation entre les Decorator de Swing et de GWT.
Deleted: jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/BoxedCompiledObjectDecorator.java
===================================================================
--- jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/BoxedCompiledObjectDecorator.java 2009-04-03 09:51:27 UTC (rev 1289)
+++ jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/BoxedCompiledObjectDecorator.java 2009-04-03 10:36:56 UTC (rev 1290)
@@ -1,27 +0,0 @@
-package jaxx.compiler;
-
-import jaxx.compiler.CompiledObject.ChildRef;
-import jaxx.runtime.SwingUtil;
-
-/**
- * A decorator to surround a compiled object (should be a component at least)
- * with a JXLayer.
- *
- * @author tony
- * @since 1.2
- */
-public class BoxedCompiledObjectDecorator extends DefaultCompiledObjectDecorator {
-
- @Override
- public void finalizeCompiler(JAXXCompiler compiler, CompiledObject root, CompiledObject object, JavaFile javaFile, String packageName, String className, String fullClassName) {
- CompiledObject parent = object.getParent();
- for (ChildRef child : parent.getChilds()) {
- if (child.getChild() == object) {
- String javaCode = child.getChildJavaCode();
- child.setChildJavaCode(SwingUtil.class.getName()+".boxComponentWithJxLayer(" + javaCode + ")");
- break;
- }
- }
- super.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName);
- }
-}
Deleted: jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/HelpRootCompiledObjectDecorator.java
===================================================================
--- jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/HelpRootCompiledObjectDecorator.java 2009-04-03 09:51:27 UTC (rev 1289)
+++ jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/HelpRootCompiledObjectDecorator.java 2009-04-03 10:36:56 UTC (rev 1290)
@@ -1,93 +0,0 @@
-package jaxx.compiler;
-
-import java.lang.reflect.Modifier;
-import java.util.Iterator;
-import java.util.Set;
-
-/**
- * A decorator to place on a root compiled object to process javaHelp on the file.
- *
- * @author tony
- * @since 1.2
- */
-public class HelpRootCompiledObjectDecorator extends DefaultCompiledObjectDecorator {
-
- /**
- * the list of discovered helpId
- */
- protected static Set<String> helpIds = new java.util.HashSet<String>();
-
- protected String getBrokerFQN(JAXXCompiler compiler) {
- String helpBrokerFQN = compiler.getOptions().getHelpBrokerFQN();
- return helpBrokerFQN;
- }
-
- protected String getHelpId(CompiledObject o) {
- String helpID = null;
- if (o.hasClientProperties()) {
- helpID = o.getClientProperty("help");
- }
- return helpID;
- }
-
- @Override
- public void finalizeCompiler(JAXXCompiler compiler, CompiledObject root, CompiledObject object, JavaFile javaFile, String packageName, String className, String fullClassName) {
- super.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName);
- CompilerOptions options = compiler.getOptions();
-
- if (options.isGenerateHelp()) {
-
- // add JaxxHelpUI interface
- Class<?> validatorInterface = jaxx.runtime.JaxxHelpUI.class;
- String helpBrokerFQN = getBrokerFQN(compiler);
- javaFile.addInterface(JAXXCompiler.getCanonicalName(validatorInterface) + "<" + helpBrokerFQN + ">");
-
- javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "registerHelpId",
- "broker.installUI(component, helpId);",
- new JavaArgument(helpBrokerFQN, "broker"),
- new JavaArgument("Component", "component"),
- new JavaArgument("String", "helpId")));
-
- javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "showHelp",
- "getBroker().showHelp(this, helpId);",
- new JavaArgument("String", "helpId")));
-
- StringBuilder buffer = new StringBuilder();
-
- String lineSeparator = JAXXCompiler.getLineSeparator();
-
- if (options.isGenerateHelp()) {
-
- // add code to init javax help system
- Iterator<CompiledObject> itr = compiler.getObjectCreationOrder();
-
- for (; itr.hasNext();) {
- CompiledObject o = itr.next();
- String helpID = getHelpId(o);
- if (helpID != null) {
- buffer.append(lineSeparator);
- // detects a helpId to register
- buffer.append("registerHelpId(_broker, " + o.getJavaCode() + ", " + helpID + ");");
- //keep the helpID for helpSet generation
- helpIds.add(helpID);
- }
- }
- }
- if (buffer.length() > 0) {
-
- StringBuilder extraCode = new StringBuilder(helpBrokerFQN).append(" _broker = getBroker();");
-
- buffer.append(lineSeparator).append("_broker.prepareUI(this);");
- buffer.append(lineSeparator);
-
- // add the calls
- compiler.appendLateInitializer(extraCode.toString());
- compiler.appendLateInitializer(buffer.toString());
- }
- }
- }
-
- public static Set<String> getHelpIds() {
- return helpIds;
- }
-}
Added: jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingBoxedCompiledObjectDecorator.java
===================================================================
--- jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingBoxedCompiledObjectDecorator.java (rev 0)
+++ jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingBoxedCompiledObjectDecorator.java 2009-04-03 10:36:56 UTC (rev 1290)
@@ -0,0 +1,27 @@
+package jaxx.compiler;
+
+import jaxx.compiler.CompiledObject.ChildRef;
+import jaxx.runtime.SwingUtil;
+
+/**
+ * A decorator to surround a compiled object (should be a component at least)
+ * with a JXLayer.
+ *
+ * @author tony
+ * @since 1.2
+ */
+public class SwingBoxedCompiledObjectDecorator extends DefaultCompiledObjectDecorator {
+
+ @Override
+ public void finalizeCompiler(JAXXCompiler compiler, CompiledObject root, CompiledObject object, JavaFile javaFile, String packageName, String className, String fullClassName) {
+ CompiledObject parent = object.getParent();
+ for (ChildRef child : parent.getChilds()) {
+ if (child.getChild() == object) {
+ String javaCode = child.getChildJavaCode();
+ child.setChildJavaCode(SwingUtil.class.getName()+".boxComponentWithJxLayer(" + javaCode + ")");
+ break;
+ }
+ }
+ super.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName);
+ }
+}
Added: jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingHelpRootCompiledObjectDecorator.java
===================================================================
--- jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingHelpRootCompiledObjectDecorator.java (rev 0)
+++ jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingHelpRootCompiledObjectDecorator.java 2009-04-03 10:36:56 UTC (rev 1290)
@@ -0,0 +1,93 @@
+package jaxx.compiler;
+
+import java.lang.reflect.Modifier;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * A decorator to place on a root compiled object to process javaHelp on the file.
+ *
+ * @author tony
+ * @since 1.2
+ */
+public class SwingHelpRootCompiledObjectDecorator extends DefaultCompiledObjectDecorator {
+
+ /**
+ * the list of discovered helpId
+ */
+ protected static Set<String> helpIds = new java.util.HashSet<String>();
+
+ protected String getBrokerFQN(JAXXCompiler compiler) {
+ String helpBrokerFQN = compiler.getOptions().getHelpBrokerFQN();
+ return helpBrokerFQN;
+ }
+
+ protected String getHelpId(CompiledObject o) {
+ String helpID = null;
+ if (o.hasClientProperties()) {
+ helpID = o.getClientProperty("help");
+ }
+ return helpID;
+ }
+
+ @Override
+ public void finalizeCompiler(JAXXCompiler compiler, CompiledObject root, CompiledObject object, JavaFile javaFile, String packageName, String className, String fullClassName) {
+ super.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName);
+ CompilerOptions options = compiler.getOptions();
+
+ if (options.isGenerateHelp()) {
+
+ // add JaxxHelpUI interface
+ Class<?> validatorInterface = jaxx.runtime.JaxxHelpUI.class;
+ String helpBrokerFQN = getBrokerFQN(compiler);
+ javaFile.addInterface(JAXXCompiler.getCanonicalName(validatorInterface) + "<" + helpBrokerFQN + ">");
+
+ javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "registerHelpId",
+ "broker.installUI(component, helpId);",
+ new JavaArgument(helpBrokerFQN, "broker"),
+ new JavaArgument("Component", "component"),
+ new JavaArgument("String", "helpId")));
+
+ javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "showHelp",
+ "getBroker().showHelp(this, helpId);",
+ new JavaArgument("String", "helpId")));
+
+ StringBuilder buffer = new StringBuilder();
+
+ String lineSeparator = JAXXCompiler.getLineSeparator();
+
+ if (options.isGenerateHelp()) {
+
+ // add code to init javax help system
+ Iterator<CompiledObject> itr = compiler.getObjectCreationOrder();
+
+ for (; itr.hasNext();) {
+ CompiledObject o = itr.next();
+ String helpID = getHelpId(o);
+ if (helpID != null) {
+ buffer.append(lineSeparator);
+ // detects a helpId to register
+ buffer.append("registerHelpId(_broker, " + o.getJavaCode() + ", " + helpID + ");");
+ //keep the helpID for helpSet generation
+ helpIds.add(helpID);
+ }
+ }
+ }
+ if (buffer.length() > 0) {
+
+ StringBuilder extraCode = new StringBuilder(helpBrokerFQN).append(" _broker = getBroker();");
+
+ buffer.append(lineSeparator).append("_broker.prepareUI(this);");
+ buffer.append(lineSeparator);
+
+ // add the calls
+ compiler.appendLateInitializer(extraCode.toString());
+ compiler.appendLateInitializer(buffer.toString());
+ }
+ }
+ }
+
+ public static Set<String> getHelpIds() {
+ return helpIds;
+ }
+}
1
0
Author: kmorin
Date: 2009-04-03 09:51:27 +0000 (Fri, 03 Apr 2009)
New Revision: 1289
Added:
jaxx/trunk/
Removed:
jaxx/1.3/
Log:
Copied: jaxx/trunk (from rev 1288, jaxx/1.3)
1
0
03 Apr '09
Author: kmorin
Date: 2009-04-03 09:50:29 +0000 (Fri, 03 Apr 2009)
New Revision: 1288
Added:
jaxx/1.3/
jaxx/1.3/jaxx-example/
Removed:
jaxx/1.3/jaxx-example/
jaxx/tags/1.3/
Log:
Copied: jaxx/1.3 (from rev 1286, jaxx/tags/1.3)
Copied: jaxx/1.3/jaxx-example (from rev 1287, jaxx/tags/1.3/jaxx-example)
1
0
03 Apr '09
Author: kmorin
Date: 2009-04-03 09:44:32 +0000 (Fri, 03 Apr 2009)
New Revision: 1287
Added:
jaxx-gwt/
jaxx-gwt/trunk/
Removed:
jaxx/trunk/
Modified:
jaxx-gwt/trunk/jaxx-compiler-api/pom.xml
jaxx-gwt/trunk/jaxx-compiler-api/src/main/java/jaxx/tags/TagManager.java
jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/GWTInitializer.java
jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTGenerator.java
jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTabbedPaneHandler.java
jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ListHandler.java
jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RadioButtonHandler.java
jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TreeHandler.java
jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/SwingInitializer.java
jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java
jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java
jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java
jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java
jaxx-gwt/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java
jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/JDialogDemo.jaxx
jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx
jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx
Log:
Modified: jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/JDialogDemo.jaxx
===================================================================
--- jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/JDialogDemo.jaxx 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/JDialogDemo.jaxx 2009-04-03 09:44:32 UTC (rev 1287)
@@ -76,4 +76,4 @@
<JLabel text='{password != null ? "Password: " + password : ""}'/>
</VBox>
</VBox>
-</DemoPanel>
\ No newline at end of file
+</DemoPanel>
Modified: jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx
===================================================================
--- jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/ValidationListDemo.jaxx 2009-04-03 09:44:32 UTC (rev 1287)
@@ -12,22 +12,22 @@
<Identity id='identity'/>
<!-- errors model -->
- <jaxx.runtime.validator.swing.SwingValidatorMessageListModel id='errors'
+ <jaxx.runtime.validator.gwt.GWTValidatorMessageListModel id='errors'
onContentsChanged='ok.setEnabled(errors.isEmpty())'/>
<!-- validators -->
- <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.swing.ui.ImageValidationUI">
+ <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.gwt.ui.ImageValidationUI">
<field name="text"/>
<field name="text2"/>
<field name="ratio"/>
</BeanValidator>
- <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.swing.ui.IconValidationUI">
+ <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.gwt.ui.IconValidationUI">
<field name="text" component="_text"/>
<field name="text2" component="_text2"/>
<field name="ratio" component="_ratio"/>
</BeanValidator>
<BeanValidator id='validator3' autoField='true' bean='identity'
- uiClass="jaxx.runtime.validator.swing.ui.TranslucentValidationUI">
+ uiClass="jaxx.runtime.validator.gwt.ui.TranslucentValidationUI">
<field name="email" component="email2"/>
</BeanValidator>
@@ -320,4 +320,4 @@
</row>
</Table>
-</DemoPanel>
\ No newline at end of file
+</DemoPanel>
Modified: jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx
===================================================================
--- jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx/tags/1.3/jaxx-example/src/main/java/jaxx/demo/ValidationTableDemo.jaxx 2009-04-03 09:44:32 UTC (rev 1287)
@@ -7,22 +7,22 @@
<Identity id='identity'/>
<!-- errors model -->
- <jaxx.runtime.validator.swing.SwingValidatorMessageTableModel id='errors2'
+ <jaxx.runtime.validator.gwt.GWTValidatorMessageTableModel id='errors2'
onTableChanged='ok.setEnabled(errors2.getRowCount()==0)'/>
<!-- validators -->
- <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.swing.ui.ImageValidationUI">
+ <BeanValidator id='validator' bean='model1' uiClass="jaxx.runtime.validator.gwt.ui.ImageValidationUI">
<field name="text"/>
<field name="text2"/>
<field name="ratio"/>
</BeanValidator>
- <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.swing.ui.IconValidationUI">
+ <BeanValidator id='validator2' bean='model2' uiClass="jaxx.runtime.validator.gwt.ui.IconValidationUI">
<field name="text" component="_text"/>
<field name="text2" component="_text2"/>
<field name="ratio" component="_ratio"/>
</BeanValidator>
<BeanValidator id='validator3' autoField='true' bean='identity'
- uiClass="jaxx.runtime.validator.swing.ui.TranslucentValidationUI">
+ uiClass="jaxx.runtime.validator.gwt.ui.TranslucentValidationUI">
<field name="email" component="email2"/>
</BeanValidator>
@@ -31,7 +31,7 @@
import jaxx.runtime.SwingUtil;
void $afterCompleteSetup() {
- errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.swing.SwingValidatorMessageTableRenderer());
+ errorTable.setDefaultRenderer(Object.class, new jaxx.runtime.validator.gwt.SwingValidatorMessageTableRenderer());
errorTable.getRowSorter().setSortKeys(java.util.Arrays.asList(new RowSorter.SortKey(0, SortOrder.ASCENDING)));
SwingUtil.setI18nTableHeaderRenderer(errorTable, n_("validator.scope"), n_("validator.scope.tip"), n_("validator.field"), n_("validator.field.tip"), n_("validator.message"), n_("validator.message.tip"));
SwingUtil.fixTableColumnWidth(errorTable, 0, 25);
@@ -329,4 +329,4 @@
</row>
</Table>
-</DemoPanel>
\ No newline at end of file
+</DemoPanel>
Copied: jaxx-gwt/trunk (from rev 1286, jaxx/trunk)
Modified: jaxx-gwt/trunk/jaxx-compiler-api/pom.xml
===================================================================
--- jaxx/trunk/jaxx-compiler-api/pom.xml 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-api/pom.xml 2009-04-03 09:44:32 UTC (rev 1287)
@@ -26,6 +26,18 @@
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-swing</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
</dependencies>
<!-- ************************************************************* -->
Modified: jaxx-gwt/trunk/jaxx-compiler-api/src/main/java/jaxx/tags/TagManager.java
===================================================================
--- jaxx/trunk/jaxx-compiler-api/src/main/java/jaxx/tags/TagManager.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-api/src/main/java/jaxx/tags/TagManager.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -136,7 +136,9 @@
* @param namespace namespace
*/
public static void registerDefaultNamespace(String tag, String namespace) {
- if (defaultNamespaces.containsKey(tag) && !defaultNamespaces.get(tag).equals(namespace)) {
+ if (defaultNamespaces.containsKey(tag)
+ && defaultNamespaces.get(tag) != null
+ && !defaultNamespaces.get(tag).equals(namespace)) {
defaultNamespaces.put(tag, null); // tag name is now ambiguous
} else {
defaultNamespaces.put(tag, namespace);
@@ -327,7 +329,7 @@
* @throws jaxx.CompilerException ?
*/
public static TagHandler getTagHandler(String namespace, String tag, boolean namespacePrefix, JAXXCompiler compiler) throws CompilerException {
- if (tag == null) {
+ if (tag == null) {
throw new NullPointerException();
}
if (namespace == null && defaultNamespaces.containsKey(tag)) {
Modified: jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/GWTInitializer.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/GWTInitializer.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/GWTInitializer.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -29,9 +29,9 @@
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.Insets;
-import jaxx.compiler.BoxedCompiledObjectDecorator;
+import jaxx.compiler.GWTBoxedCompiledObjectDecorator;
import jaxx.compiler.CompiledObjectDecorator;
-import jaxx.compiler.HelpRootCompiledObjectDecorator;
+import jaxx.compiler.GWTHelpRootCompiledObjectDecorator;
import com.google.gwt.user.client.ui.*;
@@ -79,7 +79,7 @@
TagManager.registerDefaultNamespace("JTextPane", "javax.swing.*");
TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "tab", new TabHandler());
- TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(Table.class), TableHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(jaxx.runtime.gwt.Table.class), TableHandler.class);
TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "row", new RowHandler());
TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "cell", new CellHandler());
TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "item", new ItemHandler());
@@ -91,7 +91,7 @@
TypeManager.registerTypeConverter(Insets.class, new InsetsConverter());
TypeManager.registerTypeConverter(KeyStroke.class, new KeyStrokeConverter());
- //CompiledObjectDecorator.registerDecorator("boxed", BoxedCompiledObjectDecorator.class);
- //CompiledObjectDecorator.registerDecorator("help", HelpRootCompiledObjectDecorator.class);
+ CompiledObjectDecorator.registerDecorator("boxed", GWTBoxedCompiledObjectDecorator.class);
+ CompiledObjectDecorator.registerDecorator("help", GWTHelpRootCompiledObjectDecorator.class);
}
}
\ No newline at end of file
Modified: jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTGenerator.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTGenerator.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTGenerator.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -15,13 +15,12 @@
public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException {
//TODO : move this to jaxx-compiler-swing generator
- if (ClassDescriptorLoader.getClassDescriptor("jaxx.runtime.swing.Application").isAssignableFrom(root.getObjectClass()) && !compiler.isMainDeclared()) {
+ if (ClassDescriptorLoader.getClassDescriptor("jaxx.runtime.gwt.Application").isAssignableFrom(root.getObjectClass()) && !compiler.isMainDeclared()) {
// TODO: check for existing main method first
javaFile.addInterface("com.google.gwt.core.client.EntryPoint");
javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "onModuleLoad",
"SwingUtilities.invokeLater(new Runnable() { public void run() { new " + className + "().setVisible(true); } });")
);
- System.out.println(javaFile.getMethods()[javaFile.getMethods().length-1].getName());
}
}
}
Modified: jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTabbedPaneHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTabbedPaneHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTabbedPaneHandler.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -53,7 +53,7 @@
}
int tabIndex = ++tabCount - 1;
- appendAdditionCode(tabInfo.getId() + ".addPropertyChangeListener(new jaxx.runtime.swing.TabInfoPropertyChangeListener(" + getId() + ", " + tabIndex + "));");
+ appendAdditionCode(tabInfo.getId() + ".addPropertyChangeListener(new jaxx.runtime.gwt.TabInfoPropertyChangeListener(" + getId() + ", " + tabIndex + "));");
String title = tabInfo.getTitle();
if (title != null) {
Modified: jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ListHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ListHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ListHandler.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -47,7 +47,7 @@
if (items != null && !items.isEmpty()) {
String listName = list.getId() + "$items";
//TODO Add the correct generic type
- list.appendAdditionCode("java.util.List<jaxx.runtime.swing.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.swing.Item>();");
+ list.appendAdditionCode("java.util.List<jaxx.runtime.gwt.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.gwt.Item>();");
for (Item item : items) {
String id = item.getId();
CompiledObject compiledItem = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(Item.class), compiler);
Modified: jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RadioButtonHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RadioButtonHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RadioButtonHandler.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -72,7 +72,7 @@
return "{ javax.swing.ButtonGroup $buttonGroup = " + valueCode + "; " + id + ".putClientProperty(\"$buttonGroup\", $buttonGroup); $buttonGroup.add(" + id + "); }\n";
} else if (name.equals(VALUE_PROPERTY)) {
return "{ " + id + ".putClientProperty(\"" + JAXXButtonGroup.VALUE_CLIENT_PROPERTY + "\", " + valueCode + "); Object $buttonGroup = " + id + ".getClientProperty(\"" + JAXXButtonGroup.BUTTON8GROUP_CLIENT_PROPERTY + "\");" +
- " if ($buttonGroup instanceof jaxx.runtime.swing.JAXXButtonGroup) { ((jaxx.runtime.swing.JAXXButtonGroup) $buttonGroup).updateSelectedValue(); } }\n";
+ " if ($buttonGroup instanceof jaxx.runtime.gwt.JAXXButtonGroup) { ((jaxx.runtime.gwt.JAXXButtonGroup) $buttonGroup).updateSelectedValue(); } }\n";
} else {
return super.getSetPropertyCode(id, name, valueCode, compiler);
}
Modified: jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TreeHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TreeHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TreeHandler.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -58,7 +58,7 @@
List<Item> items = tree.getItems();
if (items != null && !items.isEmpty()) {
String listName = tree.getId() + "$items";
- tree.appendAdditionCode("java.util.List<jaxx.runtime.swing.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.swing.Item>();");
+ tree.appendAdditionCode("java.util.List<jaxx.runtime.gwt.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.swing.Item>();");
createItems(tree, items, listName + ".add", compiler);
tree.appendAdditionCode(tree.getId() + ".setItems(" + listName + ");");
}
Modified: jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/SwingInitializer.java
===================================================================
--- jaxx/trunk/jaxx-compiler-swing/src/main/java/jaxx/SwingInitializer.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-swing/src/main/java/jaxx/SwingInitializer.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -29,9 +29,9 @@
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.Insets;
-import jaxx.compiler.BoxedCompiledObjectDecorator;
+import jaxx.compiler.SwingBoxedCompiledObjectDecorator;
import jaxx.compiler.CompiledObjectDecorator;
-import jaxx.compiler.HelpRootCompiledObjectDecorator;
+import jaxx.compiler.SwingHelpRootCompiledObjectDecorator;
public class SwingInitializer implements Initializer {
@@ -89,7 +89,7 @@
TypeManager.registerTypeConverter(Insets.class, new InsetsConverter());
TypeManager.registerTypeConverter(KeyStroke.class, new KeyStrokeConverter());
- CompiledObjectDecorator.registerDecorator("boxed", BoxedCompiledObjectDecorator.class);
- CompiledObjectDecorator.registerDecorator("help", HelpRootCompiledObjectDecorator.class);
+ //CompiledObjectDecorator.registerDecorator("boxed", SwingBoxedCompiledObjectDecorator.class);
+ //CompiledObjectDecorator.registerDecorator("help", SwingHelpRootCompiledObjectDecorator.class);
}
}
\ No newline at end of file
Modified: jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -11,9 +11,12 @@
import jaxx.introspection.JAXXPropertyDescriptor;
import jaxx.reflect.ClassDescriptor;
import jaxx.reflect.ClassDescriptorLoader;
-import jaxx.runtime.SwingValidatorUtil;
-import jaxx.runtime.validator.swing.SwingValidator;
-import jaxx.runtime.validator.swing.ui.AbstractBeanValidatorUI;
+//import jaxx.runtime.SwingValidatorUtil;
+import jaxx.runtime.GWTValidatorUtil;
+//import jaxx.runtime.validator.swing.SwingValidator;
+import jaxx.runtime.validator.gwt.GWTValidator;
+//import jaxx.runtime.validator.swing.ui.AbstractBeanValidatorUI;
+import jaxx.runtime.validator.gwt.ui.AbstractBeanValidatorUI;
import jaxx.tags.DefaultObjectHandler;
import jaxx.types.TypeManager;
import org.apache.commons.logging.Log;
@@ -56,7 +59,8 @@
public BeanValidatorHandler(ClassDescriptor beanClass) {
super(beanClass);
- ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, SwingValidator.class);
+ //ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, SwingValidator.class);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, GWTValidator.class);
}
@Override
@@ -459,7 +463,8 @@
}
}
- String code = SwingValidatorUtil.class.getName() + ".registerErrorListMouseListener(" + errorList + ");";
+ //String code = SwingValidatorUtil.class.getName() + ".registerErrorListMouseListener(" + errorList + ");";
+ String code = GWTValidatorUtil.class.getName() + ".registerErrorListMouseListener(" + errorList + ");";
appendAdditionCode(code);
return false;
@@ -479,7 +484,8 @@
}
}
- String code = SwingValidatorUtil.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");";
+ //String code = SwingValidatorUtil.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");";
+ String code = GWTValidatorUtil.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");";
appendAdditionCode(code);
return false;
Modified: jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -7,7 +7,8 @@
import jaxx.CompilerException;
import jaxx.compiler.JAXXCompiler;
import jaxx.reflect.ClassDescriptorLoader;
-import jaxx.runtime.validator.swing.SwingValidator;
+//import jaxx.runtime.validator.swing.SwingValidator;
+import jaxx.runtime.validator.gwt.GWTValidator;
import jaxx.tags.TagHandler;
import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator;
import org.apache.commons.logging.Log;
@@ -37,7 +38,8 @@
log.debug(tag);
}
- if (!ClassDescriptorLoader.getClassDescriptor(SwingValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) {
+ //if (!ClassDescriptorLoader.getClassDescriptor(SwingValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) {
+ if (!ClassDescriptorLoader.getClassDescriptor(GWTValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) {
compiler.reportError(TAG + " tag may only appear within " + BeanValidatorHandler.TAG + " tag but was " + tag);
return;
}
Modified: jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -7,7 +7,8 @@
import jaxx.CompilerException;
import jaxx.compiler.JAXXCompiler;
import jaxx.reflect.ClassDescriptorLoader;
-import jaxx.runtime.validator.swing.SwingValidator;
+//import jaxx.runtime.validator.swing.SwingValidator;
+import jaxx.runtime.validator.gwt.GWTValidator;
import jaxx.tags.TagHandler;
import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator;
import org.apache.commons.logging.Log;
@@ -37,7 +38,8 @@
log.info(tag);
}
- if (!ClassDescriptorLoader.getClassDescriptor(SwingValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) {
+ //if (!ClassDescriptorLoader.getClassDescriptor(SwingValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) {
+ if (!ClassDescriptorLoader.getClassDescriptor(GWTValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) {
compiler.reportError(TAG + " tag may only appear within " + BeanValidatorHandler.TAG + " tag but was " + tag);
return;
}
Modified: jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java
===================================================================
--- jaxx/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -6,7 +6,7 @@
import jaxx.compiler.JAXXCompiler;
import jaxx.reflect.ClassDescriptorLoader;
-import jaxx.runtime.validator.swing.SwingValidator;
+import jaxx.runtime.validator.gwt.GWTValidator;
import jaxx.tags.TagManager;
public class ValidatorInitializer implements jaxx.spi.Initializer {
@@ -14,8 +14,10 @@
@Override
public void initialize() {
- TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, BeanValidatorHandler.TAG, new BeanValidatorHandler(ClassDescriptorLoader.getClassDescriptor(SwingValidator.class)));
- TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(SwingValidator.class), BeanValidatorHandler.class);
+ //TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, BeanValidatorHandler.TAG, new BeanValidatorHandler(ClassDescriptorLoader.getClassDescriptor(SwingValidator.class)));
+ TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, BeanValidatorHandler.TAG, new BeanValidatorHandler(ClassDescriptorLoader.getClassDescriptor(GWTValidator.class)));
+ //TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(SwingValidator.class), BeanValidatorHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(GWTValidator.class), BeanValidatorHandler.class);
TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, FieldValidatorHandler.TAG, new FieldValidatorHandler());
TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, ExcludeFieldValidatorHandler.TAG, new FieldValidatorHandler());
}
Modified: jaxx-gwt/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java
===================================================================
--- jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2009-04-02 12:38:08 UTC (rev 1286)
+++ jaxx-gwt/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2009-04-03 09:44:32 UTC (rev 1287)
@@ -43,7 +43,7 @@
import java.util.Properties;
import java.util.Set;
import jaxx.compiler.CompiledObjectDecorator;
-import jaxx.compiler.HelpRootCompiledObjectDecorator;
+import jaxx.compiler.SwingHelpRootCompiledObjectDecorator;
import org.apache.maven.artifact.Artifact;
import org.apache.maven.project.MavenProject;
@@ -492,7 +492,7 @@
}
protected void generateHelp() throws IOException {
- Set<String> helpIds = HelpRootCompiledObjectDecorator.getHelpIds();
+ Set<String> helpIds = SwingHelpRootCompiledObjectDecorator.getHelpIds();
if (helpIds.isEmpty()) {
if (verbose) {
// no ids detected in this compilation round
1
0
02 Apr '09
Author: kmorin
Date: 2009-04-02 12:38:08 +0000 (Thu, 02 Apr 2009)
New Revision: 1286
Added:
jaxx/trunk/jaxx-compiler-gwt/
jaxx/trunk/jaxx-compiler-gwt/.classpath
jaxx/trunk/jaxx-compiler-gwt/.project
jaxx/trunk/jaxx-compiler-gwt/.settings/
jaxx/trunk/jaxx-compiler-gwt/.settings/org.eclipse.jdt.core.prefs
jaxx/trunk/jaxx-compiler-gwt/LICENSE.txt
jaxx/trunk/jaxx-compiler-gwt/README.txt
jaxx/trunk/jaxx-compiler-gwt/changelog.txt
jaxx/trunk/jaxx-compiler-gwt/pom.xml
jaxx/trunk/jaxx-compiler-gwt/src/
jaxx/trunk/jaxx-compiler-gwt/src/main/
jaxx/trunk/jaxx-compiler-gwt/src/main/java/
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/GWTInitializer.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/BoxedCompiledObjectDecorator.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTCompiler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTGenerator.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/HelpRootCompiledObjectDecorator.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ApplicationHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CellHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CheckBoxHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ComboBoxHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CompiledItemContainer.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ItemHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JAXXTabHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JInternalFrameHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JPopupMenuHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JProgressBarHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JScrollPaneHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSliderHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSpinnerHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSplitPaneHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTabbedPaneHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTextComponentHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JToolBarHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JWindowHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ListHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/MenuHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/PasswordFieldHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RadioButtonHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RowHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TabHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TableHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TreeHandler.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/ColorConverter.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/GridBagConstraintsConverter.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/InsetsConverter.java
jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/KeyStrokeConverter.java
jaxx/trunk/jaxx-compiler-gwt/src/main/resources/
jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/
jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/
jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/jaxx.compiler.Generator
jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/jaxx.spi.Initializer
jaxx/trunk/jaxx-compiler-gwt/src/site/
jaxx/trunk/jaxx-compiler-gwt/src/site/fr/
jaxx/trunk/jaxx-compiler-gwt/src/site/fr/rst/
jaxx/trunk/jaxx-compiler-gwt/src/test/
jaxx/trunk/jaxx-compiler-gwt/src/test/java/
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/ColorConverterTest.java
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/InsetsConverterTest.java
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/TagManagerTest.java
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/runtime/
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/runtime/swing/
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/runtime/swing/navigation/
jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java
jaxx/trunk/jaxx-compiler-gwt/src/test/resources/
jaxx/trunk/jaxx-compiler-gwt/src/test/resources/log4j.properties
jaxx/trunk/jaxx-gwt-action/
jaxx/trunk/jaxx-gwt-action/.classpath
jaxx/trunk/jaxx-gwt-action/.project
jaxx/trunk/jaxx-gwt-action/.settings/
jaxx/trunk/jaxx-gwt-action/.settings/org.eclipse.jdt.core.prefs
jaxx/trunk/jaxx-gwt-action/LICENSE.txt
jaxx/trunk/jaxx-gwt-action/README.txt
jaxx/trunk/jaxx-gwt-action/changelog.txt
jaxx/trunk/jaxx-gwt-action/pom.xml
jaxx/trunk/jaxx-gwt-action/src/
jaxx/trunk/jaxx-gwt-action/src/main/
jaxx/trunk/jaxx-gwt-action/src/main/java/
jaxx/trunk/jaxx-gwt-action/src/main/java/org/
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/AbstractActionConfigurationResolver.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionAnnotationProcessing.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfig.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfigConfigurationResolver.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfigurationResolver.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionNameProvider.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProvider.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProviderAnnotation.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProviderFromProperties.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/MyAbstractAction.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfig.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfigConfigurationResolver.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfig.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfigConfigurationResolver.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabContentConfig.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabFactory.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabModel.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/AbstractUIAction.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUI.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIDef.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIHandler.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIModel.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/FactoryWindowListener.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/FormElement.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/ShowUIAction.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIFactory.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIHelper.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIProvider.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/CancelAction.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUI.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUIHandler.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUIModel.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/ResetAction.java
jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/SaveAction.java
jaxx/trunk/jaxx-gwt-action/src/main/resources/
jaxx/trunk/jaxx-gwt-action/src/main/resources/META-INF/
jaxx/trunk/jaxx-gwt-action/src/main/resources/META-INF/services/
jaxx/trunk/jaxx-gwt-action/src/main/resources/META-INF/services/javax.annotation.processing.Processor
jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/
jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-gwt-action-en_GB.properties
jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-gwt-action-fr_FR.properties
jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-swing-action-en_GB.properties
jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-swing-action-fr_FR.properties
jaxx/trunk/jaxx-gwt-action/src/site/
jaxx/trunk/jaxx-gwt-action/src/site/fr/
jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/
jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/Todo.rst
jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/index.rst
jaxx/trunk/jaxx-gwt-action/src/test/
jaxx/trunk/jaxx-gwt-action/src/test/java/
jaxx/trunk/jaxx-gwt-action/src/test/java/jaxx/
jaxx/trunk/jaxx-gwt-action/src/test/java/jaxx/runtime/
jaxx/trunk/jaxx-gwt-action/src/test/java/jaxx/runtime/UtilTest.java
jaxx/trunk/jaxx-gwt-action/src/test/resources/
jaxx/trunk/jaxx-runtime-gwt/
jaxx/trunk/jaxx-runtime-gwt/.classpath
jaxx/trunk/jaxx-runtime-gwt/.project
jaxx/trunk/jaxx-runtime-gwt/.settings/
jaxx/trunk/jaxx-runtime-gwt/.settings/org.eclipse.jdt.core.prefs
jaxx/trunk/jaxx-runtime-gwt/LICENSE.txt
jaxx/trunk/jaxx-runtime-gwt/README.txt
jaxx/trunk/jaxx-runtime-gwt/changelog.txt
jaxx/trunk/jaxx-runtime-gwt/pom.xml
jaxx/trunk/jaxx-runtime-gwt/src/
jaxx/trunk/jaxx-runtime-gwt/src/main/
jaxx/trunk/jaxx-runtime-gwt/src/main/java/
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/GWTUtil.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/JaxxHelpUI.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Application.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/BlockingLayerUI.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/BlockingLayerUI2.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/CardLayout2.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/CardLayout2Ext.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/DecoratorTableCellRenderer.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/HBox.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/HBoxLayout.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/I18nTableCellRenderer.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Item.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXButtonGroup.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXComboBox.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXList.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXTab.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXToggleButton.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXTree.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JaxxHelpBroker.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Spacer.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/TabInfo.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/TabInfoPropertyChangeListener.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Table.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/VBox.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/VBoxLayout.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeCellRenderer.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeModel.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeModelBuilder.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeSelectionAdapter.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeSelectionAdapterWithCardLayout.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationUtil.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardModel.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationAction.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationActionThread.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationModel.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationState.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationStep.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardStep.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardStepUI.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUI.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUILancher.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUtil.java
jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/package.html
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-config-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-config.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-message-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-message.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-next-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-next.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-pause-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-pause.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-previous-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-previous.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-refresh-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-refresh.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-start-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-start.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-canceled-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-canceled.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-failed-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-failed.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-need_fix-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-need_fix.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-pending-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-pending.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-running-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-running.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-successed-16.png
jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-successed.png
jaxx/trunk/jaxx-runtime-gwt/src/site/
jaxx/trunk/jaxx-runtime-gwt/src/site/fr/
jaxx/trunk/jaxx-runtime-gwt/src/site/fr/rst/
jaxx/trunk/jaxx-runtime-gwt/src/test/
jaxx/trunk/jaxx-runtime-gwt/src/test/java/
jaxx/trunk/jaxx-runtime-gwt/src/test/java/jaxx/
jaxx/trunk/jaxx-runtime-gwt/src/test/java/jaxx/junit/
jaxx/trunk/jaxx-runtime-gwt/src/test/java/jaxx/runtime/
jaxx/trunk/jaxx-runtime-gwt/src/test/resources/
jaxx/trunk/jaxx-runtime-gwt/src/test/resources/jaxx/
jaxx/trunk/jaxx-runtime-gwt/src/test/resources/jaxx/junit/
jaxx/trunk/jaxx-runtime-validator-gwt/
jaxx/trunk/jaxx-runtime-validator-gwt/.classpath
jaxx/trunk/jaxx-runtime-validator-gwt/.project
jaxx/trunk/jaxx-runtime-validator-gwt/.settings/
jaxx/trunk/jaxx-runtime-validator-gwt/.settings/org.eclipse.jdt.core.prefs
jaxx/trunk/jaxx-runtime-validator-gwt/LICENSE.txt
jaxx/trunk/jaxx-runtime-validator-gwt/README.txt
jaxx/trunk/jaxx-runtime-validator-gwt/changelog.txt
jaxx/trunk/jaxx-runtime-validator-gwt/pom.xml
jaxx/trunk/jaxx-runtime-validator-gwt/src/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/GWTValidatorUtil.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidator.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessage.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListModel.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListMouseListener.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListRenderer.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableModel.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableMouseListener.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableRenderer.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/AbstractBeanValidatorUI.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/IconValidationUI.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/ImageValidationUI.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/TranslucentValidationUI.java
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/error.png
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/info.png
jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/warning.png
jaxx/trunk/jaxx-runtime-validator-gwt/src/site/
jaxx/trunk/jaxx-runtime-validator-gwt/src/site/fr/
jaxx/trunk/jaxx-runtime-validator-gwt/src/site/fr/rst/
jaxx/trunk/jaxx-runtime-validator-gwt/src/test/
jaxx/trunk/jaxx-runtime-validator-gwt/src/test/java/
jaxx/trunk/jaxx-runtime-validator-gwt/src/test/resources/
Log:
Added: jaxx/trunk/jaxx-compiler-gwt/.classpath
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/.classpath (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/.classpath 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,22 @@
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/main/resources" including="**/*" excluding="**/*~|**/*.java"/>
+ <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+ <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+ <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/commons-beanutils/commons-beanutils/1.8.0/commons-beanutils-1.8.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-jxpath/commons-jxpath/1.3/commons-jxpath-1.3.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.4/commons-lang-2.4.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-primitives/commons-primitives/1.0/commons-primitives-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/javax/help/javahelp/2.0.02/javahelp-2.0.02.jar"/>
+ <classpathentry kind="src" path="/jaxx-compiler-api"/>
+ <classpathentry kind="src" path="/jaxx-runtime-api"/>
+ <classpathentry kind="src" path="/jaxx-runtime-gwt"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/4.5/junit-4.5.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/swinglabs/jxlayer/3.0.1/jxlayer-3.0.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/codelutin/lutinutil/1.0.3/lutinutil-1.0.3.jar"/>
+</classpath>
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/.project
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/.project (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/.project 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,17 @@
+<projectDescription>
+ <name>jaxx-compiler-gwt</name>
+ <comment>Jaxx compiler gwt extension</comment>
+ <projects>
+ <project>jaxx-compiler-api</project>
+ <project>jaxx-runtime-api</project>
+ <project>jaxx-runtime-gwt</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/.settings/org.eclipse.jdt.core.prefs 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,5 @@
+#Mon Mar 30 12:41:56 CEST 2009
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
Added: jaxx/trunk/jaxx-compiler-gwt/LICENSE.txt
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/LICENSE.txt (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/LICENSE.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,166 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
Added: jaxx/trunk/jaxx-compiler-gwt/README.txt
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/README.txt (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/README.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,2 @@
+To deploy new version of pom: mvn deploy
+To install localy: mvn install
Added: jaxx/trunk/jaxx-compiler-gwt/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/changelog.txt (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/changelog.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,96 @@
+1.3 chemit 20090320
+ * 20090327 [chemit] - introduce javax help decorator
+
+1.1 chemit 20090220
+ * 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...)
+
+1.0 chemit 20090111
+
+ * 20081228 [chemit] - generify ClassDescriptor
+ - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from
+ JAXXCompiler and make possible to extract compiler engine from runtime
+
+ * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation
+ * 20081218 [chemit] - improve generation of methods
+ * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##)
+ - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option)
+ - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection
+ - add addSourcesToClassPath property to add sources directories in class-path
+ - improve classloader managment
+ - keep in DataSource objetCode
+ - fix bug when processDataBinding on a null objectCode
+ - always clean node cached values when selected it
+ - add usefull databinding method in Util
+
+ * 20081213 [chemit] - improve navigation tree node rendering with some caches
+ - introduce a ChildBuilder to simplify building of child nodes from a collection or array
+
+0.7 chemit 20081210
+ * 20081210 [chemit] - fix bug 1751
+ * 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism)
+ * 20081208 [chemit] - javabBean attribute use to initialize bean
+ - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment)
+ - introduce MultiJXPathDecorator
+ - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers
+
+ * 20081207 [chemit] use lutinproject 3.1
+ - can exclude field from validator
+ * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter
+ - fix bug when searching for a inner class
+
+ * 20081201 [chemit] - implements jaxx.runtime.JXPathDecorator
+ - add setcontextValue and removeContextValue on JAXXContextEntryDef
+ - introduce scope in BeanValidator (ERROR or WARNING) and related swing stuff
+ - only enter once in $initialize method in generated code
+
+ 0.6 chemit 20081117
+ * 20081118 [chemit] introduce NavigationUtil, save in context selected node
+ * 20081107 [chemit] improve data binding and code generation :
+ - make possible inheritance in binding
+ - add an attribute javaBean to an object : will generate a full java bean support property
+ - make possible binding to the javaBean added properties
+ - clean generated code
+
+ * 20081105 [chemit] - introduce a CardLayout2 to extends awt CardLayout
+ - introduce a NavigationTreeModel
+ - introduce a Decorator to render Object
+ - propagate constructor JAXXContext(JAXXContext) in JAXXObject generation
+ - begin of rst documentation
+
+ * 20081104 [chemit] can add extra beanInfoSearchPath in SwingInitializer
+ * 20081104 [chemit] add jaxxContextImplementorClass in option to make possible use of other JAXXContext implementor.
+ * 20081102 [chemit] improve JAXXContext :
+ - introduce a JAXXContextEntryDef to qualify an entry of a JAXXContext
+ - do javadoc in JAXXContext
+ - add logic in DefaultJAXXContext : seek in parent context if entry not found
+ * 20081102 [chemit] improve tests :
+ - fix the last failed test from Jaxx original version :)
+ - dumps tests to JUnit4 :)
+ * 20081030 [chemit] improve BeanValidator :
+ - add full PropertyChangeEvent java-bean support and a property valid
+ - when remove bean from validator, must remove errors from model
+ - make possible to have a dynamic errorListModel in jaxx files
+ * 20081030 [chemit] improve JAXXContext :
+ - fix setContextValue bug when setting twice a same type for a same key
+ - implements a DefaultJAXXContext
+ - use this default implementation with delegate pattern in JAXXObject
+ * 20081030 [chemit] add JAXXAction contract to simplify init of ui with JAXXInitialContext
+ * 20081027 [chemit] fix bug 1722
+ * 20081027 [chemit] add conversion support in validator
+ * 20081025 [chemit] improve BeanValidator tag :
+ - add a errorList attribute for set a ErrorListMouseListener on the errorList
+ - add a beanInitializer attribute for set the validator's bean at runtime
+ - add a default errorListModel value 'errors'
+ * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method
+ * 20081024 [chemit] fix validator context lost if UI is launched from another thread
+
+ 0.5 chemit 20081002
+ * 20081017 [chemit] add validator support
+ * 20081013 [chemit] can generate logger on jaxx files
+ * 20081011 [chemit] improve site
+ * 20081011 [chemit] fix bug on JavaFileParser : works again
+ * 20081002 [chemit] Using lutinproject 3.0, changing groupId to org.codelutin
+ * 20081002 [chemit] use a single module jaxx-core (no more core, runtime and jaxx-swing modules)
+ * 20081002 [chemit] Introduce JAXXContext
+ * 20081002 [chemit] Fix bug on method creation via scripting
+ * 20081002 [chemit] Improve i18n integration (works now also for tabs)
Added: jaxx/trunk/jaxx-compiler-gwt/pom.xml
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/pom.xml (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/pom.xml 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- ************************************************************* -->
+ <!-- *** POM Relationships *************************************** -->
+ <!-- ************************************************************* -->
+
+ <parent>
+ <groupId>org.codelutin</groupId>
+ <artifactId>jaxx</artifactId>
+ <version>1.3-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.codelutin.jaxx</groupId>
+ <artifactId>jaxx-compiler-gwt</artifactId>
+
+ <repositories>
+ <repository>
+ <id>gwt-maven</id>
+ <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+
+ <!-- sibling dependencies -->
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-compiler-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- GWT Dependencies -->
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-servlet</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-user</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}-libs</classifier>
+ <type>zip</type>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}</classifier>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+ <!-- ************************************************************* -->
+ <!-- *** Project Information ************************************* -->
+ <!-- ************************************************************* -->
+
+ <name>${project.artifactId}</name>
+ <description>Jaxx compiler gwt extension</description>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Settings ****************************************** -->
+ <!-- ************************************************************* -->
+ <packaging>jar</packaging>
+
+ <properties>
+
+ <gwtVersion>1.5.3</gwtVersion>
+
+ </properties>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Environment ************************************** -->
+ <!-- ************************************************************* -->
+ <scm>
+ <url>http://labs.libre-entreprise.org/plugins/scmsvn/viewcvs.php/jaxx/trunk/jaxx…</url>
+ <connection>scm:svn:svn://anonymous@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-compiler-gwt</connection>
+ <developerConnection>scm:svn:svn+ssh://sletellier@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-compiler-gwt</developerConnection>
+ </scm>
+
+ <profiles>
+ <profile>
+ <id>gwt-dev-linux</id>
+ <properties>
+ <platform>linux</platform>
+ </properties>
+ <activation>
+ <os>
+ <name>Linux</name>
+ </os>
+ </activation>
+ </profile>
+ </profiles>
+</project>
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/GWTInitializer.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/GWTInitializer.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/GWTInitializer.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,97 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx;
+
+import jaxx.tags.gwt.*;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.Application;
+import jaxx.runtime.gwt.JAXXButtonGroup;
+import jaxx.runtime.gwt.JAXXComboBox;
+import jaxx.runtime.gwt.JAXXList;
+import jaxx.runtime.gwt.JAXXTab;
+import jaxx.runtime.gwt.JAXXTree;
+import jaxx.runtime.gwt.Table;
+import jaxx.spi.Initializer;
+import jaxx.tags.DefaultObjectHandler;
+import jaxx.tags.TagManager;
+import jaxx.types.ColorConverter;
+import jaxx.types.GridBagConstraintsConverter;
+import jaxx.types.InsetsConverter;
+import jaxx.types.KeyStrokeConverter;
+import jaxx.types.TypeManager;
+import jaxx.beaninfos.BeanInfoUtil;
+
+import javax.swing.*;
+import javax.swing.text.JTextComponent;
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import jaxx.compiler.BoxedCompiledObjectDecorator;
+import jaxx.compiler.CompiledObjectDecorator;
+import jaxx.compiler.HelpRootCompiledObjectDecorator;
+
+import com.google.gwt.user.client.ui.*;
+
+public class GWTInitializer implements Initializer {
+
+ public void initialize() {
+
+ BeanInfoUtil.addJaxxBeanInfoPath("jaxx.beaninfos");
+
+ TagManager.registerTag("java.awt.*", "ButtonGroup", new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(JAXXButtonGroup.class)));
+
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(Application.class), ApplicationHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JCheckBox.class), CheckBoxHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JCheckBoxMenuItem.class), CheckBoxHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JAXXComboBox.class), ComboBoxHandler.class);
+ TagManager.registerTag("javax.swing.*", "JComboBox", new ComboBoxHandler(ClassDescriptorLoader.getClassDescriptor(JAXXComboBox.class)));
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JDialog.class), JWindowHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JFrame.class), JWindowHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JInternalFrame.class), JInternalFrameHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JAXXList.class), ListHandler.class);
+ TagManager.registerTag("javax.swing.*", "JList", new ListHandler(ClassDescriptorLoader.getClassDescriptor(JAXXList.class)));
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JMenu.class), MenuHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JPasswordField.class), PasswordFieldHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JPopupMenu.class), JPopupMenuHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JProgressBar.class), JProgressBarHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JRadioButton.class), RadioButtonHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JRadioButtonMenuItem.class), RadioButtonHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JScrollPane.class), JScrollPaneHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JSlider.class), JSliderHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JSpinner.class), JSpinnerHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JSplitPane.class), JSplitPaneHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JTabbedPane.class), JTabbedPaneHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JTextComponent.class), JTextComponentHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JToggleButton.class), RadioButtonHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JToolBar.class), JToolBarHandler.class);
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JAXXTree.class), TreeHandler.class);
+ TagManager.registerTag("javax.swing.*", "JTree", new TreeHandler(ClassDescriptorLoader.getClassDescriptor(JAXXTree.class)));
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JWindow.class), JWindowHandler.class);
+
+ TagManager.registerDefaultNamespace("JEditorPane", "javax.swing.*");
+ TagManager.registerDefaultNamespace("JFormattedTextField", "javax.swing.*");
+ TagManager.registerDefaultNamespace("JPasswordField", "javax.swing.*");
+ TagManager.registerDefaultNamespace("JTextArea", "javax.swing.*");
+ TagManager.registerDefaultNamespace("JTextField", "javax.swing.*");
+ TagManager.registerDefaultNamespace("JTextPane", "javax.swing.*");
+
+ TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "tab", new TabHandler());
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(Table.class), TableHandler.class);
+ TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "row", new RowHandler());
+ TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "cell", new CellHandler());
+ TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "item", new ItemHandler());
+
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JAXXTab.class), JAXXTabHandler.class);
+
+ TypeManager.registerTypeConverter(Color.class, new ColorConverter());
+ TypeManager.registerTypeConverter(GridBagConstraints.class, new GridBagConstraintsConverter());
+ TypeManager.registerTypeConverter(Insets.class, new InsetsConverter());
+ TypeManager.registerTypeConverter(KeyStroke.class, new KeyStrokeConverter());
+
+ //CompiledObjectDecorator.registerDecorator("boxed", BoxedCompiledObjectDecorator.class);
+ //CompiledObjectDecorator.registerDecorator("help", HelpRootCompiledObjectDecorator.class);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/BoxedCompiledObjectDecorator.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/BoxedCompiledObjectDecorator.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/BoxedCompiledObjectDecorator.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,27 @@
+package jaxx.compiler;
+
+import jaxx.compiler.CompiledObject.ChildRef;
+import jaxx.runtime.GWTUtil;
+
+/**
+ * A decorator to surround a compiled object (should be a component at least)
+ * with a JXLayer.
+ *
+ * @author tony
+ * @since 1.2
+ */
+public class BoxedCompiledObjectDecorator extends DefaultCompiledObjectDecorator {
+
+ @Override
+ public void finalizeCompiler(JAXXCompiler compiler, CompiledObject root, CompiledObject object, JavaFile javaFile, String packageName, String className, String fullClassName) {
+ CompiledObject parent = object.getParent();
+ for (ChildRef child : parent.getChilds()) {
+ if (child.getChild() == object) {
+ String javaCode = child.getChildJavaCode();
+ child.setChildJavaCode(GWTUtil.class.getName()+".boxComponentWithJxLayer(" + javaCode + ")");
+ break;
+ }
+ }
+ super.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName);
+ }
+}
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTCompiler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTCompiler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTCompiler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.compiler;
+
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultObjectHandler;
+
+import java.io.File;
+
+/**
+ * Swing JAXX compiler.
+ * <p/>
+ * todo finish javadoc
+ */
+public class GWTCompiler extends JAXXCompiler {
+
+ /*---------------------------------------------------------------------------------*/
+ /*-- Constructor methods ----------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+
+ public GWTCompiler(ClassLoader classLoader) {
+ super(classLoader,
+ new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(Object.class)),
+ "java.awt.*",
+ "java.awt.event.*",
+ "java.beans.*",
+ "java.io.*",
+ "java.lang.*",
+ "java.util.*",
+ "javax.swing.*",
+ "javax.swing.border.*",
+ "javax.swing.event.*",
+ "jaxx.runtime.gwt.JAXXButtonGroup",
+ "jaxx.runtime.gwt.HBox",
+ "jaxx.runtime.gwt.VBox",
+ "jaxx.runtime.gwt.Table",
+ "static org.codelutin.i18n.I18n._",
+ "static jaxx.runtime.Util.createImageIcon",
+ "com.google.gwt.user.client.ui.*");
+
+
+ }
+
+ /**
+ * Creates a new SwingCompiler.
+ *
+ * @param baseDir classpath location
+ * @param options options to pass to javac
+ * @param src location of file to compile
+ * @param outputClassName the out file name
+ */
+ public GWTCompiler(File baseDir, File src, String outputClassName, CompilerOptions options) {
+ super(baseDir, src, outputClassName, options,
+ new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(Object.class)),
+ "java.awt.*",
+ "java.awt.event.*",
+ "java.beans.*",
+ "java.io.*",
+ "java.lang.*",
+ "java.util.*",
+ "javax.swing.*",
+ "javax.swing.border.*",
+ "javax.swing.event.*",
+ "jaxx.runtime.gwt.JAXXButtonGroup",
+ "jaxx.runtime.gwt.HBox",
+ "jaxx.runtime.gwt.VBox",
+ "jaxx.runtime.gwt.Table",
+ "static org.codelutin.i18n.I18n._",
+ "static jaxx.runtime.Util.createImageIcon",
+ "com.google.gwt.user.client.ui.*");
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTGenerator.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTGenerator.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/GWTGenerator.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,27 @@
+package jaxx.compiler;
+
+import jaxx.reflect.ClassDescriptorLoader;
+
+import java.lang.reflect.Modifier;
+
+/** @author chemit */
+public class GWTGenerator implements Generator {
+ @Override
+ public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) {
+
+ }
+
+ @Override
+ public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException {
+
+ //TODO : move this to jaxx-compiler-swing generator
+ if (ClassDescriptorLoader.getClassDescriptor("jaxx.runtime.swing.Application").isAssignableFrom(root.getObjectClass()) && !compiler.isMainDeclared()) {
+ // TODO: check for existing main method first
+ javaFile.addInterface("com.google.gwt.core.client.EntryPoint");
+ javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "onModuleLoad",
+ "SwingUtilities.invokeLater(new Runnable() { public void run() { new " + className + "().setVisible(true); } });")
+ );
+ System.out.println(javaFile.getMethods()[javaFile.getMethods().length-1].getName());
+ }
+ }
+}
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/HelpRootCompiledObjectDecorator.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/HelpRootCompiledObjectDecorator.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/compiler/HelpRootCompiledObjectDecorator.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,93 @@
+package jaxx.compiler;
+
+import java.lang.reflect.Modifier;
+import java.util.Iterator;
+import java.util.Set;
+
+/**
+ * A decorator to place on a root compiled object to process javaHelp on the file.
+ *
+ * @author tony
+ * @since 1.2
+ */
+public class HelpRootCompiledObjectDecorator extends DefaultCompiledObjectDecorator {
+
+ /**
+ * the list of discovered helpId
+ */
+ protected static Set<String> helpIds = new java.util.HashSet<String>();
+
+ protected String getBrokerFQN(JAXXCompiler compiler) {
+ String helpBrokerFQN = compiler.getOptions().getHelpBrokerFQN();
+ return helpBrokerFQN;
+ }
+
+ protected String getHelpId(CompiledObject o) {
+ String helpID = null;
+ if (o.hasClientProperties()) {
+ helpID = o.getClientProperty("help");
+ }
+ return helpID;
+ }
+
+ @Override
+ public void finalizeCompiler(JAXXCompiler compiler, CompiledObject root, CompiledObject object, JavaFile javaFile, String packageName, String className, String fullClassName) {
+ super.finalizeCompiler(compiler, root, object, javaFile, packageName, className, fullClassName);
+ CompilerOptions options = compiler.getOptions();
+
+ if (options.isGenerateHelp()) {
+
+ // add JaxxHelpUI interface
+ Class<?> validatorInterface = jaxx.runtime.JaxxHelpUI.class;
+ String helpBrokerFQN = getBrokerFQN(compiler);
+ javaFile.addInterface(JAXXCompiler.getCanonicalName(validatorInterface) + "<" + helpBrokerFQN + ">");
+
+ javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "registerHelpId",
+ "broker.installUI(component, helpId);",
+ new JavaArgument(helpBrokerFQN, "broker"),
+ new JavaArgument("Component", "component"),
+ new JavaArgument("String", "helpId")));
+
+ javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "showHelp",
+ "getBroker().showHelp(this, helpId);",
+ new JavaArgument("String", "helpId")));
+
+ StringBuilder buffer = new StringBuilder();
+
+ String lineSeparator = JAXXCompiler.getLineSeparator();
+
+ if (options.isGenerateHelp()) {
+
+ // add code to init javax help system
+ Iterator<CompiledObject> itr = compiler.getObjectCreationOrder();
+
+ for (; itr.hasNext();) {
+ CompiledObject o = itr.next();
+ String helpID = getHelpId(o);
+ if (helpID != null) {
+ buffer.append(lineSeparator);
+ // detects a helpId to register
+ buffer.append("registerHelpId(_broker, " + o.getJavaCode() + ", " + helpID + ");");
+ //keep the helpID for helpSet generation
+ helpIds.add(helpID);
+ }
+ }
+ }
+ if (buffer.length() > 0) {
+
+ StringBuilder extraCode = new StringBuilder(helpBrokerFQN).append(" _broker = getBroker();");
+
+ buffer.append(lineSeparator).append("_broker.prepareUI(this);");
+ buffer.append(lineSeparator);
+
+ // add the calls
+ compiler.appendLateInitializer(extraCode.toString());
+ compiler.appendLateInitializer(buffer.toString());
+ }
+ }
+ }
+
+ public static Set<String> getHelpIds() {
+ return helpIds;
+ }
+}
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ApplicationHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ApplicationHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ApplicationHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.Application;
+import jaxx.types.TypeManager;
+import org.w3c.dom.Element;
+
+import javax.swing.WindowConstants;
+
+public class ApplicationHandler extends JWindowHandler {
+
+ public ApplicationHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, Application.class);
+ }
+
+
+ @Override
+ public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) throws CompilerException {
+ super.setAttribute(object, propertyName, stringValue, inline, compiler);
+ }
+
+
+ @Override
+ protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException {
+ super.setDefaults(object, tag, compiler);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CellHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CellHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CellHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,154 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.UnsupportedAttributeException;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.tags.TagHandler;
+import jaxx.types.TypeManager;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.io.IOException;
+
+public class CellHandler implements TagHandler {
+ public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compileChildrenFirstPass(tag, compiler);
+ }
+
+
+ public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ Node parent = tag.getParentNode();
+ if (parent.getNodeType() != Node.ELEMENT_NODE || !parent.getLocalName().equals("row")) {
+ compiler.reportError("cell tag may only appear within row tag");
+ return;
+ }
+
+ TableHandler.CompiledTable table = (TableHandler.CompiledTable) compiler.getOpenComponent();
+ table.newCell();
+ GridBagConstraints c = table.getCellConstraints();
+ setAttributes(c, tag);
+ compileChildrenSecondPass(tag, compiler);
+ }
+
+
+ public static void setAttribute(GridBagConstraints c, String name, String value) throws CompilerException {
+ value = value.trim();
+ if (name.equals("insets")) {
+ c.insets = (Insets) TypeManager.convertFromString(value, Insets.class);
+ } else if (name.equals("weightx")) {
+ c.weightx = Double.parseDouble(value);
+ } else if (name.equals("weighty")) {
+ c.weighty = Double.parseDouble(value);
+ } else if (name.equals("columns")) {
+ c.gridwidth = Integer.parseInt(value);
+ } else if (name.equals("rows")) {
+ c.gridheight = Integer.parseInt(value);
+ } else if (name.equals("fill")) {
+ if (value.equals("none")) {
+ c.fill = GridBagConstraints.NONE;
+ } else if (value.equals("horizontal")) {
+ c.fill = GridBagConstraints.HORIZONTAL;
+ } else if (value.equals("vertical")) {
+ c.fill = GridBagConstraints.VERTICAL;
+ } else if (value.equals("both")) {
+ c.fill = GridBagConstraints.BOTH;
+ } else {
+ throw new IllegalArgumentException("invalid value for fill attribute: '" + value + "'");
+ }
+ } else if (name.equals("anchor")) {
+ //todo use a converter
+ if (value.equals("north")) {
+ c.anchor = GridBagConstraints.NORTH;
+ } else if (value.equals("northeast")) {
+ c.anchor = GridBagConstraints.NORTHEAST;
+ } else if (value.equals("east")) {
+ c.anchor = GridBagConstraints.EAST;
+ } else if (value.equals("southeast")) {
+ c.anchor = GridBagConstraints.SOUTHEAST;
+ } else if (value.equals("south")) {
+ c.anchor = GridBagConstraints.SOUTH;
+ } else if (value.equals("southwest")) {
+ c.anchor = GridBagConstraints.SOUTHWEST;
+ } else if (value.equals("west")) {
+ c.anchor = GridBagConstraints.WEST;
+ } else if (value.equals("northwest")) {
+ c.anchor = GridBagConstraints.NORTHWEST;
+ } else if (value.equals("center")) {
+ c.anchor = GridBagConstraints.CENTER;
+ } else {
+ throw new IllegalArgumentException("invalid value for anchor attribute: '" + value + "'");
+ }
+ } else {
+ throw new UnsupportedAttributeException(name);
+ }
+ }
+
+
+ public static void setAttributes(GridBagConstraints c, Element tag) throws CompilerException {
+ NamedNodeMap children = tag.getAttributes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Attr attribute = (Attr) children.item(i);
+ String name = attribute.getName();
+ String value = attribute.getValue();
+ if (!name.startsWith("xmlns") && !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) {
+ setAttribute(c, name, value);
+ }
+ }
+ }
+
+
+ protected void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ NodeList children = tag.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ Element child = (Element) node;
+ compileChildTagFirstPass(child, compiler);
+ } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ String text = ((Text) node).getData().trim();
+ if (text.length() > 0) {
+ compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')");
+ }
+ }
+ }
+ }
+
+
+ protected void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ NodeList children = tag.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ Element child = (Element) node;
+ compileChildTagSecondPass(child, compiler);
+ } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ String text = ((Text) node).getData().trim();
+ if (text.length() > 0) {
+ compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')");
+ }
+ }
+ }
+ }
+
+
+ protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compiler.compileFirstPass(tag);
+ }
+
+
+ protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compiler.compileSecondPass(tag);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CheckBoxHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CheckBoxHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CheckBoxHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+
+import javax.swing.AbstractButton;
+import javax.swing.event.ChangeListener;
+
+public class CheckBoxHandler extends DefaultComponentHandler {
+ public CheckBoxHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, AbstractButton.class);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("isSelected", ChangeListener.class, "model");
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ComboBoxHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ComboBoxHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ComboBoxHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.Item;
+import jaxx.runtime.gwt.JAXXComboBox;
+import jaxx.tags.DefaultComponentHandler;
+import jaxx.types.TypeManager;
+import org.w3c.dom.Element;
+
+import java.awt.event.ItemListener;
+import java.io.IOException;
+import java.util.List;
+
+public class ComboBoxHandler extends DefaultComponentHandler {
+
+ public ComboBoxHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JAXXComboBox.class);
+ }
+
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getSelectedIndex", ItemListener.class);
+ addProxyEventInfo("getSelectedItem", ItemListener.class);
+ }
+
+
+ @Override
+ protected CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledItemContainer(id, getBeanClass(), compiler);
+ }
+
+
+ @Override
+ public void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ super.compileChildrenSecondPass(tag, compiler);
+ CompiledItemContainer list = (CompiledItemContainer) compiler.getOpenComponent();
+ List<Item> items = list.getItems();
+ if (items != null && !items.isEmpty()) {
+ String listName = list.getId() + "$items";
+ list.appendAdditionCode("java.util.List<jaxx.runtime.gwt.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.gwt.Item>();");
+ for (Item item : items) {
+ String id = item.getId();
+ CompiledObject compiledItem = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(Item.class), compiler);
+ compiledItem.setConstructorParams(TypeManager.getJavaCode(id) + ", " + TypeManager.getJavaCode(item.getLabel()) + ", " + TypeManager.getJavaCode(item.getValue()) + ", " + item.isSelected());
+ compiler.registerCompiledObject(compiledItem);
+ list.appendAdditionCode(listName + ".add(" + id + ");");
+ }
+ list.appendAdditionCode(list.getId() + ".setItems(" + listName + ");");
+ }
+ }
+}
+
+
+
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CompiledItemContainer.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CompiledItemContainer.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/CompiledItemContainer.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.runtime.gwt.Item;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Stack;
+
+/** Compiled representation of a class that contains Items arranged in a list or tree structure (JComboBox, JList, JTree). */
+class CompiledItemContainer extends CompiledObject {
+ private List<Item> items = new ArrayList<Item>();
+ private Stack<Item> openNodes = new Stack<Item>();
+
+ public CompiledItemContainer(String id, ClassDescriptor objectClass, JAXXCompiler compiler) throws CompilerException {
+ super(id, objectClass, compiler);
+ }
+
+
+ public void openItem(Item item) {
+ if (openNodes.isEmpty()) {
+ items.add(item);
+ } else {
+ Item openNode = openNodes.peek();
+ openNode.addChild(item);
+ }
+ openNodes.add(item);
+ }
+
+
+ public void closeItem(Item item) {
+ if (openNodes.pop() != item) {
+ throw new IllegalArgumentException(item + " was not at the top of the item stack");
+ }
+ }
+
+
+ public List<Item> getItems() {
+ return items;
+ }
+
+
+ public void setItems(List<Item> items) {
+ this.items = items;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ItemHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ItemHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ItemHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.UnsupportedAttributeException;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.Item;
+import jaxx.tags.TagHandler;
+import jaxx.types.TypeManager;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import java.io.IOException;
+import java.util.List;
+
+public class ItemHandler implements TagHandler {
+ private String DATA_BINDING = "<data binding has not been processed yet>";
+
+ public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compileChildrenFirstPass(tag, compiler);
+ }
+
+ public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ String id = tag.getAttribute("id");
+ if (id == null || id.length() == 0)
+ id = compiler.getAutoId(ClassDescriptorLoader.getClassDescriptor(Item.class));
+ String label = null;
+ String value = null;
+ boolean selected = false;
+ NamedNodeMap children = tag.getAttributes();
+
+ for (int i = 0; i < children.getLength(); i++) {
+ Attr attribute = (Attr) children.item(i);
+ String name = attribute.getName();
+ String attrValue = attribute.getValue();
+ if (name.equals("id")) {
+ // already handled
+ continue;
+ }
+ if (name.equals(Item.LABEL_PROPERTY)) {
+ String labelBinding = compiler.processDataBindings(attrValue, ClassDescriptorLoader.getClassDescriptor(String.class));
+ if (labelBinding != null)
+ compiler.registerDataBinding(labelBinding, id + ".label", id + ".setLabel(" + labelBinding + ");");
+ else
+ label = attrValue;
+ continue;
+ }
+ if (name.equals(Item.VALUE_PROPERTY)) {
+ String valueBinding = compiler.processDataBindings(attrValue, ClassDescriptorLoader.getClassDescriptor(Object.class));
+ if (valueBinding != null) {
+ value = DATA_BINDING;
+ compiler.registerDataBinding(valueBinding, id + ".value", id + ".setValue(" + valueBinding + ");");
+ } else
+ value = attrValue;
+ continue;
+ }
+ if (name.equals(Item.SELECTED_PROPERTY)) {
+ String selectedBinding = compiler.processDataBindings(attrValue, ClassDescriptorLoader.getClassDescriptor(Boolean.class));
+ if (selectedBinding != null)
+ compiler.registerDataBinding(selectedBinding, id + ".selected", id + ".setSelected(" + selectedBinding + ");");
+ else
+ selected = (Boolean) TypeManager.convertFromString(attrValue, Boolean.class);
+ continue;
+ }
+
+ if (!name.startsWith("xmlns") && !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) {
+ throw new UnsupportedAttributeException(name);
+ }
+ }
+
+ Item item = new Item(id, label, value, selected);
+ CompiledItemContainer list = (CompiledItemContainer) compiler.getOpenComponent();
+ if (value == null)
+ compiler.reportError("<item> tag is missing required 'value' attribute");
+ else {
+ if (!value.equals(DATA_BINDING)) {
+ List<Item> items = list.getItems();
+ for (Item item1 : items) {
+ if (item1.getValue().equals(value)) {
+ compiler.reportError("This container already has an <item> tag with the value '" + value + "'");
+ break;
+ }
+ }
+ }
+ list.openItem(item);
+ compileChildrenSecondPass(tag, compiler);
+ list.closeItem(item);
+ }
+ }
+
+
+ protected void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ NodeList children = tag.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ Element child = (Element) node;
+ compileChildTagFirstPass(child, compiler);
+ } else
+ if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ String text = ((Text) node).getData().trim();
+ if (text.length() > 0)
+ compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')");
+ }
+ }
+ }
+
+
+ protected void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ NodeList children = tag.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ Element child = (Element) node;
+ compileChildTagSecondPass(child, compiler);
+ } else
+ if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ String text = ((Text) node).getData().trim();
+ if (text.length() > 0)
+ compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')");
+ }
+ }
+ }
+
+
+ protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compiler.compileFirstPass(tag);
+ }
+
+
+ protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compiler.compileSecondPass(tag);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JAXXTabHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JAXXTabHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JAXXTabHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,28 @@
+/*
+* \#\#% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit, Gabriel Landais
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* \#\#% */
+package jaxx.tags.gwt;
+
+import jaxx.reflect.ClassDescriptor;
+
+/** @author chemit */
+public class JAXXTabHandler extends TableHandler {
+ public JAXXTabHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ }
+}
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JInternalFrameHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JInternalFrameHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JInternalFrameHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+import org.w3c.dom.Element;
+
+import javax.swing.JInternalFrame;
+import javax.swing.JMenuBar;
+import javax.swing.WindowConstants;
+
+public class JInternalFrameHandler extends DefaultComponentHandler {
+
+ public JInternalFrameHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JInternalFrame.class);
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledObject(id, getBeanClass(), compiler) {
+ @Override
+ public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException {
+ if (ClassDescriptorLoader.getClassDescriptor(JMenuBar.class).isAssignableFrom(child.getObjectClass())) {
+ appendAdditionCode(getId() + ".setJMenuBar(" + child.getId() + ");");
+ } else {
+ super.addChild(child, constraints, compiler);
+ }
+ }
+ };
+ }
+
+ @Override
+ protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException {
+ super.setDefaults(object, tag, compiler);
+ setAttribute(object, "visible", "true", false, compiler);
+ setAttribute(object, "closable", "true", false, compiler);
+ setAttribute(object, "defaultCloseOperation", String.valueOf(WindowConstants.DISPOSE_ON_CLOSE), false, compiler);
+ }
+
+
+ @Override
+ public void setAttributes(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException {
+ super.setAttributes(object, tag, compiler);
+ compiler.appendInitializerCode(object.getId() + ".pack();\n");
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JPopupMenuHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JPopupMenuHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JPopupMenuHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+import org.w3c.dom.Element;
+
+import javax.swing.JPopupMenu;
+
+public class JPopupMenuHandler extends DefaultComponentHandler {
+ public JPopupMenuHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JPopupMenu.class);
+ }
+
+ @Override
+ public boolean isContainer() {
+ return true;
+ }
+
+ @Override
+ protected void openComponent(CompiledObject object, Element tag, JAXXCompiler compiler) {
+ compiler.openInvisibleComponent(object);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JProgressBarHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JProgressBarHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JProgressBarHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+
+import javax.swing.JProgressBar;
+import javax.swing.event.ChangeListener;
+
+public class JProgressBarHandler extends DefaultComponentHandler {
+
+ public JProgressBarHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JProgressBar.class);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getValue", ChangeListener.class, "change");
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JScrollPaneHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JScrollPaneHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JScrollPaneHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+
+import javax.swing.JScrollPane;
+
+public class JScrollPaneHandler extends DefaultComponentHandler {
+
+ public JScrollPaneHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JScrollPane.class);
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledObject(id, getBeanClass(), compiler) {
+ boolean hasChild;
+
+ @Override
+ public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException {
+ if (constraints != null) {
+ compiler.reportError("JScrollPane does not accept constraints");
+ }
+ if (hasChild) {
+ compiler.reportError("JScrollPane may only have one child");
+ }
+ super.addChild(child, constraints, compiler);
+ hasChild = true;
+ }
+ };
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSliderHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSliderHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSliderHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,45 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+import javax.swing.JSlider;
+import javax.swing.event.ChangeListener;
+
+public class JSliderHandler extends DefaultComponentHandler {
+ public JSliderHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ if (!ClassDescriptorLoader.getClassDescriptor(JSlider.class).isAssignableFrom(beanClass))
+ throw new IllegalArgumentException(getClass().getName() + " does not support the class " + beanClass.getName());
+ }
+
+
+ protected int getAttributeOrdering(Attr attr) {
+ if (attr.getName().equals("value"))
+ return 1;
+ else
+ return super.getAttributeOrdering(attr);
+ }
+
+
+ protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException {
+ super.setDefaults(object, tag, compiler);
+ setAttribute(object, "value", "0", false, compiler);
+ }
+
+
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getValue", ChangeListener.class, "model");
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSpinnerHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSpinnerHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSpinnerHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+import org.w3c.dom.Element;
+
+import javax.swing.JSpinner;
+import javax.swing.event.ChangeListener;
+
+public class JSpinnerHandler extends DefaultComponentHandler {
+ public static String MINIMUM_PROPERTY = "minimum";
+ public static String MAXIMUM_PROPERTY = "maximum";
+ public static String VALUE_PROPERTY = "value";
+
+ public JSpinnerHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JSpinner.class);
+ }
+
+ public static class CompiledSpinner extends CompiledObject {
+ Integer minimum = null;
+ Integer maximum = null;
+ Integer value = null;
+
+ public CompiledSpinner(String id, ClassDescriptor objectClass, JAXXCompiler compiler) throws CompilerException {
+ super(id, objectClass, compiler);
+ }
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledSpinner(id, getBeanClass(), compiler);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getValue", ChangeListener.class, "model");
+ }
+
+ @Override
+ public ClassDescriptor getPropertyType(CompiledObject object, String propertyName, JAXXCompiler compiler) throws CompilerException {
+ if (propertyName.equals(MINIMUM_PROPERTY) || propertyName.equals(MAXIMUM_PROPERTY) ||
+ propertyName.equals(VALUE_PROPERTY)) {
+ return ClassDescriptorLoader.getClassDescriptor(Integer.class);
+ }
+ return super.getPropertyType(object, propertyName, compiler);
+ }
+
+ @Override
+ public void setProperty(CompiledObject object, String name, Object value, JAXXCompiler compiler) throws CompilerException {
+ if (name.equals(MINIMUM_PROPERTY)) {
+ ((CompiledSpinner) object).minimum = (Integer) value;
+ } else if (name.equals(MAXIMUM_PROPERTY)) {
+ ((CompiledSpinner) object).maximum = (Integer) value;
+ } else if (name.equals(VALUE_PROPERTY)) {
+ ((CompiledSpinner) object).value = (Integer) value;
+ } else {
+ super.setProperty(object, name, value, compiler);
+ }
+ }
+
+ @Override
+ protected void closeComponent(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException {
+ CompiledSpinner spinner = (CompiledSpinner) object;
+ if (spinner.minimum != null || spinner.maximum != null || spinner.value != null) {
+ if (spinner.getConstructorParams() != null) {
+ compiler.reportError("constructorParams and minimum/maximum may not both be specified for the same JSpinner");
+ }
+ if (spinner.minimum == null) {
+ spinner.minimum = Math.min(0, spinner.maximum != null ? spinner.maximum.intValue() : 0);
+ }
+ if (spinner.maximum == null) {
+ spinner.maximum = Math.max(100, spinner.minimum.intValue());
+ }
+ if (spinner.value == null) {
+ spinner.value = spinner.minimum;
+ }
+ spinner.setConstructorParams("new SpinnerNumberModel(" + spinner.value + ", " + spinner.minimum + ", " + spinner.maximum + ", 1)");
+ }
+
+ super.closeComponent(object, tag, compiler);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSplitPaneHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSplitPaneHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JSplitPaneHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+import org.w3c.dom.Element;
+
+import javax.swing.JSplitPane;
+import java.awt.Component;
+
+public class JSplitPaneHandler extends DefaultComponentHandler {
+ public JSplitPaneHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JSplitPane.class);
+ }
+
+ protected Component createRawComponent(Element tag) {
+ return new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
+ }
+
+ /**
+ * Add support for <code>orientation="vertical"</code> and <code>orientation="horizontal"</code>. The
+ * values required by the JAXXBeanInfo are the unwieldy <code>vertical_split</code> and <code>horizontal_split</code>
+ * (which are also recognized).
+ */
+ @Override
+ protected int constantValue(String key, String value) {
+ if (key.equals("orientation")) {
+ value = value.trim().toLowerCase();
+ if (value.equals("horizontal") || value.equals("horizontal_split")) {
+ return JSplitPane.HORIZONTAL_SPLIT;
+ }
+ if (value.equals("vertical") || value.equals("vertical_split")) {
+ return JSplitPane.VERTICAL_SPLIT;
+ }
+ throw new IllegalArgumentException("orientation must be 'horizontal' or 'vertical', found '" + value + "'");
+ }
+ return super.constantValue(key, value);
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledObject(id, getBeanClass(), compiler) {
+ private int count;
+
+ @Override
+ public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException {
+ if (constraints != null) {
+ compiler.reportError("JSplitPane does not accept constraints");
+ }
+ if (count == 0) {
+ super.addChild(child, "JSplitPane.LEFT", compiler);
+ } else if (count == 1) {
+ super.addChild(child, "JSplitPane.RIGHT", compiler);
+ } else {
+ compiler.reportError("JSplitPane is limited to two children");
+ }
+ count++;
+ }
+ };
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTabbedPaneHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTabbedPaneHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTabbedPaneHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.I18nHelper;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.TabInfo;
+import jaxx.tags.DefaultComponentHandler;
+import jaxx.types.TypeManager;
+
+import javax.swing.Icon;
+import javax.swing.JTabbedPane;
+import javax.swing.event.ChangeListener;
+import java.awt.Color;
+import java.awt.event.ContainerListener;
+
+public class JTabbedPaneHandler extends DefaultComponentHandler {
+ public JTabbedPaneHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JTabbedPane.class);
+ }
+
+ public static class CompiledTabbedPane extends CompiledObject {
+ private static final TabInfo USED = new TabInfo("ALREADY USED");
+
+ int tabCount;
+ TabInfo tabInfo;
+
+ public CompiledTabbedPane(String id, ClassDescriptor objectClass, JAXXCompiler compiler) throws CompilerException {
+ super(id, objectClass, compiler);
+ }
+
+ @Override
+ public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException {
+ if (constraints != null) {
+ compiler.reportError("JTabbedPane tabs may not have constraints");
+ }
+
+ super.addChild(child, constraints, compiler);
+
+ if (tabInfo == null) {
+ compiler.reportError("JTabbedPaneHandler may only have 'tab' tags as children (found " + child.getObjectClass() + ")");
+ return;
+ } else if (tabInfo == USED) {
+ compiler.reportError("<tab> tags may only have one child component");
+ return;
+ }
+
+ int tabIndex = ++tabCount - 1;
+ appendAdditionCode(tabInfo.getId() + ".addPropertyChangeListener(new jaxx.runtime.swing.TabInfoPropertyChangeListener(" + getId() + ", " + tabIndex + "));");
+
+ String title = tabInfo.getTitle();
+ if (title != null) {
+ if (I18nHelper.isI18nAttribute("title")) {
+ if (!title.startsWith("_(\"")) {
+ // we did not have the invocation code, add it
+ title = I18nHelper.addI18nInvocation(getId(), "title", TypeManager.getJavaCode(title), compiler);
+ }
+ } else {
+ title = TypeManager.getJavaCode(title);
+ }
+ appendAdditionCode(getId() + ".setTitleAt(" + tabIndex + ", " + title + ");");
+ }
+
+ String toolTipText = tabInfo.getToolTipText();
+ if (toolTipText != null) {
+ if (I18nHelper.isI18nAttribute("toolTipText")) {
+ if (!toolTipText.startsWith("_(\"")) {
+ // we did not have the invocation code, add it
+ toolTipText = I18nHelper.addI18nInvocation(getId(), "toolTipText", TypeManager.getJavaCode(toolTipText), compiler);
+ }
+ } else {
+ toolTipText = TypeManager.getJavaCode(toolTipText);
+ }
+ appendAdditionCode(getId() + ".setToolTipTextAt(" + tabIndex + ", " + toolTipText + ");");
+ }
+
+ boolean enabled = tabInfo.isEnabled();
+ if (!enabled) {
+ appendAdditionCode(getId() + ".setEnabledAt(" + tabIndex + ", false);");
+ }
+
+ Color foreground = tabInfo.getForeground();
+ if (foreground != null) {
+ appendAdditionCode(getId() + ".setForegroundAt(" + tabIndex + ", " + TypeManager.getJavaCode(foreground) + ");");
+ }
+
+ Color background = tabInfo.getBackground();
+ if (background != null) {
+ appendAdditionCode(getId() + ".setBackgroundAt(" + tabIndex + ", " + TypeManager.getJavaCode(background) + ");");
+ }
+
+ int mnemonic = tabInfo.getMnemonic();
+ if (mnemonic != -1) {
+ appendAdditionCode(getId() + ".setMnemonicAt(" + tabIndex + ", " + mnemonic + ");");
+ }
+
+ int displayedMnemonicIndex = tabInfo.getDisplayedMnemonicIndex();
+ if (displayedMnemonicIndex != -1) {
+ appendAdditionCode(getId() + ".setDisplayedMnemonicIndexAt(" + tabIndex + ", " + displayedMnemonicIndex + ");");
+ }
+
+ Icon icon = tabInfo.getIcon();
+ if (icon != null) {
+ appendAdditionCode(getId() + ".setIconAt(" + tabIndex + ", " + icon + ");");
+ }
+
+ Icon disabledIcon = tabInfo.getDisabledIcon();
+ if (disabledIcon != null) {
+ appendAdditionCode(getId() + ".setDisabledIconAt(" + tabIndex + ", " + disabledIcon + ");");
+ }
+
+ tabInfo = USED;
+ }
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledTabbedPane(id, getBeanClass(), compiler);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getSelectedIndex", ChangeListener.class);
+ addProxyEventInfo("getSelectedComponent", ChangeListener.class);
+ addProxyEventInfo("getTabCount", ContainerListener.class);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTextComponentHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTextComponentHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JTextComponentHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+
+import javax.swing.JTextArea;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.JTextComponent;
+import jaxx.runtime.GWTUtil;
+
+public class JTextComponentHandler extends DefaultComponentHandler {
+ private static final int DEFAULT_COLUMNS = 15;
+
+ public JTextComponentHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JTextComponent.class);
+ }
+
+ @Override
+ protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException {
+ super.setDefaults(object, tag, compiler);
+ try {
+ object.getObjectClass().getMethodDescriptor("setColumns", ClassDescriptorLoader.getClassDescriptor(int.class));
+ setAttribute(object, "columns", String.valueOf(DEFAULT_COLUMNS), false, compiler);
+ }
+ catch (NoSuchMethodException e) {
+ // ignore ?
+ }
+
+ if (ClassDescriptorLoader.getClassDescriptor(JTextArea.class).isAssignableFrom(object.getObjectClass())) {
+ setAttribute(object, "lineWrap", "true", false, compiler);
+ setAttribute(object, "wrapStyleWord", "true", false, compiler);
+ }
+ }
+
+ @Override
+ public String getSetPropertyCode(String id, String name, String valueCode, JAXXCompiler compiler) throws CompilerException {
+ if (name.equals("text")) {
+ return GWTUtil.class.getName()+".setText(" + id + ", " + valueCode + ");\n";
+ //return "jaxx.runtime.swing.Utils.setText(" + id + ", " + valueCode + ");\n";
+ }
+ return super.getSetPropertyCode(id, name, valueCode, compiler);
+ }
+
+ @Override
+ protected int getAttributeOrdering(Attr attr) {
+ // delay text in case other attributes affect how it's processed, as is the case
+ // with JEditorPane's contentType
+ if (attr.getName().equals("text")) {
+ return 1;
+ }
+ return super.getAttributeOrdering(attr);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getText", DocumentListener.class, "document");
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JToolBarHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JToolBarHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JToolBarHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+
+import javax.swing.JToolBar;
+
+public class JToolBarHandler extends DefaultComponentHandler {
+ public JToolBarHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JToolBar.class);
+ }
+
+ /**
+ * Add support for <code>orientation="vertical"</code> and <code>orientation="horizontal"</code>. These values should
+ * have been supported without any special effort on my part, but JToolBar's BeanInfo doesn't contain the enum attribute
+ * for the orientation property.
+ */
+ @Override
+ protected int constantValue(String key, String value) {
+ if (key.equals("orientation")) {
+ value = value.trim().toLowerCase();
+ if (value.equals("horizontal")) {
+ return JToolBar.HORIZONTAL;
+ }
+ if (value.equals("vertical")) {
+ return JToolBar.VERTICAL;
+ }
+ throw new IllegalArgumentException("orientation must be 'horizontal' or 'vertical', found '" + value + "'");
+ }
+ return super.constantValue(key, value);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JWindowHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JWindowHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/JWindowHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+import org.w3c.dom.Element;
+
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JMenuBar;
+import javax.swing.JWindow;
+import java.io.IOException;
+import java.util.Map;
+
+public class JWindowHandler extends DefaultComponentHandler {
+
+ public JWindowHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JWindow.class, JFrame.class, JDialog.class);
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledObject(id, getBeanClass(), compiler) {
+ @Override
+ public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException {
+ if (ClassDescriptorLoader.getClassDescriptor(JMenuBar.class).isAssignableFrom(child.getObjectClass())) {
+ appendAdditionCode(getId() + ".setJMenuBar(" + child.getId() + ");");
+ } else {
+ super.addChild(child, constraints, compiler);
+ }
+ }
+ };
+ }
+
+ @Override
+ protected void openComponent(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException {
+ if (compiler.getOpenComponent() != null) {
+ compiler.openInvisibleComponent(object);
+ } else {
+ super.openComponent(object, tag, compiler);
+ }
+ }
+
+ @Override
+ public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ super.compileSecondPass(tag, compiler);
+ CompiledObject object = objectMap.get(tag);
+ Map properties = object.getProperties();
+ if (!properties.containsKey("width") && !properties.containsKey("height")) {
+ compiler.appendLateInitializer(object.getId() + ".pack();\n");
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ListHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ListHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/ListHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.Item;
+import jaxx.runtime.gwt.JAXXList;
+import jaxx.tags.DefaultComponentHandler;
+import jaxx.types.TypeManager;
+import org.w3c.dom.Element;
+
+import javax.swing.event.ListSelectionListener;
+import java.io.IOException;
+import java.util.List;
+
+public class ListHandler extends DefaultComponentHandler {
+ public ListHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JAXXList.class);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getSelectedIndex", ListSelectionListener.class, "selectionModel");
+ addProxyEventInfo("getSelectedIndices", ListSelectionListener.class, "selectionModel");
+ addProxyEventInfo("getSelectedValue", ListSelectionListener.class, "selectionModel");
+ addProxyEventInfo("getSelectedValues", ListSelectionListener.class, "selectionModel");
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledItemContainer(id, getBeanClass(), compiler);
+ }
+
+ @Override
+ public void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ super.compileChildrenSecondPass(tag, compiler);
+ CompiledItemContainer list = (CompiledItemContainer) compiler.getOpenComponent();
+ List<Item> items = list.getItems();
+ if (items != null && !items.isEmpty()) {
+ String listName = list.getId() + "$items";
+ //TODO Add the correct generic type
+ list.appendAdditionCode("java.util.List<jaxx.runtime.swing.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.swing.Item>();");
+ for (Item item : items) {
+ String id = item.getId();
+ CompiledObject compiledItem = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(Item.class), compiler);
+ compiledItem.setConstructorParams(TypeManager.getJavaCode(id) + ", " + TypeManager.getJavaCode(item.getLabel()) + ", " + TypeManager.getJavaCode(item.getValue()) + ", " + item.isSelected());
+ compiler.registerCompiledObject(compiledItem);
+ list.appendAdditionCode(listName + ".add(" + id + ");");
+ }
+ list.appendAdditionCode(list.getId() + ".setItems(" + listName + ");");
+ }
+ }
+}
+
+
+
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/MenuHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/MenuHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/MenuHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+
+import javax.swing.JMenu;
+import javax.swing.event.MenuListener;
+
+public class MenuHandler extends DefaultComponentHandler {
+
+ public MenuHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JMenu.class);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("isSelected", MenuListener.class);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/PasswordFieldHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/PasswordFieldHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/PasswordFieldHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+
+import javax.swing.JPasswordField;
+import javax.swing.event.DocumentListener;
+
+public class PasswordFieldHandler extends JTextComponentHandler {
+
+ public PasswordFieldHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JPasswordField.class);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getPassword", DocumentListener.class, "document");
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RadioButtonHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RadioButtonHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RadioButtonHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.UnsupportedAttributeException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.JAXXButtonGroup;
+import jaxx.tags.DefaultComponentHandler;
+import jaxx.types.TypeManager;
+
+import javax.swing.AbstractButton;
+import javax.swing.event.ChangeListener;
+
+public class RadioButtonHandler extends DefaultComponentHandler {
+ private static final String VALUE_PROPERTY = JAXXButtonGroup.VALUE_CLIENT_PROPERTY.substring(1);
+ private static final String BUTTON_GROUP_PROPERTY = JAXXButtonGroup.BUTTON8GROUP_CLIENT_PROPERTY.substring(1);
+
+ public RadioButtonHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, AbstractButton.class);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("isSelected", ChangeListener.class, "model");
+ }
+
+ @Override
+ public ClassDescriptor getPropertyType(CompiledObject object, String name, JAXXCompiler compiler) throws CompilerException {
+ if (name.equals(BUTTON_GROUP_PROPERTY)) {
+ return null; // accepts either a String or a ButtonGroup
+ } else if (name.equals(VALUE_PROPERTY)) {
+ return ClassDescriptorLoader.getClassDescriptor(Object.class);
+ } else {
+ return super.getPropertyType(object, name, compiler);
+ }
+ }
+
+ @Override
+ public boolean isMemberBound(String name) throws UnsupportedAttributeException {
+ return !(name.equals(BUTTON_GROUP_PROPERTY) || name.equals(VALUE_PROPERTY)) && super.isMemberBound(name);
+ }
+
+ // handle buttonGroup assignment in addition block rather than initialization block
+ @Override
+ public void setProperty(CompiledObject object, String name, Object value, JAXXCompiler compiler) {
+ if (name.equals(BUTTON_GROUP_PROPERTY)) {
+ object.appendAdditionCode(getSetPropertyCode(object.getJavaCode(), name, TypeManager.getJavaCode(value), compiler));
+ } else {
+ super.setProperty(object, name, value, compiler);
+ }
+ }
+
+ @Override
+ public String getSetPropertyCode(String id, String name, String valueCode, JAXXCompiler compiler) throws CompilerException {
+ if (name.equals(BUTTON_GROUP_PROPERTY)) {
+ if (valueCode.startsWith("\"") && valueCode.endsWith("\"")) {
+ valueCode = valueCode.substring(1, valueCode.length() - 1);
+ CompiledObject buttonGroup = compiler.getCompiledObject(valueCode);
+ if (buttonGroup == null) {
+ buttonGroup = new CompiledObject(valueCode, ClassDescriptorLoader.getClassDescriptor(JAXXButtonGroup.class), compiler);
+ compiler.registerCompiledObject(buttonGroup);
+ }
+ }
+ return "{ javax.swing.ButtonGroup $buttonGroup = " + valueCode + "; " + id + ".putClientProperty(\"$buttonGroup\", $buttonGroup); $buttonGroup.add(" + id + "); }\n";
+ } else if (name.equals(VALUE_PROPERTY)) {
+ return "{ " + id + ".putClientProperty(\"" + JAXXButtonGroup.VALUE_CLIENT_PROPERTY + "\", " + valueCode + "); Object $buttonGroup = " + id + ".getClientProperty(\"" + JAXXButtonGroup.BUTTON8GROUP_CLIENT_PROPERTY + "\");" +
+ " if ($buttonGroup instanceof jaxx.runtime.swing.JAXXButtonGroup) { ((jaxx.runtime.swing.JAXXButtonGroup) $buttonGroup).updateSelectedValue(); } }\n";
+ } else {
+ return super.getSetPropertyCode(id, name, valueCode, compiler);
+ }
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RowHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RowHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/RowHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.Table;
+import jaxx.tags.TagHandler;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import java.awt.GridBagConstraints;
+import java.io.IOException;
+
+public class RowHandler implements TagHandler {
+ public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compileChildrenFirstPass(tag, compiler);
+ }
+
+ public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ if (!ClassDescriptorLoader.getClassDescriptor(Table.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) {
+ compiler.reportError("row tag may only appear within Table tag");
+ return;
+ }
+
+ TableHandler.CompiledTable table = (TableHandler.CompiledTable) compiler.getOpenComponent();
+ table.newRow();
+ GridBagConstraints c = table.getRowConstraints();
+ CellHandler.setAttributes(c, tag);
+ compileChildrenSecondPass(tag, compiler);
+ }
+
+ public void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ NodeList children = tag.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ Element child = (Element) node;
+ if (!child.getLocalName().equals("cell")) {
+ compiler.reportError("tag '" + tag.getLocalName() + "' may only contain cell tags as children");
+ }
+ compileChildTagFirstPass(child, compiler);
+ } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ String text = ((Text) node).getData().trim();
+ if (text.length() > 0) {
+ compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')");
+ }
+ }
+ }
+ }
+
+ public void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ NodeList children = tag.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ Element child = (Element) node;
+ if (!child.getLocalName().equals("cell")) {
+ compiler.reportError("tag '" + tag.getLocalName() + "' may only contain cell tags as children");
+ }
+ compileChildTagSecondPass(child, compiler);
+ } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ String text = ((Text) node).getData().trim();
+ if (text.length() > 0) {
+ compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')");
+ }
+ }
+ }
+ }
+
+ protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compiler.compileFirstPass(tag);
+ }
+
+ protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compiler.compileSecondPass(tag);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TabHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TabHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TabHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.I18nHelper;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.TabInfo;
+import jaxx.tags.TagHandler;
+import jaxx.types.TypeManager;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+
+import javax.swing.Icon;
+import javax.swing.JTabbedPane;
+import java.awt.Color;
+import java.io.IOException;
+
+public class TabHandler implements TagHandler {
+
+ public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compileChildrenFirstPass(tag, compiler);
+ }
+
+
+ public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ if (!ClassDescriptorLoader.getClassDescriptor(JTabbedPane.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) {
+ compiler.reportError("tab tag may only appear within JTabbedPane tag");
+ return;
+ }
+
+ JTabbedPaneHandler.CompiledTabbedPane tabs = (JTabbedPaneHandler.CompiledTabbedPane) compiler.getOpenComponent();
+
+ String id = tag.getAttribute("id");
+ if (id == null || id.length() == 0) {
+ id = compiler.getAutoId(ClassDescriptorLoader.getClassDescriptor(TabInfo.class));
+ }
+ TabInfo tabInfo = new TabInfo(id);
+ CompiledObject compiledTabInfo = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(TabInfo.class), compiler);
+ compiler.registerCompiledObject(compiledTabInfo);
+ //id = tabInfo.getId();
+ tabs.tabInfo = tabInfo;
+ setAttributes(compiledTabInfo, tabs, tag, compiler);
+ compileChildrenSecondPass(tag, compiler);
+ tabs.tabInfo = null;
+ }
+
+
+ public static void setAttribute(CompiledObject compiledTabInfo, JTabbedPaneHandler.CompiledTabbedPane tabs, String name, String value, JAXXCompiler compiler) throws CompilerException {
+ value = value.trim();
+ TabInfo tabInfo = tabs.tabInfo;
+ String id = tabInfo.getId();
+ String binding = compiler.processDataBindings(value, ClassDescriptorLoader.getClassDescriptor(Object.class));
+ if (binding != null) {
+ compiler.registerDataBinding(binding, id + "." + name, id + ".set" + org.apache.commons.lang.StringUtils.capitalize(name) + "(" + binding + ");");
+ return;
+ }
+
+ String valueCode = TypeManager.getJavaCode(value);
+
+ // add i18n support
+ if (I18nHelper.isI18nableAttribute(name, compiler)) {
+ value = valueCode = I18nHelper.addI18nInvocation(id, name, valueCode, compiler);
+ }
+
+ if (name.equals("title")) {
+ tabInfo.setTitle(value);
+ compiledTabInfo.appendInitializationCode(id + ".setTitle(" + valueCode + ");");
+ //compiledTabInfo.appendInitializationCode(id + ".setTitle(" + TypeManager.getJavaCode(value) + ");");
+ } else if (name.equals("toolTipText")) {
+ tabInfo.setToolTipText(value);
+ compiledTabInfo.appendInitializationCode(id + ".setToolTipText(" + valueCode + ");");
+ //compiledTabInfo.appendInitializationCode(id + ".setToolTipText(" + TypeManager.getJavaCode(value) + ");");
+ } else if (name.equals("icon")) {
+ Icon icon = (Icon) TypeManager.convertFromString(value, Icon.class);
+ tabInfo.setIcon(icon);
+ compiledTabInfo.appendInitializationCode(id + ".setIcon(" + TypeManager.getJavaCode(icon) + ");");
+ } else if (name.equals("enabled")) {
+ boolean enabled = (Boolean) TypeManager.convertFromString(value, Boolean.class);
+ tabInfo.setEnabled(enabled);
+ compiledTabInfo.appendInitializationCode(id + ".setEnabled(" + enabled + ");");
+ } else if (name.equals("disabledIcon")) {
+ Icon disabledIcon = (Icon) TypeManager.convertFromString(value, Icon.class);
+ tabInfo.setDisabledIcon(disabledIcon);
+ compiledTabInfo.appendInitializationCode(id + ".setDisabledIcon(" + TypeManager.getJavaCode(disabledIcon) + ");");
+ } else if (name.equals("mnemonic")) {
+ int mnemonic = (Character) TypeManager.convertFromString(value, char.class);
+ tabInfo.setMnemonic(mnemonic);
+ compiledTabInfo.appendInitializationCode(id + ".setMnemonic(" + mnemonic + ");");
+ } else if (name.equals("displayedMnemonicIndex")) {
+ int displayedMnemonicIndex = (Integer) TypeManager.convertFromString(value, int.class);
+ tabInfo.setDisplayedMnemonicIndex(displayedMnemonicIndex);
+ compiledTabInfo.appendInitializationCode(id + ".setDisplayedMnemonicIndex(" + displayedMnemonicIndex + ");");
+ } else if (name.equals("foreground")) {
+ Color foreground = (Color) TypeManager.convertFromString(value, Color.class);
+ tabInfo.setForeground(foreground);
+ compiledTabInfo.appendInitializationCode(id + ".setForeground(" + TypeManager.getJavaCode(foreground) + ");");
+ } else if (name.equals("background")) {
+ Color background = (Color) TypeManager.convertFromString(value, Color.class);
+ tabInfo.setBackground(background);
+ compiledTabInfo.appendInitializationCode(id + ".setBackground(" + TypeManager.getJavaCode(background) + ");");
+ } else if (name.equals("id")) {
+ // ignore, already handled
+ } else {
+ compiler.reportError("The <tab> tag does not support the attribute '" + name + "'");
+ }
+ }
+
+
+ public void setAttributes(CompiledObject compiledTabInfo, JTabbedPaneHandler.CompiledTabbedPane tabs, Element tag, JAXXCompiler compiler) throws CompilerException {
+ NamedNodeMap children = tag.getAttributes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Attr attribute = (Attr) children.item(i);
+ String name = attribute.getName();
+ String value = attribute.getValue();
+ if (!name.startsWith("xmlns") && !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) {
+ setAttribute(compiledTabInfo, tabs, name, value, compiler);
+ }
+ }
+ }
+
+
+ protected void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ NodeList children = tag.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ Element child = (Element) node;
+ compileChildTagFirstPass(child, compiler);
+ } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ String text = ((Text) node).getData().trim();
+ if (text.length() > 0) {
+ compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')");
+ }
+ }
+ }
+ }
+
+
+ protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compiler.compileFirstPass(tag);
+ }
+
+
+ protected void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ NodeList children = tag.getChildNodes();
+ for (int i = 0; i < children.getLength(); i++) {
+ Node node = children.item(i);
+ int nodeType = node.getNodeType();
+ if (nodeType == Node.ELEMENT_NODE) {
+ Element child = (Element) node;
+ compileChildTagSecondPass(child, compiler);
+ } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) {
+ String text = ((Text) node).getData().trim();
+ if (text.length() > 0) {
+ compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')");
+ }
+ }
+ }
+ }
+
+
+ protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ compiler.compileSecondPass(tag);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TableHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TableHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TableHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,124 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.UnsupportedAttributeException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.Table;
+import jaxx.tags.DefaultComponentHandler;
+import jaxx.types.TypeManager;
+
+import java.awt.GridBagConstraints;
+import java.awt.Insets;
+import java.util.ArrayList;
+import java.util.List;
+
+public class TableHandler extends DefaultComponentHandler {
+ public static final Insets DEFAULT_INSETS = new Insets(3, 3, 3, 3);
+
+ public TableHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, Table.class);
+ }
+
+ @Override
+ public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) throws CompilerException {
+ try {
+ if (object instanceof CompiledTable) {
+ CellHandler.setAttribute(((CompiledTable) object).getTableConstraints(), propertyName, stringValue);
+ } else {
+ super.setAttribute(object, propertyName, stringValue, inline, compiler);
+ }
+ }
+ catch (UnsupportedAttributeException e) {
+ super.setAttribute(object, propertyName, stringValue, inline, compiler);
+ }
+ }
+
+ class CompiledTable extends CompiledObject {
+ private List<Integer> rowSpans = new ArrayList<Integer>();
+
+ private GridBagConstraints tableConstraints;
+ private GridBagConstraints rowConstraints = null;
+ private GridBagConstraints cellConstraints = null;
+ private boolean emptyCell;
+
+ public CompiledTable(String id, ClassDescriptor objectClass, JAXXCompiler compiler) throws CompilerException {
+ super(id, objectClass, compiler);
+ tableConstraints = new GridBagConstraints();
+ tableConstraints.gridx = -1;
+ tableConstraints.gridy = -1;
+ tableConstraints.insets = DEFAULT_INSETS;
+ }
+
+ @Override
+ public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException {
+ if (constraints != null) {
+ compiler.reportError("Table does not accept constraints");
+ }
+ GridBagConstraints c = getCellConstraints();
+ if (c == null) {
+ compiler.reportError("Table tag may only contain row tags");
+ return;
+ }
+ if (!emptyCell) {
+ compiler.reportError("Table cells may only have one child component");
+ }
+ while (rowSpans.size() < c.gridx + c.gridwidth) {
+ rowSpans.add(null);
+ }
+ for (int x = c.gridx; x < c.gridx + c.gridwidth; x++) {
+ rowSpans.set(x, c.gridheight);
+ }
+
+ super.addChild(child, TypeManager.getJavaCode(c), compiler);
+
+ emptyCell = false;
+ }
+
+ public GridBagConstraints getTableConstraints() {
+ return tableConstraints;
+ }
+
+ public GridBagConstraints getRowConstraints() {
+ return rowConstraints;
+ }
+
+ public GridBagConstraints getCellConstraints() {
+ return cellConstraints;
+ }
+
+ public void newRow() {
+ tableConstraints.gridy++;
+ tableConstraints.gridx = -1;
+ rowConstraints = (GridBagConstraints) tableConstraints.clone();
+
+ for (int x = 0; x < rowSpans.size(); x++) {
+ int rowSpan = rowSpans.get(x);
+ if (rowSpan > 0) {
+ rowSpans.set(x, rowSpan - 1);
+ }
+ }
+ }
+
+ public void newCell() {
+ emptyCell = true;
+ rowConstraints.gridx++;
+ while (rowConstraints.gridx < rowSpans.size() && rowSpans.get(rowConstraints.gridx) > 0) {
+ rowConstraints.gridx++;
+ }
+ cellConstraints = (GridBagConstraints) rowConstraints.clone();
+ }
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledTable(id, getBeanClass(), compiler);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TreeHandler.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TreeHandler.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/tags/gwt/TreeHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.tags.gwt;
+
+import jaxx.CompilerException;
+import jaxx.compiler.CompiledObject;
+import jaxx.compiler.JAXXCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.runtime.gwt.Item;
+import jaxx.runtime.gwt.JAXXTree;
+import jaxx.tags.DefaultComponentHandler;
+import jaxx.types.TypeManager;
+import org.w3c.dom.Element;
+
+import javax.swing.event.TreeSelectionListener;
+import java.io.IOException;
+import java.util.List;
+
+public class TreeHandler extends DefaultComponentHandler {
+ public TreeHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JAXXTree.class);
+ }
+
+ @Override
+ protected void configureProxyEventInfo() {
+ super.configureProxyEventInfo();
+ addProxyEventInfo("getSelectionCount", TreeSelectionListener.class, "selectionModel");
+ addProxyEventInfo("getSelectionPath", TreeSelectionListener.class, "selectionModel");
+ addProxyEventInfo("getSelectionPaths", TreeSelectionListener.class, "selectionModel");
+ addProxyEventInfo("getSelectionRows", TreeSelectionListener.class, "selectionModel");
+ addProxyEventInfo("getSelectionValue", TreeSelectionListener.class, "selectionModel");
+ }
+
+ @Override
+ public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException {
+ return new CompiledItemContainer(id, getBeanClass(), compiler);
+ }
+
+ private void createItems(CompiledObject tree, List<Item> items, String addMethod, JAXXCompiler compiler) throws CompilerException {
+ for (Item item : items) {
+ String id = item.getId();
+ CompiledObject compiledItem = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(Item.class), compiler);
+ compiledItem.setConstructorParams(TypeManager.getJavaCode(id) + ", " + TypeManager.getJavaCode(item.getLabel()) + ", " + TypeManager.getJavaCode(item.getValue()) + ", " + item.isSelected());
+ compiler.registerCompiledObject(compiledItem);
+ tree.appendAdditionCode(addMethod + "(" + id + ");");
+ createItems(tree, item.getChildren(), id + ".addChild", compiler);
+ }
+ }
+
+ @Override
+ public void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
+ super.compileChildrenSecondPass(tag, compiler);
+ CompiledItemContainer tree = (CompiledItemContainer) compiler.getOpenComponent();
+ List<Item> items = tree.getItems();
+ if (items != null && !items.isEmpty()) {
+ String listName = tree.getId() + "$items";
+ tree.appendAdditionCode("java.util.List<jaxx.runtime.swing.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.swing.Item>();");
+ createItems(tree, items, listName + ".add", compiler);
+ tree.appendAdditionCode(tree.getId() + ".setItems(" + listName + ");");
+ }
+ }
+}
+
+
+
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/ColorConverter.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/ColorConverter.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/ColorConverter.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.types;
+
+import java.awt.Color;
+import java.lang.reflect.Field;
+
+public class ColorConverter implements TypeConverter {
+ public String getJavaCode(Object object) {
+ Color color = (Color) object;
+ return "new Color(" + color.getRed() + ", " + color.getGreen() + ", " + color.getBlue() + ")";
+ }
+
+
+ public Object convertFromString(String string, Class type) {
+ if (type != Color.class) {
+ throw new IllegalArgumentException("unsupported type: " + type);
+ }
+ if (string.length() == 7 && string.charAt(0) == '#') {
+ return new Color(Integer.parseInt(string.substring(1), 16));
+ }
+ try {
+ Field color = Color.class.getField(string);
+ return color.get(null);
+ }
+ catch (NoSuchFieldException e) {
+ throw new IllegalArgumentException("colors must be of the form #xxxxxx ('#' followed by six hexadecimal digits), or the name of a constant field in java.awt.Color (found: '" + string + "')");
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/GridBagConstraintsConverter.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/GridBagConstraintsConverter.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/GridBagConstraintsConverter.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.types;
+
+import java.awt.GridBagConstraints;
+
+public class GridBagConstraintsConverter implements TypeConverter {
+ public String getJavaCode(Object object) {
+ GridBagConstraints g = (GridBagConstraints) object;
+ return "new GridBagConstraints(" + g.gridx + ", " + g.gridy + ", " + g.gridwidth + ", " + g.gridheight + ", " +
+ g.weightx + ", " + g.weighty + ", " + g.anchor + ", " + g.fill + ", " +
+ TypeManager.getJavaCode(g.insets) + ", " + g.ipadx + ", " + g.ipady + ")";
+ }
+
+
+ public Object convertFromString(String string, Class type) {
+ throw new UnsupportedOperationException("GridBagConstraints must be represented using Java code");
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/InsetsConverter.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/InsetsConverter.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/InsetsConverter.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.types;
+
+import java.awt.Insets;
+import java.util.StringTokenizer;
+
+public class InsetsConverter implements TypeConverter {
+ public String getJavaCode(Object object) {
+ Insets insets = (Insets) object;
+ return "new Insets(" + insets.top + ", " + insets.left + ", " + insets.bottom + ", " + insets.right + ")";
+ }
+
+
+ public Object convertFromString(String string, Class type) {
+ if (type != Insets.class) {
+ throw new IllegalArgumentException("unsupported type: " + type);
+ }
+ StringTokenizer tokenizer = new StringTokenizer(string, ",");
+ int count = tokenizer.countTokens();
+ if (count == 1) {
+ int i = Integer.parseInt(tokenizer.nextToken().trim());
+ return new Insets(i, i, i, i);
+ }
+ if (count == 4) {
+ int[] insets = new int[count];
+ for (int i = 0; tokenizer.hasMoreTokens(); i++) {
+ insets[i] = Integer.parseInt(tokenizer.nextToken().trim());
+ }
+ return new Insets(insets[0], insets[1], insets[2], insets[3]);
+ }
+ throw new IllegalArgumentException("unable to convert string '" + string + "' to Insets");
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/KeyStrokeConverter.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/KeyStrokeConverter.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/java/jaxx/types/KeyStrokeConverter.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.types;
+
+import javax.swing.KeyStroke;
+
+public class KeyStrokeConverter implements TypeConverter {
+ public String getJavaCode(Object object) {
+ return "KeyStroke.getKeyStroke(\"" + object.toString() + "\")";
+ }
+
+
+ public Object convertFromString(String string, Class type) {
+ if (type != KeyStroke.class) {
+ throw new IllegalArgumentException("unsupported type: " + type);
+ }
+ return KeyStroke.getKeyStroke(string);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/jaxx.compiler.Generator
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/jaxx.compiler.Generator (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/jaxx.compiler.Generator 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1 @@
+jaxx.compiler.GWTGenerator
Added: jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/jaxx.spi.Initializer
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/jaxx.spi.Initializer (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/main/resources/META-INF/services/jaxx.spi.Initializer 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1 @@
+jaxx.GWTInitializer
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/ColorConverterTest.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/ColorConverterTest.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/ColorConverterTest.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,51 @@
+package jaxx.junit;
+
+import jaxx.types.ColorConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.Color;
+
+public class ColorConverterTest {
+
+ ColorConverter converter;
+
+ @Before
+ public void setUp() {
+ converter = new ColorConverter();
+ }
+
+ @Test
+ public void testHexValue() {
+ Color value = (Color) converter.convertFromString("#3000FF", Color.class);
+ Assert.assertEquals(value, new Color(48, 0, 255));
+ }
+
+ @Test
+ public void testUpperCaseConstant() {
+ Color value = (Color) converter.convertFromString("RED", Color.class);
+ Assert.assertEquals(value, Color.RED);
+ }
+
+ @Test
+ public void testLowerCaseConstant() {
+ Color value = (Color) converter.convertFromString("blue", Color.class);
+ Assert.assertEquals(value, Color.blue);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testMissingHash() {
+ converter.convertFromString("ABCDEF", Color.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidNumber() {
+ converter.convertFromString("#ABCDEG", Color.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidConstant() {
+ converter.convertFromString("rEd", Color.class);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/InsetsConverterTest.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/InsetsConverterTest.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/InsetsConverterTest.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,50 @@
+package jaxx.junit;
+
+import jaxx.types.InsetsConverter;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.awt.Insets;
+
+public class InsetsConverterTest {
+
+ InsetsConverter converter;
+
+ @Before
+ public void setUp() {
+ converter = new InsetsConverter();
+ }
+
+ @Test
+ public void testSingleValue() {
+ Insets value = (Insets) converter.convertFromString("3", Insets.class);
+ Assert.assertEquals(value, new Insets(3, 3, 3, 3));
+ }
+
+ @Test
+ public void testFourValues() {
+ Insets value = (Insets) converter.convertFromString("3, 0, 12, 1000000", Insets.class);
+ Assert.assertEquals(value, new Insets(3, 0, 12, 1000000));
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testTwoValues() {
+ converter.convertFromString("0, 4", Insets.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testThreeValues() {
+ converter.convertFromString("0, 4, 9", Insets.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testInvalidNumber() {
+ converter.convertFromString("0, 4, 9, A", Insets.class);
+ }
+
+ @Test(expected = IllegalArgumentException.class)
+ public void testBadFormatting() {
+ converter.convertFromString("0 - 1 - 2 - 3", Insets.class);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/TagManagerTest.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/TagManagerTest.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/junit/TagManagerTest.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,143 @@
+package jaxx.junit;
+
+import jaxx.compiler.JAXXCompiler;
+import jaxx.compiler.JAXXCompilerLaunchor;
+import jaxx.compiler.GWTCompiler;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.tags.DefaultComponentHandler;
+import jaxx.tags.DefaultObjectHandler;
+import jaxx.tags.TagHandler;
+import jaxx.tags.TagManager;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.swing.JPopupMenu;
+import java.io.ByteArrayOutputStream;
+import java.io.FileInputStream;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+public class TagManagerTest {
+
+ protected JAXXCompiler compiler;
+
+ public static class TestHandler extends DefaultObjectHandler {
+ public TestHandler(ClassDescriptor beanClass) {
+ super(beanClass);
+ }
+ }
+
+ @BeforeClass
+ public static void initTagManaer() throws Exception {
+
+ TagManager.reset(true);
+
+ }
+
+ @Before
+ public void setUp() {
+ JAXXCompilerLaunchor.newLaunchor();
+ compiler = new GWTCompiler(GWTCompiler.class.getClassLoader());
+ compiler.addImport("javax.swing.*");
+
+ }
+
+ @Test
+ public void testRegisterBean() {
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(InputStream.class), TestHandler.class);
+
+ Assert.assertTrue(TagManager.getTagHandler(ClassDescriptorLoader.getClassDescriptor(InputStream.class)) instanceof TestHandler);
+ Assert.assertTrue(TagManager.getTagHandler(ClassDescriptorLoader.getClassDescriptor(FileInputStream.class)) instanceof TestHandler);
+ }
+
+ @Test
+ public void testRegisterDefaultNamespace() {
+
+ TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(OutputStream.class), TestHandler.class);
+
+ TagManager.registerDefaultNamespace("OutputStream", "java.io.*");
+ Assert.assertTrue("Could not find handler for OutputStream despite default namespace", TagManager.getTagHandler(null, "OutputStream", compiler) instanceof TestHandler);
+
+ PrintStream oldErr = System.err;
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(buffer));
+ TagManager.registerDefaultNamespace("OutputStream", "java.dummy.*");
+ Assert.assertNull("Found handler for OutputStream despite ambiguous default namespace", TagManager.getTagHandler(null, "OutputStream", compiler));
+ System.setErr(oldErr);
+ Assert.assertTrue("No errors were produced with an ambiguous default namespace", buffer.size() > 0);
+ Assert.assertTrue(buffer.size() > 0);
+ }
+
+ @Test
+ public void testResolveClassName() {
+ Assert.assertEquals("Could not resolve class name 'Object'", TagManager.resolveClassName("Object", compiler), "java.lang.Object");
+ Assert.assertEquals("Could not resolve class name 'java.lang.Object'", TagManager.resolveClassName("java.lang.Object", compiler), "java.lang.Object");
+ Assert.assertNull("Unexpectedly resolved class name 'java.awt.Object'", TagManager.resolveClassName("java.awt.Object", compiler));
+ }
+
+ @Test
+ public void testPackages() {
+ Assert.assertNull("Unexpectedly found handler for java.awt.JButton", TagManager.getTagHandler(null, "java.awt.JButton", compiler));
+ Assert.assertNotNull("Did not find handler for JButton with default namespace of java.awt.*", TagManager.getTagHandler("java.awt.*", "JButton", compiler));
+ Assert.assertNull("Unexpectedly found handler for java.awt.*:JButton", TagManager.getTagHandler("java.awt.*", "JButton", true, compiler));
+ Assert.assertNotNull("Did not find handler for javax.swing.JButton", TagManager.getTagHandler(null, "javax.swing.JButton", compiler));
+ Assert.assertNotNull("Did not find handler for JButton with default namespace of java.swing.*", TagManager.getTagHandler("java.swing.*", "JButton", compiler));
+ Assert.assertNotNull("Did not find handler for javax.swing.*:JButton", TagManager.getTagHandler("javax.swing.*", "JButton", true, compiler));
+ }
+
+ @Test
+ public void testImport() throws Exception {
+ Assert.assertNull("Found handler for ActionListener despite no java.awt.event.* import", TagManager.getTagHandler(null, "ActionListener", compiler));
+
+ compiler.addImport("java.awt.event.*");
+
+ Assert.assertNotNull("Did not find ActionListener with java.awt.event.* import", TagManager.getTagHandler(null, "ActionListener", compiler));
+ }
+
+ @Test
+ public void testAmbiguousImport() throws Exception {
+ compiler.addImport("java.sql.*");
+ Assert.assertNotNull("Did not find java.sql.Date with only java.sql.* imported", TagManager.getTagHandler(null, "Date", compiler));
+
+ PrintStream oldErr = System.err;
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ System.setErr(new PrintStream(buffer));
+ compiler.addImport("java.util.*");
+ TagManager.reset(true);
+ Assert.assertNull("Still found a handler for Date with an ambiguous import", TagManager.getTagHandler(null, "Date", compiler));
+ System.setErr(oldErr);
+ Assert.assertTrue("No errors were produced with an ambiguous import", buffer.size() > 0);
+
+ compiler.addImport("java.util.Date");
+ Assert.assertNotNull("Did not find java.util.Date with a disambiguating import", TagManager.getTagHandler(null, "Date", compiler));
+ }
+
+ @Test
+ public void testInnerClass() {
+ TagHandler handler = TagManager.getTagHandler(null, "JPopupMenu.Separator", compiler);
+ Assert.assertTrue("Unable to resolve tag <JPopupMenu.Separator>", handler instanceof DefaultComponentHandler);
+ Assert.assertTrue(((DefaultComponentHandler) handler).getBeanClass().getName().equals(JPopupMenu.Separator.class.getName()));
+
+ handler = TagManager.getTagHandler(null, "javax.swing.JPopupMenu.Separator", compiler);
+ Assert.assertTrue("Unable to resolve tag <javax.swing.JPopupMenu.Separator>", handler instanceof DefaultComponentHandler);
+ Assert.assertTrue(((DefaultComponentHandler) handler).getBeanClass().getName().equals(JPopupMenu.Separator.class.getName()));
+ }
+
+ @Test
+ public void testWrongCase() {
+ Assert.assertNull("Unexpectedly found handler for 'object'", TagManager.getTagHandler(null, "object", compiler));
+ Assert.assertNull("Unexpectedly found handler for 'tagmanagertest'", TagManager.getTagHandler(null, "tagmanagertest", compiler));
+ }
+
+ @Test
+ public void testAliasing() {
+ Assert.assertEquals("JComboBox is not aliased to jaxx.runtime.swing.JAXXComboBox", "jaxx.runtime.swing.JAXXComboBox", TagManager.resolveClassName("JComboBox", compiler));
+ Assert.assertEquals("javax.swing.JComboBox is not aliased to jaxx.runtime.swing.JAXXComboBox", "jaxx.runtime.swing.JAXXComboBox", TagManager.resolveClassName("javax.swing.JComboBox", compiler));
+ }
+
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,396 @@
+package jaxx.runtime.swing.navigation;
+
+import jaxx.runtime.DefaultJAXXContext;
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.JAXXContextEntryDef;
+import jaxx.runtime.gwt.navigation.NavigationTreeModel;
+import jaxx.runtime.gwt.navigation.NavigationTreeModelBuilder;
+import jaxx.runtime.gwt.navigation.NavigationTreeModel.NavigationTreeNode;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+
+/**
+ * Test du model de navigation.
+ *
+ * @author chemit
+ */
+public class NavigationTreeModelTest {
+
+ private static final String ROOT_CONTEXT = "$root";
+ private static final String FAKE = "-fake";
+
+ private static final String separator = "/";
+
+ @Test
+ public void testFindNode() throws Exception {
+
+ NavigationTreeModelBuilder builder = new NavigationTreeModelBuilder(separator);
+
+ NavigationTreeNode rootNode = builder.build(null, (String) null, (String) null, ROOT_CONTEXT, null, null);
+
+ for (int i = 0; i < 4; i++) {
+ NavigationTreeNode sonNode = builder.build(rootNode, (String) null, (String) null, getNodeContext(i), null, null);
+ for (int j = 0; j < 4; j++) {
+ NavigationTreeNode sonSonNode = builder.build(sonNode, (String) null, (String) null, getNodeContext(i, j), null, null);
+ for (int k = 0; k < 4; k++) {
+ builder.build(sonSonNode, (String) null, (String) null, getNodeContext(i, j, k), null, null);
+ }
+ }
+ }
+
+ NavigationTreeModel model = builder.getModel();
+
+ NavigationTreeNode node;
+ String contextPath;
+ String currentNode;
+
+ contextPath = ROOT_CONTEXT;
+ node = model.findNode(contextPath);
+ assertNodeEquals(contextPath, ROOT_CONTEXT, 0, node, true);
+
+ node = model.findNode(ROOT_CONTEXT + FAKE);
+ Assert.assertNull(node);
+
+ for (int i = 0; i < 4; i++) {
+ currentNode = getNodeContext(i);
+ contextPath = ROOT_CONTEXT + separator + currentNode;
+ node = model.findNode(contextPath);
+ assertNodeEquals(contextPath, currentNode, 1, node, false);
+
+ for (int j = 0; j < 4; j++) {
+ currentNode = getNodeContext(i, j);
+ contextPath = ROOT_CONTEXT + separator + getNodeContext(i) + separator + currentNode;
+ node = model.findNode(contextPath);
+ assertNodeEquals(contextPath, currentNode, 2, node, false);
+
+ for (int k = 0; k < 4; k++) {
+ currentNode = getNodeContext(i, j, k);
+ contextPath = ROOT_CONTEXT + separator + getNodeContext(i) + separator + getNodeContext(i, j) + separator + currentNode;
+ node = model.findNode(contextPath);
+ assertNodeEquals(contextPath, currentNode, 3, node, false);
+ }
+
+ node = model.findNode(ROOT_CONTEXT + separator + getNodeContext(i) + separator + getNodeContext(i, j) + separator + currentNode + FAKE);
+ Assert.assertNull(node);
+ }
+
+ node = model.findNode(ROOT_CONTEXT + separator + getNodeContext(i) + separator + currentNode + FAKE);
+ Assert.assertNull(node);
+
+ }
+
+ }
+
+ /**
+ * Test the {@link NavigationTreeModel#getJAXXContextValue(jaxx.runtime.JAXXContext, String)} with an entry point
+ * as a bean.
+ * <p/>
+ * Tree is like this
+ * <pre>
+ * $root +
+ * - name <-- attached to context entry : java.lang.String.class,"name"
+ * - name2 <-- attached to context entry : java.lang.String.class,"name2"
+ * - model + <-- attached to context entry : Model.class,null
+ * - name
+ * -integerValue
+ * - sons +
+ * - 0 +
+ * - name
+ * - integerValue
+ * - sons
+ * - 1 +
+ * - name
+ * - integerValue
+ * - sons
+ * - 2 +
+ * - name
+ * - integerValue
+ * - sons
+ * </pre>
+ * <p/>
+ * With this tree, we will have to results :
+ * <pre>
+ * $root.name => context.get(String.class,"name")
+ * $root.name2 => context.get(String.class,"name2")
+ * $root.model => context.get(Model.class)
+ * $root.model.name => context.get(Model.class).getName()
+ * $root.model.integerValue => context.get(Model.class).getIntegerValue()
+ * $root.model.sons => context.get(Model.class).getSons()
+ * $root.model.sons.0 => context.get(Model.class).getSons().get(0)
+ * </pre>
+ *
+ * @throws Exception if any pb
+ */
+ @Test
+ public void testGetJAXXContextValue() throws Exception {
+
+ NavigationTreeModelBuilder builder = new NavigationTreeModelBuilder(separator);
+
+ NavigationTreeNode rootNode = builder.build(null, (String) null, (String) null, ROOT_CONTEXT, null, null);
+
+ NavigationTreeNode sonNode;
+ NavigationTreeNode sonSonNode;
+ NavigationTreeNode sonSonSonNode;
+
+ builder.build(rootNode, (String) null, JAXXContextEntryDef.newDef("name", String.class), "name", null, null);
+ builder.build(rootNode, (String) null, JAXXContextEntryDef.newDef("name2", String.class), "name2", null, null);
+
+ sonNode = builder.build(rootNode, (String) null, JAXXContextEntryDef.newDef(Model.class), "model", null, null);
+
+ builder.build(sonNode, (String) null, "../name", "name", null, null);
+ builder.build(sonNode, (String) null, "../integerValue", "integerValue", null, null);
+
+ sonSonNode = builder.build(sonNode, (String) null, "../sons", "sons", null, null);
+
+ sonSonSonNode = builder.build(sonSonNode, (String) null, "..[1]", 0 + "", null, null);
+
+ builder.build(sonSonSonNode, (String) null, "../name", "name", null, null);
+ builder.build(sonSonSonNode, (String) null, "../integerValue", "integerValue", null, null);
+ builder.build(sonSonSonNode, (String) null, "../sons", "sons", null, null);
+
+ sonSonSonNode = builder.build(sonSonNode, (String) null, "..[2]", 1 + "", null, null);
+
+ builder.build(sonSonSonNode, (String) null, "../name", "name", null, null);
+ builder.build(sonSonSonNode, (String) null, "../integerValue", "integerValue", null, null);
+ builder.build(sonSonSonNode, (String) null, "../sons", "sons", null, null);
+
+ sonSonSonNode = builder.build(sonSonNode, (String) null, (String) null, 2 + "", null, null);
+ //sonSonSonNode = model.new NavigationTreeNode(null, "..[3]", 2 + "", null, null);
+ sonSonNode.insert(sonSonSonNode, 2);
+ builder.build(sonSonSonNode, (String) null, "../..[3]/name", "name", null, null);
+ builder.build(sonSonSonNode, (String) null, "../..[3]/integerValue", "integerValue", null, null);
+ builder.build(sonSonSonNode, (String) null, "../..[3]/sons", "sons", null, null);
+
+ NavigationTreeModel model = builder.getModel();
+
+ JAXXContext context = new DefaultJAXXContext();
+ context.setContextValue("the name", "name");
+ context.setContextValue("the name2", "name2");
+
+
+ context.setContextValue(
+ new Model("modelName", 10,
+ Arrays.asList(
+ new Model("one", 1, Collections.<Model>emptyList()),
+ new Model("two", 2, Collections.<Model>emptyList()),
+ new Model("three", 3, Collections.<Model>emptyList())
+ )
+ )
+ );
+
+ Assert.assertNull(model.getJAXXContextValue(context, "$root.name" + FAKE));
+
+ testBinding(model, context, "$root/name", context.getContextValue(String.class, "name"));
+ testBinding(model, context, "$root/name2", context.getContextValue(String.class, "name2"));
+
+ Model bean = context.getContextValue(Model.class);
+
+ testBinding(model, context, "$root/model", bean);
+ testBinding(model, context, "$root/model/name", bean.getName());
+ testBinding(model, context, "$root/model/integerValue", bean.getIntegerValue());
+ testBinding(model, context, "$root/model/sons", bean.getSons());
+
+ testBinding(model, context, "$root/model/sons/0/name", bean.getSons().get(0).getName());
+ testBinding(model, context, "$root/model/sons/0/integerValue", bean.getSons().get(0).getIntegerValue());
+ testBinding(model, context, "$root/model/sons/0/sons", bean.getSons().get(0).getSons());
+
+
+ testBinding(model, context, "$root/model/sons/1/name", bean.getSons().get(1).getName());
+ testBinding(model, context, "$root/model/sons/1/integerValue", bean.getSons().get(1).getIntegerValue());
+ testBinding(model, context, "$root/model/sons/1/sons", bean.getSons().get(1).getSons());
+
+ testBinding(model, context, "$root/model/sons/2/name", bean.getSons().get(2).getName());
+ testBinding(model, context, "$root/model/sons/2/integerValue", bean.getSons().get(2).getIntegerValue());
+ testBinding(model, context, "$root/model/sons/2/sons", bean.getSons().get(2).getSons());
+ }
+
+ /**
+ * Test the {@link NavigationTreeModel#getJAXXContextValue(jaxx.runtime.JAXXContext, String)} with an entry point
+ * as a list.
+ * <p/>
+ * Tree is like this
+ * <pre>
+ * $root +
+ * - models + <-- attached to context entry : java.util.List.class,"models"
+ * - 0 +
+ * - name
+ * -integerValue
+ * - sons +
+ * - 0 +
+ * - name
+ * - 1 +
+ * - name
+ * - integerValue
+ * - sons
+ * - 2 +
+ * - name
+ * - integerValue
+ * - sons
+ * </pre>
+ * <p/>
+ * With this tree, we will have to results :
+ * <pre>
+ * $root.models => context.get(List.class,"models")
+ * $root.models.0 => context.get(List.class,"models").get(0)
+ * $root.models.0.name => context.get(List.class,"models").get(0).getName()
+ * </pre>
+ *
+ * @throws Exception if any pb
+ */
+ @Test
+ public void testGetJAXXContextValueFromList() throws Exception {
+
+ NavigationTreeModelBuilder builder = new NavigationTreeModelBuilder(separator);
+
+ NavigationTreeNode rootNode = builder.build(null, (String) null, (String) null, ROOT_CONTEXT, null, null);
+
+ NavigationTreeNode sonNode;
+ NavigationTreeNode sonSonNode;
+ NavigationTreeNode sonSonSonNode;
+
+ // first son is a list of models
+ sonNode = builder.build(rootNode, (String) null, JAXXContextEntryDef.newListDef("models"), "models", null, null);
+
+ // first son son is a model
+ sonSonNode = builder.build(sonNode, (String) null, "..[1]", "0", null, null);
+
+ builder.build(sonSonNode, (String) null, "../name", "name", null, null);
+ builder.build(sonSonNode, (String) null, "../integerValue", "integerValue", null, null);
+ sonSonNode = builder.build(sonSonNode, (String) null, "../sons", "sons", null, null);
+
+ sonSonSonNode = builder.build(sonSonNode, (String) null, "..[1]", "0", null, null);
+ builder.build(sonSonSonNode, (String) null, "../name", "name", null, null);
+
+ // second son son is a model
+ sonSonNode = builder.build(sonNode, (String) null, "..[2]", "1", null, null);
+
+ builder.build(sonSonNode, (String) null, "../name", "name", null, null);
+ builder.build(sonSonNode, (String) null, "../integerValue", "integerValue", null, null);
+ builder.build(sonSonNode, (String) null, "../sons", "sons", null, null);
+
+ // third son son is a model
+ sonSonNode = builder.build(sonNode, (String) null, "..[3]", "2", null, null);
+
+ builder.build(sonSonNode, (String) null, "../name", "name", null, null);
+ builder.build(sonSonNode, (String) null, "../integerValue", "integerValue", null, null);
+ builder.build(sonSonNode, (String) null, "../sons", "sons", null, null);
+
+ NavigationTreeModel model = builder.getModel();
+
+
+ List<Model> list = Arrays.asList(
+ new Model("entryOne", 10,
+ Arrays.asList(
+ new Model("one", 1, Collections.<Model>emptyList()),
+ new Model("two", 2, Collections.<Model>emptyList()),
+ new Model("three", 3, Collections.<Model>emptyList())
+ )
+ ),
+ new Model("entryTwo", 20,
+ Arrays.asList(
+ new Model("2one", 1, Collections.<Model>emptyList()),
+ new Model("2two", 2, Collections.<Model>emptyList()),
+ new Model("2three", 3, Collections.<Model>emptyList())
+ )
+ ),
+ new Model("entryThree", 30,
+ Arrays.asList(
+ new Model("3one", 1, Collections.<Model>emptyList()),
+ new Model("3two", 2, Collections.<Model>emptyList()),
+ new Model("3three", 3, Collections.<Model>emptyList())
+ )
+ )
+ );
+ JAXXContext context = new DefaultJAXXContext();
+ context.setContextValue(list, "models");
+
+ Model bean;
+
+ testBinding(model, context, "$root/models", list);
+
+ bean = list.get(0);
+ testBinding(model, context, "$root/models/0", bean);
+ testBinding(model, context, "$root/models/0/name", bean.getName());
+ testBinding(model, context, "$root/models/0/integerValue", bean.getIntegerValue());
+ testBinding(model, context, "$root/models/0/sons", bean.getSons());
+ testBinding(model, context, "$root/models/0/sons/0", bean.getSons().get(0));
+ testBinding(model, context, "$root/models/0/sons/0/name", bean.getSons().get(0).getName());
+
+ bean = list.get(1);
+ testBinding(model, context, "$root/models/1", bean);
+ testBinding(model, context, "$root/models/1/name", bean.getName());
+ testBinding(model, context, "$root/models/1/integerValue", bean.getIntegerValue());
+ testBinding(model, context, "$root/models/1/sons", bean.getSons());
+
+ bean = list.get(2);
+ testBinding(model, context, "$root/models/2", bean);
+ testBinding(model, context, "$root/models/2/name", bean.getName());
+ testBinding(model, context, "$root/models/2/integerValue", bean.getIntegerValue());
+ testBinding(model, context, "$root/models/2/sons", bean.getSons());
+
+ }
+
+ protected void testBinding(NavigationTreeModel model, JAXXContext context, String contextPath, Object expected) throws Exception {
+
+ Object value;
+ value = model.getJAXXContextValue(context, contextPath);
+ Assert.assertNotNull(value);
+ Assert.assertEquals(expected, value);
+ }
+
+ protected String getNodeContext(int... context) {
+ String result = "";
+ for (int i : context) {
+ result += i;
+ }
+ return result;
+ }
+
+ protected void assertNodeEquals(String contextPath, String nodeContext, int level, NavigationTreeNode node, boolean root) {
+ //System.out.println(contextPath + " : " + (node == null ? null : node.getContextPath()));
+ Assert.assertNotNull(node);
+ Assert.assertEquals(root, node.isRoot());
+ Assert.assertEquals(level, node.getLevel());
+ Assert.assertEquals(nodeContext, node.getNavigationPath());
+ Assert.assertEquals(contextPath, node.getContextPath());
+ }
+
+ public static class Model {
+
+ protected String name;
+
+ protected int integerValue;
+
+ protected List<Model> sons;
+
+ public Model(String name, int integerValue, List<Model> sons) {
+ this.name = name;
+ this.integerValue = integerValue;
+ this.sons = sons;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public int getIntegerValue() {
+ return integerValue;
+ }
+
+ public List<Model> getSons() {
+ return sons;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "<name:" + name + ",integerValue:" + integerValue + ",sons: " + sons + ">";
+ }
+ }
+
+}
Added: jaxx/trunk/jaxx-compiler-gwt/src/test/resources/log4j.properties
===================================================================
--- jaxx/trunk/jaxx-compiler-gwt/src/test/resources/log4j.properties (rev 0)
+++ jaxx/trunk/jaxx-compiler-gwt/src/test/resources/log4j.properties 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,8 @@
+# Global logging configuration
+log4j.rootLogger=ERROR, stdout
+# Console output...
+log4j.appender.stdout=org.apache.log4j.ConsoleAppender
+log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
+log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n
+
+log4j.logger.jaxx=DEBUG
Added: jaxx/trunk/jaxx-gwt-action/.classpath
===================================================================
--- jaxx/trunk/jaxx-gwt-action/.classpath (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/.classpath 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,22 @@
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/main/resources" including="**/*" excluding="**/*~|**/*.java"/>
+ <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+ <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+ <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/commons-beanutils/commons-beanutils/1.8.0/commons-beanutils-1.8.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-jxpath/commons-jxpath/1.3/commons-jxpath-1.3.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.4/commons-lang-2.4.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-primitives/commons-primitives/1.0/commons-primitives-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/javax/help/javahelp/2.0.02/javahelp-2.0.02.jar"/>
+ <classpathentry kind="var" path="M2_REPO/jboss/javassist/3.7.ga/javassist-3.7.ga.jar"/>
+ <classpathentry kind="src" path="/jaxx-runtime-api"/>
+ <classpathentry kind="src" path="/jaxx-runtime-gwt"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/4.5/junit-4.5.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/swinglabs/jxlayer/3.0.1/jxlayer-3.0.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/codelutin/lutinutil/1.0.3/lutinutil-1.0.3.jar"/>
+</classpath>
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/.project
===================================================================
--- jaxx/trunk/jaxx-gwt-action/.project (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/.project 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,16 @@
+<projectDescription>
+ <name>jaxx-gwt-action</name>
+ <comment>Jaxx lutin library gwt extension (tabs and actions)</comment>
+ <projects>
+ <project>jaxx-runtime-api</project>
+ <project>jaxx-runtime-gwt</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- jaxx/trunk/jaxx-gwt-action/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/.settings/org.eclipse.jdt.core.prefs 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,5 @@
+#Mon Mar 30 12:41:57 CEST 2009
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
Added: jaxx/trunk/jaxx-gwt-action/LICENSE.txt
===================================================================
--- jaxx/trunk/jaxx-gwt-action/LICENSE.txt (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/LICENSE.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,166 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
Added: jaxx/trunk/jaxx-gwt-action/README.txt
===================================================================
--- jaxx/trunk/jaxx-gwt-action/README.txt (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/README.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,2 @@
+To deploy new version of pom: mvn deploy
+To install localy: mvn install
Added: jaxx/trunk/jaxx-gwt-action/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-gwt-action/changelog.txt (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/changelog.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,10 @@
+1.3 chemit 20090320
+
+1.1 chemit 20090220
+ * 20090122 [chemit] - refactor poms (sibling dependencies, pluginsManagment,...)
+ - rename i18n bundles according artifactId
+
+1.0 chemit 20090111
+
+0.7 chemit 200812??
+ * 20081207 [chemit] use lutinproject 3.1
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/pom.xml
===================================================================
--- jaxx/trunk/jaxx-gwt-action/pom.xml (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/pom.xml 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,145 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+
+ <!-- ************************************************************* -->
+ <!-- *** POM Relationships *************************************** -->
+ <!-- ************************************************************* -->
+
+ <parent>
+ <groupId>org.codelutin</groupId>
+ <artifactId>jaxx</artifactId>
+ <version>1.3-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.codelutin.jaxx</groupId>
+ <artifactId>jaxx-gwt-action</artifactId>
+
+ <repositories>
+ <repository>
+ <id>gwt-maven</id>
+ <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>jboss</groupId>
+ <artifactId>javassist</artifactId>
+ <version>3.7.ga</version>
+ </dependency>
+
+ <!-- GWT Dependencies -->
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-servlet</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-user</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}-libs</classifier>
+ <type>zip</type>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}</classifier>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+ <!-- ************************************************************* -->
+ <!-- *** Project Information ************************************* -->
+ <!-- ************************************************************* -->
+
+ <name>${project.artifactId}</name>
+ <description>Jaxx lutin library gwt extension (tabs and actions)</description>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Settings ****************************************** -->
+ <!-- ************************************************************* -->
+ <packaging>jar</packaging>
+
+ <properties>
+
+ <gwtVersion>1.5.3</gwtVersion>
+
+ </properties>
+
+ <build>
+
+ <pluginManagement>
+ <plugins>
+ <plugin>
+ <artifactId>maven-compiler-plugin</artifactId>
+ <configuration>
+ <!-- the code contains some AnnotationProcessor -->
+ <compilerArgument>-proc:none</compilerArgument>
+ </configuration>
+ </plugin>
+ </plugins>
+ </pluginManagement>
+
+ <plugins>
+
+ <plugin>
+ <groupId>org.codelutin</groupId>
+ <artifactId>maven-i18n-plugin</artifactId>
+ <executions>
+ <execution>
+ <goals>
+ <goal>parserJava</goal>
+ <goal>gen</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Environment ************************************** -->
+ <!-- ************************************************************* -->
+ <scm>
+ <url>http://labs.libre-entreprise.org/plugins/scmsvn/viewcvs.php/jaxx/trunk/jaxx…</url>
+ <connection>scm:svn:svn://anonymous@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-gwt-action</connection>
+ <developerConnection>scm:svn:svn+ssh://sletellier@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-gwt-action</developerConnection>
+ </scm>
+
+ <profiles>
+ <profile>
+ <id>gwt-dev-linux</id>
+ <properties>
+ <platform>linux</platform>
+ </properties>
+ <activation>
+ <os>
+ <name>Linux</name>
+ </os>
+ </activation>
+ </profile>
+ </profiles>
+
+</project>
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/AbstractActionConfigurationResolver.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/AbstractActionConfigurationResolver.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/AbstractActionConfigurationResolver.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,70 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import javax.swing.JComponent;
+
+/**
+ * Common abstract class of a resolver of action configuration.
+ * <p/>
+ * The class implements the logic of research of the configuration annotation.
+ *
+ * @author chemit
+ */
+public abstract class AbstractActionConfigurationResolver<A extends java.lang.annotation.Annotation, C extends JComponent> implements ActionConfigurationResolver<A, C> {
+
+ /** the type of configuration's annotation */
+ protected final Class<A> annotationImpl;
+
+ /** the type of component that can fire an action */
+ protected final Class<C> componentImpl;
+
+ /**
+ * The typed method (on component) to apply configuration on the action and component.
+ *
+ * @param component the component which fires the action
+ * @param action the given action
+ * @return the configuration's annotation
+ */
+ protected abstract A applyConfiguration0(C component, MyAbstractAction action);
+
+ protected AbstractActionConfigurationResolver(Class<A> annotationImpl, Class<C> componentImpl) {
+ this.annotationImpl = annotationImpl;
+ this.componentImpl = componentImpl;
+ }
+
+ public A resolveConfiguration(MyAbstractAction action) {
+ if (action.hasDelegate()) {
+ return resolveConfiguration(action.getDelegate());
+ }
+ return action.getClass().getAnnotation(annotationImpl);
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public A applyConfiguration(JComponent component, MyAbstractAction action) {
+ if (component != null && componentImpl.isAssignableFrom(component.getClass()))
+ return applyConfiguration0((C) component, action);
+
+ return null;
+ }
+
+ public Class<A> getAnnotationImpl() {
+ return annotationImpl;
+ }
+
+ public Class<C> getComponentImpl() {
+ return componentImpl;
+ }
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionAnnotationProcessing.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionAnnotationProcessing.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionAnnotationProcessing.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,395 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+
+
+package org.codelutin.jaxx.action;
+
+import javassist.CannotCompileException;
+import javassist.ClassPool;
+import javassist.CtClass;
+import javassist.CtConstructor;
+import javassist.LoaderClassPath;
+import javassist.NotFoundException;
+import org.codelutin.util.SortedProperties;
+
+import javax.annotation.processing.AbstractProcessor;
+import javax.annotation.processing.ProcessingEnvironment;
+import javax.annotation.processing.RoundEnvironment;
+import javax.annotation.processing.SupportedAnnotationTypes;
+import javax.annotation.processing.SupportedOptions;
+import javax.annotation.processing.SupportedSourceVersion;
+import javax.lang.model.SourceVersion;
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.element.AnnotationValue;
+import javax.lang.model.element.AnnotationValueVisitor;
+import javax.lang.model.element.Element;
+import javax.lang.model.element.ExecutableElement;
+import javax.lang.model.element.TypeElement;
+import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.SimpleAnnotationValueVisitor6;
+import javax.tools.FileObject;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardLocation;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map.Entry;
+import java.util.Properties;
+import java.util.Set;
+
+
+@SupportedAnnotationTypes(value = {"org.codelutin.jaxx.action.*"})
+(a)SupportedSourceVersion(SourceVersion.RELEASE_6)
+@SupportedOptions({"jaxx.verbose"})
+/**
+ * Annotation processor to compute actions mapping.
+ *
+ * @author chemit */
+public class ActionAnnotationProcessing extends AbstractProcessor {
+
+ /** the {@link ActionProvider} service declaration relative path */
+ protected String providerDeclarationLocation = "META-INF/services/" + ActionProvider.class.getName();
+
+ /** the relative path where to store actions mapping, will be complete with the name of base action to use */
+ protected String actionsFileLocation = ActionProviderFromProperties.actionsFileLocation;
+
+ /** verbose flag (can be activated by passing an annotation parameter to compiler via <code>-Ai18n.verbose</code>) */
+ protected boolean verbose;
+
+ /** the list of class processed by the processor */
+ protected java.util.List<String> processedClass;
+
+ /** the map of actions processed, keys are the action commaned and values are fqn of implementations */
+ protected Properties actions;
+
+ /** Extractor of values of annotations found */
+ protected AnnotationValueVisitor<Object, Void> annotationValueExtractor;
+
+ /** the type element of the base action to be used by {@link ActionProvider} */
+ protected TypeElement baseActionElement;
+
+ /** the fqn of the action provider to generate */
+ protected String providerFQN;
+
+ /** the fqn of the base action class to be used */
+ protected String baseFQN;
+
+ @Override
+ public synchronized void init(ProcessingEnvironment processingEnv) {
+ super.init(processingEnv);
+ parseOptions();
+ printDebug("verbose : " + verbose);
+ printDebug("FileLocation : " + actionsFileLocation);
+ processedClass = new ArrayList<String>();
+ actions = new SortedProperties();
+ }
+
+ @Override
+ public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
+ for (TypeElement annotation : annotations) {
+
+ Set<? extends Element> annotatedWith = roundEnv.getElementsAnnotatedWith(annotation);
+
+ if (annotation.getQualifiedName().toString().equals(ActionProviderAnnotation.class.getName())) {
+ // init provider
+ if (annotatedWith.size() != 1) {
+ throw new IllegalStateException("can have only one provider defined by the annotation " + ActionProviderAnnotation.class);
+ }
+
+ baseActionElement = (TypeElement) annotatedWith.iterator().next();
+
+ //fixme it is not possible to know if baseActionElement is assigned from MyAbstractAction, since we
+ // can NOT garanted at this stage thaht the class was compiled...
+
+ baseFQN = baseActionElement.asType().toString();
+ int index = baseFQN.lastIndexOf(".") + 1;
+ String baseSimpleName = baseFQN.substring(index);
+ String packageName = baseFQN.substring(0, index);
+
+ providerFQN = packageName + baseSimpleName + "Provider";
+ printDebug("providerFQN " + providerFQN);
+ actionsFileLocation = String.format(actionsFileLocation, baseSimpleName);
+ continue;
+ }
+
+ for (Element e : annotatedWith) {
+ String className = e.toString();
+
+ if (processedClass.contains(className)) {
+ printWarning("class already processed " + className);
+ // do not process class twice
+ continue;
+ }
+
+ boolean wasTreated = registerActionsForClass(annotation.asType(), e);
+ if (wasTreated) {
+ printDebug("process class " + className);
+ processedClass.add(className);
+ } else {
+ printDebug("class was not processed " + e);
+ }
+ }
+ }
+
+ if ((roundEnv.processingOver())) {
+ printDebug("round is over " + roundEnv);
+ try {
+ if (baseActionElement != null) {
+ // found the base action class to be compiled, so we have to write provider things...
+ writeProviderClass();
+ writeProviderServiceDeclaration();
+ } else {
+
+ // baseActionClass was not compiled at this time, must find it back
+ // this means they should have an already mapping file written
+
+ actionsFileLocation = findMappingFile();
+
+ printInfo("reused actionFilesLocation " + actionsFileLocation);
+ }
+
+ writeActionMapping();
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ processedClass.clear();
+ actions.clear();
+ }
+ }
+
+ return true;
+ }
+
+ protected String findMappingFile() throws IOException {
+ String path = String.format(actionsFileLocation, "dummy_" + System.nanoTime());
+
+
+ FileObject oldFo = processingEnv.getFiler().getResource(StandardLocation.SOURCE_OUTPUT, "", path);
+ File dummyFile = new File(oldFo.toUri().toString()).getParentFile();
+ File[] files = dummyFile.listFiles(new FilenameFilter() {
+
+ public boolean accept(File dir, String name) {
+ return name.startsWith("jaxx-") && name.endsWith("-actions.properties");
+ }
+ });
+ if (files.length < 1) {
+ // this is not normal, should have exactly one file here
+ throw new IllegalStateException("no provider name found, you must add on baseaction the annotation " + ActionProviderAnnotation.class);
+ }
+ File f = files[0];
+ int index = f.getAbsolutePath().indexOf("META-INF");
+
+ return f.getAbsolutePath().substring(index);
+ }
+
+ protected boolean registerActionsForClass(TypeMirror annotationType, Element e) {
+ boolean doTreate = false;
+ for (AnnotationMirror mirror : e.getAnnotationMirrors()) {
+ if (!mirror.getAnnotationType().equals(annotationType)) {
+ // do not treate other annotations
+ continue;
+ }
+ doTreate = true;
+ printDebug("found a annotation to treate : " + mirror + " for action : " + e.toString());
+ for (String name : getActionNames(mirror)) {
+ actions.put("action." + name, e.toString());
+ printDebug("registerActionForClass " + name + " : " + e.toString());
+ }
+ }
+ return doTreate;
+ }
+
+ protected void parseOptions() {
+ java.util.Map options = processingEnv.getOptions();
+ verbose = options.containsKey("jaxx.verbose");
+ }
+
+ protected void writeProviderClass() throws IOException, NotFoundException, CannotCompileException, ClassNotFoundException {
+ OutputStream outputStream = null;
+ try {
+
+ ClassPool pool = ClassPool.getDefault();
+
+ pool.appendClassPath(new LoaderClassPath(ActionProviderFromProperties.class.getClassLoader()));
+
+ CtClass superClass = pool.get(ActionProviderFromProperties.class.getName());
+ CtClass clazz = pool.makeClass(providerFQN);
+ // define the base action class in javassist pool to make possible compilation
+ pool.makeClass(baseFQN);
+ clazz.setSuperclass(superClass);
+ // add constructor
+ CtConstructor constructor = new CtConstructor(null, clazz);
+ constructor.setBody("super( " + baseFQN + ".class);");
+ clazz.addConstructor(constructor);
+ byte[] byteCode = clazz.toBytecode();
+
+ JavaFileObject fo = processingEnv.getFiler().createClassFile(providerFQN);
+ printInfo("writing " + fo.toUri());
+ outputStream = fo.openOutputStream();
+ outputStream.write(byteCode);
+
+ } finally {
+ if (outputStream != null)
+ outputStream.close();
+ }
+ }
+
+ protected void writeProviderServiceDeclaration() throws IOException {
+ BufferedWriter w = null;
+ try {
+ FileObject fo = processingEnv.getFiler().createResource(StandardLocation.SOURCE_OUTPUT, "", providerDeclarationLocation);
+ printInfo("writing " + fo.toUri());
+ w = new BufferedWriter(fo.openWriter());
+ w.append("# generated by ").append(getClass().getName()).append("\n").toString();
+ w.append("#").append(new java.util.Date().toString()).append("\n").toString();
+ w.append(providerFQN);
+ } finally {
+ if (w != null)
+ w.close();
+ }
+ }
+
+ protected void writeActionMapping() throws IOException {
+ if (actions.isEmpty()) {
+ // nothing to write or overwrite
+ return;
+ }
+
+ BufferedWriter w = null;
+ try {
+ Properties oldProps = loadOldActionMapping();
+ if (oldProps != null) {
+ oldProps.putAll(actions);
+ actions = oldProps;
+ }
+ // ecriture de toutes les actions trouvees
+ FileObject fo = processingEnv.getFiler().createResource(StandardLocation.SOURCE_OUTPUT, "", actionsFileLocation);
+ printInfo("writing " + fo.toUri());
+ w = new BufferedWriter(fo.openWriter());
+ actions.store(w, "generated by " + getClass().getName());
+ } finally {
+ if (w != null)
+ w.close();
+ }
+ }
+
+ protected Properties loadOldActionMapping() throws IOException {
+ // reprise sur une ancienne compilation
+ FileObject oldFo = processingEnv.getFiler().getResource(StandardLocation.SOURCE_OUTPUT, "", actionsFileLocation);
+ if (!new File(oldFo.toUri().toString()).exists()) {
+ return null;
+ }
+ Properties oldProps = new SortedProperties();
+ InputStream inputStream = null;
+ try {
+ inputStream = oldFo.openInputStream();
+ if (inputStream != null) {
+ oldProps.load(inputStream);
+ }
+ oldFo.delete();
+ } finally {
+ if (inputStream != null) {
+ inputStream.close();
+ }
+ }
+
+ return oldProps;
+ }
+
+ /**
+ * Obtain the array of names to be used by the annotation
+ *
+ * @param element the dictonnary of values found in a annotation
+ * @return thee array of names detected in the annotation
+ */
+ @SuppressWarnings({"unchecked"})
+ protected String[] getActionNames(AnnotationMirror element) {
+ String[] result = null;
+ for (Entry<? extends ExecutableElement, ? extends AnnotationValue> entry : element.getElementValues().entrySet()) {
+ ExecutableElement type = entry.getKey();
+ String name = type.getSimpleName().toString();
+
+ if ("actionCommands".equals(name)) {
+ List<String> stringList = (List<String>) entry.getValue().accept(getAnnotationValueExtractor(), null);
+ result = stringList.toArray(new String[stringList.size()]);
+ // a actionCommands field means
+ break;
+ }
+ if ("actionCommandProvider".equals(name)) {
+ TypeMirror t = (TypeMirror) entry.getValue().accept(getAnnotationValueExtractor(), null);
+ String classname = t.toString();
+ printDebug("actionCommandProvider = " + classname);
+ if (classname.equals(ActionNameProvider.class.getName())) {
+ continue;
+ }
+
+ // means there is a runtime names provider
+ result = new String[]{":" + classname};
+ break;
+ }
+ if ("actionCommand".equals(name)) {
+ result = new String[]{(String) entry.getValue().accept(getAnnotationValueExtractor(), null)};
+ }
+ }
+
+ return result;
+ }
+
+ protected AnnotationValueVisitor<Object, Void> getAnnotationValueExtractor() {
+ if (annotationValueExtractor == null) {
+ annotationValueExtractor = new SimpleAnnotationValueVisitor6<Object, Void>() {
+
+ @Override
+ protected Object defaultAction(Object o, Void aVoid) {
+ return o;
+ }
+
+ @Override
+ public Object visitArray(List<? extends AnnotationValue> vals, Void aVoid) {
+ List<Object> realVals = new java.util.ArrayList<Object>();
+ for (AnnotationValue val : vals) {
+ realVals.add(val.accept(this, aVoid));
+ }
+ return realVals;
+ }
+
+ public Object visitType(TypeMirror t, Void aVoid) {
+ return t;
+ }
+ };
+ }
+ return annotationValueExtractor;
+ }
+
+ protected void printWarning(String msg) {
+ System.out.println("[WARN] " + getClass().getName() + " : " + msg);
+ }
+
+ protected void printInfo(String msg) {
+ System.out.println("[INFO] " + getClass().getName() + " : " + msg);
+ }
+
+ protected void printDebug(String msg) {
+ if (verbose) {
+ System.out.println("[DEBUG] " + getClass().getName() + " : " + msg);
+ }
+ }
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfig.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfig.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfig.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,122 @@
+/*
+* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit, Gabriel Landais
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* ##% */
+package org.codelutin.jaxx.action;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Pour enregister une action.
+ * <p/>
+ * Placer cette annotation sur la classe implantant l'action,
+ * <p/>
+ * les informations décrites seront utilisées pour instancier l'action
+ *
+ * @author chemit
+ */
+(a)Retention(RetentionPolicy.RUNTIME)
+
+(a)Target(ElementType.TYPE)
+@Inherited
+public @interface ActionConfig {
+
+ /**
+ * @return la clef de la commande (doit être unique)
+ * @see javax.swing.Action#ACTION_COMMAND_KEY
+ */
+ String actionCommand();
+
+ /** @return array of names to be used in actions mapping */
+ String[] actionCommands() default {};
+
+ /**
+ * @return the class to obtain at runtime the array of names to be used in actions mapping.
+ * <p/>
+ * <b>Note : the special value {@link org.codelutin.jaxx.action.ActionNameProvider} is used to says not to used
+ * œthis mecanism since we can not set a null value in a annotation</b>
+ */
+ Class<? extends ActionNameProvider> actionCommandProvider() default org.codelutin.jaxx.action.ActionNameProvider.class;
+
+ /**
+ * @return la clef i18n du texte de l'action, si vide ignoré
+ * @see javax.swing.Action#NAME
+ */
+ String name() default "";
+
+ /**
+ * @return la clef i18n du tooltip de l'action, si vide ignoré
+ * @see javax.swing.Action#SHORT_DESCRIPTION
+ */
+ String shortDescription() default "";
+
+ /**
+ * @return la clef i18n du texte de l'action, si vide ignoré
+ * @see javax.swing.Action#LONG_DESCRIPTION
+ */
+ String longDescription() default "";
+
+ /**
+ * @return le nom de l'icone associé, si vide ignoré
+ * @see javax.swing.Action#SMALL_ICON
+ */
+ String smallIcon() default "";
+
+ /**
+ * @return le nom du grande icone associé, si vide ignoré
+ * @see javax.swing.Action#LARGE_ICON_KEY
+ */
+ String largeIcon() default "";
+
+ /**
+ * @return accelerator
+ * @see javax.swing.Action#ACCELERATOR_KEY
+ */
+ String accelerator() default "";
+
+ /**
+ * @return mnemonic key
+ * @see javax.swing.Action#MNEMONIC_KEY
+ */
+ int mnemonic() default '\0';
+
+ /**
+ * @return mnemonic key index
+ * @see javax.swing.Action#DISPLAYED_MNEMONIC_INDEX_KEY
+ */
+ int displayedMnemonicIndex() default '\0';
+
+ /**
+ * @return la valeur par défaut pour les component selectable
+ * @see javax.swing.Action#SELECTED_KEY
+ */
+ boolean selected() default false;
+
+ /**
+ * @return enabled state
+ * @see javax.swing.Action#isEnabled()
+ */
+ boolean enabled() default true;
+
+ /** @return hideActionText state */
+ boolean hideActionText() default false;
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfigConfigurationResolver.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfigConfigurationResolver.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfigConfigurationResolver.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,67 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import static org.codelutin.i18n.I18n._;
+
+import javax.swing.AbstractButton;
+import javax.swing.Action;
+
+/**
+ * Implementation of configuration's resolver for annotation {@link ActionConfig}
+ *
+ * @author chemit
+ */
+public class ActionConfigConfigurationResolver extends AbstractActionConfigurationResolver<ActionConfig, AbstractButton> {
+
+ public ActionConfigConfigurationResolver() {
+ super(ActionConfig.class, AbstractButton.class);
+ }
+
+ protected ActionConfig applyConfiguration0(AbstractButton component, MyAbstractAction action) {
+ ActionConfig anno = resolveConfiguration(action);
+ if (anno == null) {
+ return null;
+ }
+ // inject les données
+ if (!anno.name().isEmpty()) {
+ //System.out.println("found action with name : " + anno.name());
+ action.putValue(Action.NAME, _(anno.name()));
+ }
+ //if (!anno.shortDescription().isEmpty()) {
+ action.putValue(Action.SHORT_DESCRIPTION, _(anno.shortDescription()));
+ //}
+ if (!anno.smallIcon().isEmpty()) {
+ action.putValue(Action.SMALL_ICON, org.codelutin.jaxx.util.UIHelper.createImageIcon(anno.smallIcon()));
+ }
+ if (anno.mnemonic() != '\0') {
+ action.putValue(Action.MNEMONIC_KEY, anno.mnemonic());
+ } else if (component != null) {
+ action.putValue(Action.MNEMONIC_KEY, component.getMnemonic());
+ }
+ //TODO Convert it from String action.putValue(Action.ACCELERATOR_KEY, anno.accelerator());
+
+ if (component == null) {
+ action.putValue("hideActionText", anno.hideActionText());
+ } else {
+ boolean actionText = component.getHideActionText();
+ action.putValue("hideActionText", anno.hideActionText() || actionText);
+ }
+ action.putValue(Action.SELECTED_KEY, anno.selected());
+ action.setEnabled(anno.enabled());
+
+ return anno;
+ }
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfigurationResolver.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfigurationResolver.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionConfigurationResolver.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,52 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import javax.swing.JComponent;
+
+/**
+ * The contract to be realized to resolve an {@link MyAbstractAction} configuration.
+ * <p/>
+ * Configuration is done by a Annotation of type {@link A} placed on the action class.
+ * <p/>
+ * If the instanciated action box the real action, we should always search on the boxed action.
+ * <p/>
+ * Moreover, a action can only be fired by a certain type of component (for example a Button or a ComboBox), the class
+ * of the component type is given by the {@link C} class.
+ *
+ * @author chemit
+ */
+public interface ActionConfigurationResolver<A extends java.lang.annotation.Annotation, C extends JComponent> {
+ /**
+ * Search the annotation that configure the given action (or the boxed action).
+ *
+ * @param action current action
+ * @return the configuration of the action
+ */
+ A resolveConfiguration(MyAbstractAction action);
+
+ /**
+ * @param component widget that requires the action
+ * @param action given action
+ * @return the configuration of the action
+ */
+ A applyConfiguration(JComponent component, MyAbstractAction action);
+
+ /** @return the configuration annotation dealed by this resolver */
+ Class<A> getAnnotationImpl();
+
+ /** @return the class of the component which can fired the action */
+ Class<C> getComponentImpl();
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,149 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import jaxx.runtime.JAXXObject;
+
+import javax.swing.JComponent;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.Set;
+
+/**
+ * Action factory using the <code>ActionConfig-like</code> annotations to configure actions.
+ * <p/>
+ * <p/>
+ * An {@link ActionFactory} builds actions always on a same type <code>A</code> and obtain them from some
+ * {@link ActionProvider} via methods {@link #newAction(String, JComponent)} and {@link #newAction(String)} .
+ * <p/>
+ * If the action coming from the provider is not on the same type <code>A</code>, then the action is boxed in a *
+ * action <code>A</code> and use the generic mecanism of delegation provided by {@link MyAbstractAction}.
+ * <p/>
+ * Use after the {@link #loadActions(jaxx.runtime.JAXXObject)} to instanciate actions in ui with id equals a known
+ * action...
+ * <p/>
+ * All actions instanciated are stored in a cache that you can request via method {@link #getActionFromCache(String)},
+ * {@link #cacheEntrySet()} and {@link #resetCache()}.
+ * <p/>
+ * You can also from this factory fires some action via the methods {@link #fireAction(String, Object, JComponent)} ,
+ * {@link #fireAction(String, Object)} , {@link #fireAction0(String, Object, MyAbstractAction)}.
+ * <p/>
+ * Finally, a {@link #dispose()} method is there to shut down all instanciated action when you want to dispose all uis.
+ *
+ * @author chemit
+ * @see ActionProvider
+ * @see MyAbstractAction
+ */
+public interface ActionFactory<A extends MyAbstractAction> {
+
+ /**
+ * Method to init the dictionary of knwon action implementations.
+ *
+ * @return the dictionary of known action implementations
+ */
+ Map<String, Class<? extends MyAbstractAction>> init();
+
+ /** @return the class of the base action of the factory. */
+ Class<A> getBaseClass();
+
+ /** @return the set of all the action's classes known by the factory. */
+ Set<Entry<String, Class<? extends MyAbstractAction>>> implsEntrySet();
+
+ /** @return the array of names of all actions known by the factory */
+ String[] getActionNames();
+
+ /** @return the set of all actions cached in factory indexed by their name */
+ Set<Entry<String, A>> cacheEntrySet();
+
+ /**
+ * @param actionKey the action's key
+ * @return the action in cache or <code>null</code> if action is not in cache
+ */
+ MyAbstractAction getActionFromCache(String actionKey);
+
+ /** clear the cache of instanciated actions. */
+ void resetCache();
+
+ /**
+ * @param actionKey the key of an action
+ * @return the action with this key from cache, or <code>null</code> if this action is not in cache
+ */
+
+ //A get(String actionKey);
+
+ /**
+ * For a given ui, load all actions registred in factory.
+ * <p/>
+ * The id of the widget in ui is directly mapped to a action key.
+ *
+ * @param ui the ui to treate
+ */
+ void loadActions(JAXXObject ui);
+
+ /**
+ * Obtain an action instance given his key and widget
+ *
+ * @param actionKey the key of action
+ * @param component the component using the action
+ * @return the instanciated action (could come from cache if already instanciated {@link #getActionFromCache(String)}
+ */
+ A newAction(String actionKey, JComponent component);
+
+ /**
+ * Obtain an action instance given his key (should call {@link #newAction(String, JComponent)}
+ * <p/>
+ * This is a convinient method when you want to obtain an action with no attached widget.
+ *
+ * @param actionKey the key of action
+ * @return the instanciated action (could come from cache if already instanciated {@link #getActionFromCache(String)}
+ */
+ A newAction(String actionKey);
+
+
+ /**
+ * Fire an action given his key, his source and tthe widget responsible of action
+ *
+ * @param actionKey the action's key
+ * @param source the object source of action
+ * @param component the component doing the action
+ */
+ void fireAction(String actionKey, Object source, JComponent component);
+
+ /**
+ * Fire an action given his key and his source, no widget are involved here
+ *
+ * @param actionKey the action's key
+ * @param source the object source of action
+ */
+ void fireAction(String actionKey, Object source);
+
+ /**
+ * Fire an action given his action's key, his source and the real action.
+ * <p/>
+ * This is a convinient method when you need to modified action before fire it.
+ *
+ * @param actionKey action's key
+ * @param source source of action
+ * @param action real action
+ */
+ void fireAction0(String actionKey, Object source, A action);
+
+
+ /**
+ * dispose all actions in cache using {@link MyAbstractAction#disposeUI()} on each
+ * action, then {@link #resetCache()}
+ */
+ void dispose();
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionFactoryFromProvider.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,457 @@
+/*
+* ##% Copyright (C) 2007, 2008 Code Lutin, Tony Chemit
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* ##% */
+package org.codelutin.jaxx.action;
+
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.gwt.JAXXToggleButton;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codelutin.util.Resource;
+
+import javax.swing.AbstractButton;
+import javax.swing.Action;
+import javax.swing.Icon;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import java.awt.event.ActionEvent;
+import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.ServiceLoader;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * A simple implementation of {@link ActionFactory} using some {@link ActionProvider} to seek actions.
+ * <p/>
+ * <p/>
+ * An entry is in that form : <code>action.actionName=fqn</code> where
+ * <p/>
+ * <code>actionName</code> is the key of action used in factory, and
+ * <code>fqn</code> is the fully qualified name of the implemented action class.
+ * <p/>
+ * A special clase is to have for a given entry a key like this : <code>action.:fqn'=fqn</code>, in that case,
+ * le fqn' is a classe of type {@link org.codelutin.jaxx.action.ActionNameProvider} which gives us at
+ * runtime the names of each entry to put in cache for the givne action fqn.
+ *
+ * @author chemit
+ */
+public class ActionFactoryFromProvider<A extends MyAbstractAction> implements ActionFactory<A> {
+
+ protected static Log log = LogFactory.getLog(ActionFactoryFromProvider.class);
+
+ public static <A extends MyAbstractAction> ActionFactory<A> newInstance(Class<A> klazz) {
+ return new ActionFactoryFromProvider<A>(klazz);
+ }
+
+ /** class of encapsuling action */
+ protected Class<A> baseImpl;
+
+ /** dictionary of known actions implementations */
+ private Map<String, Class<? extends MyAbstractAction>> impls;
+
+ /** dictionary of instanciated actions */
+ private Map<String, A> cache;
+
+ protected final ActionConfigConfigurationResolver actionConfigInitializer;
+ protected final ToggleActionConfigConfigurationResolver toggleActionConfigInitializer;
+ protected final SelectActionConfigConfigurationResolver selectActionConfigInitializer;
+
+ protected List<AbstractActionConfigurationResolver> configurationResolvers;
+
+ protected ActionFactoryFromProvider(Class<A> baseImpl) {
+ this.baseImpl = baseImpl;
+ this.impls = init();
+ this.cache = new TreeMap<String, A>();
+ this.configurationResolvers = new java.util.ArrayList<AbstractActionConfigurationResolver>();
+
+ this.toggleActionConfigInitializer = registerInitializer(ToggleActionConfigConfigurationResolver.class);
+ this.actionConfigInitializer = registerInitializer(ActionConfigConfigurationResolver.class);
+ this.selectActionConfigInitializer = registerInitializer(SelectActionConfigConfigurationResolver.class);
+ }
+
+ public Class<A> getBaseClass() {
+ return baseImpl;
+ }
+
+ public void resetCache() {
+ cache.clear();
+ }
+
+ /*public A get(String actionKey) {
+ return cache.get(actionKey);
+ }*/
+
+ public void loadActions(JAXXObject ui) {
+ if (log.isDebugEnabled()) {
+ log.debug("for ui " + ui.getClass());
+ }
+ for (Map.Entry<String, Class<? extends MyAbstractAction>> entry : implsEntrySet()) {
+ String actionKey = entry.getKey();
+ Object comp = ui.getObjectById(actionKey);
+ if (comp == null || !(comp instanceof AbstractButton || comp instanceof JComboBox)) {
+ // nothing to do
+ continue;
+ }
+ if (log.isTraceEnabled()) {
+ log.trace("detect action " + actionKey);
+ }
+ if (comp instanceof AbstractButton) {
+ AbstractButton component = (AbstractButton) comp;
+ A action = newAction(actionKey, component);
+
+ component.setAction(action);
+
+ if (component instanceof JAXXToggleButton) {
+ JAXXToggleButton glueComponent = (JAXXToggleButton) component;
+ glueComponent.setIcon((Icon) action.getValue(Action.SMALL_ICON));
+ Integer integer = (Integer) action.getValue(Action.MNEMONIC_KEY);
+ if (integer != null) {
+ glueComponent.setNormalMnemonic(integer);
+ }
+ glueComponent.setSelectedIcon((Icon) action.getValue(Action.SMALL_ICON + 2));
+ integer = (Integer) action.getValue(Action.MNEMONIC_KEY + 2);
+ if (integer != null) {
+ glueComponent.setGlueMnemonic(integer);
+ }
+ glueComponent.setGlueText((String) action.getValue(Action.NAME + 2));
+ glueComponent.setGlueTooltipText((String) action.getValue(Action.SHORT_DESCRIPTION + 2));
+
+ glueComponent.setNormalText((String) action.getValue(Action.NAME));
+ glueComponent.setNormalTooltipText((String) action.getValue(Action.SHORT_DESCRIPTION));
+ }
+
+ Boolean value = (Boolean) action.getValue("hideActionText");
+ component.setHideActionText(value != null && value);
+ action.setEnabled(true);
+ continue;
+ }
+ // is JComboBox
+ JComboBox component = (JComboBox) comp;
+ A action = newAction(actionKey, component);
+
+ component.setAction(action);
+ Integer val = (Integer) action.getValue("selectedIndex");
+ if (val != null && val != -1 && val < component.getItemCount() && val != component.getSelectedIndex()) {
+ component.setSelectedIndex(val);
+ }
+ }
+ }
+
+ /**
+ * @param actionKey le nom de l'action tel que définie dans le fichier
+ * de mapping (sans le prefix action.)
+ * @param component le button où rattacher l'action
+ * @return une nouvelle instance de l'action associée à sa clef.
+ */
+ public A newAction(String actionKey, JComponent component) {
+ // try first in cache
+ A result = getActionFromCache(actionKey);
+ if (result != null) {
+ return result;
+ }
+
+ try {
+ result = newActionInstance(actionKey);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("create <" + actionKey + " : " + result + ">");
+ }
+
+ // recherche de l'annotation de configuration
+ ActionConfigurationResolver<?, ?> configurationResolver = resolveActionConfiguration(result);
+
+ if (configurationResolver != null) {
+ configurationResolver.applyConfiguration(component, result);
+ }
+
+ try {
+
+ if (configurationResolver != null) {
+ if (AbstractButton.class.isAssignableFrom(configurationResolver.getComponentImpl())) {
+ finalizeNewAction((AbstractButton) component, result, configurationResolver);
+ }
+
+ if (JComboBox.class.isAssignableFrom(configurationResolver.getComponentImpl())) {
+ finalizeNewAction((JComboBox) component, result, configurationResolver);
+ }
+
+ return result;
+ }
+
+ if (component == null || component instanceof AbstractButton) {
+ finalizeNewAction((AbstractButton) component, result, configurationResolver);
+ return result;
+ }
+
+ if (component instanceof JComboBox) {
+ finalizeNewAction((JComboBox) component, result, configurationResolver);
+ }
+ } finally {
+ // save result in cache
+ cache.put(actionKey, result);
+ }
+
+ return result;
+ }
+
+ public A newAction(String actionKey) {
+ return newAction(actionKey, null);
+ }
+
+ public String[] getActionNames() {
+ return impls.keySet().toArray(new String[impls.size()]);
+ }
+
+ public Set<Entry<String, Class<? extends MyAbstractAction>>> implsEntrySet() {
+ return impls.entrySet();
+ }
+
+ public Set<Entry<String, A>> cacheEntrySet() {
+ return cache.entrySet();
+ }
+
+ public void fireAction(String actionKey, Object source, JComponent component) {
+ A action = newAction(actionKey, component);
+ fireAction0(actionKey, source, action);
+ }
+
+ public void fireAction(String actionKey, Object source) {
+ fireAction(actionKey, source, null);
+ }
+
+ /**
+ * @param actionKey la clef de l'action
+ * @return l'action deja stockee dans le cache d'action, ou <code>null</code> si non trouvée.
+ */
+ public A getActionFromCache(String actionKey) {
+ // on vérifie que l'action existe bien
+ checkRegistredAction(actionKey);
+
+ A action = null;
+ // try in cache
+ if (cache.containsKey(actionKey)) {
+ // use cached action
+ action = cache.get(actionKey);
+ if (log.isDebugEnabled()) {
+ log.debug("use cache action " + action);
+ }
+ }
+ return action;
+ }
+
+ public void dispose() {
+ if (log.isInfoEnabled()) {
+ log.info(this);
+ }
+ for (String actionKey : getActionNames()) {
+ MyAbstractAction action = getActionFromCache(actionKey);
+ if (action != null) {
+ action.disposeUI();
+ }
+ }
+ resetCache();
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ resetCache();
+ impls.clear();
+ }
+
+ /**
+ * @param component le button où rattacher l'action
+ * @param action action
+ * @param configurationResolver initializer
+ */
+ protected void finalizeNewAction(AbstractButton component, MyAbstractAction action, ActionConfigurationResolver<?, ?> configurationResolver) {
+
+ if (configurationResolver == null) {
+ // no configurationResolver matching,
+ if (component != null) {
+ action.putValue(Action.ACTION_COMMAND_KEY, component.getName());
+ action.putValue(Action.SHORT_DESCRIPTION, component.getToolTipText());
+ action.putValue(Action.SMALL_ICON, component.getIcon());
+ action.putValue(Action.NAME, component.getText());
+ action.putValue(Action.MNEMONIC_KEY, component.getMnemonic());
+ action.putValue("hideActionText", component.getHideActionText());
+ if (component instanceof JAXXToggleButton) {
+ JAXXToggleButton glueComponent = (JAXXToggleButton) component;
+ action.putValue(Action.SHORT_DESCRIPTION, glueComponent.getNormalTooltipText());
+ action.putValue(Action.NAME, glueComponent.getNormalText());
+ action.putValue(Action.SMALL_ICON, glueComponent.getIcon());
+ action.putValue(Action.MNEMONIC_KEY, glueComponent.getNormalMnemonic());
+ action.putValue(Action.SHORT_DESCRIPTION + 2, glueComponent.getGlueTooltipText());
+ action.putValue(Action.NAME + 2, glueComponent.getGlueText());
+ action.putValue(Action.SMALL_ICON + 2, glueComponent.getSelectedIcon());
+ action.putValue(Action.MNEMONIC_KEY + 2, glueComponent.getGlueMnemonic());
+ }
+ }
+
+ }
+
+ String text = (String) action.getValue(Action.NAME);
+ Integer mnemo = (Integer) action.getValue(Action.MNEMONIC_KEY);
+ if (mnemo != null && mnemo != '\0') {
+ int pos = text.indexOf((char) mnemo.intValue());
+ if (pos == -1) {
+ pos = text.indexOf(Character.toLowerCase((char) mnemo.intValue()));
+ }
+ action.putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, pos);
+ }
+
+ }
+
+ /**
+ * @param component le select box où rattacher l'action
+ * @param action action
+ * @param configurationResolver initializer
+ */
+ protected void finalizeNewAction(JComboBox component, MyAbstractAction action, ActionConfigurationResolver<?, ?> configurationResolver) {
+
+ if (configurationResolver == null) {
+ action.putValue(Action.ACTION_COMMAND_KEY, component.getName());
+ action.putValue(Action.SHORT_DESCRIPTION, component.getToolTipText());
+ //result.putValue("selectedIndex", component.getSelectedIndex());
+ }
+
+ }
+
+ protected ActionConfigurationResolver resolveActionConfiguration(MyAbstractAction action) {
+ for (ActionConfigurationResolver resolver : configurationResolvers) {
+ if (resolver.resolveConfiguration(action) != null) {
+ return resolver;
+ }
+ }
+ return null;
+ }
+
+ protected <I extends AbstractActionConfigurationResolver> I registerInitializer(Class<I> initizalizer) {
+ try {
+ I instance = initizalizer.newInstance();
+ configurationResolvers.add(instance);
+ return instance;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void fireAction0(String actionKey, Object source, A action) {
+ if (action == null) {
+ log.warn("could not find action " + actionKey);
+ return;
+ }
+ ActionEvent event = new ActionEvent(source, ActionEvent.ACTION_FIRST, actionKey);
+ action.actionPerformed(event);
+ }
+
+ protected void checkRegistredAction(String actionKey) {
+ if (!impls.containsKey(actionKey)) {
+ throw new IllegalStateException("can not find a registered action for key " + actionKey);
+ }
+ }
+
+
+ @SuppressWarnings({"unchecked"})
+ protected A newActionInstance(String actionKey) throws InstantiationException, IllegalAccessException, InvocationTargetException, NoSuchMethodException {
+ Class<? extends MyAbstractAction> klazz = impls.get(actionKey);
+ MyAbstractAction result;
+ result = klazz.getConstructor(String.class).newInstance(actionKey);
+ result.putValue(Action.ACTION_COMMAND_KEY, actionKey);
+ if (!getBaseClass().isAssignableFrom(klazz)) {
+ // the instanciated action must be boxed in the base Action of the factory
+ result = getBaseClass().getConstructor(MyAbstractAction.class).newInstance(result);
+ }
+ return (A) result;
+ }
+
+
+ public Map<String, Class<? extends MyAbstractAction>> init() {
+ if (log.isDebugEnabled()) {
+ log.debug("start loading " + this);
+ }
+ URLClassLoader newCL = fixClassLoader(getClass());
+ ClassLoader cl = Thread.currentThread().getContextClassLoader();
+ if (newCL != null) {
+ // replace current cl by our fiexed cl
+ Thread.currentThread().setContextClassLoader(newCL);
+ }
+ // obtain a ServiceLoader on ActionProvider
+ ServiceLoader<ActionProvider> loader = ServiceLoader.load(ActionProvider.class);
+ Map<String, Class<? extends MyAbstractAction>> cache = new TreeMap<String, Class<? extends MyAbstractAction>>();
+
+ for (ActionProvider<?> actionProvider : loader) {
+ if (log.isDebugEnabled()) {
+ log.debug("found " + actionProvider);
+ }
+ cache.putAll(actionProvider.getClasses());
+ }
+ if (newCL != null) {
+ // to avoid side effects, push back old cl
+ Thread.currentThread().setContextClassLoader(cl);
+ }
+ return cache;
+ }
+
+ /**
+ * Fix the class loader when application is launched from a java -jar
+ * The ServiceLoader seems not to find services from jar manifest...
+ * <p/>
+ * Our solution is to get all jar from the jar manifest and create a URLClassLoader, this is not perfect but works.
+ * <p/>
+ * TODO Put this nice code in a ServiceLoaderUtil in lutinutil...
+ *
+ * @param klass class to use to obtain classloader
+ * @return the fixed classloader
+ */
+ public static URLClassLoader fixClassLoader(Class klass) {
+ ClassLoader l = klass.getClassLoader();
+ URLClassLoader cl;
+ if (!(l instanceof URLClassLoader)) {
+ log.warn("using cl is not a URL classloader " + l);
+ cl = new URLClassLoader(new URL[0], l);
+ } else {
+ cl = (URLClassLoader) l;
+ }
+ if (cl.getURLs().length == 1) {
+ // come from a java -jar, must expand all jar to make possible ServiceLoader to work
+ try {
+ //todo put this in lutinutil ServiceLoaderUtil
+ URL[] urls = Resource.getClassPathURLsFromJarManifest(cl.getURLs()[0]);
+ URLClassLoader newCL = new URLClassLoader(urls);
+ if (log.isTraceEnabled()) {
+ for (URL url : newCL.getURLs()) {
+ log.trace(url);
+ }
+ }
+ return newCL;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ return null;
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionNameProvider.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionNameProvider.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionNameProvider.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,34 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+/**
+ * Contrat pour obtenir les noms d'une action de maniere dynamique.
+ * <p/>
+ * Cette méthode sera appelee par un {@link ActionProvider} lorsque la clef dans le
+ * fichier de mapping est <code>:fqn</code> (où fqn correspond à une implantation de ce contrat).
+ * <p/>
+ * Ainsi on peut associer à une action donnee plusieurs instances avec des noms différents mais de le meme comportement.
+ * <p/>
+ * Par exemple, une changement de locale ou seule la locale varie (et elle sera retrouvee a partir du nom de l'action).
+ *
+ * @author chemit
+ */
+public interface ActionNameProvider {
+
+ /** @return la liste des noms à utiliser par la classe d'action. */
+ String[] getActionCommands();
+
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProvider.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProvider.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProvider.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,35 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+/**
+ * Contract to be realized by a provider of Actions.
+ * <p/>
+ * A provider of actions is based on a certain type of {@link MyAbstractAction} (<code>A</code>) with an accessor
+ * {@link #getBaseClass()} and deliver some implementations of such actions indexed by their logical names via the
+ * method {#link #getClasses()}.
+ *
+ * @author chemit
+ * @see MyAbstractAction
+ */
+public interface ActionProvider<A extends MyAbstractAction> {
+
+ /** @return the base classe of provided actions */
+ Class<A> getBaseClass();
+
+ /** @return the provided actions classes */
+ java.util.Map<String, Class<? extends A>> getClasses();
+
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProviderAnnotation.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProviderAnnotation.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProviderAnnotation.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,34 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Pour enregister un provider d'action.
+ * <p/>
+ * Placer cette annotation sur la classe de base d'action,
+ * <p/>
+ *
+ * @author chemit
+ */
+(a)Retention(RetentionPolicy.RUNTIME)
+
+(a)Target(ElementType.TYPE)
+public @interface ActionProviderAnnotation {
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProviderFromProperties.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProviderFromProperties.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ActionProviderFromProperties.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,135 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import static org.codelutin.i18n.I18n._;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.Map;
+import java.util.Properties;
+import java.util.TreeMap;
+
+/** @author chemit */
+public class ActionProviderFromProperties<A extends MyAbstractAction> implements ActionProvider<A> {
+
+ /** default prefix for an entryin mapping file. */
+ protected static final String ACTION_KEY_PREFIX = "action.";
+
+ protected static final String actionsFileLocation = "META-INF/jaxx-%1$s-actions.properties";
+
+ protected String propertiesPath;
+
+ protected static Log log = LogFactory.getLog(ActionProviderFromProperties.class);
+
+ protected Class<A> baseClass;
+
+ protected Map<String, Class<? extends A>> actions;
+
+
+ protected ActionProviderFromProperties(Class<A> baseClass) {
+
+ this.baseClass = baseClass;
+ this.propertiesPath = "/" + String.format(actionsFileLocation, baseClass.getSimpleName());
+ this.actions = initCache();
+ }
+
+ public Class<A> getBaseClass() {
+ return baseClass;
+ }
+
+ public Map<String, Class<? extends A>> getClasses() {
+ return actions;
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "<baseClass:" + baseClass.getSimpleName() + ">";
+ }
+
+ protected void clearCache() {
+ if (actions != null) {
+ actions.clear();
+ actions = null;
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ clearCache();
+ }
+
+ @SuppressWarnings({"unchecked"})
+ protected Map<String, Class<? extends A>> initCache() {
+
+ InputStream inputStream = null;
+
+ Properties properties = new Properties();
+
+ try {
+ inputStream = getClass().getResourceAsStream(propertiesPath);
+ if (inputStream == null) {
+ //throw new NullPointerException("could not find action file " + propertiesPath);
+ // actually, there is nothing to load, this is not an error
+ } else {
+ log.info("load " + propertiesPath);
+ properties.load(inputStream);
+ }
+ } catch (IOException e) {
+ String message = _("jaxx.error.load.actions.file", e.getMessage());
+ log.warn(message);
+ throw new RuntimeException(message);
+ } finally {
+ if (inputStream != null) {
+ try {
+ inputStream.close();
+ } catch (IOException e) {
+ log.warn(_("jaxx.error.close.actions.file", e.getMessage()));
+ //throw new RuntimeException(_("jaxx.error.load.actions.file", e.getMessage()));
+ }
+ }
+ }
+
+ Map<String, Class<? extends A>> cache = new TreeMap<String, Class<? extends A>>();
+ int prefix = ACTION_KEY_PREFIX.length();
+ for (Map.Entry<Object, Object> entry : properties.entrySet()) {
+ String key = entry.getKey() + "";
+ String qfn = entry.getValue() + "";
+ try {
+ Class<? extends A> implCass;
+ implCass = (Class<? extends A>) Class.forName(qfn);
+ String actionKey = key.substring(prefix);
+ if (actionKey.startsWith(":")) {
+ // this is a RuntimeActionNameProvider
+ Class<ActionNameProvider> klazz = (Class<ActionNameProvider>) Class.forName(actionKey.substring(1));
+ for (String s : klazz.newInstance().getActionCommands()) {
+ log.debug("found action <" + s + " : " + implCass + ">");
+ cache.put(s, implCass);
+ }
+ continue;
+ }
+ log.debug("found action <" + actionKey + " : " + implCass + ">");
+ cache.put(actionKey, implCass);
+ } catch (Exception e) {
+ throw new RuntimeException(_("jaxx.error.load.actions.class", key, qfn), e);
+ }
+ }
+
+ return cache;
+ }
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/MyAbstractAction.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/MyAbstractAction.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/MyAbstractAction.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,259 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import jaxx.runtime.JAXXObject;
+import org.apache.commons.logging.LogFactory;
+import static org.codelutin.i18n.I18n._;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JComponent;
+import java.awt.event.ActionEvent;
+import java.beans.PropertyChangeListener;
+
+/**
+ * Action de base à utiliser pour encapsuler toutes les actions du système.
+ * <p/>
+ * Ces actions seront chargées par des {@link ActionProvider} et des {@link ActionFactory}.
+ *
+ * @author chemit
+ */
+public abstract class MyAbstractAction extends AbstractAction {
+
+ protected static org.apache.commons.logging.Log log = LogFactory.getLog(MyAbstractAction.class);
+
+ private static final long serialVersionUID = -810023044364620841L;
+
+ protected ActionEvent e;
+
+ protected MyAbstractAction delegate;
+
+ protected abstract String getPrefix();
+
+ protected MyAbstractAction(String name) {
+ super(name);
+ }
+
+ protected MyAbstractAction(MyAbstractAction delegate) {
+ super((String) delegate.getValue(Action.NAME));
+ this.delegate = delegate;
+ }
+
+ public void actionPerformed(java.awt.event.ActionEvent e) {
+ if (hasDelegate()) {
+ // delegate to real action
+ delegate.actionPerformed(e);
+ return;
+ }
+ log.debug("------------------------------------------------------------");
+ log.debug("event : " + e);
+ log.debug("source : " + e.getSource());
+ this.e = e;
+ try {
+ boolean accepted = beforeAction(e);
+ log.debug("action : " + this);
+ if (accepted) {
+ log.info(getActionName() + " (treate:" + accepted + ") : " + this);
+ } else {
+ log.debug(getActionName() + " (treate:" + accepted + ") : " + this);
+ }
+ if (accepted) {
+ doAction(e);
+ setStatus(_("jaxx.action.done", getName()));
+ updateUI();
+ }
+ } catch (Exception e1) {
+ showError(e1);
+ } finally {
+ this.e = null;
+ // always clear action after use : actions are staless
+ clear();
+ }
+ }
+
+ public String getI18nToolTipText() {
+ if (hasDelegate()) {
+ return delegate.getI18nToolTipText();
+ }
+ return getPrefix() + ".action." + getActionName() + ".tooltip";
+ }
+
+ public void updateUI() {
+ if (hasDelegate()) {
+ delegate.updateUI();
+ }
+ // nothing by default
+ }
+
+ public void disposeUI() {
+ if (hasDelegate()) {
+ delegate.disposeUI();
+ }
+ // nothing by default
+ }
+
+ public MyAbstractAction getDelegate() {
+ return delegate;
+ }
+
+ public boolean hasDelegate() {
+ return delegate != null;
+ }
+
+ protected String getName() {
+ return (String) getValue(NAME);
+ }
+
+ protected String getActionName() {
+ return (String) getValue(ACTION_COMMAND_KEY);
+ }
+
+ protected void setStatus(String status) {
+ // do nothing from here
+ if (log.isDebugEnabled()) {
+ log.debug(status);
+ }
+ }
+
+ protected boolean beforeAction(ActionEvent evt) throws Exception {
+ boolean enabled = isEnabled();
+ if (enabled && hasDelegate()) {
+ return delegate.beforeAction(evt);
+ }
+ return enabled;
+ }
+
+ protected void doAction(ActionEvent evt) throws Exception {
+ if (hasDelegate()) {
+ delegate.doAction(evt);
+ }
+ // nothing by default
+ }
+
+ protected JComponent getUIObject(String name, JAXXObject container) {
+ if (container == null) {
+ return null;
+ }
+ return (JComponent) container.getObjectById(name);
+ }
+
+ protected void clear() {
+ if (hasDelegate()) {
+ delegate.clear();
+ }
+ // nothing by default
+ }
+
+ protected void showError(Exception e) {
+ log.error(e);
+ }
+
+ // -----------------------------------------------------------------------------
+ // --- super class delegate methods -------------------------------------------
+ // -----------------------------------------------------------------------------
+
+ @Override
+ public Object getValue(String key) {
+ if (hasDelegate()) {
+ return delegate.getValue(key);
+ }
+ return super.getValue(key);
+ }
+
+ @Override
+ public void putValue(String key, Object newValue) {
+ if (hasDelegate()) {
+ delegate.putValue(key, newValue);
+ }
+ super.putValue(key, newValue);
+ }
+
+ @Override
+ public boolean isEnabled() {
+ if (hasDelegate()) {
+ return delegate.isEnabled();
+ }
+ return super.isEnabled();
+ }
+
+ @Override
+ public void setEnabled(boolean newValue) {
+ if (hasDelegate()) {
+ delegate.setEnabled(newValue);
+ }
+ super.setEnabled(newValue);
+ }
+
+ @Override
+ public Object[] getKeys() {
+ if (hasDelegate()) {
+ return getKeys();
+ }
+ return super.getKeys();
+ }
+
+ @Override
+ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+ if (hasDelegate()) {
+ delegate.firePropertyChange(propertyName, oldValue, newValue);
+ }
+ super.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ @Override
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ if (hasDelegate()) {
+ delegate.addPropertyChangeListener(listener);
+ }
+ super.addPropertyChangeListener(listener);
+ }
+
+ @Override
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ if (hasDelegate()) {
+ delegate.removePropertyChangeListener(listener);
+ }
+ super.removePropertyChangeListener(listener);
+ }
+
+ @Override
+ public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
+ if (hasDelegate()) {
+ return delegate.getPropertyChangeListeners();
+ }
+ return super.getPropertyChangeListeners();
+ }
+
+ @Override
+ protected Object clone() throws CloneNotSupportedException {
+ if (hasDelegate()) {
+ return clone();
+ }
+ return super.clone();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(super.toString());
+ if (hasDelegate()) {
+ sb.append("[delegate: ").append(delegate.toString()).append("]");
+ } else {
+ sb.append("<key:").append(getActionName()).append(">");
+ }
+ return sb.toString();
+ }
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfig.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfig.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfig.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,95 @@
+/*
+* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit, Gabriel Landais
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* ##% */
+package org.codelutin.jaxx.action;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Pour enregister une action.
+ * <p/>
+ * Placer cette annotation sur la classe implantant l'action,
+ * <p/>
+ * les informations décrites seront utilisées pour instancier l'action
+ *
+ * @author chemit
+ */
+(a)Retention(RetentionPolicy.RUNTIME)
+
+(a)Target(ElementType.TYPE)
+@Inherited
+public @interface SelectActionConfig {
+
+ /**
+ * @return la clef de la commande (doit être unique)
+ * @see javax.swing.Action#ACTION_COMMAND_KEY
+ */
+ String actionCommand();
+
+ /** @return array of names to be used in actions mapping */
+ String[] actionCommands() default {};
+
+ /**
+ * @return the class to obtain at runtime the array of names to be used in actions mapping.
+ * <p/>
+ * <b>Note : the special value {@link org.codelutin.jaxx.action.ActionNameProvider} is used to says not to used
+ * œthis mecanism since we can not set a null value in a annotation</b>
+ */
+ Class<? extends ActionNameProvider> actionCommandProvider() default org.codelutin.jaxx.action.ActionNameProvider.class;
+
+ /**
+ * @return la clef i18n du texte de l'action, si vide ignoré
+ * @see javax.swing.Action#NAME
+ */
+ String name() default "";
+
+ /**
+ * @return la clef i18n du tooltip de l'action, si vide ignoré
+ * @see javax.swing.Action#SHORT_DESCRIPTION
+ */
+ String shortDescription() default "";
+
+ /**
+ * @return la clef i18n du texte de l'action, si vide ignoré
+ * @see javax.swing.Action#LONG_DESCRIPTION
+ */
+ String longDescription() default "";
+
+ /**
+ * @return accelerator key
+ * @see javax.swing.Action#ACCELERATOR_KEY
+ */
+ String accelerator() default "";
+
+ /**
+ * @return la valeur par défaut pour les component selectable
+ * @see javax.swing.Action#SELECTED_KEY
+ */
+ int selectedIndex() default 0;
+
+ /**
+ * @return enabled state
+ * @see javax.swing.Action#isEnabled()
+ */
+ boolean enabled() default true;
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfigConfigurationResolver.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfigConfigurationResolver.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfigConfigurationResolver.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,53 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import static org.codelutin.i18n.I18n._;
+
+import javax.swing.Action;
+import javax.swing.JComboBox;
+
+/**
+ * Implementation of configuration's resolver for annotation {@link SelectActionConfig}
+ *
+ * @author chemit
+ */
+public class SelectActionConfigConfigurationResolver extends AbstractActionConfigurationResolver<SelectActionConfig, JComboBox> {
+
+ public SelectActionConfigConfigurationResolver() {
+ super(SelectActionConfig.class, JComboBox.class);
+ }
+
+ protected SelectActionConfig applyConfiguration0(JComboBox component, MyAbstractAction action) {
+ SelectActionConfig anno = resolveConfiguration(action);
+ if (anno == null) {
+ return null;
+ }
+ // inject les données
+ if (!anno.name().isEmpty()) {
+ action.putValue(Action.NAME, _(anno.name()));
+ }
+ if (!anno.shortDescription().isEmpty()) {
+ action.putValue(Action.SHORT_DESCRIPTION, _(anno.shortDescription()));
+ } else {
+ action.putValue(Action.SHORT_DESCRIPTION, _(component.getToolTipText()));
+ }
+ action.putValue("selectedIndex", anno.selectedIndex());
+ //TODO Convert it from String action.putValue(Action.ACCELERATOR_KEY, anno.accelerator());
+ action.setEnabled(anno.enabled());
+
+ return anno;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfig.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfig.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfig.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,156 @@
+/*
+* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit, Gabriel Landais
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* ##% */
+package org.codelutin.jaxx.action;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Inherited;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Pour enregister une action de type Toggle (ToggleButton).
+ * <p/>
+ * Placer cette annotation sur la classe implantant l'action,
+ * <p/>
+ * les informations décrites seront utilisées pour instancier l'action
+ *
+ * @author chemit
+ */
+(a)Retention(RetentionPolicy.RUNTIME)
+(a)Target(ElementType.TYPE)
+@Inherited
+public @interface ToggleActionConfig {
+ /**
+ * @return la clef de la commande (doit être unique)
+ * @see javax.swing.Action#ACTION_COMMAND_KEY
+ */
+ String actionCommand();
+
+ /** @return array of names to be used in actions mapping */
+ String[] actionCommands() default {};
+
+ /**
+ * @return the class to obtain at runtime the array of names to be used in actions mapping.
+ * <p/>
+ * <b>Note : the special value {@link org.codelutin.jaxx.action.ActionNameProvider} is used to says not to used
+ * œthis mecanism since we can not set a null value in a annotation</b>
+ */
+ Class<? extends ActionNameProvider> actionCommandProvider() default org.codelutin.jaxx.action.ActionNameProvider.class;
+
+ /**
+ * @return la clef i18n du texte de l'action, si vide ignoré
+ * @see javax.swing.Action#NAME
+ */
+ String name() default "";
+
+ /**
+ * @return la clef i18n du tooltip de l'action, si vide ignoré
+ * @see javax.swing.Action#SHORT_DESCRIPTION
+ */
+ String shortDescription() default "";
+
+ /**
+ * @return la clef i18n du texte de l'action, si vide ignoré
+ * @see javax.swing.Action#LONG_DESCRIPTION
+ */
+ String longDescription() default "";
+
+ /**
+ * @return le nom de l'icone associé, si vide ignoré
+ * @see javax.swing.Action#SMALL_ICON
+ */
+ String smallIcon() default "";
+
+ /**
+ * @return le nom du grande icone associé, si vide ignoré
+ * @see javax.swing.Action#LARGE_ICON_KEY
+ */
+ String largeIcon() default "";
+
+ /**
+ * @return accelerator key of default state
+ * @see javax.swing.Action#ACCELERATOR_KEY
+ */
+ String accelerator() default "";
+
+ /**
+ * @return mnemonic key of default state
+ * @see javax.swing.Action#MNEMONIC_KEY
+ */
+ int mnemonic() default '\0';
+
+ /**
+ * @return la clef i18n du texte de l'action, si vide ignoré
+ * @see javax.swing.Action#NAME
+ */
+ String name2() default "";
+
+ /**
+ * @return la clef i18n du tooltip de l'action, si vide ignoré
+ * @see javax.swing.Action#SHORT_DESCRIPTION
+ */
+ String shortDescription2() default "";
+
+ /**
+ * @return la clef i18n du texte de l'action, si vide ignoré
+ * @see javax.swing.Action#LONG_DESCRIPTION
+ */
+ String longDescription2() default "";
+
+ /**
+ * @return le nom de l'icone associé, si vide ignoré
+ * @see javax.swing.Action#SMALL_ICON
+ */
+ String smallIcon2() default "";
+
+ /**
+ * @return le nom du grande icone associé, si vide ignoré
+ * @see javax.swing.Action#LARGE_ICON_KEY
+ */
+ String largeIcon2() default "";
+
+ /**
+ * @return accelerator key of default state
+ * @see javax.swing.Action#ACCELERATOR_KEY
+ */
+ String accelerator2() default "";
+
+ /**
+ * @return mnemonic key of second state
+ * @see javax.swing.Action#MNEMONIC_KEY
+ */
+ int mnemonic2() default '\0';
+
+ /**
+ * @return la valeur par défaut pour les component selectable
+ * @see javax.swing.Action#SELECTED_KEY
+ */
+ boolean selected() default false;
+
+ /**
+ * @return enaled state
+ * @see javax.swing.Action#isEnabled()
+ */
+ boolean enabled() default true;
+
+ /** @return hideActionText state */
+ boolean hideActionText() default false;
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfigConfigurationResolver.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfigConfigurationResolver.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfigConfigurationResolver.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,79 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.action;
+
+import static org.codelutin.i18n.I18n._;
+
+import javax.swing.AbstractButton;
+import javax.swing.Action;
+
+/**
+ * Implementation of configuration's resolver for annotation {@link ToggleActionConfig}
+ *
+ * @author chemit
+ */
+public class ToggleActionConfigConfigurationResolver extends AbstractActionConfigurationResolver<ToggleActionConfig, AbstractButton> {
+
+ public ToggleActionConfigConfigurationResolver() {
+ super(ToggleActionConfig.class, AbstractButton.class);
+ }
+
+ protected ToggleActionConfig applyConfiguration0(AbstractButton component, MyAbstractAction action) {
+ ToggleActionConfig anno = resolveConfiguration(action);
+ if (anno == null) {
+ return null;
+ }
+ // inject les données
+ if (!anno.name().isEmpty()) {
+ //System.out.println("found action with name : " + anno.name());
+ action.putValue(Action.NAME, _(anno.name()));
+ }
+ if (!anno.name2().isEmpty()) {
+ //System.out.println("found action with name2 : " + anno.name2());
+ action.putValue(Action.NAME + "2", _(anno.name2()));
+ }
+
+ if (!anno.shortDescription().isEmpty()) {
+ action.putValue(Action.SHORT_DESCRIPTION, _(anno.shortDescription()));
+ }
+ if (!anno.shortDescription2().isEmpty()) {
+ action.putValue(Action.SHORT_DESCRIPTION + "2", _(anno.shortDescription2()));
+ }
+
+ if (!anno.smallIcon().isEmpty()) {
+ action.putValue(Action.SMALL_ICON, org.codelutin.jaxx.util.UIHelper.createImageIcon(anno.smallIcon()));
+ }
+ if (!anno.smallIcon2().isEmpty()) {
+ action.putValue(Action.SMALL_ICON + "2", org.codelutin.jaxx.util.UIHelper.createImageIcon(anno.smallIcon2()));
+ }
+
+ if (anno.mnemonic() != '\0') {
+ action.putValue(Action.MNEMONIC_KEY, anno.mnemonic());
+ } else if (component != null) {
+ action.putValue(Action.MNEMONIC_KEY, component.getMnemonic());
+ }
+ if (anno.mnemonic2() != '\0') {
+ action.putValue(Action.MNEMONIC_KEY + "2", anno.mnemonic2());
+ }
+ //TODO Convert it from String action.putValue(Action.ACCELERATOR_KEY, anno.accelerator());
+
+
+ action.putValue("hideActionText", anno.hideActionText());
+ action.putValue(Action.SELECTED_KEY, anno.selected());
+ action.setEnabled(anno.enabled());
+
+ return anno;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabContentConfig.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabContentConfig.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabContentConfig.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,54 @@
+/*
+* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit, Gabriel Landais
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* ##% */
+package org.codelutin.jaxx.tab;
+
+import jaxx.runtime.gwt.JAXXTab;
+
+import javax.swing.JTabbedPane;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Pour enregister un tab
+ *
+ * @author chemit
+ */
+(a)Retention(RetentionPolicy.RUNTIME)
+
+(a)Target(ElementType.FIELD)
+
+public @interface TabContentConfig {
+
+ Class<? extends TabModel> model();
+
+ Class<? extends JAXXTab> impl();
+
+ Class<? extends JTabbedPane> parentImpl();
+
+ boolean useToogle() default false;
+
+ String name();
+
+ String shortDescription();
+
+ String[] dynamicFields() default {};
+
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabFactory.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabFactory.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabFactory.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,219 @@
+/*
+* \#\#% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* \#\#% */
+package org.codelutin.jaxx.tab;
+
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.gwt.JAXXTab;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JComponent;
+import javax.swing.JTabbedPane;
+import java.awt.Component;
+import java.lang.reflect.Field;
+import java.util.Map;
+import java.util.Set;
+import java.util.TreeMap;
+
+/**
+ * Une usine pour les Tabs, leur configs et leur modèles
+ *
+ * @author tony
+ * @see TabContentConfig
+ * @see TabModel
+ */
+
+public abstract class TabFactory {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ protected static Log log = LogFactory.getLog(TabFactory.class);
+
+ /** dictionary of configs */
+ protected Map<String, TabContentConfig> configs;
+
+ /** dictionary of instanciated actions */
+ protected Map<String, JAXXTab> cache;
+
+ /** dictionary of instanciated models */
+ protected Map<String, TabModel> models;
+
+ protected abstract Map<String, TabContentConfig> initFactory();
+
+ protected abstract void initTab(JAXXTab tab, String tabName, TabContentConfig config);
+
+ protected JAXXTab newTab(String tabName) {
+
+ checkRegistredConfig(tabName);
+
+ // try in cache
+ if (cache.containsKey(tabName)) {
+ // use cached tab
+ return cache.get(tabName);
+ }
+
+ TabContentConfig config = configs.get(tabName);
+
+ JAXXTab instance;
+ try {
+ instance = config.impl().newInstance();
+ if (log.isDebugEnabled()) {
+ log.debug("new tab : " + instance);
+ }
+
+ cache.put(tabName, instance);
+
+ initJAXXTab(config, instance);
+ initTab(instance, tabName, config);
+
+ return instance;
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public Set<String> keySet() {
+ return cache.keySet();
+ }
+
+ public TabContentConfig getConfig(String tabName) {
+ checkRegistredConfig(tabName);
+ return configs.get(tabName);
+ }
+
+ public JAXXTab getUI(String tabName) {
+ return cache.get(tabName);
+ }
+
+ public TabModel getModel(String tabName, Object... params) {
+
+ if (models.containsKey(tabName)) {
+ return models.get(tabName);
+ }
+ TabContentConfig config = getConfig(tabName);
+ TabModel tabModel;
+ try {
+ tabModel = initTabModel(config, params);
+ if (log.isDebugEnabled()) {
+ log.debug("new tab model : " + tabModel);
+ }
+ models.put(tabName, tabModel);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ return tabModel;
+ }
+
+ protected TabModel initTabModel(TabContentConfig config, Object... params) throws InstantiationException, IllegalAccessException {
+ TabModel tabModel;
+ tabModel = config.model().newInstance();
+ return tabModel;
+ }
+
+ public void showTab(final JTabbedPane container, String tabName) {
+
+ TabContentConfig config = getConfig(tabName);
+
+ JAXXTab comp = newTab(tabName);
+
+ int index = getTabIndex(container, comp);
+ if (index == -1) {
+ registerTab(container, tabName, config, comp);
+ }
+
+ container.setSelectedComponent(comp);
+ }
+
+ public void closeTab(JTabbedPane container, String tabName) {
+
+ TabContentConfig config = getConfig(tabName);
+
+ final JComponent comp = cache.get(tabName);
+
+ int index = getTabIndex(container, comp);
+ if (index != -1) {
+ container.removeTabAt(index);
+ if (log.isDebugEnabled()) {
+ log.debug(config + " index " + index);
+ }
+ }
+ }
+
+ public int getTabIndex(final JTabbedPane container, JComponent comp) {
+ if (container != null && comp != null) {
+ for (int i = 0; i < container.getTabCount(); i++) {
+ Component o = container.getComponentAt(i);
+ if (o.equals(comp)) {
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public void resetCache() {
+ cache.clear();
+ models.clear();
+ }
+
+
+ protected TabFactory() {
+ configs = initFactory();
+ cache = new TreeMap<String, JAXXTab>();
+ models = new TreeMap<String, TabModel>();
+ }
+
+ protected JComponent addTabHeader(final JTabbedPane container, final String tabName, final TabContentConfig config, final JAXXTab comp) {
+ // by default, no tab header
+ return null;
+ }
+
+ protected void registerTab(final JTabbedPane container, final String tabName, final TabContentConfig config, final JAXXTab comp) {
+
+ container.addTab(tabName, comp);
+
+ JComponent header = addTabHeader(container, tabName, config, comp);
+
+ if (header != null) {
+
+ container.setTabComponentAt(container.getTabCount() - 1, header);
+ }
+ }
+
+ @SuppressWarnings({"unchecked"})
+ protected void initJAXXTab(TabContentConfig config, JAXXTab instance) throws NoSuchFieldException, IllegalAccessException {
+ if (instance instanceof JAXXObject) {
+ JAXXObject ui = (JAXXObject) instance;
+ for (String dynamicField : config.dynamicFields()) {
+ String dynamciName = dynamicField + '_' + config.name();
+ Object obj = ui.getObjectById(dynamicField);
+ Field m = ui.getClass().getDeclaredField("$objectMap");
+ m.setAccessible(true);
+ Map<Object, Object> map = (Map<Object, Object>) m.get(ui);
+ map.put(dynamciName, obj);
+ }
+ }
+ }
+
+ protected void checkRegistredConfig(String tabName) {
+ if (!configs.containsKey(tabName)) {
+ throw new IllegalStateException("can not find a registered TabContentConfig for tab name " + tabName);
+ }
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabModel.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabModel.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/tab/TabModel.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,30 @@
+/*
+* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* ##% */
+package org.codelutin.jaxx.tab;
+
+import java.io.Serializable;
+
+/** @author chemit */
+public interface TabModel extends Serializable {
+
+ String getName();
+
+ void setName(String name);
+
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/AbstractUIAction.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/AbstractUIAction.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/AbstractUIAction.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,53 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/** @author chemit */
+public abstract class AbstractUIAction<H extends DialogUIHandler<?, ?>> extends javax.swing.AbstractAction {
+
+ protected static Log log = LogFactory.getLog(AbstractUIAction.class);
+
+ protected transient DialogUI<? extends H> ui;
+
+ private static final long serialVersionUID = 1L;
+
+ protected AbstractUIAction(String name, javax.swing.Icon icon, DialogUI<? extends H> ui) {
+ super(name, icon);
+ this.ui = ui;
+ }
+
+ protected H getHandler() {
+ checkInit();
+ return ui.getHandler();
+ }
+
+ protected void setUi(DialogUI<? extends H> ui) {
+ this.ui = ui;
+ }
+
+ public DialogUI<? extends H> getUi() {
+ return ui;
+ }
+
+ protected void checkInit() throws IllegalStateException {
+ /*if (ui == null) {
+ throw new IllegalStateException("no handler, nor ui referenced in " + this);
+ } */
+ }
+
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUI.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUI.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,129 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.AbstractAction;
+import javax.swing.AbstractButton;
+import javax.swing.ImageIcon;
+import javax.swing.JDialog;
+import java.awt.event.WindowEvent;
+import java.awt.event.WindowListener;
+import java.lang.reflect.Constructor;
+
+/**
+ * A abstract dialog contract to be realised by a dialogUI (WindowEvent adapter)
+ * <p/>
+ * TODO : make jaxx authorized implementing interface for root tag :)
+ *
+ * @author chemit
+ */
+public abstract class DialogUI<H extends DialogUIHandler> extends JDialog implements WindowListener {
+
+ protected static Log log = LogFactory.getLog(DialogUI.class);
+
+ public javax.swing.AbstractAction newAction(Class<?> actionClass, Object... params) {
+ Constructor<?> constructor = null;
+ for (Constructor<?> cons : actionClass.getConstructors()) {
+ Class<?>[] prototype = cons.getParameterTypes();
+ if (prototype.length > 0 && DialogUI.class.isAssignableFrom(prototype[0])) {
+ // use this constructor
+ constructor = cons;
+ break;
+ }
+ }
+ if (constructor == null) {
+ throw new IllegalStateException("could not find a matching constructor for " + actionClass);
+ }
+
+ // wrap params
+ Object[] parameters = new Object[1 + params.length];
+ parameters[0] = this;
+ System.arraycopy(params, 0, parameters, 1, params.length);
+ try {
+ AbstractAction action = (AbstractAction) constructor.newInstance(parameters);
+ if (log.isInfoEnabled()) {
+ log.info(action);
+ }
+ return action;
+ } catch (Exception e) {
+ throw new IllegalStateException("could not init the action " + actionClass + " for reason : " + e.getMessage());
+ }
+ }
+
+ private H handler;
+
+ public abstract AbstractButton getHelp();
+
+ public abstract Object getObjectById(java.lang.String s);
+
+ protected DialogUI() {
+ UIHelper.setQuitAction(this);
+ addWindowListener(this);
+ //TODO will be handled by jaxx with javax.help...
+ //getHelp().setAction(newAction(HelpAction.class));
+ }
+
+ public H getHandler() {
+ return handler;
+ }
+
+ public void setHandler(H handler) {
+ this.handler = handler;
+ }
+
+ protected ImageIcon createActionIcon(String name) {
+ return UIHelper.createActionIcon(name);
+ }
+
+ public void windowOpened(WindowEvent e) {
+ }
+
+ public void windowClosed(WindowEvent e) {
+ }
+
+ public void windowClosing(WindowEvent e) {
+ }
+
+ public void windowIconified(WindowEvent e) {
+ }
+
+ public void windowDeiconified(WindowEvent e) {
+ }
+
+ public void windowActivated(WindowEvent e) {
+ }
+
+ public void windowDeactivated(WindowEvent e) {
+ }
+
+ @Override
+ public synchronized void addWindowListener(WindowListener l) {
+ super.addWindowListener(l);
+ if (log.isDebugEnabled()) {
+ log.debug("after added (" + getWindowListeners().length + ") : " + l);
+ }
+ }
+
+ @Override
+ public synchronized void removeWindowListener(WindowListener l) {
+ super.removeWindowListener(l);
+ if (log.isDebugEnabled()) {
+ log.debug("after removed (" + getWindowListeners().length + ") : " + l);
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIDef.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIDef.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIDef.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,235 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+import static org.codelutin.i18n.I18n._;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.ImageIcon;
+import java.lang.reflect.Constructor;
+
+/**
+ * Definition of an ui, with his model, handler and ui class definitions.
+ * <p/>
+ * The class contains also a shared instace of concrete ui.
+ *
+ * @author chemit
+ */
+public class DialogUIDef<M extends DialogUIModel, U extends DialogUI<H>, H extends DialogUIHandler<M, U>> implements java.io.Serializable {
+
+ static protected final Log log = LogFactory.getLog(DialogUIDef.class);
+
+ public static <M extends DialogUIModel, U extends DialogUI<H>, H extends DialogUIHandler<M, U>> DialogUIDef<M, U, H> newDef(Class<H> handlerClass, Class<U> uiClass, Class<M> modelClass, String showActionLibelle, String showActionTip, String uiTitle) {
+ DialogUIDef<M, U, H> result;
+ result = new DialogUIDef<M, U, H>(handlerClass, uiClass, modelClass, showActionLibelle, showActionTip, uiTitle);
+ return result;
+ }
+
+ /**
+ * model class
+ */
+ private final Class<M> modelClass;
+
+ /**
+ * handler class
+ */
+ private final Class<H> handlerClass;
+
+ /**
+ * abstract ui class
+ */
+ private final Class<U> uiClass;
+
+ /**
+ * concrete lookup ui class
+ */
+ private Class<? extends U> uiImplClass;
+
+ /**
+ * shared instance of ui
+ */
+ protected U uiInstance;
+
+ /**
+ * unique name of ui def
+ */
+ protected final String name;
+
+ protected final String uiTitle;
+ protected final String showActionLibelle;
+ protected final String showActionTip;
+
+ protected ImageIcon showUIActionIcon;
+
+
+ private static final long serialVersionUID = 1L;
+
+ private DialogUIDef(Class<H> handlerClass, Class<U> uiClass, Class<M> modelClass,
+ String showActionLibelle, String showActionTip, String uiTitle) {
+ this.handlerClass = handlerClass;
+ this.uiClass = uiClass;
+ this.modelClass = modelClass;
+ this.showActionLibelle = showActionLibelle;
+ this.name = uiClass.getSimpleName().toLowerCase();
+ this.showActionTip = showActionTip;
+ this.uiTitle = uiTitle;
+ }
+
+ public Class<U> getUiClass() {
+ return uiClass;
+ }
+
+ public Class<H> getHandlerClass() {
+ return handlerClass;
+ }
+
+ public Class<M> getModelClass() {
+ return modelClass;
+ }
+
+ public Class<? extends U> getUiImplClass() {
+ return uiImplClass;
+ }
+
+ public String getUiTitle() {
+ return _(uiTitle);
+ }
+
+ public String getShowActionLibelle() {
+ return _(showActionLibelle);
+ }
+
+ public String getShowActionTip() {
+ return _(showActionTip);
+ }
+
+ public ImageIcon getShowUIActionIcon() {
+ if (showUIActionIcon == null) {
+ showUIActionIcon = UIHelper.createActionIcon("show-" + name);
+ }
+ return showUIActionIcon;
+ }
+
+ @SuppressWarnings({"unchecked"})
+ public void setUiImplClass(Class<?> uiImplClass) {
+ this.uiImplClass = (Class<? extends U>) uiImplClass;
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ return this == o || o instanceof DialogUIDef && uiClass.equals(((DialogUIDef) o).uiClass);
+ }
+
+ @Override
+ public int hashCode() {
+ return uiClass.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(super.toString()).append('<');
+ sb.append(printClass("handler", handlerClass, true));
+ sb.append(printClass("model", modelClass, true));
+ sb.append(printClass("ui", uiClass, true));
+ sb.append(printClass("uiImpl", uiImplClass, false));
+ return sb.toString();
+ }
+
+ protected U getUiInstance() {
+ // no lazy instanciation, to control ui instanciation...
+ /*if (uiInstance == null) {
+ if (uiImplClass == null) {
+ throw new IllegalStateException("no concrete ui impl found in " + this);
+ }
+ synchronized (this) {
+ try {
+ uiInstance = uiImplClass.newInstance();
+ } catch (Exception e) {
+ throw new IllegalStateException("could not instanciate ui " + this,e);
+ }
+ }
+ }*/
+ return uiInstance;
+ }
+
+ protected void setUiInstance(U uiInstance) {
+ this.uiInstance = uiInstance;
+ }
+
+ protected U newUI() {
+ if (uiImplClass == null) {
+ throw new IllegalStateException("no concrete ui impl found in " + this);
+ }
+ try {
+ U result = uiImplClass.newInstance();
+ log.info(result);
+ return result;
+ } catch (Exception e) {
+ throw new IllegalStateException("could not instanciate ui " + this, e);
+ }
+ }
+
+ protected M newModel() {
+ if (modelClass == null) {
+ throw new IllegalStateException("no model impl found in " + this);
+ }
+ try {
+ M model = modelClass.newInstance();
+ log.info(model);
+ return model;
+ } catch (Exception e) {
+ throw new IllegalStateException("could not instanciate ui " + this, e);
+ }
+ }
+
+ protected H newHandler(U ui, M model, Object... params) {
+ if (handlerClass == null) {
+ throw new IllegalStateException("no handler impl found in " + this);
+ }
+ try {
+ Class[] prototype = getHandlerPrototype(params);
+ Object[] parameters = getHandlerParameters(ui, model, params);
+ H result = handlerClass.getConstructor(prototype).newInstance(parameters);
+ log.info(result);
+ return result;
+ } catch (Exception e) {
+ throw new IllegalStateException("could not instanciate ui " + this, e);
+ }
+ }
+
+ protected Object[] getHandlerParameters(U ui, M model, Object[] params) {
+ Object[] result = new Object[2 + params.length];
+ result[0] = ui;
+ result[1] = model;
+ System.arraycopy(params, 0, result, 2, params.length);
+ return result;
+ }
+
+ protected Class[] getHandlerPrototype(Object[] params) {
+ int length = params.length;
+ for (Constructor<?> constructor : handlerClass.getConstructors()) {
+ Class<?>[] prototype = constructor.getParameterTypes();
+ if (prototype.length == 2 + length && prototype[0] == uiClass && prototype[1] == modelClass) {
+ return prototype;
+ }
+ }
+ throw new IllegalStateException("could not find a matching constructor in " + handlerClass);
+ }
+
+ protected String printClass(String s, Class<?> aClass, boolean notLast) {
+ return s + ':' + (aClass == null ? null : aClass.getSimpleName()) + (notLast ? ", " : ">");
+ }
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIHandler.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIHandler.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,70 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.awt.event.WindowListener;
+import java.beans.PropertyChangeListener;
+
+/**
+ * DialogUI handler
+ *
+ * @author chemit
+ */
+public abstract class DialogUIHandler<M extends DialogUIModel, U extends DialogUI<? extends DialogUIHandler>> implements PropertyChangeListener {
+
+ protected static Log log = LogFactory.getLog(DialogUIHandler.class);
+
+ /** ui handled */
+ private U ui;
+
+ /** model handled */
+ private M model;
+
+ protected DialogUIHandler(U ui, M model) {
+ this.ui = ui;
+ this.model = model;
+ }
+
+ public U getUi() {
+ return ui;
+ }
+
+ public M getModel() {
+ return model;
+ }
+
+ public void init() {
+ if (model == null) {
+ throw new IllegalStateException("no model was defined for " + this);
+ }
+ model.addPropertyChangeListener(this);
+ }
+
+ public void dispose() {
+ model.dispose();
+ for (WindowListener windowListener : getUi().getWindowListeners()) {
+ getUi().removeWindowListener(windowListener);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ dispose();
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIModel.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIModel.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/DialogUIModel.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,97 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+/**
+ * Abstract ui model, with property change support.
+ *
+ * @author chemit
+ */
+public abstract class DialogUIModel {
+
+ static protected final Log log = LogFactory.getLog(DialogUIModel.class);
+
+ /** support for change properties support */
+ protected PropertyChangeSupport changeSupport;
+
+ public synchronized void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ if (listener == null) {
+ return;
+ }
+ if (changeSupport == null) {
+ changeSupport = new PropertyChangeSupport(this);
+ }
+ changeSupport.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ if (listener == null) {
+ return;
+ }
+ if (changeSupport == null) {
+ changeSupport = new PropertyChangeSupport(this);
+ }
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ if (listener == null || changeSupport == null) {
+ return;
+ }
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ public synchronized void removePropertyChangeListeners() {
+ if (changeSupport == null) {
+ return;
+ }
+ for (PropertyChangeListener listener : getPropertyChangeListeners()) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+ }
+
+ public synchronized PropertyChangeListener[] getPropertyChangeListeners() {
+ if (changeSupport == null) {
+ return new PropertyChangeListener[0];
+ }
+ return changeSupport.getPropertyChangeListeners();
+ }
+
+ public void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+ if (changeSupport == null || (oldValue == null && newValue == null) ||
+ (oldValue != null && oldValue.equals(newValue))) {
+ return;
+ }
+ changeSupport.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ public void dispose() {
+ for (PropertyChangeListener listener : changeSupport.getPropertyChangeListeners()) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ dispose();
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/FactoryWindowListener.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/FactoryWindowListener.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/FactoryWindowListener.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,84 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+/**
+ * A windowListenr for ui managed by {@link org.codelutin.jaxx.util.UIFactory}.
+ * <p/>
+ * To be used when all ui from factory are closed, via {@link #allWindowsClosed(java.awt.event.WindowEvent)} method.
+ *
+ * @author chemit
+ */
+public abstract class FactoryWindowListener extends WindowAdapter {
+
+ /**
+ * method to be invoked when all ui registred in factory are really disposed.
+ *
+ * @param e event
+ */
+ public abstract void allWindowsClosed(WindowEvent e);
+
+ /** underlying factory of ui */
+ private UIFactory factory;
+
+ /** flag to make sure {@link #allWindowsClosed(java.awt.event.WindowEvent)} is called only once. */
+ private boolean wasClosed;
+
+ @Override
+ public void windowClosed(WindowEvent e) {
+ if (UIFactory.log.isDebugEnabled()) {
+ UIFactory.log.debug(this + " : " + e);
+ }
+ if (e.getWindow().isVisible()) {
+ // only deal with real closed and none visible windows...
+ return;
+ }
+ for (DialogUIDef def : factory.getDefs()) {
+ DialogUI ui = def.uiInstance;
+ if (ui != null && ui.isVisible()) {
+ // at least one ui visible, do not close all
+ return;
+ }
+ }
+
+ if (wasClosed) {
+ // make sure to process only once
+ return;
+ }
+ if (UIFactory.log.isInfoEnabled()) {
+ UIFactory.log.info("closing factory listener " + this);
+ }
+
+ synchronized (this) {
+ try {
+ allWindowsClosed(e);
+ } finally {
+ wasClosed = true;
+ factory.removeFactoryWindowListener(this);
+ }
+ }
+ }
+
+ protected UIFactory getFactory() {
+ return factory;
+ }
+
+ protected void setFactory(UIFactory factory) {
+ this.factory = factory;
+ }
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/FormElement.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/FormElement.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/FormElement.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,29 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+/** @author chemit */
+public interface FormElement<U extends DialogUI> {
+
+ String name();
+
+ int ordinal();
+
+ Object getValue(U ui);
+
+ void setValue(U ui, String value);
+
+ javax.swing.JLabel getLabel(U ui);
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/ShowUIAction.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/ShowUIAction.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/ShowUIAction.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,135 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.event.ActionEvent;
+
+/** @author chemit */
+public abstract class ShowUIAction<M extends DialogUIModel, U extends DialogUI<H>, H extends DialogUIHandler<M, U>> extends javax.swing.AbstractAction {
+
+ protected static Log log = LogFactory.getLog(AbstractUIAction.class);
+
+ protected transient DialogUI<?> ui;
+
+ private static final long serialVersionUID = 1L;
+
+ protected DialogUIDef<M, U, H> uiDef;
+
+ protected transient UIFactory factory;
+
+ protected String position;
+
+ protected boolean undecorated = true;
+
+ protected U initUI(ActionEvent e) {
+ return getFactory().getUI(uiDef);
+ }
+
+ public ShowUIAction(DialogUI<?> ui, DialogUIDef<M, U, H> uiDef, UIFactory factory, boolean showText) {
+ super(uiDef.getShowActionLibelle(), uiDef.getShowUIActionIcon());
+ this.ui = ui;
+ this.uiDef = uiDef;
+ String name = (String) getValue(NAME);
+ putValue(DISPLAYED_MNEMONIC_INDEX_KEY, name.length() - 1);
+ putValue(ACCELERATOR_KEY, (int) name.charAt(name.length() - 1));
+ if (!showText) {
+ putValue(NAME, null);
+ }
+ putValue(SHORT_DESCRIPTION, uiDef.getShowActionTip());
+ this.factory = factory;
+ }
+
+ public DialogUI<?> getUi() {
+ return ui;
+ }
+
+ public DialogUIDef<M, U, H> getUiDef() {
+ return uiDef;
+ }
+
+ public UIFactory getFactory() {
+ return factory;
+ }
+
+ public void setUiDef(DialogUIDef<M, U, H> uiDef) {
+ this.uiDef = uiDef;
+ }
+
+ public void setPosition(String position) {
+ this.position = position;
+ }
+
+ public void setUndecorated(boolean undecorated) {
+ this.undecorated = undecorated;
+ }
+
+ public void actionPerformed(java.awt.event.ActionEvent e) {
+ checkInit();
+ U ui = initUI(e);
+ ui.setTitle(uiDef.getUiTitle());
+ log.info(ui.getTitle());
+ //TODO ui.setUndecorated(undecorated);
+ setPosition(this.getUi(), ui, position);
+
+ ui.setVisible(true);
+ }
+
+ protected void setPosition(javax.swing.JDialog parentUI, javax.swing.JDialog ui, String position) {
+ if (position == null || parentUI == null) {
+ return;
+ }
+ Point parentLocation = parentUI.getLocationOnScreen();
+ Dimension parentSize = parentUI.getSize();
+
+ if (position.equals("bottom-left")) {
+ int top = (int) (parentLocation.getY() + parentSize.getHeight());
+ int left = (int) (parentLocation.getX());
+ Point newLocation = new Point(left, top);
+ newLocation.setLocation(left, top);
+ ui.setLocation(newLocation);
+ return;
+ }
+ if (position.equals("top-left")) {
+ int top = (int) (parentLocation.getY());
+ int left = (int) (parentLocation.getX());
+ Point newLocation = new Point(left, top);
+ newLocation.setLocation(left, top);
+ ui.setLocation(newLocation);
+ return;
+ }
+ if (position.equals("top-right")) {
+ int top = (int) (parentLocation.getY());
+ int left = (int) (parentLocation.getX() + parentSize.getWidth());
+ Point newLocation = new Point(left, top);
+ newLocation.setLocation(left, top);
+ ui.setLocation(newLocation);
+ return;
+ }
+ if (position.equals(("center"))) {
+ //TODO
+ }
+ }
+
+ protected void checkInit() throws IllegalStateException {
+ if (factory == null) {
+ throw new IllegalStateException("no factory found in " + this);
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIFactory.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIFactory.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIFactory.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,184 @@
+/**
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codelutin.util.StringUtil;
+
+import javax.swing.event.EventListenerList;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+
+/**
+ * Factory for UI, using a cache and a provider to find ui implementations.
+ *
+ * @author chemit
+ */
+public class UIFactory {
+
+ static protected final Log log = LogFactory.getLog(UIFactory.class);
+
+ private final String applicationName;
+
+ private final DialogUIDef[] defs;
+
+ private final EventListenerList listeners;
+
+ public UIFactory(String applicationName, DialogUIDef[] defs, FactoryWindowListener... listeners) {
+ this.applicationName = applicationName;
+ this.listeners = new EventListenerList();
+ for (FactoryWindowListener listener : listeners) {
+ listener.setFactory(this);
+ addFactoryWindowListener(listener);
+ }
+ this.defs = defs;
+ long t0 = System.nanoTime();
+ if (log.isDebugEnabled()) {
+ log.debug("start at " + new java.util.Date());
+ }
+ try {
+ init();
+ } catch (Exception e) {
+ log.error(e);
+ throw new RuntimeException(e);
+ } finally {
+ if (log.isDebugEnabled()) {
+ log.info("end in " + StringUtil.convertTime(t0, System.nanoTime()));
+ }
+ }
+ }
+
+ public void addFactoryWindowListener(FactoryWindowListener l) {
+ listeners.add(FactoryWindowListener.class, l);
+ if (log.isDebugEnabled()) {
+ log.debug("after added (" + listeners.getListenerCount() + ") : " + l);
+ }
+ }
+
+ public void removeFactoryWindowListener(FactoryWindowListener l) {
+ listeners.remove(FactoryWindowListener.class, l);
+ for (DialogUIDef def : getDefs()) {
+ if (def.uiInstance != null) {
+ def.uiInstance.removeWindowListener(l);
+ }
+ }
+ if (log.isDebugEnabled()) {
+ log.debug(" after removed (" + listeners.getListenerCount() + ") : " + l);
+ }
+ if (listeners.getListenerCount(FactoryWindowListener.class) == 0) {
+ // close for real factory
+ close();
+ }
+ }
+
+ public void close() {
+ log.info(this + " at " + new java.util.Date());
+ for (DialogUIDef<?, ?, ?> def : defs) {
+ DialogUI<?> ui = def.uiInstance;
+ if (ui != null) {
+ ui.getHandler().dispose();
+ def.uiInstance = null;
+ }
+ }
+ if (listeners.getListenerCount(FactoryWindowListener.class) > 0) {
+ log.warn("some listeners where not properly removed, force deletion...");
+ for (FactoryWindowListener listener : listeners.getListeners(FactoryWindowListener.class)) {
+ removeFactoryWindowListener(listener);
+ }
+ }
+
+ }
+
+ protected void init() {
+
+ UIProvider[] providers = detectProviders();
+
+ for (DialogUIDef<?, ?, ?> def : defs) {
+ initDef(providers, def);
+ if (def.getUiImplClass() == null) {
+ throw new IllegalStateException("could not find implementation for ui def " + def);
+ }
+ }
+ }
+
+ protected void initDef(UIProvider[] providers, DialogUIDef<?, ?, ?> def) {
+ for (UIProvider provider : providers) {
+ Class<?> uiImplClass = provider.findUIImplementation(def);
+ if (uiImplClass != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("init done for " + def);
+ }
+ // ui implementation was found
+ break;
+ }
+ }
+ }
+
+ protected UIProvider[] detectProviders() {
+ long t0 = System.nanoTime();
+ List<UIProvider> providers = new ArrayList<UIProvider>();
+ for (UIProvider provider : ServiceLoader.load(UIProvider.class)) {
+ if (applicationName.equals(provider.getApplicationName())) {
+ if (log.isDebugEnabled()) {
+ log.debug("provider detected [" + provider + ']');
+ }
+ providers.add(provider);
+ }
+ }
+ log.info("found " + providers.size() + " ui provider(s) in " + StringUtil.convertTime(t0, System.nanoTime()) + " : " + providers);
+ return providers.toArray(new UIProvider[providers.size()]);
+ }
+
+ protected DialogUIDef[] getDefs() {
+ return defs;
+ }
+
+ @Override
+ protected void finalize() throws Throwable {
+ super.finalize();
+ close();
+ }
+
+ public <M extends DialogUIModel, U extends DialogUI<H>, H extends DialogUIHandler<M, U>> U getUI(DialogUIDef<M, U, H> uiType, Object... params) {
+ U ui = uiType.uiInstance;
+ if (ui == null) {
+ try {
+ ui = uiType.newUI();
+ M model = uiType.newModel();
+ H handler = uiType.newHandler(ui, model, params);
+ registerUI(uiType, ui, handler);
+ } catch (Exception e) {
+ throw new IllegalStateException("could not instanciate ui handler " + uiType + " for reason : " + e.getMessage(), e);
+ }
+ }
+ return ui;
+ }
+
+ protected <M extends DialogUIModel, U extends DialogUI<H>, H extends DialogUIHandler<M, U>> void registerUI(DialogUIDef<M, U, H> uiType, U ui, H handler) {
+ ui.setHandler(handler);
+ handler.init();
+ uiType.setUiInstance(ui);
+ for (FactoryWindowListener listener : listeners.getListeners(FactoryWindowListener.class)) {
+ if (log.isDebugEnabled()) {
+ log.debug("----- addFactoryWindowListener " + listener + " to " + ui);
+ }
+ ui.addWindowListener(listener);
+ }
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIHelper.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIHelper.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIHelper.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,70 @@
+/*
+* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* ##% */
+package org.codelutin.jaxx.util;
+
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JRootPane;
+import javax.swing.KeyStroke;
+import java.awt.event.ActionEvent;
+
+/**
+ * Ui helper class.
+ *
+ * @author tony
+ */
+public class UIHelper {
+
+ public static ImageIcon createImageIcon(String path) {
+ java.net.URL imgURL = UIHelper.class.getResource("/icons/" + path);
+ if (imgURL != null) {
+ return new ImageIcon(imgURL);
+ } else {
+ throw new IllegalArgumentException("could not find icon " + path);
+ }
+ }
+
+ /**
+ * Attach to <code>ui</code> an abort action,accessible by <code>ESC</code> key.
+ *
+ * @param ui ui
+ */
+ public static void setQuitAction(final JDialog ui) {
+ JRootPane rootPane = ui.getRootPane();
+
+ Action quitAction = new AbstractAction("quit") {
+ private static final long serialVersionUID = -869095664995763057L;
+
+ public void actionPerformed(ActionEvent e) {
+ ui.dispose();
+ }
+ };
+ rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke("ESCAPE"), "quit");
+ rootPane.getActionMap().put("quit", quitAction);
+ ui.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
+ }
+
+ public static ImageIcon createActionIcon(String name) {
+ return createImageIcon("action-" + name + ".png");
+ }
+
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIProvider.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIProvider.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/UIProvider.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,86 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util;
+
+/** @author chemit */
+public abstract class UIProvider {
+
+ /** the name of application using this provider */
+ protected String applicationName;
+
+ /** the name of ui implementation used by this provider */
+ protected String providerName;
+
+ /** array of ui implementations */
+ protected Class<?>[] implementations;
+
+ protected UIProvider(String applicationName, String providerName, Class<?>... implementations) {
+ this.applicationName = applicationName;
+ this.providerName = providerName;
+ this.implementations = implementations;
+ }
+
+ public String getProviderName() {
+ return providerName;
+ }
+
+ public String getApplicationName() {
+ return applicationName;
+ }
+
+ public Class<?>[] getImplementations() {
+ return implementations;
+ }
+
+ public Class<?> findUIImplementation(DialogUIDef<?, ?, ?> def) {
+ Class<? extends DialogUI<?>> uiClass = def.getUiClass();
+ for (Class<?> klass : implementations) {
+ if (uiClass.isAssignableFrom(klass)) {
+ def.setUiImplClass(klass);
+ return klass;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder(super.toString()).append('<');
+ sb.append(printClass("application", applicationName, true));
+ sb.append(printClass("provider", providerName, true));
+ sb.append(printClass("uis", implementations.length, false));
+ return sb.toString();
+ }
+
+ protected String printClass(String s, Object aClass, boolean notLast) {
+ return s + ':' + (aClass == null ? null : aClass) + (notLast ? ", " : ">");
+ }
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (!(o instanceof UIProvider)) return false;
+
+ UIProvider that = (UIProvider) o;
+ return applicationName.equals(that.applicationName) && providerName.equals(that.providerName);
+
+ }
+
+ @Override
+ public int hashCode() {
+ return (31 * applicationName.hashCode()) + providerName.hashCode();
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/CancelAction.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/CancelAction.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/CancelAction.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,43 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util.config;
+
+import org.codelutin.jaxx.util.AbstractUIAction;
+import org.codelutin.jaxx.util.DialogUI;
+import org.codelutin.jaxx.util.UIHelper;
+
+import java.awt.event.ActionEvent;
+
+/** @author chemit */
+public class CancelAction<E extends Enum<E>, H extends DialogConfigUIHandler<E, ?, ?>> extends AbstractUIAction<H> {
+ private static final long serialVersionUID = 1L;
+
+ public CancelAction(DialogUI<? extends H> dialogUI, boolean showLabel) {
+ super(null, UIHelper.createActionIcon("cancel-config"), dialogUI);
+ if (showLabel) {
+ String text = org.codelutin.i18n.I18n._("lutinui.config.cancel");
+ putValue(NAME, text);
+ putValue(DISPLAYED_MNEMONIC_INDEX_KEY, 0);
+ putValue(MNEMONIC_KEY, (int) text.charAt(0));
+ }
+ String libelle = org.codelutin.i18n.I18n._("lutinui.config.cancel.tooltip");
+ putValue(SHORT_DESCRIPTION, libelle);
+
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ getUi().dispose();
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUI.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUI.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,105 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util.config;
+
+import org.codelutin.jaxx.util.DialogUI;
+
+import javax.swing.AbstractButton;
+import javax.swing.JCheckBox;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JPasswordField;
+import javax.swing.JRadioButton;
+import javax.swing.JTextField;
+
+/**
+ * A abstract dialog contract to be realised by a dialogUI (WindowEvent adapter)
+ * <p/>
+ * TODO : make jaxx authorized implementing interface for root tag :)
+ *
+ * @author chemit
+ */
+public abstract class DialogConfigUI<E extends Enum<E>, H extends DialogConfigUIHandler<E, ?, ?>> extends DialogUI<H> {
+
+ public abstract AbstractButton getOk();
+
+ public abstract AbstractButton getReset();
+
+ public abstract AbstractButton getCancel();
+
+ public JComponent getElement(E key) {
+ Object id = getObjectById(key.name());
+ if (id == null) {
+ log.error(new NullPointerException("no widget for key "+key));
+ return null;
+ }
+ if (!(id instanceof JComponent)) {
+ throw new IllegalArgumentException(id + " is not a JComponent");
+ }
+ return (JComponent) id;
+ }
+
+ public Object getElementValue(E key) {
+ JComponent o = getElement(key);
+ if (o instanceof JPasswordField) {
+ return new String(((JPasswordField) o).getPassword());
+ }
+ if (o instanceof JTextField) {
+ return ((JTextField) o).getText();
+ }
+ if (o instanceof JRadioButton) {
+ return ((JRadioButton) o).isSelected();
+ }
+ if (o instanceof JCheckBox) {
+ return ((JCheckBox) o).isSelected();
+ }
+
+ if (o instanceof JComboBox) {
+ return ((JComboBox) o).getSelectedItem();
+ }
+ return "";
+ }
+
+ public void setElementValue(E key, Object value) {
+ JComponent o = getElement(key);
+
+ String strValue = value == null ? "" : String.valueOf(value);
+ if (o instanceof JPasswordField) {
+ ((JPasswordField) o).setText(strValue);
+ }
+ if (o instanceof JTextField) {
+ ((JTextField) o).setText(strValue);
+ }
+ if (o instanceof JRadioButton) {
+ ((JRadioButton) o).setSelected(Boolean.valueOf(strValue.isEmpty() ? "false" : strValue));
+ }
+ if (o instanceof JCheckBox) {
+ ((JCheckBox) o).setSelected(Boolean.valueOf(strValue.isEmpty() ? "false" : strValue));
+ }
+ if (o instanceof JComboBox) {
+ ((JComboBox) o).setSelectedItem(value);
+ }
+ }
+
+ public JLabel getElementLabel(E key) {
+ return (JLabel) getObjectById(key.name() + "Label");
+ }
+
+ public void doCheck(E key) {
+ getHandler().doCheck(key);
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUIHandler.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUIHandler.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUIHandler.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,156 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util.config;
+
+import org.codelutin.jaxx.util.DialogUIHandler;
+import org.codelutin.util.ConverterUtil;
+import org.codelutin.util.config.Config;
+import org.codelutin.util.config.Property;
+
+import javax.swing.JComponent;
+import java.awt.Color;
+import java.beans.PropertyChangeEvent;
+import java.util.EnumMap;
+import java.util.EnumSet;
+
+/**
+ * DialogUI handler
+ *
+ * @author chemit
+ */
+public abstract class DialogConfigUIHandler<E extends Enum<E>, M extends DialogConfigUIModel<E, ?>, U extends DialogConfigUI<E, ?>> extends DialogUIHandler<M, U> {
+
+ protected DialogConfigUIHandler(U ui, M model) {
+ super(ui, model);
+ }
+
+ public void propertyChange(PropertyChangeEvent evt) {
+ if (log.isDebugEnabled()) {
+ log.debug(evt.getPropertyName() + " old:" + evt.getOldValue() + ", new:" + evt.getNewValue());
+ }
+ String action = evt.getPropertyName();
+
+ if (DialogConfigUIModel.CONFIG_PROPERTY_CHANGED.equals(action)) {
+ // update ui with model values,
+ populateUI();
+ // revalidate form
+ doCheckAll();
+ return;
+ }
+
+ if (DialogConfigUIModel.MODIFIED_PROPERTY_CHANGED.equals(action)) {
+ Boolean newValue = (Boolean) evt.getNewValue();
+ boolean modified = newValue != null && newValue;
+ getUi().getReset().setEnabled(modified);
+ getUi().getOk().setEnabled(modified && getModel().isConfigValid());
+ return;
+ }
+
+ if (DialogConfigUIModel.UNVALID_PROPERTY_CHANGED.equals(action)) {
+ updateUI();
+ return;
+ }
+
+ throw new IllegalStateException("unimplemented property changed : " + evt + " for " + this);
+ }
+
+ public void doCheck(E key) {
+ Object uiValue = getUi().getElementValue(key);
+ DialogConfigUIModel<E, ?> model = getModel();
+ Object currentValue = model.getCurrent().getProperty(key);
+ if (currentValue == null) {
+ currentValue = "";
+ } else {
+ currentValue = String.valueOf(currentValue);
+ }
+
+ model.validateProperty(key, uiValue);
+ model.changeModifiedState(key, uiValue, currentValue);
+ }
+
+ public void doCheckAll() {
+ DialogConfigUIModel<E, ?> model = getModel();
+ EnumSet<E> unvalids = EnumSet.noneOf(model.klass);
+ for (E e : model.getCheckedKeysSet()) {
+ Object uiValue = getUi().getElementValue(e);
+ if (!model.isValid(e, uiValue)) {
+ unvalids.add(e);
+ }
+ }
+ model.setUnvalids(unvalids);
+ unvalids.clear();
+ }
+
+ protected boolean prepareSave() {
+ DialogConfigUI<E, ?> ui = getUi();
+ DialogConfigUIModel<E, ?> model = getModel();
+
+ Config<E> current = model.getCurrent();
+
+ if (!model.isConfigValid()) {
+ log.warn("do not save a unvalid config : " + model.getUnvalids());
+ return false;
+ }
+
+ if (!model.isModified()) {
+ log.warn("nothing to save");
+ return false;
+ }
+ EnumSet<E> toTreate = model.getCheckedKeysSet();
+ // transfert checkable values from ui to model
+ for (E key : model.getModifieds()) {
+ if (!toTreate.contains(key)) {
+ continue;
+ }
+ Object value = ui.getElementValue(key);
+ Class<?> type = ((Property) key).getType();
+ Object newValue = ConverterUtil.convert(type, value);
+ current.setProperty(key, newValue);
+ }
+
+ return true;
+ }
+
+ protected void populateUI() {
+ U ui = getUi();
+ EnumMap<E, Object> map = getModel().getCurrent().getProperties();
+ for (E e : getModel().getCheckedKeysSet()) {
+ Object value = map.get(e);
+ populateUI(ui, e, value);
+ }
+ }
+
+ protected void populateUI(U ui, E key, Object value) {
+ ui.setElementValue(key, value);
+ }
+
+ protected void updateUI() {
+ EnumSet<E> unvalids = getModel().getUnvalids();
+ for (E key : unvalids) {
+ setLabelColor(key, false);
+ }
+ for (E key : EnumSet.complementOf(unvalids)) {
+ setLabelColor(key, true);
+ }
+ }
+
+ protected void setLabelColor(E key, boolean valid) {
+ JComponent component = getUi().getElementLabel(key);
+ if (component != null && component.isVisible()) {
+ component.setForeground(valid ? Color.black : Color.red);
+ }
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUIModel.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUIModel.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/DialogConfigUIModel.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,220 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util.config;
+
+import org.codelutin.jaxx.util.DialogUIModel;
+import org.codelutin.util.config.Config;
+
+import java.util.EnumSet;
+
+/**
+ * Abstract config ui model.
+ *
+ * @author chemit
+ */
+public abstract class DialogConfigUIModel<E extends Enum<E>, C extends Config<E>> extends DialogUIModel {
+
+ public static final String CONFIG_PROPERTY_CHANGED = "config";
+ public static final String MODIFIED_PROPERTY_CHANGED = "modify";
+ public static final String UNVALID_PROPERTY_CHANGED = "unvalid";
+
+ /** @return a empty config */
+ protected abstract C newConfig();
+
+ /**
+ * @param key property key
+ * @param value value to validate
+ * @return <code>true</code> if given value is valid for property, <code>false>/code> otherwise
+ */
+ protected abstract boolean isValid(E key, Object value);
+
+ /**
+ * object used to init model and save model, this is an external object.
+ * <p/>
+ * The object must have bean read-write properties for each value of E
+ */
+ protected Object src;
+
+ /** current config used in model */
+ protected C current;
+
+ /** set of modified properties */
+ protected EnumSet<E> modifieds;
+
+ /** set of unvalid properties */
+ protected EnumSet<E> unvalids;
+
+ /** enum class */
+ protected Class<E> klass;
+
+ /** set of key not to check */
+ protected EnumSet<E> uncheckedKeys;
+
+ /** set of all keys checkable */
+ protected EnumSet<E> checkedKeysSet;
+
+ protected DialogConfigUIModel(Class<E> klass) {
+ this.klass = klass;
+ this.current = newConfig();
+ this.modifieds = EnumSet.noneOf(klass);
+ this.unvalids = EnumSet.noneOf(klass);
+ }
+
+ public EnumSet<E> getCheckedKeysSet() {
+ if (checkedKeysSet == null) {
+ if (uncheckedKeys != null) {
+ checkedKeysSet = EnumSet.complementOf(uncheckedKeys);
+ } else {
+ checkedKeysSet = EnumSet.allOf(klass);
+ }
+ }
+ return checkedKeysSet;
+ }
+
+ public Object getSrc() {
+ return src;
+ }
+
+ public C getCurrent() {
+ return current;
+ }
+
+ public EnumSet<E> getUnivserse() {
+ return getCurrent().getUniverse();
+ }
+
+ public EnumSet<E> getModifieds() {
+ return modifieds;
+ }
+
+ public EnumSet<E> getUnvalids() {
+ return unvalids;
+ }
+
+ public boolean isModified() {
+ return !modifieds.isEmpty();
+ }
+
+ public boolean isConfigValid() {
+ return unvalids.isEmpty();
+ }
+
+ public void populate(Object src) {
+ this.src = src;
+ this.current = newConfig();
+ if (src != null) {
+ this.current.copyFrom(src);
+ }
+ this.modifieds.clear();
+ this.unvalids.clear();
+ setModified(false);
+ firePropertyChange(CONFIG_PROPERTY_CHANGED, null, this);
+ }
+
+ public void reset() {
+ populate(src);
+ }
+
+ public void setModified(boolean modified) {
+ firePropertyChange(MODIFIED_PROPERTY_CHANGED, null, modified);
+ }
+
+ public void setUnvalid(boolean unvalid) {
+ firePropertyChange(UNVALID_PROPERTY_CHANGED, null, unvalid);
+ }
+
+ public void addModified(E key) {
+ if (!modifieds.contains(key)) {
+ modifieds.add(key);
+ log.debug(key);
+ }
+ setModified(!modifieds.isEmpty());
+ }
+
+ public void removeModified(E key) {
+
+ if (modifieds.contains(key)) {
+ modifieds.remove(key);
+ }
+ setModified(!modifieds.isEmpty());
+ }
+
+ public void removeModified(EnumSet<E> keys) {
+ for (E key : keys) {
+ if (modifieds.contains(key)) {
+ modifieds.remove(key);
+ }
+ }
+ setModified(!modifieds.isEmpty());
+ }
+
+ public void setUnvalids(EnumSet<E> keys) {
+ for (E key : keys) {
+ if (!unvalids.contains(key)) {
+ unvalids.add(key);
+ }
+ }
+ for (E key : EnumSet.complementOf(keys)) {
+ if (unvalids.contains(key)) {
+ unvalids.remove(key);
+ }
+ }
+ setUnvalid(!unvalids.isEmpty());
+ }
+
+
+ public void addUnvalid(E key) {
+ if (!unvalids.contains(key)) {
+ unvalids.add(key);
+ }
+ setUnvalid(!unvalids.isEmpty());
+ }
+
+ public void removeUnvalid(E key) {
+ if (unvalids.contains(key)) {
+ unvalids.remove(key);
+ }
+ setUnvalid(!unvalids.isEmpty());
+ }
+
+ public void save() {
+ current.copyTo(src, modifieds);
+ modifieds.clear();
+ // redisplay config
+ firePropertyChange(CONFIG_PROPERTY_CHANGED, null, this);
+ }
+
+ public void changeModifiedState(E key, Object uiValue, Object currentValue) {
+ if (uiValue!=null && uiValue.equals(currentValue)) {
+ removeModified(key);
+ } else {
+ addModified(key);
+ }
+ }
+
+ public void clear(E key) {
+ log.info(key);
+ modifieds.remove(key);
+ unvalids.remove(key);
+ }
+
+ protected void validateProperty(E key, Object uiValue) {
+ if (isValid(key, uiValue)) {
+ removeUnvalid(key);
+ } else {
+ addUnvalid(key);
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/ResetAction.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/ResetAction.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/ResetAction.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,43 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util.config;
+
+import org.codelutin.jaxx.util.AbstractUIAction;
+import org.codelutin.jaxx.util.DialogUI;
+import org.codelutin.jaxx.util.UIHelper;
+
+import java.awt.event.ActionEvent;
+
+/** @author chemit */
+public class ResetAction<E extends Enum<E>, H extends DialogConfigUIHandler<E, ?, ?>> extends AbstractUIAction<H> {
+ private static final long serialVersionUID = 1L;
+
+ public ResetAction(DialogUI<? extends H> dialogUI, boolean showLabel) {
+ super(null, UIHelper.createActionIcon("reset-config"), dialogUI);
+ if (showLabel) {
+ String text = org.codelutin.i18n.I18n._("lutinui.config.reset");
+ putValue(NAME, text);
+ putValue(DISPLAYED_MNEMONIC_INDEX_KEY, 0);
+ putValue(MNEMONIC_KEY, (int) text.charAt(0));
+ }
+ String libelle = org.codelutin.i18n.I18n._("lutinui.config.reset.tooltip");
+ putValue(SHORT_DESCRIPTION, libelle);
+
+ }
+
+ public void actionPerformed(ActionEvent e) {
+ getHandler().getModel().reset();
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/SaveAction.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/SaveAction.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/java/org/codelutin/jaxx/util/config/SaveAction.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,50 @@
+/**
+ * ##% Copyright (C) 2008 Code Lutin, Tony Chemit
+ * This program is free software; you
+ * can redistribute it and/or modify it under the terms of the GNU General
+ * Public License as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. This program is
+ * distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+ * PARTICULAR PURPOSE. See the GNU General Public License for more details. You
+ * should have received a copy of the GNU General Public License along with this
+ * program; if not, write to the Free Software Foundation, Inc., 59 Temple Place
+ * - Suite 330, Boston, MA 02111-1307, USA.
+ * ##%
+ */
+package org.codelutin.jaxx.util.config;
+
+import org.codelutin.jaxx.util.AbstractUIAction;
+import org.codelutin.jaxx.util.DialogUI;
+import org.codelutin.jaxx.util.UIHelper;
+
+import java.awt.event.ActionEvent;
+
+/** @author chemit */
+public class SaveAction<E extends Enum<E>, H extends DialogConfigUIHandler<E, ?, ?>> extends AbstractUIAction<H> {
+ private static final long serialVersionUID = 1L;
+
+ public SaveAction(DialogUI<? extends H> dialogUI, boolean showLabel) {
+ super(null, UIHelper.createActionIcon("save-config"), dialogUI);
+ if (showLabel) {
+ String text = org.codelutin.i18n.I18n._("lutinui.config.save");
+ putValue(NAME, text);
+ putValue(DISPLAYED_MNEMONIC_INDEX_KEY, 0);
+ putValue(MNEMONIC_KEY, (int) text.charAt(0));
+ }
+ String libelle = org.codelutin.i18n.I18n._("lutinui.config.save.tooltip");
+ putValue(SHORT_DESCRIPTION, libelle);
+ }
+
+ public void actionPerformed(ActionEvent e) {
+
+ if (getHandler().prepareSave()) {
+
+ // save model to src
+ getHandler().getModel().save();
+
+ // close ui
+ getUi().dispose();
+ }
+ }
+}
Added: jaxx/trunk/jaxx-gwt-action/src/main/resources/META-INF/services/javax.annotation.processing.Processor
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/resources/META-INF/services/javax.annotation.processing.Processor (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/resources/META-INF/services/javax.annotation.processing.Processor 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1 @@
+org.codelutin.jaxx.action.ActionAnnotationProcessing
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-gwt-action-en_GB.properties
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-gwt-action-en_GB.properties (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-gwt-action-en_GB.properties 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,10 @@
+jaxx.action.done=jaxx.action.done
+jaxx.error.close.actions.file=jaxx.error.close.actions.file
+jaxx.error.load.actions.class=jaxx.error.load.actions.class
+jaxx.error.load.actions.file=jaxx.error.load.actions.file
+lutinui.config.cancel=lutinui.config.cancel
+lutinui.config.cancel.tooltip=lutinui.config.cancel.tooltip
+lutinui.config.reset=lutinui.config.reset
+lutinui.config.reset.tooltip=lutinui.config.reset.tooltip
+lutinui.config.save=lutinui.config.save
+lutinui.config.save.tooltip=lutinui.config.save.tooltip
Added: jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-gwt-action-fr_FR.properties
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-gwt-action-fr_FR.properties (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-gwt-action-fr_FR.properties 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,10 @@
+jaxx.action.done=
+jaxx.error.close.actions.file=
+jaxx.error.load.actions.class=
+jaxx.error.load.actions.file=
+lutinui.config.cancel=
+lutinui.config.cancel.tooltip=
+lutinui.config.reset=
+lutinui.config.reset.tooltip=
+lutinui.config.save=
+lutinui.config.save.tooltip=
Added: jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-swing-action-en_GB.properties
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-swing-action-en_GB.properties (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-swing-action-en_GB.properties 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,10 @@
+jaxx.action.done=Action '%1$s' done.
+jaxx.error.close.actions.file=Error while closing file of actions
+jaxx.error.load.actions.class=Error while loading actions
+jaxx.error.load.actions.file=Error while loading file of actions
+lutinui.config.cancel=Cancel
+lutinui.config.cancel.tooltip=Cancel and quit
+lutinui.config.reset=Reset
+lutinui.config.reset.tooltip=Reset configuration
+lutinui.config.save=Save
+lutinui.config.save.tooltip=Save configuration and quit
Added: jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-swing-action-fr_FR.properties
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-swing-action-fr_FR.properties (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/main/resources/i18n/jaxx-swing-action-fr_FR.properties 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,10 @@
+jaxx.action.done=Action '%1$s' termin\u00E9e.
+jaxx.error.close.actions.file=Erreur lors de la fermeture du fichier d'actions
+jaxx.error.load.actions.class=Erreur lors du chargement des actions
+jaxx.error.load.actions.file=Erreur lors du chargement du fchier d'actions
+lutinui.config.cancel=Annuler
+lutinui.config.cancel.tooltip=Annuler les modification et quitter
+lutinui.config.reset=R\u00E9initialiser
+lutinui.config.reset.tooltip=R\u00E9initialiser la configuration
+lutinui.config.save=Sauver
+lutinui.config.save.tooltip=Sauver la configuration et quitter
Added: jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/Todo.rst
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/Todo.rst (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/Todo.rst 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,4 @@
+TODO
+====
+
+a faire
\ No newline at end of file
Added: jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/index.rst
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/index.rst (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/site/fr/rst/index.rst 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,13 @@
+jaxx-swing-action
+=================
+
+.. contents::
+
+
+Présentation
+------------
+
+Framework de gestion des actions et onglets TODO
+
+**Veuillez consulter la JavaDoc pour de plus ample détails sur les différentes
+librairies.**
Added: jaxx/trunk/jaxx-gwt-action/src/test/java/jaxx/runtime/UtilTest.java
===================================================================
--- jaxx/trunk/jaxx-gwt-action/src/test/java/jaxx/runtime/UtilTest.java (rev 0)
+++ jaxx/trunk/jaxx-gwt-action/src/test/java/jaxx/runtime/UtilTest.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,25 @@
+package jaxx.runtime;
+
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+
+public class UtilTest extends junit.framework.TestCase {
+ private int count;
+
+
+ public void testGetEventListener() {
+ count = 0;
+ DocumentListener listener = (DocumentListener) jaxx.runtime.Util.getEventListener(javax.swing.event.DocumentListener.class, this, "incCount");
+ listener.insertUpdate(null);
+ assertEquals(count, 1);
+ DocumentListener listener2 = (DocumentListener) jaxx.runtime.Util.getEventListener(javax.swing.event.DocumentListener.class, this, "incCount");
+ listener2.removeUpdate(null);
+ assertEquals(count, 2);
+ //assertTrue("Received two different event listeners despite using identical parameters", listener == listener2);
+ }
+
+
+ public void incCount(DocumentEvent e) {
+ count++;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/.classpath
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/.classpath (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/.classpath 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,20 @@
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/main/resources" including="**/*" excluding="**/*~|**/*.java"/>
+ <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+ <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+ <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/commons-beanutils/commons-beanutils/1.8.0/commons-beanutils-1.8.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-jxpath/commons-jxpath/1.3/commons-jxpath-1.3.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.4/commons-lang-2.4.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-primitives/commons-primitives/1.0/commons-primitives-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/javax/help/javahelp/2.0.02/javahelp-2.0.02.jar"/>
+ <classpathentry kind="src" path="/jaxx-runtime-api"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/4.5/junit-4.5.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/swinglabs/jxlayer/3.0.1/jxlayer-3.0.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/codelutin/lutinutil/1.0.3/lutinutil-1.0.3.jar"/>
+</classpath>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/.project
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/.project (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/.project 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,15 @@
+<projectDescription>
+ <name>jaxx-runtime-gwt</name>
+ <comment>Jaxx runtime gwt extension</comment>
+ <projects>
+ <project>jaxx-runtime-api</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/.settings/org.eclipse.jdt.core.prefs 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,5 @@
+#Mon Mar 30 12:41:55 CEST 2009
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
Added: jaxx/trunk/jaxx-runtime-gwt/LICENSE.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/LICENSE.txt (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/LICENSE.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,166 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
Added: jaxx/trunk/jaxx-runtime-gwt/README.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/README.txt (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/README.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,2 @@
+To deploy new version of pom: mvn deploy
+To install localy: mvn install
Added: jaxx/trunk/jaxx-runtime-gwt/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/changelog.txt (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/changelog.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,110 @@
+1.3 chemit 20090321
+ * 20090327 [chemit] - add javax help mecanism
+ * 20090318 [chemit] - introduce the BlockingLayerUI2 class (should be merge with BlockingLayerUI)
+ * 20090318 [chemit] - introduce the CardLayout2Ext class
+ * 20090312 [chemit] - add some usefull code from ObServe (load Nimbus L&F, load ui configuration)
+ * 20090309 [chemit] - in BlockingLayerUI, add a new state 'block' to enable/disable blocking mode with a blockingColor
+ * 20090303 [chemit] - in BlockingLayerUI, add a new state 'useIcon' to enable/disable use of the action icon
+ - add a simple WizardModel
+ * 20090301 [chemit] - add usefull methods in JAXXButtonGroup
+
+1.2 letellier 2009022?
+ * 20090223 [chemit] - rename jaxx.runtime.swing.Utils to jaxx.runtime.SwingUtil
+
+1.1 chemit 20090220
+ * 20090124 [chemit] - add a cache on context path to improve performance on NavigationTreeNode
+ - improve I18nTableCellRenderer to display toolTipText
+ * 20090123 [chemit] - improve NavigationTreeNodeRenderer (now can customized node internalClass)
+ * 20090121 [letellier] - add some usefull methods in JAXXList and JAXXComboBox
+
+1.0 chemit 20090111
+ * 20090111 [chemit] - integrate new architecture to allow to have runtime code with NO link with compiler :)
+ * 20090105 [chemit] - improve CardLayout2
+0.8 ??? 200812??
+ * 20081228 [chemit] - generify ClassDescriptor
+ - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from
+ JAXXCompiler and make possible to extract compiler engine from runtime
+
+ * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation
+ * 20081218 [chemit] - improve generation of methods
+ * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##)
+ - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option)
+ - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection
+ - add addSourcesToClassPath property to add sources directories in class-path
+ - improve classloader managment
+ - keep in DataSource objetCode
+ - fix bug when processDataBinding on a null objectCode
+ - always clean node cached values when selected it
+ - add usefull databinding method in Util
+
+* 20081213 [chemit] - improve navigation tree node rendering with some caches
+ - introduce a ChildBuilder to simplify building of child nodes from a collection or array
+
+0.7 chemit 20081210
+* 20081210 [chemit] - fix bug 1751
+* 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism)
+* 20081208 [chemit] - javabBean attribute use to initialize bean
+ - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment)
+ - introduce MultiJXPathDecorator
+ - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers
+
+ * 20081207 [chemit] use lutinproject 3.1
+ - can exclude field from validator
+ * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter
+ - fix bug when searching for a inner class
+
+ * 20081201 [chemit] - implements jaxx.runtime.JXPathDecorator
+ - add setcontextValue and removeContextValue on JAXXContextEntryDef
+ - introduce scope in BeanValidator (ERROR or WARNING) and related swing stuff
+ - only enter once in $initialize method in generated code
+
+ 0.6 chemit 20081117
+ * 20081118 [chemit] introduce NavigationUtil, save in context selected node
+ * 20081107 [chemit] improve data binding and code generation :
+ - make possible inheritance in binding
+ - add an attribute javaBean to an object : will generate a full java bean support property
+ - make possible binding to the javaBean added properties
+ - clean generated code
+
+ * 20081105 [chemit] - introduce a CardLayout2 to extends awt CardLayout
+ - introduce a NavigationTreeModel
+ - introduce a Decorator to render Object
+ - propagate constructor JAXXContext(JAXXContext) in JAXXObject generation
+ - begin of rst documentation
+
+ * 20081104 [chemit] can add extra beanInfoSearchPath in SwingInitializer
+ * 20081104 [chemit] add jaxxContextImplementorClass in option to make possible use of other JAXXContext implementor.
+ * 20081102 [chemit] improve JAXXContext :
+ - introduce a JAXXContextEntryDef to qualify an entry of a JAXXContext
+ - do javadoc in JAXXContext
+ - add logic in DefaultJAXXContext : seek in parent context if entry not found
+ * 20081102 [chemit] improve tests :
+ - fix the last failed test from Jaxx original version :)
+ - dumps tests to JUnit4 :)
+ * 20081030 [chemit] improve BeanValidator :
+ - add full PropertyChangeEvent java-bean support and a property valid
+ - when remove bean from validator, must remove errors from model
+ - make possible to have a dynamic errorListModel in jaxx files
+ * 20081030 [chemit] improve JAXXContext :
+ - fix setContextValue bug when setting twice a same type for a same key
+ - implements a DefaultJAXXContext
+ - use this default implementation with delegate pattern in JAXXObject
+ * 20081030 [chemit] add JAXXAction contract to simplify init of ui with JAXXInitialContext
+ * 20081027 [chemit] fix bug 1722
+ * 20081027 [chemit] add conversion support in validator
+ * 20081025 [chemit] improve BeanValidator tag :
+ - add a errorList attribute for set a ErrorListMouseListener on the errorList
+ - add a beanInitializer attribute for set the validator's bean at runtime
+ - add a default errorListModel value 'errors'
+ * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method
+ * 20081024 [chemit] fix validator context lost if UI is launched from another thread
+ ver-0-5 chemit 20081002
+ * 20081017 [chemit] add validator support
+ * 20081013 [chemit] can generate logger on jaxx files
+ * 20081011 [chemit] improve site
+ * 20081011 [chemit] fix bug on JavaFileParser : works again
+ * 20081002 [chemit] Using lutinproject 3.0, changing groupId to org.codelutin
+ * 20081002 [chemit] use a single module jaxx-core (no more core, runtime and jaxx-swing modules)
+ * 20081002 [chemit] Introduce JAXXContext
+ * 20081002 [chemit] Fix bug on method creation via scripting
+ * 20081002 [chemit] Improve i18n integration (works now also for tabs)
Added: jaxx/trunk/jaxx-runtime-gwt/pom.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/pom.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/pom.xml 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,108 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- ************************************************************* -->
+ <!-- *** POM Relationships *************************************** -->
+ <!-- ************************************************************* -->
+
+ <parent>
+ <groupId>org.codelutin</groupId>
+ <artifactId>jaxx</artifactId>
+ <version>1.3-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.codelutin.jaxx</groupId>
+ <artifactId>jaxx-runtime-gwt</artifactId>
+
+ <repositories>
+ <repository>
+ <id>gwt-maven</id>
+ <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+
+ <!-- sibling dependencies -->
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-api</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- GWT Dependencies -->
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-servlet</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-user</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}-libs</classifier>
+ <type>zip</type>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}</classifier>
+ <scope>provided</scope>
+ </dependency>
+
+
+ </dependencies>
+
+ <!-- ************************************************************* -->
+ <!-- *** Project Information ************************************* -->
+ <!-- ************************************************************* -->
+
+ <name>${project.artifactId}</name>
+ <description>Jaxx runtime gwt extension</description>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Settings ****************************************** -->
+ <!-- ************************************************************* -->
+ <packaging>jar</packaging>
+
+ <properties>
+
+ <gwtVersion>1.5.3</gwtVersion>
+
+ </properties>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Environment ************************************** -->
+ <!-- ************************************************************* -->
+ <scm>
+ <url>http://labs.libre-entreprise.org/plugins/scmsvn/viewcvs.php/jaxx/trunk/jaxx…</url>
+ <connection>scm:svn:svn://anonymous@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-runtime-gwt</connection>
+ <developerConnection>scm:svn:svn+ssh://sletellier@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-runtime-gwt</developerConnection>
+ </scm>
+
+ <profiles>
+ <profile>
+ <id>gwt-dev-linux</id>
+ <properties>
+ <platform>linux</platform>
+ </properties>
+ <activation>
+ <os>
+ <name>Linux</name>
+ </os>
+ </activation>
+ </profile>
+ </profiles>
+</project>
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.beaninfos;
+
+import jaxx.runtime.gwt.HBox;
+
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.beans.SimpleBeanInfo;
+
+public class HBoxBeanInfo extends SimpleBeanInfo {
+ public BeanInfo[] getAdditionalBeanInfo() {
+ try {
+ return new BeanInfo[]{Introspector.getBeanInfo(JPanel.class)};
+ }
+ catch (IntrospectionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ public PropertyDescriptor[] getPropertyDescriptors() {
+ try {
+ PropertyDescriptor spacing = new PropertyDescriptor("spacing", HBox.class);
+ spacing.setBound(true);
+
+ PropertyDescriptor margin = new PropertyDescriptor("margin", HBox.class);
+ margin.setBound(true);
+
+ PropertyDescriptor horizontalAlignment = new PropertyDescriptor("horizontalAlignment", HBox.class);
+ horizontalAlignment.setBound(true);
+ horizontalAlignment.setValue("enumerationValues", new Object[]{
+ "left", SwingConstants.LEFT, "SwingConstants.LEFT",
+ "center", SwingConstants.CENTER, "SwingConstants.CENTER",
+ "right", SwingConstants.RIGHT, "SwingConstants.RIGHT"
+ });
+
+ PropertyDescriptor verticalAlignment = new PropertyDescriptor("verticalAlignment", HBox.class);
+ verticalAlignment.setBound(true);
+ verticalAlignment.setValue("enumerationValues", new Object[]{
+ "top", SwingConstants.TOP, "SwingConstants.TOP",
+ "middle", SwingConstants.CENTER, "SwingConstants.CENTER",
+ "bottom", SwingConstants.BOTTOM, "SwingConstants.BOTTOM"
+ });
+
+ return new PropertyDescriptor[]{spacing, margin, horizontalAlignment, verticalAlignment};
+ }
+ catch (IntrospectionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.beaninfos;
+
+import jaxx.runtime.gwt.VBox;
+
+import javax.swing.JPanel;
+import javax.swing.SwingConstants;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.beans.SimpleBeanInfo;
+
+public class VBoxBeanInfo extends SimpleBeanInfo {
+ public BeanInfo[] getAdditionalBeanInfo() {
+ try {
+ return new BeanInfo[]{Introspector.getBeanInfo(JPanel.class)};
+ }
+ catch (IntrospectionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ public PropertyDescriptor[] getPropertyDescriptors() {
+ try {
+ PropertyDescriptor spacing = new PropertyDescriptor("spacing", VBox.class);
+ spacing.setBound(true);
+
+ PropertyDescriptor margin = new PropertyDescriptor("margin", VBox.class);
+ margin.setBound(true);
+
+ PropertyDescriptor horizontalAlignment = new PropertyDescriptor("horizontalAlignment", VBox.class);
+ horizontalAlignment.setBound(true);
+ horizontalAlignment.setValue("enumerationValues", new Object[]{
+ "left", SwingConstants.LEFT, "SwingConstants.LEFT",
+ "center", SwingConstants.CENTER, "SwingConstants.CENTER",
+ "right", SwingConstants.RIGHT, "SwingConstants.RIGHT"
+ });
+
+ PropertyDescriptor verticalAlignment = new PropertyDescriptor("verticalAlignment", VBox.class);
+ verticalAlignment.setBound(true);
+ verticalAlignment.setValue("enumerationValues", new Object[]{
+ "top", SwingConstants.TOP, "SwingConstants.TOP",
+ "middle", SwingConstants.CENTER, "SwingConstants.CENTER",
+ "bottom", SwingConstants.BOTTOM, "SwingConstants.BOTTOM"
+ });
+
+ return new PropertyDescriptor[]{spacing, margin, horizontalAlignment, verticalAlignment};
+ }
+ catch (IntrospectionException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/GWTUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/GWTUtil.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/GWTUtil.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,484 @@
+package jaxx.runtime;
+
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Rectangle;
+import java.beans.BeanInfo;
+import java.beans.IntrospectionException;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import javax.swing.DefaultComboBoxModel;
+import javax.swing.JComboBox;
+import javax.swing.JTable;
+import javax.swing.SwingUtilities;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import javax.swing.text.AbstractDocument;
+import javax.swing.text.JTextComponent;
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.NoSuchElementException;
+import java.util.Properties;
+import javax.swing.Icon;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import javax.swing.JLabel;
+import javax.swing.JTabbedPane;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+
+import jaxx.runtime.gwt.I18nTableCellRenderer;
+import jaxx.runtime.gwt.Item;
+import jaxx.runtime.gwt.JAXXComboBox;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jdesktop.jxlayer.JXLayer;
+
+/**
+ * The runtime swing util class with some nice stuff.
+ *
+ * Note : Replace previous class jaxx.runtime.swing.Utils in previous versions.
+ *
+ * @author tony
+ * @since 1.2
+ */
+public class GWTUtil extends Util {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(GWTUtil.class);
+ private static Field numReaders;
+ private static Field notifyingListeners;
+ public static final String ICON_PREFIX = "icon.";
+ public static final String COLOR_PREFIX = "color.";
+
+ public static void setText(final JTextComponent c, final String text) {
+ try {
+ // AbstractDocument deadlocks if we try to acquire a write lock while a read lock is held by the current thread
+ // If there are any readers, dispatch an invokeLater. This should only happen in the event of circular bindings.
+ // Similarly, circular bindings can result in an "Attempt to mutate in notification" error, which we deal with
+ // by checking for the 'notifyingListeners' property.
+ AbstractDocument document = (AbstractDocument) c.getDocument();
+ if (numReaders == null) {
+ numReaders = AbstractDocument.class.getDeclaredField("numReaders");
+ numReaders.setAccessible(true);
+ }
+ if (notifyingListeners == null) {
+ notifyingListeners = AbstractDocument.class.getDeclaredField("notifyingListeners");
+ notifyingListeners.setAccessible(true);
+ }
+
+ if (notifyingListeners.get(document).equals(Boolean.TRUE)) {
+ return;
+ }
+
+ if ((Integer) numReaders.get(document) > 0) {
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ if (!c.getText().equals(text)) {
+ c.setText(text);
+ }
+ }
+ });
+ return;
+ }
+
+ String oldText = c.getText();
+ if (oldText == null || !oldText.equals(text)) {
+ c.setText(text);
+ }
+ } catch (NoSuchFieldException e) {
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ } catch (SecurityException e) {
+ c.setText(text);
+ }
+ }
+
+ /**
+ * Fill a combo box model with some datas, and select after all the given object
+ *
+ * @param combo the combo to fill
+ * @param data data ot inject in combo
+ * @param select the object to select in combo after reflling his model
+ */
+ public static void fillComboBox(JComboBox combo, Collection<?> data, Object select) {
+ if (!(combo.getModel() instanceof DefaultComboBoxModel)) {
+ throw new IllegalArgumentException("this method need a DefaultComboBoxModel for this model but was " + combo.getModel().getClass());
+ }
+ DefaultComboBoxModel model = (DefaultComboBoxModel) combo.getModel();
+ // evince the model
+ model.removeListDataListener(combo);
+ model.removeAllElements();
+ for (Object o : data) {
+ model.addElement(o);
+ }
+ // attach the model
+ model.addListDataListener(combo);
+ model.setSelectedItem(select);
+ }
+
+ /**
+ * Fill a combo box model with some datas, and select after all the given object
+ *
+ * @param combo the combo to fill
+ * @param data data ot inject in combo
+ * @param select the object to select in combo after reflling his model
+ * @param firstNull add a first null element
+ */
+ public static void fillComboBox(JAXXComboBox combo, Collection<?> data, Object select, boolean firstNull) {
+ List<Item> items = new ArrayList<Item>();
+ if (firstNull) {
+ items.add(new Item("null", " ", null, false));
+ }
+ for (Object d : data) {
+ items.add(new Item(d.toString(), d.toString(), d, d.equals(select)));
+ }
+ combo.setItems(items);
+ }
+
+ public static void fixTableColumnWidth(JTable table, int columnIndex, int width) {
+ TableColumn column = table.getColumnModel().getColumn(columnIndex);
+ column.setMaxWidth(width);
+ column.setMinWidth(width);
+ column.setWidth(width);
+ column.setPreferredWidth(width);
+ }
+
+ public static void setTableColumnEditor(JTable table, int columnIndex, TableCellEditor editor) {
+ TableColumn column = table.getColumnModel().getColumn(columnIndex);
+ column.setCellEditor(editor);
+ }
+
+ public static void setTableColumnRenderer(JTable table, int columnIndex, TableCellRenderer editor) {
+ TableColumn column = table.getColumnModel().getColumn(columnIndex);
+ column.setCellRenderer(editor);
+ }
+
+ public static void setI18nTableHeaderRenderer(JTable table, String... libelles) {
+ table.getTableHeader().setDefaultRenderer(new I18nTableCellRenderer(table.getTableHeader().getDefaultRenderer(), libelles));
+ }
+
+ /**
+ * Box a component in a {@link org.jdesktop.jxlayer.JXLayer}.
+ *
+ * @param component the component to box
+ * @return the {@link org.jdesktop.jxlayer.JXLayer} boxing the component
+ */
+ public static JXLayer boxComponentWithJxLayer(JComponent component) {
+ JXLayer layer = getLayer(component);
+ if (layer != null) {
+ return layer;
+ }
+ layer = new org.jdesktop.jxlayer.JXLayer();
+ layer.add(component);
+ return layer;
+ }
+
+ public static List<JComponent> getLayeredComponents(JAXXObject object) {
+ List<JComponent> result = new ArrayList<JComponent>();
+ for (Entry<String, Object> child : object.get$objectMap().entrySet()) {
+ if (child.getValue() == null) {
+ log.warn("find a null object in $objectMap " + child.getKey());
+ continue;
+ }
+ if (JComponent.class.isAssignableFrom(child.getValue().getClass())) {
+ JComponent comp = (JComponent) child.getValue();
+ if (isLayered(comp)) {
+ result.add(comp);
+ }
+ }
+ }
+ return result;
+ }
+
+ public static JXLayer<JComponent> getLayer(JComponent comp) {
+ if (!isLayered(comp)) {
+ return null;
+ }
+ return (JXLayer<JComponent>) comp.getParent();
+ }
+
+ public static boolean isLayered(JComponent comp) {
+ Container parent = comp.getParent();
+ return parent != null && parent instanceof JXLayer;
+ }
+
+ /**
+ * recherche les composants portant le meme nom que les champs de la classe
+ * clazz. Cette methode est statique pour pouvoir eventuellement l'utiliser
+ * dans un autre context (je pense par exemple a la generation jaxx).
+ * <p/>
+ * <p/>
+ * Si la recherche echoue pour quelque raison que se soit, aucune exception
+ * n'est leve, et la map retournee est tout simplement vide ou incomplete
+ *
+ * @param clazz la classe ou recherche les champs
+ * @param container le container ou rechercher les composants d'edition
+ * @return le dictionnaire des composants recherches.
+ */
+ public static Map<String, JComponent> lookingForEditor(Class clazz, Container container) {
+ Map<String, JComponent> result = new HashMap<String, JComponent>();
+ try {
+ // looking for all component with name set
+ Map<String, JComponent> allNamedComponent = new HashMap<String, JComponent>();
+ List<Container> todo = new LinkedList<Container>();
+ todo.add(container);
+ while (todo.size() > 0) {
+ for (ListIterator<Container> i = todo.listIterator(); i.hasNext();) {
+ Container parent = i.next();
+ i.remove();
+ for (Component c : parent.getComponents()) {
+ if (c instanceof Container) {
+ i.add((Container) c);
+ String name = c.getName();
+ if (c instanceof JComponent &&
+ name != null && !"".equals(name)) {
+ allNamedComponent.put(name, (JComponent) c);
+ }
+ }
+ }
+ }
+ }
+
+ // looking for all properties on class
+ BeanInfo info = Introspector.getBeanInfo(clazz);
+ PropertyDescriptor[] props = info.getPropertyDescriptors();
+
+ // find if one properties have same name that component
+ for (PropertyDescriptor prop : props) {
+ String name = prop.getName();
+ if (allNamedComponent.containsKey(name)) {
+ result.put(name, allNamedComponent.get(name));
+ }
+ }
+
+ } catch (IntrospectionException eee) {
+ log.warn("Can't introspect bean", eee);
+ }
+
+ if (log.isDebugEnabled()) {
+ log.debug("Result: " + result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Centrer un component graphique au center d'un autre component.
+ *
+ * <b>Note:</b> si le parent est null, alors on ne fait rien.
+ *
+ * @param parent le component parent
+ * @param component le component à centrer
+ */
+ public static void center(Component parent, Component component) {
+ if (parent == null) {
+ return;
+ }
+ Rectangle r = parent.getBounds();
+ int x = r.x + (r.width - component.getSize().width) / 2;
+ int y = r.y + (r.height - component.getSize().height) / 2;
+ component.setLocation(x, y);
+ }
+
+ /**
+ * Try to load the Nimbus look and feel.
+ * <p/>
+ * @throws UnsupportedLookAndFeelException
+ * if nimbus is not applicable
+ * @throws ClassNotFoundException
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ */
+ public static void initNimbusLoookAndFeel() throws UnsupportedLookAndFeelException, ClassNotFoundException, InstantiationException, IllegalAccessException {
+
+ for (UIManager.LookAndFeelInfo laf : UIManager.getInstalledLookAndFeels()) {
+ if ("Nimbus".equals(laf.getName())) {
+ UIManager.setLookAndFeel(laf.getClassName());
+ }
+ }
+ }
+
+ /**
+ * Load the ui.properties file and set in {@link UIManager} colors and icons found.
+ *
+ * @param defaultUIConfig le path vers le fichier de la config d'ui par défaut (doit etre dansle class-path)
+ * @param extraUIConfig le path vers une surcharge de la config d'ui (doit etre dans le class-path)
+ *
+ * @throws IOException if could not load the ui.properties file
+ */
+ public static void loadUIConfig(String defaultUIConfig, String extraUIConfig) throws IOException {
+
+ Properties p = new Properties();
+ log.info("loading default UI config " + defaultUIConfig);
+ p.load(GWTUtil.class.getResourceAsStream(defaultUIConfig));
+ if (log.isDebugEnabled()) {
+ log.debug(p.toString());
+ }
+ if (extraUIConfig != null) {
+ InputStream extraStream = GWTUtil.class.getResourceAsStream(extraUIConfig);
+ if (extraStream == null) {
+ log.warn("could not find extraUIConfig : " + extraUIConfig);
+ } else {
+ log.info("loading extra UI config " + extraUIConfig);
+ Properties p2 = new Properties(p);
+ p2.load(extraStream);
+ if (log.isDebugEnabled()) {
+ log.debug(p2.toString());
+ }
+ p.putAll(p2);
+ }
+ }
+ for (Entry<Object, Object> entry : p.entrySet()) {
+ String key = (String) entry.getKey();
+ if (key.startsWith(ICON_PREFIX)) {
+ ImageIcon icon;
+ try {
+ icon = createImageIcon((String) entry.getValue());
+ UIManager.put(key.substring(ICON_PREFIX.length()), icon);
+ } catch (Exception e) {
+ log.warn("could not load icon " + entry.getValue());
+ }
+ continue;
+ }
+ if (key.startsWith(COLOR_PREFIX)) {
+ String value = (String) entry.getValue();
+ String[] rgb = value.split(",");
+ UIManager.put(key.substring(COLOR_PREFIX.length()), new Color(Integer.valueOf(rgb[0]), Integer.valueOf(rgb[1]), Integer.valueOf(rgb[2])));
+ }
+ }
+ }
+
+ /**
+ * Iterate the components of a {@link JTabbedPane} in natural order.
+ *
+ * Says using method {@link JTabbedPane#getComponent(int)}
+ * @param tabs the
+ * @return
+ * @since 1.4
+ */
+ public static TabbedPaneIterator<Component> newTabbedPaneIterator(JTabbedPane tabs) {
+ return new TabbedPaneIterator<Component>(false, tabs) {
+
+ @Override
+ protected Component get(int index, Component comp) {
+ return comp;
+ }
+ };
+ }
+
+ /**
+ * A simple iterator on a {@link JTabbedPane}.
+ *
+ * Implements the method {@link #get(int, java.awt.Component)} to obtain
+ * the data required given the component (or index).
+ *
+ * You can also inverse the order by usin the method {@link #reverse()}.
+ *
+ * Note: After the use of the method {@link #reverse()} the iterator returns
+ * to the first element.
+ *
+ * @param <O> the type of return elements.
+ * @since 1.4
+ */
+ public static abstract class TabbedPaneIterator<O> implements Iterator<O> {
+
+ final JTabbedPane tabs;
+ boolean reverse;
+ int index;
+ int increment;
+
+ protected abstract O get(int index, Component comp);
+
+ public TabbedPaneIterator(boolean reverse, JTabbedPane tabs) {
+ this.tabs = tabs;
+ setReverse(reverse);
+ }
+
+ public void reset() {
+ setReverse(reverse);
+ }
+
+ public int size() {
+ return tabs.getTabCount();
+ }
+
+ public TabbedPaneIterator<O> reverse() {
+ setReverse(!reverse);
+ return this;
+ }
+
+ @Override
+ public boolean hasNext() {
+ return reverse ? index > 0 : index < tabs.getTabCount();
+ }
+
+ public int getIndex() {
+ return index;
+ }
+
+ @Override
+ public O next() {
+ if (!hasNext()) {
+ throw new NoSuchElementException();
+ }
+ Component next = tabs.getComponentAt(index);
+ O result = get(index, next);
+ index += increment;
+ return result;
+ }
+
+ @Override
+ public void remove() {
+ throw new IllegalStateException("not implemented for " + this);
+ }
+
+ @Override
+ public String toString() {
+ return super.toString() + "< reverse:" + reverse + ", index:" + index + ", size:" + tabs.getTabCount() + " >";
+ }
+
+ protected void setReverse(boolean reverse) {
+ if (reverse) {
+ index = tabs.getTabCount() - 1;
+ increment = -1;
+ } else {
+ index = 0;
+ increment = 1;
+ }
+ this.reverse = reverse;
+ }
+ }
+
+ public static JLabel newLabel(String text, Object iconKey, int aligment) {
+ Icon icon = null;
+ if (iconKey instanceof Icon) {
+ icon = (Icon) iconKey;
+ } else if (iconKey instanceof String) {
+ icon = jaxx.runtime.Util.getUIManagerActionIcon((String) iconKey);
+ }
+ JLabel result;
+ if (icon == null) {
+ result = new JLabel(text, aligment);
+ } else {
+ result = new JLabel(text, icon, aligment);
+ }
+ return result;
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/JaxxHelpUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/JaxxHelpUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/JaxxHelpUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,24 @@
+package jaxx.runtime;
+
+import java.awt.Component;
+
+import jaxx.runtime.gwt.JaxxHelpBroker;
+
+/**
+ *
+ * Contract to be added on JAXXObject wihch wants to use javax help.
+ *
+ * @param <B> type of broker.
+ *
+ * @author tony
+ * @since 1.3
+ * @see JaxxHelpBroker
+ */
+public interface JaxxHelpUI<B extends JaxxHelpBroker> {
+
+ B getBroker();
+
+ void registerHelpId(B broker, Component component, String helpId);
+
+ void showHelp(String helpId);
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Application.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Application.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Application.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,56 @@
+package jaxx.runtime.gwt;
+
+import javax.swing.JFrame;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.UnsupportedLookAndFeelException;
+import java.awt.GraphicsConfiguration;
+
+public class Application extends JFrame {
+ // Special: jaxxc will automatically add a main() method to any components which
+ // extend <Application>
+
+
+ public Application() {
+ }
+
+
+ public Application(GraphicsConfiguration gc) {
+ super(gc);
+ }
+
+
+ public Application(String title) {
+ super(title);
+ }
+
+
+ public Application(String title, GraphicsConfiguration gc) {
+ super(title, gc);
+ }
+
+
+ public void setLookAndFeel(String lookAndFeel) {
+ if (lookAndFeel.equals("system"))
+ lookAndFeel = UIManager.getSystemLookAndFeelClassName();
+ else if (lookAndFeel.equals("cross_platform"))
+ lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName();
+ try {
+ UIManager.setLookAndFeel(lookAndFeel);
+ if (isDisplayable())
+ SwingUtilities.updateComponentTreeUI(this);
+ }
+ catch (ClassNotFoundException e) {
+ throw new RuntimeException(e);
+ }
+ catch (InstantiationException e) {
+ throw new RuntimeException(e);
+ }
+ catch (IllegalAccessException e) {
+ throw new RuntimeException(e);
+ }
+ catch (UnsupportedLookAndFeelException e) {
+ throw new RuntimeException(e);
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/BlockingLayerUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/BlockingLayerUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/BlockingLayerUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,259 @@
+package jaxx.runtime.gwt;
+
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import org.jdesktop.jxlayer.JXLayer;
+
+/**
+ *
+ * A JXLayer ui implementation that permits to block a component but still
+ * allow an action when clicking on the right-top icon painted on the layer.
+ *
+ * You can change the blocking and accepting icon.
+ *
+ * To hook an click on the layer's icon, you can :
+ *
+ * <ul><li>pass an Action via method {@link #setAcceptAction(Action)}</li>
+ * <li>override the method {@link #acceptEvent(java.awt.event.MouseEvent, org.jdesktop.jxlayer.JXLayer)}</li>
+ * </ul>
+ *
+ * @author tony
+ * @since 1.2
+ */
+public class BlockingLayerUI extends org.jdesktop.jxlayer.plaf.AbstractLayerUI<JComponent> {
+
+ public static final String CAN_CLICK_PROPERTY = "canClick";
+ public static final String ACCEPT_ICON_PROPERTY = "acceptIcon";
+ public static final String BLOCK_ICON_PROPERTY = "blockIcon";
+ public static final String BLOCK_PROPERTY = "block";
+ private static final long serialVersionUID = 1L;
+ /**
+ * Action to be treated when click on icon
+ */
+ protected Action acceptAction;
+ /**
+ * Icon when you can not click
+ */
+ protected BufferedImage blockIcon;
+ /**
+ * Icon when you can click
+ */
+ protected BufferedImage acceptIcon;
+ /**
+ * Optinal color to put fill background when blocking
+ */
+ protected Color blockingColor;
+ /**
+ * Internal state to known when we can accept click
+ */
+ protected boolean canClick;
+ /**
+ * A flag to enable or disable the use of the icon.
+ *
+ * If set to false, no icon will be displayed and no action
+ * will be possible.
+ *
+ * By default, this is active.
+ */
+ protected boolean useIcon = true;
+ /**
+ * Internal state when should block event and paint layer
+ */
+ protected boolean block;
+
+ public void setAcceptAction(Action acceptAction) {
+ this.acceptAction = acceptAction;
+ }
+
+ public void setAcceptIcon(ImageIcon acceptIcon) {
+ this.acceptIcon = prepareIcon(acceptIcon);
+ firePropertyChange(ACCEPT_ICON_PROPERTY, null, acceptIcon);
+ setDirty(true);
+ }
+
+ public void setBlockIcon(ImageIcon blockIcon) {
+ this.blockIcon = prepareIcon(blockIcon);
+ firePropertyChange(BLOCK_ICON_PROPERTY, null, blockIcon);
+ setDirty(true);
+ }
+
+ public void setCanClick(boolean canClick) {
+ boolean oldvalue = this.canClick;
+ this.canClick = canClick;
+ firePropertyChange(CAN_CLICK_PROPERTY, oldvalue, canClick);
+ if (oldvalue != canClick) {
+ setDirty(true);
+ }
+ }
+
+ public void setBlock(boolean block) {
+ boolean oldvalue = this.block;
+ this.block = block;
+ firePropertyChange(BLOCK_PROPERTY, oldvalue, block);
+ if (oldvalue != block) {
+ setDirty(true);
+ }
+ }
+
+ @Override
+ public void setDirty(boolean isDirty) {
+ super.setDirty(isDirty);
+ }
+
+ public void setBlockIcon(BufferedImage blockIcon) {
+ this.blockIcon = blockIcon;
+ }
+
+ public void setBlockingColor(Color blockingColor) {
+ this.blockingColor = blockingColor;
+ }
+
+ public BufferedImage getBlockIcon() {
+ return blockIcon;
+ }
+
+ protected BufferedImage getAcceptIcon() {
+ return acceptIcon;
+ }
+
+ public boolean isCanClick() {
+ return canClick;
+ }
+
+ public void setUseIcon(boolean useIcon) {
+ boolean oldvalue = this.useIcon;
+ this.useIcon = useIcon;
+ if (oldvalue != useIcon) {
+ setDirty(true);
+ }
+ }
+
+ @Override
+ public BlockingLayerUI clone() {
+ BlockingLayerUI clone = new BlockingLayerUI();
+ clone.acceptAction = acceptAction;
+ clone.acceptIcon = acceptIcon;
+ clone.blockIcon = blockIcon;
+ clone.useIcon = useIcon;
+ clone.block = block;
+ clone.blockingColor = blockingColor;
+ clone.setCanClick(false);
+ return clone;
+ }
+
+ @Override
+ protected void processKeyEvent(KeyEvent e, JXLayer<JComponent> l) {
+ if (useIcon || block) {
+ e.consume();
+ }
+ }
+
+ @Override
+ protected void processMouseMotionEvent(MouseEvent e, JXLayer<JComponent> l) {
+ if (useIcon) {
+ updateCanClickState(l, e);
+ }
+ if (useIcon || block) {
+ e.consume();
+ }
+ }
+
+ @Override
+ protected void processMouseEvent(MouseEvent e, JXLayer<JComponent> l) {
+ if (useIcon) {
+ switch (e.getID()) {
+ case MouseEvent.MOUSE_ENTERED:
+ updateCanClickState(l, e);
+ break;
+ case MouseEvent.MOUSE_EXITED:
+ setCanClick(false);
+ break;
+ case MouseEvent.MOUSE_CLICKED:
+ if (canClick) {
+ acceptEvent(e, l);
+ }
+ break;
+ }
+ }
+ if (useIcon || block) {
+ e.consume();
+ }
+
+ }
+
+ @Override
+ protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) {
+ super.paintLayer(g2, l);
+ if (block && blockingColor != null) {
+ // to be in sync with the view if the layer has a border
+ /*Insets layerInsets = l.getInsets();
+ g2.translate(layerInsets.left, layerInsets.top);
+
+ JComponent view = l.getView();
+ // To prevent painting on view's border
+ Insets insets = view.getInsets();
+ g2.clip(new Rectangle(insets.left, insets.top,
+ view.getWidth() - insets.left - insets.right,
+ view.getHeight() - insets.top - insets.bottom));
+ */
+
+ g2.setColor(blockingColor);
+ g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .1f));
+ g2.fillRect(0, 0, l.getWidth(), l.getHeight());
+ }
+ if (useIcon && getCurrentIcon() != null) {
+ g2.drawImage(getCurrentIcon(), l.getWidth() - getCurrentIcon().getWidth() - 1, 0, null);
+ }
+ }
+
+ protected void acceptEvent(MouseEvent e, JXLayer<JComponent> l) {
+ if (acceptAction != null) {
+ acceptAction.putValue("layer", l);
+ Component source = l.getView();
+ acceptAction.actionPerformed(new ActionEvent(source, 0, "accept"));
+ }
+ }
+
+ protected BufferedImage getCurrentIcon() {
+ return canClick ? acceptIcon : blockIcon;
+ }
+
+ protected BufferedImage prepareIcon(ImageIcon image) {
+ BufferedImage icon = new BufferedImage(image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2 = (Graphics2D) icon.getGraphics();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g2.drawImage(image.getImage(), 0, 0, null);
+ g2.dispose();
+ return icon;
+ }
+
+ protected void updateCanClickState(JXLayer<JComponent> l, MouseEvent e) {
+ // udpate toolTipText
+ Point layerLocation = l.getView().getLocation();
+ Point mousePoint = e.getPoint();
+ BufferedImage currentIcon = getCurrentIcon();
+ if (currentIcon == null) {
+ setCanClick(false);
+ return;
+ }
+ int minX = (int) layerLocation.getX() + l.getWidth() - currentIcon.getWidth();
+ int maxX = (int) layerLocation.getX() + l.getWidth();
+ int minY = 0;
+ int maxY = currentIcon.getHeight();
+ boolean accept = minX <= mousePoint.getX() && mousePoint.getX() <= maxX;
+ accept &= minY <= mousePoint.getLocation().getY() && mousePoint.getLocation().getY() <= maxY;
+ setCanClick(accept);
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/BlockingLayerUI2.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/BlockingLayerUI2.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/BlockingLayerUI2.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,206 @@
+package jaxx.runtime.gwt;
+
+import java.awt.Component;
+import java.awt.Graphics2D;
+import java.awt.Point;
+import java.awt.RenderingHints;
+import java.awt.event.ActionEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+import javax.swing.Action;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import org.jdesktop.jxlayer.JXLayer;
+
+/**
+ *
+ * A JXLayer ui implementation that permits to block a component but still
+ * allow an action when clicking everywhere on the layer.
+ *
+ * Moreover, an icon can be added on the right-top icon painted and changed
+ * when the mouse is over the layer.
+ *
+ * You can change the blocking and accepting icon.
+ *
+ * To hook an click on the layer's icon, you can :
+ *
+ * <ul><li>pass an Action via method {@link #setAcceptAction(Action)}</li>
+ * <li>override the method {@link #acceptEvent(java.awt.event.MouseEvent, org.jdesktop.jxlayer.JXLayer)}</li>
+ * </ul>
+ *
+ * @author tony
+ * @since 1.3
+ */
+public class BlockingLayerUI2 extends org.jdesktop.jxlayer.plaf.AbstractLayerUI<JComponent> {
+
+ public static final String CAN_CLICK_PROPERTY = "canClick";
+ public static final String ACCEPT_ICON_PROPERTY = "acceptIcon";
+ public static final String BLOCK_ICON_PROPERTY = "blockIcon";
+ private static final long serialVersionUID = 1L;
+ /**
+ * Action to be treated when click on icon
+ */
+ protected Action acceptAction;
+ /**
+ * Icon when you can not click
+ */
+ protected BufferedImage blockIcon;
+ /**
+ * Icon when you can click
+ */
+ protected BufferedImage acceptIcon;
+ /**
+ * Internal state to known when we can accept click
+ */
+ protected boolean canClick;
+
+ public void setAcceptAction(Action acceptAction) {
+ this.acceptAction = acceptAction;
+ }
+
+ public void setAcceptIcon(ImageIcon acceptIcon) {
+ this.acceptIcon = prepareIcon(acceptIcon);
+ firePropertyChange(ACCEPT_ICON_PROPERTY, null, acceptIcon);
+ setDirty(true);
+ }
+
+ public void setBlockIcon(ImageIcon blockIcon) {
+ this.blockIcon = prepareIcon(blockIcon);
+ firePropertyChange(BLOCK_ICON_PROPERTY, null, blockIcon);
+ setDirty(true);
+ }
+
+ public void setCanClick(boolean canClick) {
+ boolean oldvalue = this.canClick;
+ this.canClick = canClick;
+ firePropertyChange(CAN_CLICK_PROPERTY, oldvalue, canClick);
+ if (oldvalue != canClick) {
+ setDirty(true);
+ }
+ }
+
+ @Override
+ public void setDirty(boolean isDirty) {
+ super.setDirty(isDirty);
+ }
+
+ public void setBlockIcon(BufferedImage blockIcon) {
+ this.blockIcon = blockIcon;
+ }
+
+ public BufferedImage getBlockIcon() {
+ return blockIcon;
+ }
+
+ protected BufferedImage getAcceptIcon() {
+ return acceptIcon;
+ }
+
+ public boolean isCanClick() {
+ return canClick;
+ }
+
+ @Override
+ public BlockingLayerUI2 clone() {
+ BlockingLayerUI2 clone = new BlockingLayerUI2();
+ clone.acceptAction = acceptAction;
+ clone.acceptIcon = acceptIcon;
+ clone.blockIcon = blockIcon;
+ clone.setCanClick(false);
+ return clone;
+ }
+
+ @Override
+ protected void processKeyEvent(KeyEvent e, JXLayer<JComponent> l) {
+
+ e.consume();
+
+ }
+
+ @Override
+ protected void processMouseMotionEvent(MouseEvent e, JXLayer<JComponent> l) {
+
+ e.consume();
+
+ }
+
+ @Override
+ protected void processMouseEvent(MouseEvent e, JXLayer<JComponent> l) {
+ switch (e.getID()) {
+ case MouseEvent.MOUSE_ENTERED:
+ setCanClick(true);
+ break;
+ case MouseEvent.MOUSE_EXITED:
+ setCanClick(false);
+ break;
+ case MouseEvent.MOUSE_CLICKED:
+ if (canClick) {
+ acceptEvent(e, l);
+ }
+ break;
+ }
+ e.consume();
+ }
+
+ @Override
+ protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) {
+ super.paintLayer(g2, l);
+
+ // to be in sync with the view if the layer has a border
+ /*Insets layerInsets = l.getInsets();
+ g2.translate(layerInsets.left, layerInsets.top);
+
+ JComponent view = l.getView();
+ // To prevent painting on view's border
+ Insets insets = view.getInsets();
+ g2.clip(new Rectangle(insets.left, insets.top,
+ view.getWidth() - insets.left - insets.right,
+ view.getHeight() - insets.top - insets.bottom));
+ */
+
+ if (getCurrentIcon() != null) {
+ g2.drawImage(getCurrentIcon(), l.getWidth() - getCurrentIcon().getWidth() - 1, 0, null);
+ }
+ }
+
+ protected void acceptEvent(MouseEvent e, JXLayer<JComponent> l) {
+ if (acceptAction != null) {
+ acceptAction.putValue("layer", l);
+ Component source = l.getView();
+ acceptAction.actionPerformed(new ActionEvent(source, 0, "accept"));
+ }
+ }
+
+ protected BufferedImage getCurrentIcon() {
+ return canClick ? acceptIcon : blockIcon;
+ }
+
+ protected BufferedImage prepareIcon(ImageIcon image) {
+ BufferedImage icon = new BufferedImage(image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2 = (Graphics2D) icon.getGraphics();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g2.drawImage(image.getImage(), 0, 0, null);
+ g2.dispose();
+ return icon;
+ }
+
+ protected void updateCanClickState(JXLayer<JComponent> l, MouseEvent e) {
+ // udpate toolTipText
+ Point layerLocation = l.getView().getLocation();
+ Point mousePoint = e.getPoint();
+ BufferedImage currentIcon = getCurrentIcon();
+ if (currentIcon == null) {
+ setCanClick(false);
+ return;
+ }
+ int minX = (int) layerLocation.getX() + l.getWidth() - currentIcon.getWidth();
+ int maxX = (int) layerLocation.getX() + l.getWidth();
+ int minY = 0;
+ int maxY = currentIcon.getHeight();
+ boolean accept = minX <= mousePoint.getX() && mousePoint.getX() <= maxX;
+ accept &= minY <= mousePoint.getLocation().getY() && mousePoint.getLocation().getY() <= maxY;
+ setCanClick(accept);
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/CardLayout2.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/CardLayout2.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/CardLayout2.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,221 @@
+package jaxx.runtime.gwt;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.awt.CardLayout;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.io.Serializable;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * An override of the awt {@link java.awt.CardLayout}.
+ * <p/>
+ * Because in the original layout is not overridable : everything is package level accessible.
+ * <p/>
+ * This new class offers to test if a constrains (as a Serializable) is actually dealed by the layout,
+ * via the method {@link #contains(java.io.Serializable)}.
+ * <p/>
+ * We had also another method to obtain the current visible component in a container layouted by the class,
+ * via the method {@link #getVisibleComponent(java.awt.Container)}.
+ *
+ * @author chemit
+ * @version 1.0
+ */
+public class CardLayout2 extends CardLayout {
+
+ /** log */
+ static private Log log = LogFactory.getLog(CardLayout2.class);
+
+ private static final long serialVersionUID = 1L;
+
+ /** list of already loaded context (since the {@link #vector} attribute is package visible... */
+ protected List<Serializable> contexts = new LinkedList<Serializable>();
+
+ /**
+ * A flag to compute dimension only on visible component.
+ * <p/>
+ * This is usefull when we only care of the visible component.
+ */
+ protected boolean useOnlyVisibleComponentDimension;
+
+ @Override
+ public void addLayoutComponent(Component comp, Object constraints) {
+ super.addLayoutComponent(comp, constraints);
+ contexts.add((Serializable) constraints);
+ if (log.isDebugEnabled()) {
+ log.debug(this + " new constraints : " + constraints);
+ }
+ }
+
+ /**
+ * Test if a constrains is contained in the layout.
+ *
+ * @param constraints l'identifiant a tester
+ * @return <code>true</code> si l'identifiant est deja present dans le layout, <code>false</code> autrement.
+ */
+ public boolean contains(Serializable constraints) {
+ return contexts.contains(constraints);
+ }
+
+ /**
+ * Obtain the visible component in the container.
+ *
+ * @param container the container using this layout
+ * @return the component visible in the container.
+ */
+ public Component getVisibleComponent(Container container) {
+ if (container.getLayout() != this) {
+ throw new IllegalArgumentException("the container is not managed by the current layout");
+ }
+ for (Component component : container.getComponents()) {
+ if (component.isVisible()) {
+ return component;
+ }
+ }
+ // no component actually visible
+ return null;
+ }
+
+ public Component getComponent(Container container, String constraints) {
+ if (container.getLayout() != this) {
+ throw new IllegalArgumentException("the container is not manage by the current layout");
+ }
+ if (!contexts.contains(constraints)) {
+ throw new IllegalArgumentException("the constraints '" + constraints + "' is not supported by this layout : " + contexts);
+ }
+ int index = contexts.indexOf(constraints);
+ return container.getComponents()[index];
+ }
+
+ /**
+ * Determines the preferred size of the container argument using
+ * this card layout.
+ *
+ * @param parent the parent container in which to do the layout
+ * @return the preferred dimensions to lay out the subcomponents
+ * of the specified container
+ * @see java.awt.Container#getPreferredSize
+ * @see java.awt.CardLayout#minimumLayoutSize
+ */
+ @Override
+ public Dimension preferredLayoutSize(Container parent) {
+ Dimension dimension = null;
+ if (useOnlyVisibleComponentDimension) {
+ Component comp = getVisibleComponent(parent);
+ if (comp != null) {
+ dimension = comp.getPreferredSize();
+ }
+ }
+ if (dimension == null) {
+ dimension = super.preferredLayoutSize(parent);
+ }
+ return dimension;
+ }
+
+ /**
+ * Calculates the minimum size for the specified panel.
+ *
+ * @param parent the parent container in which to do the layout
+ * @return the minimum dimensions required to lay out the
+ * subcomponents of the specified container
+ * @see java.awt.Container#doLayout
+ * @see java.awt.CardLayout#preferredLayoutSize
+ */
+ @Override
+ public Dimension minimumLayoutSize(Container parent) {
+ Dimension dimension = null;
+ if (useOnlyVisibleComponentDimension) {
+ Component comp = getVisibleComponent(parent);
+ if (comp != null) {
+ dimension = comp.getMinimumSize();
+ }
+ }
+ if (dimension == null) {
+ dimension = super.minimumLayoutSize(parent);
+ }
+ return dimension;
+ }
+
+ /**
+ * Returns the maximum dimensions for this layout given the components
+ * in the specified target container.
+ *
+ * @param target the component which needs to be laid out
+ * @see java.awt.Container
+ * @see #minimumLayoutSize
+ * @see #preferredLayoutSize
+ */
+ @Override
+ public Dimension maximumLayoutSize(Container target) {
+ Dimension dimension = null;
+ if (useOnlyVisibleComponentDimension) {
+ Component comp = getVisibleComponent(target);
+ if (comp != null) {
+ dimension = comp.getMaximumSize();
+ }
+ }
+ if (dimension == null) {
+ dimension = super.maximumLayoutSize(target);
+ }
+ return dimension;
+ }
+
+ /**
+ * Lays out the specified container using this card layout.
+ * <p/>
+ * Each component in the <code>parent</code> container is reshaped
+ * to be the size of the container, minus space for surrounding
+ * insets, horizontal gaps, and vertical gaps.
+ *
+ * @param parent the parent container in which to do the layout
+ * @see java.awt.Container#doLayout
+ */
+ @Override
+ public void layoutContainer(Container parent) {
+ if (useOnlyVisibleComponentDimension) {
+ Component comp = getVisibleComponent(parent);
+ if (comp != null) {
+ //dimension = comp.getMinimumSize();
+ Insets insets = parent.getInsets();
+ comp.setBounds(getHgap() + insets.left, getVgap() + insets.top,
+ parent.getWidth() - (getHgap() * 2 + insets.left + insets.right),
+ parent.getHeight() - (getVgap() * 2 + insets.top + insets.bottom));
+ } else {
+ super.layoutContainer(parent);
+ }
+ } else {
+ super.layoutContainer(parent);
+ }
+ }
+
+ public boolean isUseOnlyVisibleComponentDimension() {
+ return useOnlyVisibleComponentDimension;
+ }
+
+ public void setUseOnlyVisibleComponentDimension(boolean useOnlyVisibleComponentDimension) {
+ this.useOnlyVisibleComponentDimension = useOnlyVisibleComponentDimension;
+ }
+
+ /**
+ * remove from cardlayout and linked container all his components.
+ *
+ * @param parent the parent container linked with the layout
+ */
+ public void reset(Container parent) {
+ if (parent.getLayout() != this) {
+ throw new IllegalArgumentException("wrong parent for CardLayout");
+ }
+ for (Component component : parent.getComponents()) {
+ removeLayoutComponent(component);
+ parent.remove(component);
+ }
+ contexts.clear();
+
+ }
+
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/CardLayout2Ext.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/CardLayout2Ext.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/CardLayout2Ext.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,99 @@
+package jaxx.runtime.gwt;
+
+import java.awt.Container;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import jaxx.runtime.JAXXObject;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Une extension de {@link CardLayout2} pour pouvoir automatiquement afficher un
+ * contenu à partir de la propriété {@link #selected}.
+ *
+ * Ainsi, en changeant cette propriété via la méthode {@link #setSelected(String)},
+ * le contenu sera changé automatiquement, ce qui permet une utilisation direct
+ * dans jaxx sans à avoir à écrire d'écouteur.
+ *
+ * @author tony
+ * @since 1.3
+ * @see CardLayout2
+ */
+public class CardLayout2Ext extends CardLayout2 {
+
+ /** log */
+ static private Log log = LogFactory.getLog(CardLayout2.class);
+ private static final long serialVersionUID = 1L;
+ public static final String SELECTED_PROPERTY_NAME = "selected";
+ /**
+ * pour propager les changements dans le modèle vers l'ui
+ */
+ protected PropertyChangeSupport pcs;
+ /**
+ * le contenu sélectionné
+ */
+ protected String selected;
+ private String containerName;
+ private JAXXObject ui;
+ private Container container;
+
+ public CardLayout2Ext(JAXXObject ui, String containerName) {
+ pcs = new PropertyChangeSupport(this);
+ this.ui = ui;
+ this.containerName = containerName;
+ }
+
+ public String getSelected() {
+ return selected;
+ }
+
+ public String getPreviousSelected() {
+ int index = contexts.indexOf(selected);
+ if (index < 1) {
+ return null;
+ }
+ return contexts.get(index - 1) + "";
+ }
+
+ public String getNextSelected() {
+ int index = contexts.indexOf(selected);
+ if (index >= contexts.size()) {
+ return null;
+ }
+ return contexts.get(index + 1) + "";
+ }
+
+ public void setSelected(String selected) {
+ this.selected = selected;
+ show(getContainer(), selected);
+ }
+
+ public Container getContainer() {
+ if (container == null) {
+ container = (Container) ui.getObjectById(containerName);
+ }
+ return container;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListeners() {
+ for (PropertyChangeListener l : pcs.getPropertyChangeListeners()) {
+ pcs.removePropertyChangeListener(l);
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/DecoratorTableCellRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/DecoratorTableCellRenderer.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/DecoratorTableCellRenderer.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,33 @@
+package jaxx.runtime.gwt;
+
+import jaxx.runtime.Decorator;
+
+import javax.swing.JTable;
+import javax.swing.table.TableCellRenderer;
+import java.awt.Component;
+
+/**
+ * A simple TableCellRenderer using a delegate TableCellRenderer to render everything elese thant the text :
+ * the text is I18nalize.
+ *
+ * @author chemit
+ */
+public class DecoratorTableCellRenderer implements TableCellRenderer {
+
+ /** the delegate cell renderer */
+ protected TableCellRenderer delegate;
+
+ protected Decorator decorator;
+
+ public DecoratorTableCellRenderer(TableCellRenderer delegate, Decorator decorator) {
+ this.delegate = delegate;
+ this.decorator = decorator;
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasfocus, int row, int column) {
+ if (value != null) {
+ value = decorator.toString(value);
+ }
+ return delegate.getTableCellRendererComponent(table, value, isSelected, hasfocus, row, column);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/HBox.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/HBox.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/HBox.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.JPanel;
+import java.awt.Insets;
+
+/**
+ * Panel which uses an {@link HBoxLayout} by default.
+ *
+ * @author Ethan Nicholas
+ */
+public class HBox extends JPanel {
+ public static final String SPACING_PROPERTY = "spacing";
+ public static final String MARGIN_PROPERTY = "margin";
+ public static final String HORIZONTAL_ALIGNMENT_PROPERTY = "horizontalAlignment";
+ public static final String VERTICAL_ALIGNMENT_PROPERTY = "verticalAlignment";
+
+ private Insets margin;
+
+ public HBox() {
+ super(new HBoxLayout());
+ }
+
+
+ /**
+ * Returns the spacing between components, in pixels. Spacing is applied between components only,
+ * not to the top or bottom of the container.
+ *
+ * @return spacing between components
+ */
+ public int getSpacing() {
+ return ((HBoxLayout) getLayout()).getSpacing();
+ }
+
+
+ /**
+ * Sets the spacing between components. Spacing is applied between components only,
+ * not to the top or bottom of the container.
+ *
+ * @param spacing new spacing value
+ */
+ public void setSpacing(int spacing) {
+ int oldValue = getSpacing();
+ ((HBoxLayout) getLayout()).setSpacing(spacing);
+ firePropertyChange(SPACING_PROPERTY, oldValue, spacing);
+ revalidate();
+ }
+
+
+ public int getHorizontalAlignment() {
+ return ((HBoxLayout) getLayout()).getHorizontalAlignment();
+ }
+
+
+ public void setHorizontalAlignment(int horizontalAlignment) {
+ int oldValue = getHorizontalAlignment();
+ ((HBoxLayout) getLayout()).setHorizontalAlignment(horizontalAlignment);
+ firePropertyChange(HORIZONTAL_ALIGNMENT_PROPERTY, oldValue, horizontalAlignment);
+ revalidate();
+ }
+
+
+ public int getVerticalAlignment() {
+ return ((HBoxLayout) getLayout()).getVerticalAlignment();
+ }
+
+
+ public void setVerticalAlignment(int verticalAlignment) {
+ int oldValue = getVerticalAlignment();
+ ((HBoxLayout) getLayout()).setVerticalAlignment(verticalAlignment);
+ firePropertyChange(VERTICAL_ALIGNMENT_PROPERTY, oldValue, verticalAlignment);
+ revalidate();
+ }
+
+
+ public Insets getMargin() {
+ return margin;
+ }
+
+
+ public void setMargin(Insets margin) {
+ Insets oldValue = this.margin;
+ this.margin = (Insets) margin.clone();
+ firePropertyChange(MARGIN_PROPERTY, oldValue, margin);
+ }
+
+
+ @Override
+ public Insets getInsets() {
+ Insets result = super.getInsets();
+ if (margin != null) {
+ result.top += margin.top;
+ result.left += margin.left;
+ result.right += margin.right;
+ result.bottom += margin.bottom;
+ }
+ return result;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/HBoxLayout.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/HBoxLayout.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/HBoxLayout.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.SwingConstants;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+
+/**
+ * Horizontal box layout. The layout rules followed by this class are quite different than the core BoxLayout class,
+ * and in general represent a more useful algorithm.
+ *
+ * @author Ethan Nicholas
+ */
+public class HBoxLayout implements LayoutManager {
+ private int spacing = 6;
+ private int horizontalAlignment = SwingConstants.LEFT;
+ private int verticalAlignment = SwingConstants.TOP;
+
+
+ public int getSpacing() {
+ return spacing;
+ }
+
+
+ public void setSpacing(int spacing) {
+ this.spacing = spacing;
+ }
+
+
+ public int getHorizontalAlignment() {
+ return horizontalAlignment;
+ }
+
+
+ public void setHorizontalAlignment(int horizontalAlignment) {
+ this.horizontalAlignment = horizontalAlignment;
+ }
+
+
+ public int getVerticalAlignment() {
+ return verticalAlignment;
+ }
+
+
+ public void setVerticalAlignment(int verticalAlignment) {
+ this.verticalAlignment = verticalAlignment;
+ }
+
+
+ public void addLayoutComponent(String name, Component comp) {
+ }
+
+
+ public void layoutContainer(Container parent) {
+ Insets insets = parent.getInsets();
+ int parentHeight = parent.getSize().height - insets.top - insets.bottom;
+ int count = parent.getComponentCount();
+ Dimension preferredSize = parent.getPreferredSize();
+ int x;
+ switch (horizontalAlignment) {
+ case SwingConstants.LEFT:
+ x = insets.left;
+ break;
+ case SwingConstants.CENTER:
+ x = insets.left + (parent.getWidth() - preferredSize.width) / 2;
+ break;
+ case SwingConstants.RIGHT:
+ x = insets.left + (parent.getWidth() - preferredSize.width);
+ break;
+ default:
+ throw new IllegalArgumentException("invalid horizontal alignment: " + horizontalAlignment);
+ }
+
+ for (int i = 0; i < count; i++) {
+ Component component = parent.getComponent(i);
+ Dimension childPreferredSize = component.getPreferredSize();
+ int height = Math.min(childPreferredSize.height, parentHeight);
+ int y;
+ switch (verticalAlignment) {
+ case SwingConstants.TOP:
+ y = insets.top;
+ break;
+ case SwingConstants.CENTER:
+ y = insets.top + (parentHeight - childPreferredSize.height) / 2;
+ break;
+ case SwingConstants.BOTTOM:
+ y = insets.top + (parentHeight - childPreferredSize.height);
+ break;
+ default:
+ throw new IllegalArgumentException("invalid vertical alignment: " + verticalAlignment);
+ }
+ component.setBounds(x, y, childPreferredSize.width, height);
+ x += childPreferredSize.width + spacing;
+ }
+ }
+
+
+ public Dimension minimumLayoutSize(Container parent) {
+ int width = (parent.getComponentCount() - 1) * spacing;
+ int height = 0;
+ for (int i = parent.getComponentCount() - 1; i >= 0; i--) {
+ Dimension minimumSize = parent.getComponent(i).getMinimumSize();
+ width += minimumSize.width;
+ height = Math.max(height, minimumSize.height);
+ }
+ Insets insets = parent.getInsets();
+ return new Dimension(width + insets.left + insets.right, height + insets.top + insets.bottom);
+ }
+
+
+ public Dimension preferredLayoutSize(Container parent) {
+ int width = (parent.getComponentCount() - 1) * spacing;
+ int height = 0;
+ for (int i = parent.getComponentCount() - 1; i >= 0; i--) {
+ Dimension preferredSize = parent.getComponent(i).getPreferredSize();
+ width += preferredSize.width;
+ height = Math.max(height, preferredSize.height);
+ }
+ Insets insets = parent.getInsets();
+ return new Dimension(width + insets.left + insets.right, height + insets.top + insets.bottom);
+ }
+
+
+ public void removeLayoutComponent(Component comp) {
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/I18nTableCellRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/I18nTableCellRenderer.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/I18nTableCellRenderer.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,56 @@
+package jaxx.runtime.gwt;
+
+import static org.codelutin.i18n.I18n._;
+
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.table.TableColumn;
+import java.awt.Component;
+
+/**
+ * A simple TableCellRenderer using a delegate TableCellRenderer to render everything elese thant the text :
+ * the text is I18nalize.
+ *
+ * @author chemit
+ */
+public class I18nTableCellRenderer implements TableCellRenderer {
+
+ /** i18n keys of libelles to display */
+ protected final String[] keys;
+
+ /** i18n keys of toolTipTexts to display */
+ protected final String[] tips;
+
+ /** the delegate cell renderer */
+ protected TableCellRenderer delegate;
+
+ public I18nTableCellRenderer(TableCellRenderer delegate, String... keysAndTips) {
+ this.delegate = delegate;
+ if (keysAndTips.length == 0) {
+ throw new IllegalArgumentException("can not have empty keysAndTips parameters (means no column ?)");
+ }
+ if (keysAndTips.length % 2 == 1) {
+ throw new IllegalArgumentException("must have some couple (text,tooltTipText), but had a even number of data in keysAndTips parameter");
+ }
+ int size = keysAndTips.length / 2;
+ this.keys = new String[size];
+ this.tips = new String[size];
+ for (int i = 0; i < size; i++) {
+ this.keys[i] = keysAndTips[2 * i];
+ this.tips[i] = keysAndTips[2 * i + 1];
+ }
+ }
+
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasfocus, int row, int column) {
+ if (column > keys.length) {
+ throw new IndexOutOfBoundsException("colum can not be greater than " + keys.length);
+ }
+ TableColumn col = table.getColumn(table.getColumnName(column));
+ int index = col.getModelIndex();
+ value = _(keys[index]);
+ JComponent rendererComponent = (JComponent) delegate.getTableCellRendererComponent(table, value, isSelected, hasfocus, row, column);
+ rendererComponent.setToolTipText(_(tips[index]));
+ return rendererComponent;
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Item.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Item.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Item.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,192 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.event.SwingPropertyChangeSupport;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.List;
+
+// This needs to be split into two classes, Item and TreeItem
+/**
+ * An item in a component such as <code>JComboBox</code> or <code>JTree</code>. The <code>Item</code>
+ * class corresponds to the <code><item></code> tag in JAXX source files.
+ */
+public class Item {
+ public static final String LABEL_PROPERTY = "label";
+ public static final String VALUE_PROPERTY = "value";
+ public static final String SELECTED_PROPERTY = "selected";
+
+ private String id;
+ private String label;
+ private Object value;
+ private boolean selected;
+ private List<Item> children;
+ private Item parent;
+ private PropertyChangeSupport propertyChangeSupport;
+
+ /**
+ * Creates a new Item. This should only be called from compiled JAXX files.
+ *
+ * @param id the item's ID
+ * @param label the string that should be used to represent the item visually
+ * @param value the item's actual value
+ * @param selected <code>true</code> if the item should be selected by default
+ */
+ public Item(String id, String label, Object value, boolean selected) {
+ this.id = id;
+ this.label = label;
+ this.value = value;
+ this.selected = selected;
+ }
+
+ /**
+ * Returns this item's ID.
+ *
+ * @return the JAXX ID attribute
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Returns the string that should be used to represent the item at display time. If <code>null</code>,
+ * <code>String.valueOf(getValue())</code> will be used instead.
+ *
+ * @return this item's display string
+ * @see #setLabel
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * Sets the item's display string. If <code>null, String.valueOf(getValue())</code> will be used instead.
+ *
+ * @param label the new display string
+ * @see #getLabel
+ */
+ public void setLabel(String label) {
+ String oldLabel = this.label;
+ this.label = label;
+ firePropertyChange(LABEL_PROPERTY, oldLabel, label);
+ }
+
+ /**
+ * Returns the item's actual value as it appears in the component's model. The <code>Item</code> itself is not
+ * visible from the model, only the value.
+ *
+ * @return the item's value
+ * @see #setValue
+ */
+ public Object getValue() {
+ return value;
+ }
+
+ /**
+ * Sets the item's value as it appears in the component's model. The <code>Item</code> itself is not
+ * visible from the model, only the value.
+ *
+ * @param value the new value
+ * @see #getValue
+ */
+ public void setValue(Object value) {
+ Object oldValue = this.value;
+ this.value = value;
+ firePropertyChange(VALUE_PROPERTY, oldValue, value);
+ }
+
+ /**
+ * Returns <code>true</code> if this item is currently selected. This is a bound property.
+ *
+ * @return <code>true</code> if item is selected
+ * @see #setSelected
+ */
+ public boolean isSelected() {
+ return selected;
+ }
+
+ /**
+ * Sets the item's selection state. This is a bound property.
+ *
+ * @param selected the new selection state
+ * @see #isSelected
+ */
+ public void setSelected(boolean selected) {
+ boolean oldSelected = this.selected;
+ this.selected = selected;
+ firePropertyChange(SELECTED_PROPERTY, oldSelected, selected);
+ }
+
+ /**
+ * Adds a new child node (Items can be nested in trees).
+ *
+ * @param item the new child item
+ */
+ public void addChild(Item item) {
+ if (children == null) {
+ children = new ArrayList<Item>();
+ }
+ children.add(item);
+ item.parent = this;
+ }
+
+ /**
+ * Returns a list of this item's children.
+ *
+ * @return a list of all nested child nodes
+ */
+ public List<Item> getChildren() {
+ if (children == null) {
+ children = new ArrayList<Item>();
+ }
+ return children;
+ }
+
+ /**
+ * Returns the <code>Item</code> containing this <code>Item</code>, or <code>null</code> for a top-level
+ * <code>Item</code>.
+ *
+ * @return the item parent (or null)
+ */
+ public Item getParent() {
+ return parent;
+ }
+
+ private PropertyChangeSupport getPropertyChangeSupport() {
+ if (propertyChangeSupport == null) {
+ propertyChangeSupport = new SwingPropertyChangeSupport(this);
+ }
+ return propertyChangeSupport;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ getPropertyChangeSupport().addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String property, PropertyChangeListener listener) {
+ getPropertyChangeSupport().addPropertyChangeListener(property, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ getPropertyChangeSupport().removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String property, PropertyChangeListener listener) {
+ getPropertyChangeSupport().removePropertyChangeListener(property, listener);
+ }
+
+ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+ if (propertyChangeSupport != null) {
+ getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue);
+ }
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getName() + "[" + value + "]";
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXButtonGroup.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXButtonGroup.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXButtonGroup.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.AbstractButton;
+import javax.swing.ButtonGroup;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.EventListenerList;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Enumeration;
+
+public class JAXXButtonGroup extends ButtonGroup {
+ public static final String SELECTED_VALUE_PROPERTY = "selectedValue";
+
+ public static final String BUTTON8GROUP_CLIENT_PROPERTY = "$buttonGroup";
+
+ public static final String VALUE_CLIENT_PROPERTY = "$value";
+
+ public static final String SELECTED_TIP_CLIENT_PROPERTY = "$selected.toolTipText";
+
+ public static final String NOT_SELECTED_TIP_CLIENT_PROPERTY = "$not.selected.toolTipText";
+
+ protected EventListenerList listenerList = new EventListenerList();
+
+ private PropertyChangeSupport propertyChangeSupport;
+ private transient Object selectedValue;
+
+ protected boolean useToolTipText;
+
+ protected transient ChangeEvent changeEvent = new ChangeEvent(this);
+
+ private transient ChangeListener changeListener = new ChangeListener() {
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ updateSelectedValue();
+ if (useToolTipText) {
+ updateToolTipText();
+ }
+ }
+ };
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void add(AbstractButton button) {
+ super.add(button);
+ button.addChangeListener(changeListener);
+ updateSelectedValue();
+ }
+
+ @Override
+ public void remove(AbstractButton button) {
+ super.remove(button);
+ button.removeChangeListener(changeListener);
+ updateSelectedValue();
+ }
+
+
+ public void updateSelectedValue() {
+ Enumeration<AbstractButton> e = getElements();
+ while (e.hasMoreElements()) {
+ AbstractButton button = e.nextElement();
+ if (button.isSelected()) {
+ Object buttonValue = button.getClientProperty(VALUE_CLIENT_PROPERTY );
+ if (buttonValue != getSelectedValue()) {
+ setSelectedValue(buttonValue);
+ }
+ }
+ }
+ }
+
+ public void updateToolTipText() {
+ Enumeration<AbstractButton> e = getElements();
+ while (e.hasMoreElements()) {
+ AbstractButton button = e.nextElement();
+ String key = button.isSelected() ? SELECTED_TIP_CLIENT_PROPERTY : NOT_SELECTED_TIP_CLIENT_PROPERTY;
+ button.setToolTipText((String) button.getClientProperty(key));
+ }
+ }
+
+ public boolean isUseToolTipText() {
+ return useToolTipText;
+ }
+
+ public Object getSelectedValue() {
+ return selectedValue;
+ }
+
+ public AbstractButton getSelectedButton() {
+ Enumeration<AbstractButton> e = getElements();
+ while (e.hasMoreElements()) {
+ AbstractButton button = e.nextElement();
+ if (button.isSelected()) {
+ return button;
+ }
+ }
+ return null;
+ }
+
+ public AbstractButton getButton(Object value) {
+ Enumeration<AbstractButton> e = getElements();
+ while (e.hasMoreElements()) {
+ AbstractButton button = e.nextElement();
+ Object buttonValue = button.getClientProperty(VALUE_CLIENT_PROPERTY );
+ if (value.equals(buttonValue)) {
+ return button;
+ }
+ }
+ return null;
+ }
+
+
+ public void setSelectedValue(Object value) {
+ Object oldValue = getSelectedValue();
+ this.selectedValue = value;
+ firePropertyChange(oldValue);
+ }
+
+ public void setUseToolTipText(boolean useToolTipText) {
+ this.useToolTipText = useToolTipText;
+ }
+
+ public void setSelectedButton(Object value) {
+ setSelectedValue(value);
+ if (value == null) {
+ Enumeration<AbstractButton> e = getElements();
+ while (e.hasMoreElements()) {
+ AbstractButton button = e.nextElement();
+ setSelected(button.getModel(), false);
+ }
+ return;
+ }
+
+ Enumeration<AbstractButton> e = getElements();
+ while (e.hasMoreElements()) {
+ AbstractButton button = e.nextElement();
+ Object buttonValue = button.getClientProperty(VALUE_CLIENT_PROPERTY );
+ if (value.equals(buttonValue)) {
+ button.setSelected(true);
+ break;
+ }
+ }
+ }
+
+ protected PropertyChangeSupport getPropertyChangeSupport() {
+ if (propertyChangeSupport == null) {
+ propertyChangeSupport = new PropertyChangeSupport(this);
+ }
+ return propertyChangeSupport;
+ }
+
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ getPropertyChangeSupport().addPropertyChangeListener(listener);
+ }
+
+
+ public void addPropertyChangeListener(String property, PropertyChangeListener listener) {
+ getPropertyChangeSupport().addPropertyChangeListener(property, listener);
+ }
+
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ getPropertyChangeSupport().removePropertyChangeListener(listener);
+ }
+
+
+ public void removePropertyChangeListener(String property, PropertyChangeListener listener) {
+ getPropertyChangeSupport().removePropertyChangeListener(property, listener);
+ }
+
+
+ private void firePropertyChange(Object oldValue) {
+ if (propertyChangeSupport != null) {
+ getPropertyChangeSupport().firePropertyChange(SELECTED_VALUE_PROPERTY,
+ oldValue, getSelectedValue());
+ }
+ fireStateChanged();
+ }
+
+ /**
+ * Adds a <code>ChangeListener</code> to the button.
+ *
+ * @param l the listener to be added
+ */
+ public void addChangeListener(ChangeListener l) {
+ listenerList.add(ChangeListener.class, l);
+ }
+
+ /**
+ * Removes a ChangeListener from the button.
+ *
+ * @param l the listener to be removed
+ */
+ public void removeChangeListener(ChangeListener l) {
+ listenerList.remove(ChangeListener.class, l);
+ }
+
+ /**
+ * Returns an array of all the <code>ChangeListener</code>s added
+ * to this AbstractButton with addChangeListener().
+ *
+ * @return all of the <code>ChangeListener</code>s added or an empty
+ * array if no listeners have been added
+ * @since 1.4
+ */
+ public ChangeListener[] getChangeListeners() {
+ return listenerList.getListeners(ChangeListener.class);
+ }
+
+ /**
+ * Notifies all listeners that have registered interest for
+ * notification on this event type. The event instance
+ * is lazily created.
+ *
+ * @see EventListenerList
+ */
+ protected void fireStateChanged() {
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length - 2; i >= 0; i -= 2) {
+ if (listeners[i] == ChangeListener.class) {
+ // Lazily create the event:
+ if (changeEvent == null) {
+ changeEvent = new ChangeEvent(this);
+ }
+ ((ChangeListener) listeners[i + 1]).stateChanged(changeEvent);
+ }
+ }
+ }
+
+
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXComboBox.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXComboBox.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXComboBox.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.AbstractListModel;
+import javax.swing.ComboBoxModel;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JComboBox;
+import javax.swing.JList;
+import javax.swing.ListModel;
+import java.awt.Component;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class JAXXComboBox extends JComboBox {
+ public class JAXXComboBoxModel extends AbstractListModel implements ComboBoxModel {
+ private List<Item> items;
+ private Object selectedItem;
+ private static final long serialVersionUID = -8940733376638766414L;
+
+ public JAXXComboBoxModel(List<Item> items) {
+ this.items = items;
+
+ PropertyChangeListener listener = new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent e) {
+ if (e.getPropertyName().equals(Item.SELECTED_PROPERTY)) {
+ Item item = (Item) e.getSource();
+ int itemIndex = JAXXComboBoxModel.this.items.indexOf(item);
+ // TODO: fix cut-and-pasting badness
+ int[] oldSelection = new int[]{getSelectedIndex()};
+ int[] newSelection;
+ int index = -1;
+ for (int i = 0; i < oldSelection.length; i++) {
+ if (oldSelection[i] == itemIndex) {
+ index = i;
+ break;
+ }
+ }
+ if (item.isSelected()) {
+ if (index != -1) // it was already selected
+ {
+ return;
+ }
+ newSelection = new int[oldSelection.length + 1];
+ System.arraycopy(oldSelection, 0, newSelection, 0, oldSelection.length);
+ newSelection[newSelection.length - 1] = itemIndex;
+ } else {
+ if (index == -1) // it already wasn't selected
+ {
+ return;
+ }
+ newSelection = new int[oldSelection.length - 1];
+ System.arraycopy(oldSelection, 0, newSelection, 0, index);
+ System.arraycopy(oldSelection, index + 1, newSelection, index, oldSelection.length - 1 - index);
+ }
+ setSelectedIndex(newSelection[0]);
+ } else {
+ // TODO: more cut-and-pasting badness
+ for (int i = 0; i < getSize(); i++) {
+ if (getElementAt(i) == ((Item) e.getSource()).getValue()) {
+ fireContentsChanged(JAXXComboBoxModel.this, i, i);
+ if (getSelectedIndex() == i) {
+ fireItemStateChanged(new ItemEvent(JAXXComboBox.this, ItemEvent.ITEM_STATE_CHANGED, getElementAt(i), ItemEvent.DESELECTED));
+ }
+ return;
+ }
+ }
+ }
+ }
+ };
+ for (Item item : items) {
+ item.addPropertyChangeListener(listener);
+ }
+ }
+
+
+ public Object getElementAt(int i) {
+ return items.get(i).getValue();
+ }
+
+
+ public int getSize() {
+ return items.size();
+ }
+
+
+ public Object getSelectedItem() {
+ return selectedItem;
+ }
+
+
+ public void setSelectedItem(Object selectedItem) {
+ if ((this.selectedItem != null && !this.selectedItem.equals(selectedItem)) ||
+ this.selectedItem == null && selectedItem != null) {
+ this.selectedItem = selectedItem;
+ fireContentsChanged(this, -1, -1);
+ }
+ }
+ }
+
+
+ public JAXXComboBox() {
+ setRenderer(new DefaultListCellRenderer() {
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ ListModel model = list.getModel();
+ if (model instanceof JAXXComboBoxModel) {
+ List/*<Item>*/ items = ((JAXXComboBoxModel) model).items;
+ Item item = null;
+ if (index == -1) {
+ for (Object item1 : items) {
+ Item testItem = (Item) item1;
+ if (testItem.getValue() == value) {
+ item = testItem;
+ break;
+ }
+ }
+ } else {
+ item = (Item) items.get(index);
+ }
+
+ if (item != null) {
+ String label = item.getLabel();
+ if (label != null) {
+ value = label;
+ }
+ }
+ }
+ return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ }
+ });
+
+ addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent e) {
+ ListModel model = getModel();
+ if (model instanceof JAXXComboBoxModel) {
+ List<Item> items = ((JAXXComboBoxModel) model).items;
+ for (int i = items.size() - 1; i >= 0; i--) {
+ boolean selected = getSelectedIndex() == i;
+ Item item = items.get(i);
+ if (selected != item.isSelected()) {
+ item.setSelected(selected);
+ }
+ }
+ }
+ }
+ });
+ }
+
+ /**
+ * Fill a combo box model with some datas, and select after all the given object
+ *
+ * @param data data ot inject in combo
+ * @param select the object to select in combo after reflling his model
+ * @param methodName method to invoke to display data's name
+ */
+ public void fillComboBox(Collection<?> data, Object select, String methodName) {
+ // prepare method to use
+ Method m;
+ try {
+ m = select.getClass().getMethod(methodName);
+ m.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("could not find method " + methodName + " on " + select.getClass());
+ }
+
+ List<Item> items = new ArrayList<Item>();
+ for (Object o : data) {
+ boolean selected = o.equals(select);
+ try {
+ items.add(new Item(o.toString(), (String) m.invoke(o), o, selected));
+ } catch (IllegalAccessException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ }
+ }
+ setItems(items);
+ }
+
+ // this way we can keep it marked protected and still allow code in this file to call it
+ @Override
+ protected void fireItemStateChanged(ItemEvent e) {
+ super.fireItemStateChanged(e);
+ }
+
+ public void setItems(List<Item> items) {
+ setModel(new JAXXComboBoxModel(items));
+ List<Integer> selectedIndexList = new ArrayList<Integer>();
+ for (int i = 0; i < items.size(); i++) {
+ if (items.get(i).isSelected()) {
+ selectedIndexList.add(i);
+ }
+ }
+ int[] selectedIndices = new int[selectedIndexList.size()];
+ for (int i = 0; i < selectedIndexList.size(); i++) {
+ selectedIndices[i] = selectedIndexList.get(i);
+ }
+ if (selectedIndices.length > 0) {
+ setSelectedIndex(selectedIndices[0]);
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXList.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXList.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXList.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,295 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.AbstractListModel;
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.JList;
+import javax.swing.ListModel;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class JAXXList extends JList {
+ public class JAXXListModel extends AbstractListModel {
+ private List<Item> items;
+ private static final long serialVersionUID = -1598924187490122036L;
+
+ public JAXXListModel(List<Item> items) {
+ this.items = items;
+
+ PropertyChangeListener listener = new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent e) {
+ if (e.getPropertyName().equals(Item.SELECTED_PROPERTY)) {
+ Item item = (Item) e.getSource();
+ int itemIndex = JAXXListModel.this.items.indexOf(item);
+ int[] oldSelection = getSelectedIndices();
+ int[] newSelection;
+ int index = -1;
+ for (int i = 0; i < oldSelection.length; i++) {
+ if (oldSelection[i] == itemIndex) {
+ index = i;
+ break;
+ }
+ }
+ if (item.isSelected()) {
+ if (index != -1) // it was already selected
+ {
+ return;
+ }
+ newSelection = new int[oldSelection.length + 1];
+ System.arraycopy(oldSelection, 0, newSelection, 0, oldSelection.length);
+ newSelection[newSelection.length - 1] = itemIndex;
+ } else {
+ if (index == -1) // it already wasn't selected
+ {
+ return;
+ }
+ newSelection = new int[oldSelection.length - 1];
+ System.arraycopy(oldSelection, 0, newSelection, 0, index);
+ System.arraycopy(oldSelection, index + 1, newSelection, index, oldSelection.length - 1 - index);
+ }
+ setSelectedIndices(newSelection);
+ } else {
+ for (int i = 0; i < getSize(); i++) {
+ if (getElementAt(i) == ((Item) e.getSource()).getValue()) {
+ fireContentsChanged(JAXXListModel.this, i, i);
+ if (isSelectedIndex(i)) {
+ fireSelectionValueChanged(i, i, false);
+ }
+ return;
+ }
+ }
+ }
+ }
+ };
+ for (Item item : items) {
+ item.addPropertyChangeListener(listener);
+ }
+ }
+
+
+ public Object getElementAt(int i) {
+ return items.get(i).getValue();
+ }
+
+
+ public int getSize() {
+ return items.size();
+ }
+ }
+
+ public JAXXList() {
+ setCellRenderer(new DefaultListCellRenderer() {
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+ ListModel model = list.getModel();
+ if (model instanceof JAXXListModel) {
+ Item item = ((JAXXListModel) model).items.get(index);
+ String label = item.getLabel();
+ if (label != null) {
+ value = label;
+ }
+ }
+ return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+ }
+ });
+
+ addListSelectionListener(new ListSelectionListener() {
+ public void valueChanged(ListSelectionEvent e) {
+ ListModel model = getModel();
+ if (model instanceof JAXXListModel) {
+ List<Item> items = ((JAXXListModel) model).items;
+ for (int i = items.size() - 1; i >= 0; i--) {
+ boolean selected = isSelectedIndex(i);
+ Item item = items.get(i);
+ if (selected != item.isSelected()) {
+ item.setSelected(selected);
+ }
+ }
+ }
+ }
+ });
+ }
+
+
+ // this way we can keep it marked protected and still allow code in this file to call it
+ @Override
+ protected void fireSelectionValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) {
+ super.fireSelectionValueChanged(firstIndex, lastIndex, isAdjusting);
+ }
+
+
+ public void setSelectedValue(Object value) {
+ super.setSelectedValue(value, true);
+ }
+
+
+ public void setItems(List<Item> items) {
+ setModel(new JAXXListModel(items));
+ List<Integer> selectedIndexList = new ArrayList<Integer>();
+ for (int i = 0; i < items.size(); i++) {
+ if (items.get(i).isSelected()) {
+ selectedIndexList.add(i);
+ }
+ }
+ int[] selectedIndices = new int[selectedIndexList.size()];
+ for (int i = 0; i < selectedIndexList.size(); i++) {
+ selectedIndices[i] = selectedIndexList.get(i);
+ }
+ setSelectedIndices(selectedIndices);
+ }
+
+ /**
+ * Fill a list model with some datas, and select after all the given object
+ *
+ * @param data data ot inject in combo
+ * @param selects the objects to select in list after reflling his model
+ */
+ public void fillList(Collection<?> data, Collection<?> selects) {
+ if (selects == null){
+ selects = java.util.Collections.EMPTY_LIST;
+ }
+ List<Item> items = new ArrayList<Item>();
+ for (Object o : data) {
+ boolean selected = false;
+ for (Object select : selects) {
+ if (selected = o.equals(select)) {
+ break;
+ }
+ }
+ items.add(new Item(o.toString(), o.toString(), o, selected));
+ }
+ setItems(items);
+ }
+
+ /**
+ * Fill a list model with some datas, and select after all the given object
+ *
+ * @param data data ot inject in combo
+ * @param select object to select in list after reflling his model
+ */
+ public void fillList(Collection<?> data, Object select) {
+ List<Item> items = new ArrayList<Item>();
+ for (Object o : data) {
+ boolean selected = o.equals(select);
+ items.add(new Item(o.toString(), o.toString(), o, selected));
+ }
+ setItems(items);
+ }
+
+ /**
+ * Fill a list model with some datas, and select after all the given object
+ *
+ * @param data data ot inject in combo
+ * @param select object to select in list after reflling his model
+ * @param methodName method to invoke to display data's name
+ */
+ public void fillList(Collection<?> data, Object select, String methodName) {
+ // prepare method to use
+ Method m = null;
+
+ List<Item> items = new ArrayList<Item>();
+ for (Object o : data) {
+ boolean selected = o.equals(select);
+ if (m == null){
+ try {
+ m = o.getClass().getMethod(methodName);
+ m.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("could not find method " + methodName + " on " + o.getClass());
+ }
+ }
+ try {
+ items.add(new Item(o.toString(), (String) m.invoke(o), o, selected));
+ } catch (SecurityException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ } catch (IllegalArgumentException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ }
+ }
+ setItems(items);
+ }
+
+ /**
+ * Fill a list model with some datas, and select after all the given object
+ *
+ * @param data data ot inject in combo
+ * @param selects the objects to select in list after reflling his model
+ * @param methodName method to invoke to display data's name
+ */
+ public void fillList(Collection<?> data, Collection<?> selects, String methodName) {
+ // prepare method to use
+ Method m = null;
+
+ List<Item> items = new ArrayList<Item>();
+ for (Object o : data) {
+ boolean selected = selects.contains(o);
+ if (m == null){
+ try {
+ m = o.getClass().getMethod(methodName);
+ m.setAccessible(true);
+ } catch (NoSuchMethodException e) {
+ throw new IllegalArgumentException("could not find method " + methodName + " on " + o.getClass());
+ }
+ }
+ try {
+ items.add(new Item(o.toString(), (String) m.invoke(o), o, selected));
+ } catch (SecurityException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ } catch (IllegalAccessException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ } catch (IllegalArgumentException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ } catch (InvocationTargetException e) {
+ // shoudl never happen ?
+ throw new RuntimeException(e);
+ }
+ }
+ setItems(items);
+ }
+
+ /**
+ * Set the selected Objects
+ *
+ * @param values Objects must be selected in the list
+ */
+ public void setSelectedValues(Object[] values){
+ List<Integer> selectedIndices = new ArrayList<Integer>();
+ ListModel model = getModel();
+ for (int i = 0; i < model.getSize(); i++){
+ Object o = model.getElementAt(i);
+ for (Object value : values){
+ if (o.equals(value)){
+ selectedIndices.add(i);
+ break;
+ }
+ }
+ }
+ int[] ints=new int[selectedIndices.size()];
+ for(int i = 0; i < ints.length; i++){
+ ints[i]=((Integer)selectedIndices.get(i)).intValue();
+ }
+ setSelectedIndices(ints);
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXTab.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXTab.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXTab.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,23 @@
+/*
+* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin,
+* Tony Chemit
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+* ##% */
+package jaxx.runtime.gwt;
+
+/** @author chemit */
+public class JAXXTab extends Table {
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXToggleButton.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXToggleButton.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXToggleButton.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,94 @@
+package jaxx.runtime.gwt;
+
+public class JAXXToggleButton extends javax.swing.JToggleButton {
+
+ protected String glueText;
+ protected String normalText;
+ protected String glueTooltipText;
+ protected String normalTooltipText;
+ protected int normalMnemonic;
+ protected int glueMnemonic;
+
+ protected boolean _init;
+
+
+ public String getGlueText() {
+ return glueText;
+ }
+
+ public String getNormalText() {
+ return normalText;
+ }
+
+ public String getGlueTooltipText() {
+ return glueTooltipText;
+ }
+
+ public String getNormalTooltipText() {
+ return normalTooltipText;
+ }
+
+ public void setGlueText(String glueText) {
+ this.glueText = glueText;
+
+ }
+
+ public void setNormalText(String normalText) {
+ this.normalText = normalText;
+
+ }
+
+ public void setGlueTooltipText(String glueTooltipText) {
+ this.glueTooltipText = glueTooltipText;
+ }
+
+ public int getNormalMnemonic() {
+ return normalMnemonic;
+ }
+
+ public void setNormalMnemonic(int normalMnemonic) {
+ this.normalMnemonic = normalMnemonic;
+ }
+
+ public int getGlueMnemonic() {
+ return glueMnemonic;
+ }
+
+ public void setGlueMnemonic(int glueMnemonic) {
+ this.glueMnemonic = glueMnemonic;
+ }
+
+ public void setNormalTooltipText(String normalTooltipText) {
+ this.normalTooltipText = normalTooltipText;
+ if (!_init) {
+ init();
+ _init = true;
+ }
+ }
+
+ @Override
+ public void setSelected(boolean b) {
+ super.setSelected(b);
+ if (isSelected()) {
+ setText(getGlueText());
+ setToolTipText(getGlueTooltipText());
+ setMnemonic(getGlueMnemonic());
+ } else {
+ setText(getNormalText());
+ setToolTipText(getNormalTooltipText());
+ setMnemonic(getNormalMnemonic());
+ }
+ revalidate();
+ }
+
+ public void init() {
+ setSelected(false);
+ }
+
+ /* end raw body code */
+ public JAXXToggleButton() {
+ super();
+ _init = false;
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXTree.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXTree.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JAXXTree.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,213 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.JTree;
+import javax.swing.event.TreeModelEvent;
+import javax.swing.event.TreeModelListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+import java.awt.Component;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JAXXTree extends JTree {
+ private static final String SYNTHETIC = "<synthetic root node>";
+
+ public class JAXXTreeModel implements TreeModel {
+ private Item root;
+ private List<TreeModelListener> listeners = new ArrayList<TreeModelListener>();
+
+ public JAXXTreeModel(List<Item> items) {
+ if (items.size() == 1) {
+ this.root = items.get(0);
+ }
+ else {
+ this.root = new Item(null, null, SYNTHETIC, false);
+ for (Item item : items) {
+ root.addChild(item);
+ }
+ }
+
+ PropertyChangeListener listener = new PropertyChangeListener() {
+ public void propertyChange(PropertyChangeEvent e) {
+ if (e.getPropertyName().equals(Item.SELECTED_PROPERTY)) {
+ Item item = (Item) e.getSource();
+ if (item.isSelected()) {
+ addSelectionPath(getTreePath(item));
+ }
+ else {
+ removeSelectionPath(getTreePath(item));
+ }
+ } else {
+ Item item = (Item) e.getSource();
+ boolean root = item.getParent() == null;
+ TreePath path = !root ? getTreePath(item.getParent()) : null;
+ fireTreeNodesChanged(new TreeModelEvent(JAXXTreeModel.this, path,
+ !root ? new int[]{item.getParent().getChildren().indexOf(item)} : null,
+ new Object[]{item.getValue()}));
+ }
+ }
+ };
+ addPropertyChangeListener(root, listener);
+ }
+
+
+ private void addPropertyChangeListener(Item item, PropertyChangeListener listener) {
+ item.addPropertyChangeListener(listener);
+ List<Item> children = item.getChildren();
+ for (Item aChildren : children) {
+ addPropertyChangeListener(aChildren, listener);
+ }
+ }
+
+
+ public void addTreeModelListener(TreeModelListener listener) {
+ listeners.add(listener);
+ }
+
+
+ /* This is an inefficient implementation, but hand-coded tree structures are unlikely to contain
+enough nodes for that to really matter. This could be sped up with caching. */
+ private Item findItem(Object value) {
+ return findItem(root, value);
+ }
+
+
+ private Item findItem(Item node, Object value) {
+ if (node.getValue() == value)
+ return node;
+ else {
+ List<Item> children = node.getChildren();
+ for (Item aChildren : children) {
+ Item result = findItem(aChildren, value);
+ if (result != null)
+ return result;
+ }
+ return null;
+ }
+ }
+
+
+ private TreePath getTreePath(Item node) {
+ List<Object> path = new ArrayList<Object>();
+ while (node != null) {
+ path.add(0, node.getValue());
+ node = node.getParent();
+ }
+ return new TreePath(path.toArray());
+ }
+
+
+ public Object getChild(Object parent, int index) {
+ Item node = findItem(parent);
+ return node.getChildren().get(index).getValue();
+ }
+
+
+ public int getChildCount(Object parent) {
+ Item node = findItem(parent);
+ return node.getChildren().size();
+ }
+
+
+ public int getIndexOfChild(Object parent, Object child) {
+ Item node = findItem(parent);
+ List<Item> children = node.getChildren();
+ for (int i = 0,j = children.size();i<j; i++)
+ if (children.get(i).getValue() == child) {
+ return i;
+ }
+ return -1;
+ }
+
+
+ public Object getRoot() {
+ return root.getValue();
+ }
+
+
+ public boolean isLeaf(Object node) {
+ Item item = findItem(node);
+ return item != null && item.getChildren().size() == 0;
+ }
+
+
+ public void removeTreeModelListener(TreeModelListener listener) {
+ listeners.remove(listener);
+ }
+
+
+ public void fireTreeNodesChanged(TreeModelEvent e) {
+ for (TreeModelListener listener : listeners) {
+ listener.treeNodesChanged(e);
+ }
+ }
+
+
+ public void valueForPathChanged(TreePath path, Object newValue) {
+ }
+ }
+
+ public JAXXTree() {
+ setCellRenderer(new DefaultTreeCellRenderer() {
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ TreeModel model = tree.getModel();
+ if (model instanceof JAXXTreeModel) {
+ Item item = ((JAXXTreeModel) model).findItem(value);
+ if (item != null) {
+ String label = item.getLabel();
+ if (label != null) {
+ value = label;
+ }
+ }
+ }
+ return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
+ }
+ });
+
+ addTreeSelectionListener(new TreeSelectionListener() {
+ public void valueChanged(TreeSelectionEvent e) {
+ TreeModel model = getModel();
+ if (model instanceof JAXXTreeModel) {
+ scan((JAXXTreeModel) model, ((JAXXTreeModel) model).root);
+ }
+ }
+
+
+ private void scan(JAXXTreeModel model, Item item) {
+ TreePath path = model.getTreePath(item);
+ if (item.isSelected() != isPathSelected(path)) {
+ item.setSelected(!item.isSelected());
+ }
+ List<Item> children = item.getChildren();
+ for (Item aChildren : children) {
+ scan(model, aChildren);
+ }
+ }
+ });
+ }
+
+
+ public void setItems(List<Item> items) {
+ JAXXTreeModel model = new JAXXTreeModel(items);
+ if (model.getRoot() != null) {
+ setRootVisible(model.getRoot() != SYNTHETIC);
+ }
+ setModel(model);
+ }
+
+
+ public Object getSelectionValue() {
+ TreePath selectionPath = getSelectionPath();
+ return selectionPath != null ? selectionPath.getLastPathComponent() : null;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JaxxHelpBroker.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JaxxHelpBroker.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/JaxxHelpBroker.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,510 @@
+package jaxx.runtime.gwt;
+
+import java.applet.Applet;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.awt.event.MouseEvent;
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.List;
+import java.util.Map;
+import java.util.Vector;
+import javax.help.CSH;
+import javax.help.CSH.DisplayHelpFromSource;
+import javax.help.HelpBroker;
+import javax.help.HelpSet;
+import javax.swing.AbstractButton;
+import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.JAXXObject;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * La classe pour encapsuler l'aide de l'application.
+ *
+ * @param <B> le type de broker
+ * @author tony
+ * @since 1.4
+ */
+public abstract class JaxxHelpBroker<B extends JaxxHelpBroker> {
+
+ public static final String JAXX_CONTEXT_ENTRY = "jaxxcontext";
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(JaxxHelpBroker.class);
+ protected final String helpsetName;
+ protected final String defaultID;
+ protected final String helpKey;
+ // Main HelpSet & Broker
+ protected final HelpSet helpset;
+ protected final HelpBroker helpBroker;
+ protected ActionListener showHelpAction;
+ protected Hashtable<Component, Cursor> cursors;
+ protected Cursor onItemCursor;
+
+ protected JaxxHelpBroker(String helpsetName, String helpKey, String defaultID) {
+ if (helpsetName == null) {
+ throw new NullPointerException("parameter helpsetName can not be null!");
+ }
+ this.helpsetName = helpsetName;
+ this.helpKey = helpKey;
+ this.defaultID = defaultID;
+ try {
+ ClassLoader cl = getClass().getClassLoader();
+ URL url = HelpSet.findHelpSet(cl, helpsetName);
+ helpset = new HelpSet(cl, url);
+ helpBroker = helpset.createHelpBroker();
+ } catch (Exception ee) {
+ throw new IllegalStateException("could not find help set " + helpsetName + " for reason " + ee.getMessage(), ee);
+ }
+ }
+
+ public AbstractButton getShowHelperButton(JAXXObject c) {
+ return (AbstractButton) c.getObjectById("showHelp");
+ }
+
+ public void prepareUI(JAXXObject c) {
+ if (c == null) {
+ throw new NullPointerException("parameter c can not be null!");
+ }
+
+ // l'ui doit avoir un boutton showHelp
+ AbstractButton help = getShowHelperButton(c);
+
+ if (help == null) {
+ log.warn("no showButton detected for " + c.getClass());
+ } else {
+ boolean needListener = true;
+ for (ActionListener a : help.getActionListeners()) {
+ if (a instanceof DisplayHelpFromSource) {
+ needListener = false;
+ break;
+ }
+ }
+ if (needListener) {
+ // attach context to button
+ help.putClientProperty(JAXX_CONTEXT_ENTRY, c.getDelegateContext());
+ help.addActionListener(getShowHelpAction(c));
+ }
+
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("for " + c);
+ }
+
+ //installUI(c, new java.util.ArrayList<String>());
+ }
+
+ public HelpBroker getHelpBroker() {
+ return helpBroker;
+ }
+
+ public String getHelpKey() {
+ return helpKey;
+ }
+
+ public HelpSet getHelpset() {
+ return helpset;
+ }
+
+ public String getHelpsetName() {
+ return helpsetName;
+ }
+
+ public String getDefaultID() {
+ return defaultID;
+ }
+
+ public void showHelpSet() {
+ log.info(this);
+ new CSH.DisplayHelpFromSource(helpBroker);
+ }
+
+ public void showHelp(JAXXContext context, String helpId) {
+ }
+
+ public void installUI(Component comp, String helpId) {
+ CSH.setHelpIDString(comp, helpId);
+ }
+
+ protected void installUI(Object comp, List<String> scanned) {
+ //log.info(comp);
+ if (comp instanceof JComponent) {
+ JComponent c = (JComponent) comp;
+ if (scanned.contains(c.getName())) {
+ return;
+ } else {
+ scanned.add(c.getName());
+ }
+ Object id = c.getClientProperty(helpKey);
+ if (id != null && id instanceof String) {
+ String helpId = (String) id;
+
+ CSH.setHelpIDString(c, helpId);
+
+ log.info(c.getName() + " : " + helpId);
+
+ if (log.isDebugEnabled()) {
+ log.debug(c.getName() + " : " + helpId);
+
+ }
+ }
+ }
+
+ if (comp instanceof JAXXObject) {
+ JAXXObject jo = (JAXXObject) comp;
+
+
+ Map<String, Object> $objectMap = jo.get$objectMap();
+ for (String key : $objectMap.keySet()) {
+
+ if (scanned.contains(key)) {
+ continue;
+ }
+
+ Object o = $objectMap.get(key);
+
+ if (o == comp) {
+ continue;
+ }
+
+ if (o instanceof JAXXObject) {
+ installUI(o, scanned);
+ scanned.add(key);
+ continue;
+ }
+ if (o instanceof JComponent) {
+ installUI(o, scanned);
+ continue;
+ }
+ }
+ }
+ }
+
+ protected ActionListener getShowHelpAction(JAXXContext context) {
+ if (showHelpAction == null) {
+ showHelpAction = addShowHelpAction(context);
+ }
+ return showHelpAction;
+ }
+
+ protected ActionListener addShowHelpAction(JAXXContext context) {
+ return new CSH.DisplayHelpAfterTracking(helpBroker);
+ }
+
+ protected String getHelpID(Component source) {
+ String helpID = null;
+
+ // It is necessery for UIManager.get("HelpOnItemCursor");
+
+ // Get the onItemCursor
+ onItemCursor = (Cursor) UIManager.get("HelpOnItemCursor");
+ if (onItemCursor == null) {
+ return null;
+ }
+
+ // change all the cursors on all windows
+ Vector topComponents = null;
+ cursors = null;
+
+ if (onItemCursor != null) {
+ cursors = new Hashtable<Component, Cursor>();
+ topComponents = getTopContainers(source);
+ Enumeration enums = topComponents.elements();
+ while (enums.hasMoreElements()) {
+ setAndStoreCursors((Container) enums.nextElement(), onItemCursor);
+ }
+ }
+ /*MouseEvent event = getMouseEvent();
+
+ if (event != null) {
+ Component comp = (Component)event.getSource();
+ log.info("component traking!!!!!!!! " + comp.getName()+" : "+comp.getClass().getName());
+ }*/
+
+
+ Object o = CSH.trackCSEvents();
+
+ if (o instanceof Component) {
+
+ helpID = CSH.getHelpIDString((Component) o);
+
+ log.info("component traking " + ((Component) o).getName() + " : " + helpID);
+
+ if (log.isDebugEnabled()) {
+ log.debug("component traking " + ((Component) o).getName() + " : " + helpID);
+ }
+ }
+
+ /*HelpSet objHS = getHelpset();
+ try {
+ ID id = ID.create(helpID, objHS);
+ if (id == null) {
+ id = objHS.getHomeID();
+ }
+
+ } catch (Exception e2) {
+ e2.printStackTrace();
+ }
+ if (helpID == null) {
+ helpID = getDefaultID();
+ }*/
+
+ // restore the old cursors
+ if (topComponents != null) {
+ Enumeration containers = topComponents.elements();
+ while (containers.hasMoreElements()) {
+ resetAndRestoreCursors((Container) containers.nextElement());
+ }
+ }
+ cursors = null;
+
+ return helpID;
+ }
+
+ /*
+ * Get all top level containers to change it's cursors
+ */
+ protected Vector getTopContainers(Object source) {
+ // This method is used to obtain all top level components of application
+ // for which the changing of cursor to question mark is wanted.
+ // Method Frame.getFrames() is used to get list of Frames and
+ // Frame.getOwnedWindows() method on elements of the list
+ // returns all Windows, Dialogs etc. It works correctly in application.
+ // Problem is in applets. There is no way how to get reference to applets
+ // from elsewhere than applet itself. So, if request for CSH (this means
+ // pressing help button or select help menu item) does't come from component
+ // in a Applet, cursor for applets is not changed to question mark. Only for
+ // Frames, Windows and Dialogs is cursor changed properly.
+
+ Vector<Component> containers = new Vector<Component>();
+ Component topComponent = null;
+ topComponent = getRoot(source);
+ if (topComponent instanceof Applet) {
+ try {
+ Enumeration<Applet> applets = ((Applet) topComponent).getAppletContext().getApplets();
+ while (applets.hasMoreElements()) {
+ containers.add(applets.nextElement());
+ }
+ } catch (NullPointerException npe) {
+ containers.add(topComponent);
+ }
+ }
+ Frame frames[] = Frame.getFrames();
+ for (int i = 0; i < frames.length; i++) {
+ Window[] windows = frames[i].getOwnedWindows();
+ for (int j = 0; j < windows.length; j++) {
+ containers.add(windows[j]);
+ }
+ if (!containers.contains(frames[i])) {
+ containers.add(frames[i]);
+ }
+ }
+ return containers;
+ }
+
+ protected Component getRoot(Object comp) {
+ Object parent = comp;
+ while (parent != null) {
+ comp = parent;
+ if (comp instanceof MenuComponent) {
+ parent = ((MenuComponent) comp).getParent();
+ } else if (comp instanceof Component) {
+ if (comp instanceof Window) {
+ break;
+ }
+ if (comp instanceof Applet) {
+ break;
+ }
+ parent = ((Component) comp).getParent();
+ } else {
+ break;
+ }
+ }
+ if (comp instanceof Component) {
+ return ((Component) comp);
+ }
+ return null;
+ }
+
+
+ /*
+ * Set the cursor for a component and its children.
+ * Store the old cursors for future resetting
+ */
+ protected void setAndStoreCursors(Component comp, Cursor cursor) {
+ if (comp == null) {
+ return;
+ }
+ Cursor compCursor = comp.getCursor();
+ if (compCursor != cursor) {
+ cursors.put(comp, compCursor);
+ log.debug("set cursor on " + comp);
+ comp.setCursor(cursor);
+ }
+ if (comp instanceof Container) {
+ Component component[] = ((Container) comp).getComponents();
+ for (int i = 0; i < component.length; i++) {
+ setAndStoreCursors(component[i], cursor);
+ }
+ }
+ }
+
+ /*
+ * Actually restore the cursor for a component and its children
+ */
+ protected void resetAndRestoreCursors(Component comp) {
+ if (comp == null) {
+ return;
+ }
+ Cursor oldCursor = cursors.get(comp);
+ if (oldCursor != null) {
+ log.debug("restored cursor " + oldCursor + " on " + comp);
+ comp.setCursor(oldCursor);
+ }
+ if (comp instanceof Container) {
+ Component component[] = ((Container) comp).getComponents();
+ for (int i = 0; i < component.length; i++) {
+ resetAndRestoreCursors(component[i]);
+ }
+ }
+ }
+
+ /**
+ * Context Sensitive Event Tracking
+ *
+ * Creates a new EventDispatchThread from which to dispatch events. This
+ * method returns when stopModal is invoked.
+ *
+ * @return MouseEvent The mouse event occurred. Null if
+ * cancelled on an undetermined object.
+ */
+ public static MouseEvent getMouseEvent() {
+ // Should the cursor change to a quesiton mark here or
+ // require the user to change the cursor externally to this method?
+ // The problem is that each component can have it's own cursor.
+ // For that reason it might be better to have the user change the
+ // cusor rather than us.
+
+ // To track context-sensitive events get the event queue and process
+ // the events the same way EventDispatchThread does. Filter out
+ // ContextSensitiveEvents SelectObject & Cancel (MouseDown & ???).
+ // Note: This code only handles mouse events. Accessiblity might
+ // require additional functionality or event trapping
+
+ // If the eventQueue can't be retrieved, the thread gets interrupted,
+ // or the thread isn't a instanceof EventDispatchThread then return
+ // a null as we won't be able to trap events.
+ try {
+ if (EventQueue.isDispatchThread()) {
+ EventQueue eq = null;
+
+ // Find the eventQueue. If we can't get to it then just return
+ // null since we won't be able to trap any events.
+
+ try {
+ eq = Toolkit.getDefaultToolkit().getSystemEventQueue();
+ } catch (Exception ee) {
+ log.debug(ee);
+ }
+
+ // Safe guard
+ if (eq == null) {
+ return null;
+ }
+
+ int eventNumber = -1;
+
+ // Process the events until an object has been selected or
+ // the context-sensitive search has been canceled.
+ while (true) {
+ // This is essentially the body of EventDispatchThread
+ // modified to trap context-senstive events and act
+ // appropriately
+ eventNumber++;
+ AWTEvent event = eq.getNextEvent();
+ Object src = event.getSource();
+ // can't call eq.dispatchEvent
+ // so I pasted it's body here
+
+ // debug(event);
+
+ // Not sure if I should suppress ActiveEvents or not
+ // Modal dialogs do. For now we will not suppress the
+ // ActiveEvent events
+
+ if (event instanceof ActiveEvent) {
+ ((ActiveEvent) event).dispatch();
+ continue;
+ }
+
+ if (src instanceof Component) {
+ // Trap the context-sensitive events here
+ if (event instanceof KeyEvent) {
+ KeyEvent e = (KeyEvent) event;
+ // if this is the cancel key then exit
+ // otherwise pass all other keys up
+ if (e.getKeyCode() == KeyEvent.VK_CANCEL ||
+ e.getKeyCode() == KeyEvent.VK_ESCAPE) {
+ e.consume();
+ return null;
+ } else {
+ e.consume();
+ // dispatchEvent(event);
+ }
+ } else if (event instanceof MouseEvent) {
+ MouseEvent e = (MouseEvent) event;
+ int eID = e.getID();
+ if ((eID == MouseEvent.MOUSE_CLICKED ||
+ eID == MouseEvent.MOUSE_PRESSED ||
+ eID == MouseEvent.MOUSE_RELEASED) &&
+ SwingUtilities.isLeftMouseButton(e)) {
+ if (eID == MouseEvent.MOUSE_CLICKED) {
+ if (eventNumber == 0) {
+ dispatchEvent(event);
+ continue;
+ }
+ }
+ e.consume();
+ return e;
+ } else {
+ e.consume();
+ }
+ } else {
+ dispatchEvent(event);
+ }
+ } else if (src instanceof MenuComponent) {
+ if (event instanceof InputEvent) {
+ ((InputEvent) event).consume();
+ }
+ } else {
+ System.err.println("unable to dispatch event: " + event);
+ }
+ }
+ }
+ } catch (InterruptedException e) {
+ log.debug(e);
+ }
+ log.debug("Fall Through code");
+ return null;
+ }
+
+ private static void dispatchEvent(AWTEvent event) {
+ Object src = event.getSource();
+ if (event instanceof ActiveEvent) {
+ // This could become the sole method of dispatching in time.
+ ((ActiveEvent) event).dispatch();
+ } else if (src instanceof Component) {
+ ((Component) src).dispatchEvent(event);
+ } else if (src instanceof MenuComponent) {
+ ((MenuComponent) src).dispatchEvent(event);
+ } else {
+ System.err.println("unable to dispatch event: " + event);
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Spacer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Spacer.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Spacer.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,10 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.JComponent;
+
+public class Spacer extends JComponent {
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/TabInfo.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/TabInfo.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/TabInfo.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,165 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.Icon;
+import javax.swing.event.SwingPropertyChangeSupport;
+import java.awt.Color;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+public class TabInfo {
+ public static String BACKGROUND_PROPERTY = "background";
+ public static String DISABLED_ICON_PROPERTY = "disabledIcon";
+ public static String DISPLAYED_MNEMONIC_INDEX_PROPERTY = "displayedMnemonicIndex";
+ public static String ENABLED_PROPERTY = "enabled";
+ public static String FOREGROUND_PROPERTY = "foreground";
+ public static String ICON_PROPERTY = "icon";
+ public static String MNEMONIC_PROPERTY = "mnemonic";
+ public static String TITLE_PROPERTY = "title";
+ public static String TOOL_TIP_TEXT_PROPERTY = "toolTipText";
+
+ private String id;
+ private Color background;
+ private Icon disabledIcon;
+ private int displayedMnemonicIndex = -1;
+ private boolean enabled = true;
+ private Color foreground;
+ private Icon icon;
+ private int mnemonic = -1;
+ private String title;
+ private String toolTipText;
+
+ private PropertyChangeSupport propertyChangeSupport;
+
+ public TabInfo() {
+ }
+
+ public TabInfo(String id) {
+ this.id = id;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public Color getBackground() {
+ return background;
+ }
+
+ public void setBackground(Color background) {
+ Color oldValue = this.background;
+ this.background = background;
+ firePropertyChange(BACKGROUND_PROPERTY, oldValue, background);
+ }
+
+ public Icon getDisabledIcon() {
+ return disabledIcon;
+ }
+
+ public void setDisabledIcon(Icon disabledIcon) {
+ Icon oldValue = this.disabledIcon;
+ this.disabledIcon = disabledIcon;
+ firePropertyChange(DISABLED_ICON_PROPERTY, oldValue, disabledIcon);
+ }
+
+ public int getDisplayedMnemonicIndex() {
+ return displayedMnemonicIndex;
+ }
+
+ public void setDisplayedMnemonicIndex(int displayedMnemonicIndex) {
+ int oldValue = this.displayedMnemonicIndex;
+ this.displayedMnemonicIndex = displayedMnemonicIndex;
+ firePropertyChange(DISPLAYED_MNEMONIC_INDEX_PROPERTY, oldValue, displayedMnemonicIndex);
+ }
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ public void setEnabled(boolean enabled) {
+ boolean oldValue = this.enabled;
+ this.enabled = enabled;
+ firePropertyChange(ENABLED_PROPERTY, oldValue, enabled);
+ }
+
+ public Color getForeground() {
+ return foreground;
+ }
+
+ public void setForeground(Color foreground) {
+ Color oldValue = this.foreground;
+ this.foreground = foreground;
+ firePropertyChange(FOREGROUND_PROPERTY, oldValue, foreground);
+ }
+
+ public Icon getIcon() {
+ return icon;
+ }
+
+ public void setIcon(Icon icon) {
+ Icon oldValue = this.icon;
+ this.icon = icon;
+ firePropertyChange(ICON_PROPERTY, oldValue, icon);
+ }
+
+ public int getMnemonic() {
+ return mnemonic;
+ }
+
+ public void setMnemonic(int mnemonic) {
+ int oldValue = this.mnemonic;
+ this.mnemonic = mnemonic;
+ firePropertyChange(MNEMONIC_PROPERTY, oldValue, mnemonic);
+ }
+
+ public String getTitle() {
+ return title;
+ }
+
+ public void setTitle(String title) {
+ String oldValue = this.title;
+ this.title = title;
+ firePropertyChange(TITLE_PROPERTY, oldValue, title);
+ }
+
+ public String getToolTipText() {
+ return toolTipText;
+ }
+
+ public void setToolTipText(String toolTipText) {
+ String oldValue = this.toolTipText;
+ this.toolTipText = toolTipText;
+ firePropertyChange(TOOL_TIP_TEXT_PROPERTY, oldValue, toolTipText);
+ }
+
+ private PropertyChangeSupport getPropertyChangeSupport() {
+ if (propertyChangeSupport == null) {
+ propertyChangeSupport = new SwingPropertyChangeSupport(this);
+ }
+ return propertyChangeSupport;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ getPropertyChangeSupport().addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String property, PropertyChangeListener listener) {
+ getPropertyChangeSupport().addPropertyChangeListener(property, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ getPropertyChangeSupport().removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String property, PropertyChangeListener listener) {
+ getPropertyChangeSupport().removePropertyChangeListener(property, listener);
+ }
+
+ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+ if (propertyChangeSupport != null)
+ getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue);
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/TabInfoPropertyChangeListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/TabInfoPropertyChangeListener.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/TabInfoPropertyChangeListener.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.Icon;
+import javax.swing.JTabbedPane;
+import java.awt.Color;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+
+public class TabInfoPropertyChangeListener implements PropertyChangeListener {
+ private JTabbedPane tabs;
+ private int tabIndex;
+
+ public TabInfoPropertyChangeListener(JTabbedPane tabs, int tabIndex) {
+ this.tabs = tabs;
+ this.tabIndex = tabIndex;
+ }
+
+ public void propertyChange(PropertyChangeEvent e) {
+ String name = e.getPropertyName();
+ if (name.equals(TabInfo.TITLE_PROPERTY))
+ tabs.setTitleAt(tabIndex, (String) e.getNewValue());
+ else if (name.equals(TabInfo.TOOL_TIP_TEXT_PROPERTY))
+ tabs.setToolTipTextAt(tabIndex, (String) e.getNewValue());
+ else if (name.equals(TabInfo.FOREGROUND_PROPERTY))
+ tabs.setForegroundAt(tabIndex, (Color) e.getNewValue());
+ else if (name.equals(TabInfo.BACKGROUND_PROPERTY))
+ tabs.setBackgroundAt(tabIndex, (Color) e.getNewValue());
+ else if (name.equals(TabInfo.MNEMONIC_PROPERTY))
+ tabs.setMnemonicAt(tabIndex, (Integer) e.getNewValue());
+ else if (name.equals(TabInfo.DISPLAYED_MNEMONIC_INDEX_PROPERTY))
+ tabs.setDisplayedMnemonicIndexAt(tabIndex, (Integer) e.getNewValue());
+ else if (name.equals(TabInfo.ICON_PROPERTY))
+ tabs.setIconAt(tabIndex, (Icon) e.getNewValue());
+ else if (name.equals(TabInfo.DISABLED_ICON_PROPERTY))
+ tabs.setDisabledIconAt(tabIndex, (Icon) e.getNewValue());
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Table.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Table.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/Table.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.JPanel;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+
+/**
+ * Panel which uses a {@link GridBagLayout} by default.
+ *
+ * @author Ethan Nicholas
+ */
+public class Table extends JPanel {
+ public static final Insets DEFAULT_INSETS = new Insets(3, 3, 3, 3);
+
+ private GridBagConstraints tableConstraints = new GridBagConstraints();
+ private GridBagConstraints rowConstraints = null;
+ private GridBagConstraints cellConstraints = null;
+
+
+ public Table() {
+ super.setLayout(new GridBagLayout());
+
+ tableConstraints.insets = DEFAULT_INSETS;
+ }
+
+
+ public void setLayout(LayoutManager layout) {
+ // do nothing
+ }
+
+
+ public GridBagConstraints getTableConstraints() {
+ return tableConstraints;
+ }
+
+
+ public GridBagConstraints getRowConstraints() {
+ return rowConstraints;
+ }
+
+
+ public GridBagConstraints getCellConstraints() {
+ return cellConstraints;
+ }
+
+
+ public void newRow() {
+ tableConstraints.gridy++;
+ rowConstraints = (GridBagConstraints) tableConstraints.clone();
+ }
+
+
+ public void newCell() {
+ rowConstraints.gridx++;
+ cellConstraints = (GridBagConstraints) rowConstraints.clone();
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/VBox.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/VBox.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/VBox.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.JPanel;
+import java.awt.Insets;
+
+/**
+ * Panel which uses a {@link VBoxLayout} by default.
+ *
+ * @author Ethan Nicholas
+ */
+public class VBox extends JPanel {
+ public static final String SPACING_PROPERTY = "spacing";
+ public static final String MARGIN_PROPERTY = "margin";
+ public static final String HORIZONTAL_ALIGNMENT_PROPERTY = "horizontalAlignment";
+ public static final String VERTICAL_ALIGNMENT_PROPERTY = "verticalAlignment";
+
+ private Insets margin;
+
+ public VBox() {
+ super(new VBoxLayout());
+ }
+
+
+ /**
+ * Returns the spacing between components, in pixels. Spacing is applied between components only,
+ * not to the top or bottom of the container.
+ *
+ * @return spacing between components
+ */
+ public int getSpacing() {
+ return ((VBoxLayout) getLayout()).getSpacing();
+ }
+
+
+ /**
+ * Sets the spacing between components. Spacing is applied between components only,
+ * not to the top or bottom of the container.
+ *
+ * @param spacing new spacing value
+ */
+ public void setSpacing(int spacing) {
+ int oldValue = getSpacing();
+ ((VBoxLayout) getLayout()).setSpacing(spacing);
+ firePropertyChange(SPACING_PROPERTY, oldValue, spacing);
+ revalidate();
+ }
+
+
+ public int getHorizontalAlignment() {
+ return ((VBoxLayout) getLayout()).getHorizontalAlignment();
+ }
+
+
+ public void setHorizontalAlignment(int horizontalAlignment) {
+ int oldValue = getHorizontalAlignment();
+ ((VBoxLayout) getLayout()).setHorizontalAlignment(horizontalAlignment);
+ firePropertyChange(HORIZONTAL_ALIGNMENT_PROPERTY, oldValue, horizontalAlignment);
+ revalidate();
+ }
+
+
+ public int getVerticalAlignment() {
+ return ((VBoxLayout) getLayout()).getVerticalAlignment();
+ }
+
+
+ public void setVerticalAlignment(int verticalAlignment) {
+ int oldValue = getVerticalAlignment();
+ ((VBoxLayout) getLayout()).setVerticalAlignment(verticalAlignment);
+ firePropertyChange(VERTICAL_ALIGNMENT_PROPERTY, oldValue, verticalAlignment);
+ revalidate();
+ }
+
+
+ public Insets getMargin() {
+ return margin;
+ }
+
+
+ public void setMargin(Insets margin) {
+ Insets oldValue = this.margin;
+ this.margin = (Insets) margin.clone();
+ firePropertyChange(MARGIN_PROPERTY, oldValue, margin);
+ }
+
+
+ public Insets getInsets() {
+ Insets result = super.getInsets();
+ if (margin != null) {
+ result.top += margin.top;
+ result.left += margin.left;
+ result.right += margin.right;
+ result.bottom += margin.bottom;
+ }
+ return result;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/VBoxLayout.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/VBoxLayout.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/VBoxLayout.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2006 Ethan Nicholas. All rights reserved.
+ * Use is subject to license terms.
+ */
+package jaxx.runtime.gwt;
+
+import javax.swing.SwingConstants;
+import java.awt.Component;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.Insets;
+import java.awt.LayoutManager;
+
+/**
+ * Vertical box layout. The layout rules followed by this class are quite different than the core BoxLayout class,
+ * and in general represent a more useful algorithm.
+ *
+ * @author Ethan Nicholas
+ */
+public class VBoxLayout implements LayoutManager {
+ private int spacing = 6;
+ private int horizontalAlignment = SwingConstants.LEFT;
+ private int verticalAlignment = SwingConstants.TOP;
+
+
+ public int getSpacing() {
+ return spacing;
+ }
+
+
+ public void setSpacing(int spacing) {
+ this.spacing = spacing;
+ }
+
+
+ public int getHorizontalAlignment() {
+ return horizontalAlignment;
+ }
+
+
+ public void setHorizontalAlignment(int horizontalAlignment) {
+ this.horizontalAlignment = horizontalAlignment;
+ }
+
+
+ public int getVerticalAlignment() {
+ return verticalAlignment;
+ }
+
+
+ public void setVerticalAlignment(int verticalAlignment) {
+ this.verticalAlignment = verticalAlignment;
+ }
+
+
+ public void addLayoutComponent(String name, Component comp) {
+ }
+
+
+ public void layoutContainer(Container parent) {
+ Insets insets = parent.getInsets();
+ int parentWidth = parent.getSize().width - insets.left - insets.right;
+ int count = parent.getComponentCount();
+ Dimension preferredSize = parent.getPreferredSize();
+ int y;
+ switch (verticalAlignment) {
+ case SwingConstants.TOP:
+ y = insets.top;
+ break;
+ case SwingConstants.CENTER:
+ y = insets.top + (parent.getHeight() - preferredSize.height) / 2;
+ break;
+ case SwingConstants.BOTTOM:
+ y = insets.top + (parent.getHeight() - preferredSize.height);
+ break;
+ default:
+ throw new IllegalArgumentException("invalid vertical alignment: " + verticalAlignment);
+ }
+
+ for (int i = 0; i < count; i++) {
+ Component component = parent.getComponent(i);
+ Dimension childPreferredSize = component.getPreferredSize();
+ int width = Math.min(childPreferredSize.width, parentWidth);
+ int x;
+ switch (horizontalAlignment) {
+ case SwingConstants.LEFT:
+ x = insets.left;
+ break;
+ case SwingConstants.CENTER:
+ x = insets.left + (parentWidth - childPreferredSize.width) / 2;
+ break;
+ case SwingConstants.RIGHT:
+ x = insets.left + (parentWidth - childPreferredSize.width);
+ break;
+ default:
+ throw new IllegalArgumentException("invalid horizontal alignment: " + horizontalAlignment);
+ }
+ component.setBounds(x, y, width, childPreferredSize.height);
+ y += childPreferredSize.height + spacing;
+ }
+ }
+
+
+ public Dimension minimumLayoutSize(Container parent) {
+ int width = 0;
+ int height = (parent.getComponentCount() - 1) * spacing;
+ for (int i = parent.getComponentCount() - 1; i >= 0; i--) {
+ Dimension minimumSize = parent.getComponent(i).getMinimumSize();
+ width = Math.max(width, minimumSize.width);
+ height += minimumSize.height;
+ }
+ Insets insets = parent.getInsets();
+ return new Dimension(width + insets.left + insets.right, height + insets.top + insets.bottom);
+ }
+
+
+ public Dimension preferredLayoutSize(Container parent) {
+ int width = 0;
+ int height = (parent.getComponentCount() - 1) * spacing;
+ for (int i = parent.getComponentCount() - 1; i >= 0; i--) {
+ Dimension preferredSize = parent.getComponent(i).getPreferredSize();
+ width = Math.max(width, preferredSize.width);
+ height += preferredSize.height;
+ }
+ Insets insets = parent.getInsets();
+ return new Dimension(width + insets.left + insets.right, height + insets.top + insets.bottom);
+ }
+
+
+ public void removeLayoutComponent(Component comp) {
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeCellRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeCellRenderer.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeCellRenderer.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,94 @@
+package jaxx.runtime.gwt.navigation;
+
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.gwt.navigation.NavigationTreeModel.NavigationTreeNode;
+import jaxx.runtime.gwt.navigation.NavigationUtil.NodeRenderer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.codelutin.util.StringUtil;
+
+import javax.swing.JTree;
+import javax.swing.UIManager;
+import javax.swing.tree.DefaultTreeCellRenderer;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreePath;
+import java.awt.Component;
+
+/**
+ * A simple cell renderer which use the {@link NavigationTreeNode#renderer} to display node.
+ *
+ * @author chemit
+ */
+public class NavigationTreeCellRenderer implements TreeCellRenderer {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(NavigationTreeCellRenderer.class);
+
+ protected JAXXContext context;
+
+ protected DefaultTreeCellRenderer delegate;
+
+ protected static long t = 0;
+
+ public NavigationTreeCellRenderer(JAXXContext context) {
+ this.context = context;
+ UIManager.put("Tree.rendererFillBackground", false);
+ delegate = new DefaultTreeCellRenderer();
+ }
+
+ public NavigationTreeCellRenderer(JAXXContext context, DefaultTreeCellRenderer delegate) {
+ this.context = context;
+ this.delegate = delegate;
+ }
+
+ @Override
+ public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+ TreePath path = tree.getPathForRow(row);
+ if (path == null) {
+ return delegate;
+ }
+
+ if (value != null) {
+ long t0 = System.nanoTime();
+ NodeRenderer renderer = getNodeRenderer(value);
+ long t1 = System.nanoTime();
+ if (renderer != null) {
+ value = renderer.toString(context);
+ long t2 = System.nanoTime();
+ if (log.isDebugEnabled()) {
+ log.debug("use renderer [" + (t++) + "]<" + row + ">" + renderer.decorator + " <" + StringUtil.convertTime(t0, t1) + "/" + StringUtil.convertTime(t1, t2) + ">");
+ }
+ }
+ }
+
+ return delegate.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus);
+ }
+
+ /**
+ * @param value the value which should be a node
+ * @return the nodeRenderer attached to node via the {@link NavigationTreeNode#userObject},
+ * or <code>null</code> if value is null, or value is not int good type.
+ */
+ protected NodeRenderer getNodeRenderer(Object value) {
+ NodeRenderer render = null;
+
+ if (value != null) {
+ NavigationTreeNode node = getNode(value);
+
+ if (node != null && node.getUserObject() instanceof NodeRenderer) {
+ render = (NodeRenderer) node.getUserObject();
+ }
+ }
+ return render;
+ }
+
+ /**
+ * @param value the value which should be a node
+ * @return the cast {@link NavigationTreeNode}, or <code>null</code> if value is null.
+ */
+ protected NavigationTreeNode getNode(Object value) {
+ return value instanceof NavigationTreeNode ? (NavigationTreeNode) value : null;
+ }
+
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeModel.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,590 @@
+package jaxx.runtime.gwt.navigation;
+
+
+import jaxx.runtime.JAXXAction;
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.JAXXContextEntryDef;
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.gwt.navigation.NavigationUtil.NodeRenderer;
+
+import org.apache.commons.jxpath.JXPathContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeNode;
+import java.util.Enumeration;
+import java.util.StringTokenizer;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Le modele utilisé pour un arbre de navigation.
+ * <p/>
+ * Il est composé de {@link NavigationTreeModel.NavigationTreeNode}
+ *
+ * @author chemit
+ */
+public class NavigationTreeModel extends DefaultTreeModel {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(NavigationTreeModel.class);
+
+ static private final long serialVersionUID = 1L;
+
+ /** the separator char used to produce the navigation path of a node. */
+ protected final String navigationPathSeparator;
+
+ public NavigationTreeModel(TreeNode root, String navigationPathSeparator) {
+ super(root);
+ this.navigationPathSeparator = navigationPathSeparator;
+ }
+
+ @Override
+ public NavigationTreeNode getRoot() {
+ return (NavigationTreeNode) super.getRoot();
+ }
+
+ /**
+ * Search from the root node a node named by his fully path (concatenation of nodes
+ * {@link NavigationTreeNode#navigationPath} valued separated by dot.
+ * <p/>
+ * Example :
+ * <p/>
+ * <pre>$root.child1.leaf1</pre>
+ *
+ * @param path the fully path of the searched node.
+ * @return the node matching the fully context from the root node, or <code>null</code> if not find.
+ */
+ public NavigationTreeNode findNode(String path) {
+ return findNode(getRoot(), path, (Pattern) null);
+ }
+
+ /**
+ * Apply first the regex pattern to obtain the searched node fi the given <code>regex</code> is not null.
+ * <p/>
+ * Search then from the root node a node named by his fully path (concatenation of nodes
+ * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}.
+ * <p/>
+ * <p/>
+ * Example :
+ * <p/>
+ * <pre>$root.child1.leaf1</pre>
+ *
+ * @param path the fully path of the searched node.
+ * @param regex a optional regex to apply to path before searching
+ * @return the node matching the fully context from the root node, or <code>null</code> if not found.
+ */
+ public NavigationTreeNode findNode(String path, String regex) {
+ return findNode(getRoot(), path, regex);
+ }
+
+ /**
+ * Apply first the regex pattern to obtain the searched node.
+ * <p/>
+ * Search then from the root node a node named by his fully path (concatenation of nodes
+ * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}.
+ * <p/>
+ * Example :
+ * <p/>
+ * <pre>$root.child1.leaf1</pre>
+ *
+ * @param path the fully path of the searched node.
+ * @param regex a optional regex to apply to path before searching
+ * @return the node matching the fully context from the root node, or <code>null</code> if not found.
+ */
+ public NavigationTreeNode findNode(String path, Pattern regex) {
+ return findNode(getRoot(), path, regex);
+ }
+
+
+ /**
+ * Search from a given root node a node named by his fully path (concatenation of nodes
+ * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}.
+ *
+ * @param root root node to be used
+ * @param path the fully path of the searched node.
+ * @return the node matching the fully context from the given root node, or <code>null</code> if not found.
+ */
+ public NavigationTreeNode findNode(NavigationTreeNode root, String path) {
+ return findNode(root, path, (Pattern) null);
+ }
+
+ /**
+ * Apply first the regex pattern to obtain the searched node.
+ * <p/>
+ * Search then from a given root node a node named by his fully path (concatenation of nodes)
+ * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}.
+ *
+ * @param root root node to be used
+ * @param path the fully path of the searched node.
+ * @param regex a previous regex to apply to path : must have a matches
+ * @return the node matching the fully context from the given root node, or <code>null</code> if not found.
+ */
+ public NavigationTreeNode findNode(NavigationTreeNode root, String path, String regex) {
+ return findNode(root, path, regex == null ? null : Pattern.compile(regex));
+ }
+
+ /**
+ * Apply first the regex pattern to obtain the searched node.
+ * <p/>
+ * Search then from a given root node a node named by his fully path (concatenation of nodes
+ * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}.
+ *
+ * @param root root node to be used
+ * @param path the fully path of the searched node.
+ * @param regex a previous regex to apply to path : must have a matches
+ * @return the node matching the fully context from the given root node, or <code>null</code> if not found.
+ */
+ public NavigationTreeNode findNode(NavigationTreeNode root, String path, Pattern regex) {
+ if (regex != null) {
+ Matcher matcher = regex.matcher(path);
+ if (!matcher.matches() || matcher.groupCount() < 1) {
+ log.warn("no matching regex " + regex + " to " + path);
+ return null;
+ }
+ path = matcher.group(1);
+ if (log.isDebugEnabled()) {
+ log.debug("matching regex " + regex + " : " + path);
+ }
+ }
+ StringTokenizer stk = new StringTokenizer(path, navigationPathSeparator);
+ NavigationTreeNode result = root;
+ // pas the first token (matches the root node)
+ if (root.isRoot() && stk.hasMoreTokens()) {
+ String rootPath = stk.nextToken();
+ if (!rootPath.equals(root.getNavigationPath())) {
+ return null;
+ }
+ }
+ while (stk.hasMoreTokens()) {
+ result = result.getChild(stk.nextToken());
+ }
+ return result;
+ }
+
+
+ /**
+ * Obtain the associated bean value from context corresponding to node from given navigation path.
+ *
+ * @param context the context where to seek value
+ * @param navigationPath the current context path of the node
+ * @return the value associated in context with the given navigation path
+ */
+ public Object getJAXXContextValue(JAXXContext context, String navigationPath) {
+ Object result;
+ NavigationTreeNode node = findNode(navigationPath, (Pattern) null);
+ result = getJAXXContextValue(context, node);
+ return result;
+ }
+
+ /**
+ * Obtain the associated bean value from context corresponding to node
+ *
+ * @param context the context where to seek value
+ * @param node the current node
+ * @return the value associated in context with the given node.
+ */
+ public Object getJAXXContextValue(JAXXContext context, NavigationTreeNode node) {
+ if (node == null) {
+ return null;
+ //fixme should throw a NPE exception
+ //throw new NullPointerException("node can not be null");
+ }
+ return node.getJAXXContextValue(context);
+ }
+
+
+ @Override
+ public void nodeChanged(TreeNode node) {
+ nodeChanged(node, false);
+ }
+
+ public void nodeChanged(TreeNode node, boolean deep) {
+ NavigationTreeNode n = (NavigationTreeNode) node;
+ n.clearCache(!deep);
+ super.nodeChanged(node);
+ if (deep) {
+ Enumeration childs = node.children();
+ while (childs.hasMoreElements()) {
+ NavigationTreeNode o = (NavigationTreeNode) childs.nextElement();
+ nodeChanged(o, true);
+ }
+ }
+ }
+
+ /**
+ * la représentation d'un noeud dans le modele {@link NavigationTreeModel}
+ *
+ * @author chemit
+ */
+ public class NavigationTreeNode extends DefaultMutableTreeNode {
+
+ private static final long serialVersionUID = 1L;
+
+ /** pour representer le context du noeud. */
+ protected String navigationPath;
+
+ /**
+ * the cached complete navigation path from root node
+ * used for performance issues.
+ */
+ protected String cachedNavigationPath;
+
+ /** the JAXXObject class associated with this node (can be null) */
+ protected Class<? extends JAXXObject> jaxxClass;
+
+ /** the JAXXAction class associated with this node and will be put in ui context */
+ protected Class<? extends JAXXAction> jaxxActionClass;
+
+ /** the definition of the JAXXContext entry associated to this node, if null will seek in parent */
+ protected JAXXContextEntryDef jaxxContextEntryDef;
+
+ /** jxPath to process to obtain real value associated from context with the node (can be null) */
+ protected String jaxxContextEntryPath;
+
+ /** cache of bean associated with bean to improve performance */
+ protected transient Object cachedBean;
+
+ /** renderer of the node */
+ protected NodeRenderer renderer;
+
+ /**
+ * The type of the related bean associated with the node.
+ * <p/>
+ * Note: This type is here to override the NodeRenderer internalClass, since
+ * we could need to override this data.
+ * <p/>
+ * If this property is let to null, then we will use the NodeRenderer one
+ */
+ protected Class<?> internalClass;
+
+ public NavigationTreeNode(Object renderer,
+ Object jaxxContextEntryDef,
+ String navigationPath,
+ Class<? extends JAXXObject> jaxxClass,
+ Class<? extends JAXXAction> jaxxActionClass) {
+ super(renderer);
+ if (renderer instanceof NodeRenderer) {
+ // the renderer must keep a reference of the node
+ this.renderer = (NodeRenderer) renderer;
+ this.renderer.setNode(this);
+ } else if (renderer instanceof String) {
+ // nothing special to be done
+ } else if (renderer != null) {
+ // wrong renderer type
+ throw new IllegalArgumentException("to define a renderer, must be a String (simple libelle) or a " + NodeRenderer.class + ", but was " + renderer);
+ }
+ this.navigationPath = navigationPath;
+ this.jaxxClass = jaxxClass;
+ this.jaxxActionClass = jaxxActionClass;
+
+ if (jaxxContextEntryDef instanceof JAXXContextEntryDef) {
+ this.jaxxContextEntryDef = ((JAXXContextEntryDef) jaxxContextEntryDef);
+ } else if (jaxxContextEntryDef instanceof String) {
+ this.jaxxContextEntryPath = (String) jaxxContextEntryDef;
+ } else if (jaxxContextEntryDef != null) {
+ // wrong context definition type
+ throw new IllegalArgumentException("to define a context link, must be a String (jxpath) or a " + JAXXContextEntryDef.class + ", but was " + jaxxContextEntryDef);
+ }
+ }
+
+ public NavigationTreeNode(Object renderer,
+ JAXXContextEntryDef jaxxContextEntryDef,
+ String jaxxContextEntryPath,
+ String navigationPath,
+ Class<? extends JAXXObject> jaxxClass,
+ Class<? extends JAXXAction> jaxxActionClass) {
+ super(renderer);
+ if (renderer instanceof NodeRenderer) {
+ // the renderer must keep a reference of the node
+ this.renderer = (NodeRenderer) renderer;
+ this.renderer.setNode(this);
+ } else if (renderer instanceof String) {
+ // nothing special to be done
+ } else if (renderer != null) {
+ // wrong renderer type
+ throw new IllegalArgumentException("to define a renderer, must be a String (simple libelle) or a " + NodeRenderer.class + ", but was " + renderer);
+ }
+ this.navigationPath = navigationPath;
+ this.jaxxClass = jaxxClass;
+ this.jaxxActionClass = jaxxActionClass;
+ this.jaxxContextEntryDef = jaxxContextEntryDef;
+ this.jaxxContextEntryPath = jaxxContextEntryPath;
+ }
+
+ public String getNavigationPath() {
+ return navigationPath;
+ }
+
+ public void setNavigationPath(String navigationPath) {
+ this.navigationPath = navigationPath;
+ }
+
+ public Class<? extends JAXXObject> getJaxxClass() {
+ return jaxxClass;
+ }
+
+ public void setJaxxClass(Class<? extends JAXXObject> jaxxClass) {
+ this.jaxxClass = jaxxClass;
+ }
+
+ public void setInternalClass(Class<?> internalClass) {
+ this.internalClass = internalClass;
+ }
+
+ public Class<? extends JAXXAction> getJaxxActionClass() {
+ return jaxxActionClass;
+ }
+
+ public void setJaxxActionClass(Class<? extends JAXXAction> jaxxActionClass) {
+ this.jaxxActionClass = jaxxActionClass;
+ }
+
+ public JAXXContextEntryDef getJaxxContextEntryDef() {
+ return jaxxContextEntryDef;
+ }
+
+ public void setJaxxContextEntryDef(JAXXContextEntryDef jaxxContextEntryDef) {
+ this.jaxxContextEntryDef = jaxxContextEntryDef;
+ }
+
+ public String getJaxxContextEntryPath() {
+ return jaxxContextEntryPath;
+ }
+
+ public void setJaxxContextEntryPath(String jaxxContextEntryPath) {
+ this.jaxxContextEntryPath = jaxxContextEntryPath;
+ }
+
+ public Class<?> getInternalClass() {
+ return internalClass == null ? renderer.getInternalClass() : internalClass;
+ }
+
+ /** @return the fully context pathof the node from the root node to this. */
+ public String getContextPath() {
+ if (cachedNavigationPath == null) {
+ TreeNode[] path = getPath();
+ StringBuilder sb = new StringBuilder();
+ for (TreeNode treeNode : path) {
+ NavigationTreeNode myNode = (NavigationTreeNode) treeNode;
+ sb.append(navigationPathSeparator).append(myNode.getNavigationPath());
+ }
+ cachedNavigationPath = sb.substring(1);
+ }
+ return cachedNavigationPath;
+ }
+
+ @Override
+ public NavigationTreeNode getChildAt(int index) {
+ return (NavigationTreeNode) super.getChildAt(index);
+ }
+
+ @Override
+ public NavigationTreeNode getParent() {
+ return (NavigationTreeNode) super.getParent();
+ }
+
+ /**
+ * @param navigationPath the name of the {@link #navigationPath} to be matched in the cild of this node.
+ * @return the child of this node with given {@link # navigationPath} value.
+ */
+ public NavigationTreeNode getChild(String navigationPath) {
+ for (int i = 0, max = getChildCount(); i < max; i++) {
+ NavigationTreeNode son = getChildAt(i);
+ if (navigationPath.equals(son.getNavigationPath())) {
+ return son;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Obtain the associated bean value from context corresponding to node
+ *
+ * @param context the context to seek
+ * @return the value associated in context with the given context path
+ */
+ public Object getJAXXContextValue(JAXXContext context) {
+ Object result;
+
+ if (cachedBean != null) {
+ // use cached bean
+ return cachedBean;
+ }
+
+ if (getJaxxContextEntryDef() != null && jaxxContextEntryPath == null) {
+ // the node maps directly a value in context, with no jxpath resolving
+ result = getJaxxContextEntryDef().getContextValue(context);
+ // save in cache
+ setCachedBean(result);
+ return result;
+ }
+ // find the first ancestor node with a context def
+ NavigationTreeNode parentNode = getFirstAncestorWithDef();
+ if (parentNode == null) {
+ log.warn("could not find a ancestor node with a definition of a context entry from node (" + this + ")");
+ // todo must be an error
+ // no parent found
+ return null;
+ }
+
+ Object parentBean = parentNode.getJaxxContextEntryDef().getContextValue(context);
+
+ if (parentBean == null) {
+ // must be an error no bean found
+ log.warn("culd not find a bean attached in context from context entry definition " + parentNode.getJaxxContextEntryDef());
+ return null;
+ }
+
+ if (parentNode.jaxxContextEntryPath != null) {
+ // apply the jxpath on parentBean
+ JXPathContext jxcontext = JXPathContext.newContext(parentBean);
+
+ parentBean = jxcontext.getValue(parentNode.jaxxContextEntryPath);
+ }
+
+ // save in cache
+ parentNode.setCachedBean(parentBean);
+
+ if (this == parentNode) {
+ // current node is the node matching the context entry value and no jxpath is found
+ return parentBean;
+ }
+
+ if (jaxxContextEntryPath == null) {
+ // todo must be an error
+ log.warn("must find a jaxxContextEntryPath on node (" + this + ")");
+ return null;
+ }
+
+ String jxpathExpression = computeJXPath(jaxxContextEntryPath, parentNode);
+
+ if (jxpathExpression == null) {
+ /// todo must be an error
+ log.warn("could not build jxpath from node " + parentNode + " to " + this);
+ // could not retreave the jxpath...
+ return null;
+ }
+ if (jxpathExpression.startsWith("[")) {
+ // special case when we want to access a collection
+ jxpathExpression = '.' + jxpathExpression;
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("jxpath : " + jxpathExpression);
+ }
+
+ JXPathContext jxcontext = JXPathContext.newContext(parentBean);
+
+ result = jxcontext.getValue(jxpathExpression);
+
+ // save in cache
+ setCachedBean(result);
+
+ return result;
+ }
+
+ /**
+ * @return the first ancestor with a none null {@link #jaxxContextEntryDef}
+ * or <code>null</code> if none find..
+ */
+ protected NavigationTreeNode getFirstAncestorWithDef() {
+ if (jaxxContextEntryDef != null) {
+ return this;
+ }
+ return getParent() == null ? null : getParent().getFirstAncestorWithDef();
+ }
+
+ protected String computeJXPath(String expr, NavigationTreeNode parentNode) {
+ if (parentNode == this) {
+ // reach the parent limit node, return the expr computed
+ return expr;
+ }
+ int firstIndex = expr.indexOf("..");
+ int lastIndex = expr.lastIndexOf("..");
+
+ if (firstIndex == -1) {
+ // this is a error, since current node is not parent limit node,
+ // we must find somewhere a way to go up in nodes
+ throw new IllegalArgumentException(expr + " should contains at least one \"..\"");
+ }
+
+ if (firstIndex != 0) {
+ // this is a error, the ../ must be at the beginning of the expression
+ throw new IllegalArgumentException("\"..\" must be at the beginning but was : " + expr);
+ }
+
+ NavigationTreeNode ancestor = getParent();
+
+ if (firstIndex == lastIndex) {
+ // found only one go up, so must be substitute by the parent node context
+
+ String newExpr = expr.substring(2);
+ //String newExpr = expr.substring(expr.startsWith("../") ? 3 : 2);
+
+ if (getParent().equals(parentNode)) {
+
+ // parent node is the final parent node, so no substitution needed
+ return newExpr;
+ //return parentNode.computeJXPath(newExpr, parentNode);
+ }
+
+ // ancestor must have a jaxxContextEntryPath
+ if (ancestor.jaxxContextEntryPath == null) {
+ throw new IllegalArgumentException("with the expression " + expr + ", the ancestor node (" + ancestor + ") must have a jaxxContextEntryPath definition, but was not ");
+ }
+
+ newExpr = ancestor.jaxxContextEntryPath + newExpr;
+
+ return ancestor.computeJXPath(newExpr, parentNode);
+ }
+
+ // have more than one go up, so the ancestor node can not have a jaxxContextEntryPath
+ if (ancestor.jaxxContextEntryPath != null) {
+ throw new IllegalArgumentException("with the expression " + expr + ", the ancestor node can not have a jaxxContextEntryPath definition");
+ }
+
+ // substitute the last ..[/] and delegate to ancestor
+ String newExpr = expr.substring(0, lastIndex - 1) + expr.substring(lastIndex + (expr.charAt(lastIndex + 3) == '/' ? 3 : 2));
+
+ return ancestor.computeJXPath(newExpr, parentNode);
+ }
+
+ public void clearCache() {
+ clearCache(false);
+ }
+
+ public void clearCache(boolean deep) {
+
+ // clear bean cache
+ cachedBean = null;
+
+ // clear context navigation cache
+ cachedNavigationPath = null;
+
+ // clear render cache
+ if (renderer != null) {
+ renderer.setRendererCachedValue(null);
+ }
+
+ if (deep) {
+ // clear cache in childs
+ Enumeration childs = this.children();
+ while (childs.hasMoreElements()) {
+ NavigationTreeNode o = (NavigationTreeNode) childs.nextElement();
+ o.clearCache();
+ }
+ }
+ }
+
+ public Object getCachedBean() {
+ return cachedBean;
+ }
+
+ public void setCachedBean(Object cachedBean) {
+ this.cachedBean = cachedBean;
+ }
+ }
+
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeModelBuilder.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeModelBuilder.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeModelBuilder.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,152 @@
+package jaxx.runtime.gwt.navigation;
+
+import jaxx.runtime.Decorator;
+import jaxx.runtime.JAXXAction;
+import jaxx.runtime.JAXXContextEntryDef;
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.gwt.navigation.NavigationTreeModel.NavigationTreeNode;
+import jaxx.runtime.gwt.navigation.NavigationUtil.NodeRenderer;
+
+/** @author chemit */
+public class NavigationTreeModelBuilder {
+
+ protected NavigationTreeModel model;
+
+ public NavigationTreeModelBuilder(String navigationSeparator) {
+ model = new NavigationTreeModel(null, navigationSeparator);
+ }
+
+ public NavigationTreeModel getModel() {
+ return model;
+ }
+
+ public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle,
+ JAXXContextEntryDef entryDef,
+ String entryPath,
+ String contextName,
+ Class<? extends JAXXObject> uiClass,
+ Class<? extends JAXXAction> actionClass) {
+ NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(libelle), entryDef, entryPath, contextName, uiClass, actionClass);
+ return addChildNode(parentNode, node);
+ }
+
+ public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle,
+ JAXXContextEntryDef entryDef,
+ String contextName,
+ Class<? extends JAXXObject> uiClass,
+ Class<? extends JAXXAction> actionClass) {
+ NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(libelle), entryDef, contextName, uiClass, actionClass);
+ return addChildNode(parentNode, node);
+ }
+
+ public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle,
+ String entryPath,
+ String contextName,
+ Class<? extends JAXXObject> uiClass,
+ Class<? extends JAXXAction> actionClass) {
+ NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(libelle), entryPath, contextName, uiClass, actionClass);
+ return addChildNode(parentNode, node);
+ }
+
+ public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator,
+ JAXXContextEntryDef entryDef,
+ String entryPath,
+ String contextName,
+ Class<? extends JAXXObject> uiClass,
+ Class<? extends JAXXAction> actionClass) {
+ NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(decorator), entryDef, entryPath, contextName, uiClass, actionClass);
+ return addChildNode(parentNode, node);
+ }
+
+ public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator,
+ JAXXContextEntryDef entryDef,
+ String contextName,
+ Class<? extends JAXXObject> uiClass,
+ Class<? extends JAXXAction> actionClass) {
+ NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(decorator), entryDef, contextName, uiClass, actionClass);
+ return addChildNode(parentNode, node);
+ }
+
+ public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator,
+ String entryPath,
+ String contextName,
+ Class<? extends JAXXObject> uiClass,
+ Class<? extends JAXXAction> actionClass) {
+ NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(decorator), entryPath, contextName, uiClass, actionClass);
+ return addChildNode(parentNode, node);
+ }
+
+ protected NavigationTreeNode addChildNode(NavigationTreeNode parentNode, NavigationTreeNode node) {
+ if (parentNode == null) {
+ model.setRoot(node);
+ } else {
+ parentNode.add(node);
+ }
+ model.nodeStructureChanged(parentNode);
+ return node;
+ }
+
+ public NavigationTreeNode removeChildNode(NavigationTreeNode node) {
+ NavigationTreeNode parentNode = node.getParent();
+ model.removeNodeFromParent(node);
+ return parentNode;
+ }
+
+ public static abstract class ChildBuilder<O> {
+
+ protected NavigationTreeModelBuilder builder;
+
+ protected ChildBuilder(NavigationTreeModelBuilder builder) {
+ this.builder = builder;
+ }
+
+ protected abstract void init(Class<? extends O> klass);
+
+ protected abstract Decorator<? extends O> getDecorator(O child);
+
+ protected abstract String getJXPath(O child);
+
+ protected abstract String getNavigationPath(O child);
+
+ public void build(NavigationTreeNode parent, boolean cacheValues, Class<? extends O> klass, java.util.Collection<? extends O> beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) {
+
+ if (beans == null || beans.isEmpty()) {
+ // no bean to treate
+ return;
+ }
+
+ init(klass);
+
+ NavigationTreeNode node;
+
+ for (O o : beans) {
+ node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass);
+ if (cacheValues) {
+ // cache the bean value to improve performance
+ node.setCachedBean(o);
+ }
+ }
+ }
+
+ public void build(NavigationTreeNode parent, boolean cacheValues, Class<? extends O> klass, O[] beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) {
+
+ if (beans == null || beans.length == 0) {
+ // no bean to treate
+ return;
+ }
+
+ init(klass);
+
+ NavigationTreeNode node;
+
+ for (O o : beans) {
+ node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass);
+ if (cacheValues) {
+ // cache the bean value to improve performance
+ node.setCachedBean(o);
+ }
+ }
+ }
+ }
+
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeSelectionAdapter.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeSelectionAdapter.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeSelectionAdapter.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,243 @@
+package jaxx.runtime.gwt.navigation;
+
+import jaxx.runtime.JAXXAction;
+import jaxx.runtime.JAXXContextEntryDef;
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.gwt.navigation.NavigationTreeModel.NavigationTreeNode;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JTree;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+import java.awt.Component;
+
+/** A {@link javax.swing.event.TreeSelectionListener} implementation@author chemit */
+public abstract class NavigationTreeSelectionAdapter implements TreeSelectionListener {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(NavigationTreeSelectionAdapter.class);
+
+ //static public final String NAVIGATION_CONTEXT_PATH = "navigation-context-path";
+
+ //static public final String NAVIGATION_SELECTED_NODE = "navigation-selected-node";
+
+ static public final String NAVIGATION_SELECTED_BEAN = "navigation-selected-bean";
+
+ static public final JAXXContextEntryDef<String> NAVIGATION_SELECTED_PATH_ENTRY_DEF = JAXXContextEntryDef.newDef("navigation-selected-path", String.class);
+
+ static public final JAXXContextEntryDef<NavigationTreeNode> NAVIGATION_SELECTED_NODE_ENTRY_DEF = JAXXContextEntryDef.newDef("navigation-selected-node", NavigationTreeNode.class);
+
+ static public final JAXXContextEntryDef<Boolean> GO_BACK_DEF = JAXXContextEntryDef.newDef("goBack", Boolean.class);
+
+ /** defined the stategy of instanciation of ui */
+ public enum Strategy {
+ /** instanciate a ui for a node */
+ PER_NODE,
+ /** instanciate only one a ui for a type,nodes will share the instanciation */
+ PER_UI_TYPE
+ }
+
+ /** la classe d'ui par defaut, associé à un noeud de l'arbe */
+ protected Class<? extends JAXXObject> defaultUIClass;
+
+ protected Class<? extends JAXXAction> defaultUIHandlerClass;
+
+ /** l'ui contenant l'arbre de navigation */
+ protected JAXXObject context;
+
+ protected Strategy strategy;
+
+ protected NavigationTreeSelectionAdapter(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context, Strategy strategy) {
+ this.defaultUIClass = defaultUIClass;
+ this.defaultUIHandlerClass = defaultUIHandlerClass;
+ this.context = context;
+ this.strategy = strategy;
+ }
+
+
+ protected abstract NavigationTreeModel getNavigationTreeModel();
+
+ /**
+ * @return le composent actuellement visible associé au noeud courant ou au noeud précédent
+ * lors d'un changement de noeud.
+ */
+ protected abstract Component getCurrentUI();
+
+ /**
+ * @param node le noeud associé à l'ui à retrouver
+ * @return l'ui associé au novueau noeud sélectionné
+ */
+ protected abstract Component getUI(NavigationTreeNode node);
+
+ /**
+ * @param event l'evenement de selection de noeud
+ * @param component le composent actuellement visible
+ * @return <code>true</code> si le composent a bien été fermé, <code>false</code> sinon
+ * @throws Exception if any
+ */
+ protected abstract boolean closeUI(TreeSelectionEvent event, Component component) throws Exception;
+
+ /**
+ * Instancie une nouvelle ui associé à un noeud de l'arbre de navigation
+ *
+ * @param node le noeud associé à l'ui à créer
+ * @return la nouvelle ui associée au noeud
+ * @throws Exception if any
+ */
+ protected abstract Component createUI(NavigationTreeNode node) throws Exception;
+
+ /**
+ * Ouvre l'ui associée au noeud sélectionné dans l'arbre de navigation.
+ *
+ * @param newUI l'ui associé au noeud sélectionné à ouvrir
+ * @param node le node de l'ui a ouvrir
+ * @throws Exception if any
+ */
+ protected abstract void openUI(Component newUI, NavigationTreeNode node) throws Exception;
+
+ /**
+ * Retourne au noeud précdemment sélectionné dans l'arbre de navigation, avec la possibilité de notifier
+ * une erreure survenue.
+ *
+ * @param event l'évènement de changement de noeud sélectionné.
+ * @param e l'erreur recontrée (ou null si pas d"erreur)
+ */
+ protected abstract void goBackToPreviousNode(TreeSelectionEvent event, Exception e);
+
+ /**
+ * Prepare le nouveau noeud sélectionné.
+ *
+ * @param event l'évènement de selection du noeud
+ * @return le noeud selectionné et preparé
+ */
+ protected NavigationTreeNode prepareNode(TreeSelectionEvent event) {
+ NavigationTreeNode node = (NavigationTreeNode) event.getPath().getLastPathComponent();
+
+ if (node.getJaxxClass() == null) {
+ // no ui is associated with this node, display a empty content
+ node.setJaxxClass(defaultUIClass);
+ }
+
+ if (node.getJaxxActionClass() == null) {
+ node.setJaxxActionClass(defaultUIHandlerClass);
+ }
+ return node;
+ }
+
+ public void valueChanged(TreeSelectionEvent event) {
+ if (event.getOldLeadSelectionPath() != null && event.getOldLeadSelectionPath().equals(event.getPath())) {
+ // do not treate this if no path changed
+ return;
+ }
+
+ Boolean goBack = GO_BACK_DEF.getContextValue(context);
+ if (goBack != null && goBack) {
+ // do not treate this, apsecial flag told us :)
+ GO_BACK_DEF.removeContextValue(context);
+ return;
+ }
+
+ try {
+
+ NavigationTreeNode node = prepareNode(event);
+
+ String path = node.getContextPath();
+
+ if (log.isTraceEnabled()) {
+ log.trace(path);
+ }
+
+ Component newUI = getUI(node);
+ Component component = getCurrentUI();
+
+ if (newUI != null && strategy == Strategy.PER_NODE && newUI.equals(component)) {
+ // call back from goto back to previous node, do nothing
+ return;
+ }
+
+ if (!closeUI(event, component)) {
+ GO_BACK_DEF.setContextValue(context, Boolean.TRUE);
+ // previous ui was not closed, so reselect the previous node in navigation
+ goBackToPreviousNode(event, null);
+ // and quit
+ return;
+ }
+
+ // now, we are free to open the ui associated with the selected node in navigation
+
+ // always clean cache on the node before all
+ node.cachedBean = null;
+ if (node.renderer != null) {
+ node.renderer.setRendererCachedValue(null);
+ }
+ // before all, attach bean in context associated with the selected node in naivgation tree
+ Object data = getNavigationTreeModel().getJAXXContextValue(context, path);
+
+ addSelectedBeanInContext(node, data);
+
+ if (newUI == null) {
+ // instanciate a new ui associated with the selected node
+ newUI = createUI(node);
+ }
+
+ // save in context current node context path
+ NAVIGATION_SELECTED_PATH_ENTRY_DEF.setContextValue(context, node.getContextPath());
+
+ // save in context current node
+ NAVIGATION_SELECTED_NODE_ENTRY_DEF.setContextValue(context, node);
+
+ // really open the ui associated with the selected node
+ openUI(newUI, node);
+
+ } catch (Exception e) {
+ // remove data from context
+
+ // if any error, go back to previvous node
+ goBackToPreviousNode(event, e);
+ }
+ }
+
+ protected void addSelectedBeanInContext(NavigationTreeNode node, Object data) {
+
+ if (log.isDebugEnabled()) {
+ log.debug("find data for contextPath <" + node.getContextPath() + "> : " + (data == null ? null : data.getClass()));
+ }
+
+ context.removeContextValue(Object.class, NAVIGATION_SELECTED_BEAN);
+
+ if (data != null) {
+ context.setContextValue(data, NAVIGATION_SELECTED_BEAN);
+ //todo should we not use this to avoid conflict in context ?
+ context.setContextValue(data);
+ }
+ }
+
+ protected String getNodeConstraints(NavigationTreeNode node) {
+ String constraints;
+ switch (strategy) {
+ case PER_NODE:
+ constraints = node.getContextPath();
+ break;
+ case PER_UI_TYPE:
+ constraints = node.getJaxxClass().getName();
+ break;
+ default:
+ throw new IllegalArgumentException("could not find constraint for node : " + node);
+ }
+ return constraints;
+ }
+
+ protected void returnToPreviousNode(JTree tree, TreeSelectionEvent event) {
+ // go back to previous node
+ // put in context a tag to not come back again here
+ TreePath oldPath = event.getOldLeadSelectionPath();
+ //NavigationTreeNode oldNode = (NavigationTreeNode) oldPath.getLastPathComponent();
+ if (oldPath != null) {
+ tree.setSelectionPath(oldPath);
+ }
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeSelectionAdapterWithCardLayout.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeSelectionAdapterWithCardLayout.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationTreeSelectionAdapterWithCardLayout.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,109 @@
+package jaxx.runtime.gwt.navigation;
+
+import jaxx.runtime.JAXXAction;
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.JAXXInitialContext;
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.gwt.CardLayout2;
+import jaxx.runtime.gwt.navigation.NavigationTreeModel.NavigationTreeNode;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JPanel;
+import javax.swing.event.TreeSelectionEvent;
+import java.awt.Component;
+
+/**
+ * Simple {@link NavigationTreeSelectionAdapter} implementation with a {@link jaxx.runtime.gwt.CardLayout2} to manage components to
+ * associated with tree's nodes.
+ * <p/>
+ * For each node, the ui associated has a constraints in a cardlayout which is the node context path.
+ * <p/>
+ * A single container managed by the cardlayout is used to display the components associated with tree's nodes.
+ *
+ * @author chemit
+ */
+public abstract class NavigationTreeSelectionAdapterWithCardLayout extends NavigationTreeSelectionAdapter {
+
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(NavigationTreeSelectionAdapterWithCardLayout.class);
+
+ /**
+ * All components associated with a tree's node is displayed in a single container.
+ *
+ * @return the containter of components
+ */
+ protected abstract JPanel getContentContainer();
+
+ /**
+ * the cardlayout managing components associated with tree node. The constraints
+ * of each component is the node contextPath.
+ *
+ * @return the layout used to display components associated with tree's nodes.
+ */
+ protected abstract CardLayout2 getContentLayout();
+
+ public NavigationTreeSelectionAdapterWithCardLayout(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context, Strategy strategy) {
+ super(defaultUIClass, defaultUIHandlerClass, context,strategy);
+
+ if (getContentContainer() == null) {
+ throw new IllegalArgumentException("could not have a null 'contentContainer' in ui " + context);
+ }
+ if (getContentLayout() == null) {
+ throw new IllegalArgumentException("could not have a null 'contentLayout' in ui " + context);
+ }
+ }
+
+ protected Component getCurrentUI() {
+ CardLayout2 layout = getContentLayout();
+ JPanel container = getContentContainer();
+ return layout.getVisibleComponent(container);
+ }
+
+ protected Component getUI(NavigationTreeNode node) {
+ CardLayout2 layout = getContentLayout();
+ JPanel container = getContentContainer();
+ String path = getNodeConstraints(node);
+ return layout.contains(path) ? layout.getComponent(container, path) : null;
+ }
+
+ protected void openUI(Component newUI, NavigationTreeNode node) throws Exception {
+
+ CardLayout2 layout = getContentLayout();
+ JPanel container = getContentContainer();
+ // switch layout
+ layout.show(container, getNodeConstraints(node));
+ }
+
+ protected boolean closeUI(TreeSelectionEvent event, Component component) throws Exception {
+ // by default, we says that component was succesfull closed
+ return true;
+ }
+
+ protected Component createUI(NavigationTreeNode node) throws Exception {
+ JAXXObject newUI;
+
+ if (node.getJaxxActionClass() != null) {
+ JAXXAction action = node.getJaxxActionClass().newInstance();
+ // init context with
+ JAXXInitialContext context = action.init(this.context);
+ // must instanciate the ui with an JAXXInitialContext
+ newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(context);
+ } else {
+ if (log.isWarnEnabled()) {
+ log.warn("no action associated with ui " + node.getJaxxClass());
+ }
+ // no action associated, just
+ newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(this.context);
+ }
+ if (log.isDebugEnabled()) {
+ log.debug("instanciate new ui " + newUI);
+ }
+
+ getContentContainer().add((Component) newUI, getNodeConstraints(node));
+ return (Component) newUI;
+ }
+}
+
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationUtil.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/navigation/NavigationUtil.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,155 @@
+package jaxx.runtime.gwt.navigation;
+
+import jaxx.runtime.Decorator;
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.gwt.navigation.NavigationTreeModel.NavigationTreeNode;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import static org.codelutin.i18n.I18n._;
+
+import java.lang.reflect.InvocationTargetException;
+import java.util.regex.Pattern;
+
+/**
+ * Usefull methods on {@link NavigationTreeModel} and others.
+ *
+ * @author chemit
+ * @see jaxx.runtime.gwt.navigation.NavigationTreeModel
+ * @see jaxx.runtime.gwt.navigation.NavigationTreeModel.NavigationTreeNode
+ */
+public class NavigationUtil {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(NavigationUtil.class);
+
+ public static String getCurrentNavigationNath(JAXXContext context) {
+ return NavigationTreeSelectionAdapter.NAVIGATION_SELECTED_PATH_ENTRY_DEF.getContextValue(context);
+ }
+
+ public static NavigationTreeNode getSelectedNode(JAXXContext context) {
+ return NavigationTreeSelectionAdapter.NAVIGATION_SELECTED_NODE_ENTRY_DEF.getContextValue(context);
+ }
+
+ public static <O> O getSelectedBean(JAXXContext context, Class<O> clazz) {
+ return context.getContextValue(clazz, NavigationTreeSelectionAdapter.NAVIGATION_SELECTED_BEAN);
+ }
+
+ public static Object getContextValue(JAXXContext context, String contextKey, String navigationPath) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException {
+
+ NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey);
+
+ return navigationModel.getJAXXContextValue(context, navigationPath);
+ }
+
+ public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath) {
+
+ NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey);
+
+ return navigationModel.findNode(navigationPath);
+ }
+
+ public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath, String regex) {
+
+ NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey);
+
+ return navigationModel.findNode(navigationPath, regex);
+ }
+
+
+ public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath, Pattern regex) {
+
+ NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey);
+
+ return navigationModel.findNode(navigationPath, regex);
+ }
+
+ public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath, String regex, String suffix) {
+
+ NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey);
+
+ NavigationTreeNode navigationTreeNode = navigationModel.findNode(navigationPath, regex);
+ if (navigationTreeNode != null && suffix != null) {
+ navigationTreeNode = navigationModel.findNode(navigationTreeNode, suffix);
+ }
+ return navigationTreeNode;
+ }
+
+ public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath, Pattern regex, String suffix) {
+
+ NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey);
+
+ NavigationTreeNode navigationTreeNode = navigationModel.findNode(navigationPath, regex);
+ if (navigationTreeNode != null && suffix != null) {
+ navigationTreeNode = navigationModel.findNode(navigationTreeNode, suffix);
+ }
+ return navigationTreeNode;
+ }
+
+ public static class NodeRenderer implements java.io.Serializable {
+
+ protected String libelle;
+
+ protected Decorator decorator;
+
+ protected NavigationTreeNode node;
+
+ protected Class<?> internalClass;
+
+ protected String rendererCachedValue;
+
+ private static final long serialVersionUID = -1238962588426200861L;
+
+ public NodeRenderer(String libelle) {
+ this.libelle = libelle;
+ this.internalClass = String.class;
+ }
+
+ public NodeRenderer(Decorator decorator) {
+ this.decorator = decorator;
+ this.internalClass = decorator.getInternalClass();
+ }
+
+ public String toString(JAXXContext context) {
+ if (rendererCachedValue != null) {
+ return rendererCachedValue;
+ }
+
+ String result;
+
+ if (libelle != null) {
+ // simple libelle renderer
+ result = _(libelle);
+ } else {
+
+ // with decorator renderer
+
+ try {
+ Object bean = node.getJAXXContextValue(context);
+ result = decorator.toString(bean);
+
+ } catch (Exception e) {
+ result = "";
+ }
+ }
+ setRendererCachedValue(result);
+ return result;
+ }
+
+ public void setNode(NavigationTreeNode node) {
+ this.node = node;
+ }
+
+ public Class<?> getInternalClass() {
+ return internalClass;
+ }
+
+ public void setRendererCachedValue(String rendererCachedValue) {
+ this.rendererCachedValue = rendererCachedValue;
+ if (log.isDebugEnabled()) {
+ log.debug(rendererCachedValue);
+ }
+ }
+ }
+
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardModel.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,238 @@
+package jaxx.runtime.gwt.wizard;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+/**
+ * Un modèle de wizard.
+ *
+ *
+ * <b>Note:</b> le type des étapes doit être uné énumération qui implante
+ * {@link WizardStep}.
+ *
+ * @param <E> le type des étapes.
+ *
+ * @author tony
+ * @since 1.3
+ * @see WizardStep
+ */
+public class WizardModel<E extends WizardStep> {
+
+ public static final String STEPS_PROPERTY_NAME = "steps";
+ public static final String STEP_PROPERTY_NAME = "step";
+ public static final String PREVIOUS_STEP_PROPERTY_NAME = "previousStep";
+ public static final String NEXT_STEP_PROPERTY_NAME = "nextStep";
+ public static final String VALID_STEP_PROPERTY_NAME = "validStep";
+ /**
+ * le type d'une etape du model (doit etre une enumeration)
+ */
+ protected final Class<E> stepClass;
+ /**
+ * Toutes les étapes à passer
+ */
+ protected java.util.List<E> steps;
+ /**
+ * L'étape courante
+ */
+ protected E step;
+ /**
+ * drapeau pour valider l'état de l'étape courante
+ */
+ protected boolean validStep;
+ /**
+ * drapeau lorsque le modele effectue des operations
+ * de transformation de modele mais que les écouteurs
+ * ne devraient pas tenir compte des modifications
+ */
+ protected boolean valueAdjusting;
+ /**
+ * pour propager les changements dans le modèle vers l'ui
+ */
+ protected PropertyChangeSupport pcs;
+
+ public WizardModel(Class<E> stepClass, E... steps) {
+ if (!Enum.class.isAssignableFrom(stepClass)) {
+ throw new IllegalArgumentException("stepClass must be an Enumeration but was " + stepClass.getName());
+ }
+ this.stepClass = stepClass;
+ this.pcs = new PropertyChangeSupport(this);
+ this.steps = new java.util.ArrayList<E>();
+ if (steps.length > 0) {
+ setSteps(steps);
+ }
+ }
+
+ public void start() {
+ if (steps.isEmpty()) {
+ throw new IllegalStateException("can not start, no step found");
+ }
+ step = null;
+ E startStep = steps.get(0);
+ setStep(startStep);
+ }
+
+ public void gotoNextStep() {
+ E nextStep = getNextStep();
+ if (nextStep == null) {
+ throw new IllegalStateException("no next step to go");
+ }
+ setStep(nextStep);
+ }
+
+ public void gotoPreviousStep() {
+ E previousStep = getPreviousStep();
+ if (previousStep == null) {
+ throw new IllegalStateException("no previous step to go");
+ }
+ setStep(previousStep);
+ }
+
+ public void gotoStep(E e) {
+ if (e == null) {
+ throw new NullPointerException("step can not be null");
+ }
+ if (!steps.contains(e)) {
+ throw new IllegalStateException("step " + e.toString() + " is not in universe of steps (" + steps + ")");
+ }
+ setStep(e);
+ }
+
+ public E getStep() {
+ return step;
+ }
+
+ public int getStepIndex(E s) {
+ int index = steps.indexOf(s);
+ return index;
+ }
+
+ public boolean isValidStep() {
+ return validStep;
+ }
+
+ public E getPreviousStep() {
+ E e = getPreviousStep(step);
+ return e;
+ }
+
+ public E getPreviousStep(E step) {
+ int index = getStepIndex(step);
+ if (index < 1) {
+ // si pas de step ou sur premier step
+ return null;
+ }
+ return steps.get(index - 1);
+ }
+
+ public E getNextStep(E step) {
+ int index = getStepIndex(step);
+ if (index < 1) {
+ // si pas de step ou sur premier step
+ return null;
+ }
+ return steps.get(index - 1);
+ }
+
+ public E getNextStep() {
+ int index = getStepIndex(step);
+ if (index == -1 || index == steps.size() - 1) {
+ // si pas de step positionne ou dernier etape
+ return null;
+ }
+ return steps.get(index + 1);
+ }
+
+ public java.util.List<E> getSteps() {
+ return steps;
+ }
+
+ public boolean isValueAdjusting() {
+ return valueAdjusting;
+ }
+
+ /**
+ * Change l'univers des etapes.
+ *
+ * Note: on presume ici que l'étape courante est toujours la meme.
+ *
+ * @param steps le nouvel univers des etapes
+ */
+ public void setSteps(E... steps) {
+ java.util.List<E> oldValue = this.steps;
+ this.steps = java.util.Collections.unmodifiableList(java.util.Arrays.asList(steps));
+ firePropertyChange(STEPS_PROPERTY_NAME, oldValue, this.steps);
+ // la propriete nextStep peut avoir changee
+ firePropertyChange(NEXT_STEP_PROPERTY_NAME, null, getNextStep());
+ }
+
+ public void setValueAdjusting(boolean valueAdjusting) {
+ this.valueAdjusting = valueAdjusting;
+ }
+
+ public boolean validate(E s) {
+ return step != null;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListeners() {
+ for (PropertyChangeListener l : pcs.getPropertyChangeListeners()) {
+ pcs.removePropertyChangeListener(l);
+ }
+ }
+
+ public void validate() {
+ if (step == null) {
+ // pas de validation quand aucune etape n'est sélectionnée
+ return;
+ }
+ boolean validate = validate(step);
+ this.validStep = validate;
+ // toujours forcer la propagation
+ firePropertyChange(VALID_STEP_PROPERTY_NAME, null, validStep);
+ }
+
+ protected Class<E> getStepClass() {
+ return stepClass;
+ }
+
+ protected void setStep(E step) {
+ E oldValue = this.step;
+ this.step = step;
+ firePropertyChange(STEP_PROPERTY_NAME, oldValue, step);
+ // la propriete nextStep peut avoir changee
+ firePropertyChange(NEXT_STEP_PROPERTY_NAME, null, getNextStep());
+ // la propriete previousStep peut avoir changee
+ firePropertyChange(PREVIOUS_STEP_PROPERTY_NAME, null, getPreviousStep());
+ validate();
+ }
+
+ protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
+ pcs.firePropertyChange(propertyName, oldValue, newValue);
+ }
+
+ protected void fireIndexedPropertyChange(String propertyName, int index, Object oldValue, Object newValue) {
+ pcs.fireIndexedPropertyChange(propertyName, index, oldValue, newValue);
+ }
+
+ protected E[] updateStepUniverse() {
+ return null;
+ }
+
+ protected void updateUniverse() {
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationAction.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationAction.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationAction.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,108 @@
+package jaxx.runtime.gwt.wizard;
+
+import javax.swing.SwingWorker;
+import jaxx.runtime.JAXXContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * La classe de base a implanter pour definir l'action d'une operation
+ * dans un wizard.
+ *
+ * @author tony
+ * @param <E> le type d'étapes
+ * @param <M> le type de modèle
+ * @since 1.3
+ */
+public abstract class WizardOperationAction<E extends WizardOperationStep, M extends WizardOperationModel<E>> extends SwingWorker<WizardOperationState, String> {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static final Log log = LogFactory.getLog(WizardOperationAction.class);
+ E operation;
+ WizardOperationState operationState;
+ Exception error;
+
+ public WizardOperationAction(E operation) {
+ super();
+ if (!operation.isOperation()) {
+ throw new IllegalArgumentException("the step " + operation + " has no operation defined");
+ }
+ this.operation = operation;
+ }
+
+ public E getOperation() {
+ return operation;
+ }
+
+ public Exception getError() {
+ return error;
+ }
+
+ public void setError(Exception e) {
+ error = e;
+ }
+
+ public void sendMessage(String msg) {
+ firePropertyChange("message", null, msg);
+ }
+
+ public abstract void start(JAXXContext context);
+
+ public abstract void beforeAction(JAXXContext context, M model) throws Exception;
+
+ public abstract WizardOperationState doAction(M model) throws Exception;
+
+ public abstract WizardOperationState onError(M model, Exception e);
+
+ public abstract WizardOperationState onCancel(M model, Exception e);
+
+ protected abstract M getModel();
+
+ public WizardOperationState getOperationState() {
+ return operationState;
+ }
+
+ protected abstract JAXXContext getContext();
+
+ @Override
+ public String toString() {
+ return super.toString() + " < operation: " + operation + ", state: " + getState() + " >";
+ }
+
+ @Override
+ protected WizardOperationState doInBackground() throws Exception {
+ log.trace(this);
+ WizardOperationState result;
+ M model = getModel();
+ try {
+ beforeAction(getContext(), model);
+ result = doAction(model);
+ } catch (Exception e) {
+ error = e;
+ result = onError(model, e);
+ }
+ return result;
+ }
+
+ @Override
+ protected void done() {
+ log.trace(this);
+ WizardOperationState result = null;
+ try {
+ if (isCancelled()) {
+
+ result = onCancel(getModel(), error);
+ } else {
+ result = get();
+ }
+ } catch (Exception e) {
+ result = WizardOperationState.FAILED;
+ error = e;
+ // ne devrait jamais arrivé ?
+ log.error(e.getMessage(), e);
+ } finally {
+ // on enregistre le resultat de l'opération
+ this.operationState = result;
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationActionThread.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationActionThread.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationActionThread.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,204 @@
+package jaxx.runtime.gwt.wizard;
+
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.Date;
+import javax.swing.SwingWorker.StateValue;
+import jaxx.runtime.JAXXContext;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * Thread qui réalise les opérations.
+ *
+ * Pour exécuter une nouvelle opération, on utilise la méthode
+ * {@link #launchOperation(SynchroActionWorker)}.
+ *
+ * Note: Pour bloquer (ou débloquer) le thread, on utilise la méthode {@link #setWaiting(boolean)}
+ *
+ * @param <E> le type des etapes
+ * @param <M> le type de modele
+ * @param <A> le type d'action d'operation
+ *
+ * @author tony
+ * @since 1.3
+ */
+public abstract class WizardOperationActionThread<E extends WizardOperationStep, M extends WizardOperationModel<E>, A extends WizardOperationAction<E, M>> extends Thread implements PropertyChangeListener {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static final Log log = LogFactory.getLog(WizardOperationActionThread.class);
+ /**
+ * l'état du thread si annulé
+ */
+ private boolean canceled;
+ protected Class<M> modelClass;
+ protected A currentAction;
+ /**
+ * un lock pour permettre la suspension et la reprise du thread
+ * lors du mode interactif.
+ */
+ private final Object LOCK = new Object();
+
+ protected abstract M getModel();
+
+ protected abstract JAXXContext getContext();
+
+ public WizardOperationActionThread(Class<M> modelClass) throws IllegalArgumentException {
+ super(WizardOperationActionThread.class.getSimpleName() + " " + new Date());
+ this.modelClass = modelClass;
+ }
+
+ public void cancel() {
+ log.info("cancel " + this);
+ this.canceled = true;
+
+ // on annule le modele
+ getModel().cancel();
+
+ // on rend la main au thread
+ setWaiting(false);
+ }
+
+ @SuppressWarnings("unchecked")
+ public A launchOperation(E operation) {
+
+ if (currentAction != null && (!currentAction.isDone() || currentAction.operationState == WizardOperationState.RUNNING)) {
+ // on ne peut traiter qu'une seule opération à la fois
+ throw new IllegalStateException("can not add a operation when thread is busy, or has another operation to be done");
+ }
+ currentAction = (A) getModel().getOperationAction(operation);
+
+ // on libere le thread pour qu'il execute l'opération
+ setWaiting(false);
+
+ return currentAction;
+ }
+
+ public A getCurrentAction() {
+ return currentAction;
+ }
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ log.trace(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
+ if ("state".equals(evt.getPropertyName())) {
+ StateValue state = (StateValue) evt.getNewValue();
+ if (state == StateValue.DONE) {
+ // on rend la main au thread pour qu'il attende une prochaine operation
+ setWaiting(false);
+ }
+ }
+ }
+
+ @Override
+ public void run() {
+ try {
+
+ // on vérifie que le context contient bien le modèle
+ if (getModel() == null) {
+ throw new NullPointerException("could not find model " + modelClass + " for " + this);
+ }
+
+ while (!canceled) {
+
+ if (canceled) {
+ // une annulation a été demandé
+ // donc même si une opération est demandée, on ne la traite
+ // pas
+ break;
+ }
+
+ // en attente qu'une opération
+ // le block est bloqué jusqu'à arrivée d'une opération
+ // ou une demande d'annulation
+ setWaiting(true);
+
+ // le thread a repris la main, donc plus en attente
+ log.trace("no more waiting " + this);
+
+ if (!canceled) {
+ // une opération a été demandée
+
+ // le thread écoute les modifications de l'action
+ currentAction.addPropertyChangeListener(this);
+
+ // l'opération passe en etant en cours
+ getModel().setOperationState(WizardOperationState.RUNNING);
+
+ // démarrage de l'opération dans un worker
+ currentAction.start(getContext());
+ // le thread est bloqué jusqu'à la fin de l'opération
+ // ou une demande d'annulation
+ setWaiting(true);
+
+ // le thread reprend la main des que l'operation
+ // est terminée ou a été annulée, on passera alors
+ // dans la méthode onPropertyChanged
+
+ if (canceled) {
+ getModel().setOperationState(WizardOperationState.CANCELED);
+ } else {
+ getModel().setOperationState(currentAction.getOperationState());
+ }
+
+ // le thread n'écoute plus l'action car elle est terminée
+ // ou annulée
+ currentAction.removePropertyChangeListener(this);
+ // suppression de l'action
+ //currentAction = null;
+ }
+
+ }
+
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ } finally {
+ unlockThread();
+ log.trace(this + " will close...");
+ close();
+ }
+ }
+
+ /**
+ * La méthode pour nettoyer le thread, a la fermeture.
+ *
+ */
+ protected void close() {
+ // par defaut, on ne fait rien
+ log.trace(this);
+ }
+
+ protected void setWaiting(boolean waiting) {
+
+ if (waiting && !canceled) {
+ // locking thread
+ try {
+ lockThread();
+ } catch (InterruptedException ex) {
+ log.error(ex.getMessage(), ex);
+ canceled = true;
+ }
+ }
+
+ if (!waiting) {
+ // release lock
+ unlockThread();
+ }
+ }
+
+ protected void lockThread() throws InterruptedException {
+ synchronized (LOCK) {
+ log.trace(this);
+ // lock
+ LOCK.wait();
+ }
+ }
+
+ protected void unlockThread() {
+ synchronized (LOCK) {
+ log.trace(this);
+ // unlock
+ LOCK.notify();
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationModel.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,263 @@
+package jaxx.runtime.gwt.wizard;
+
+import java.util.Arrays;
+import java.util.EnumMap;
+import java.util.EnumSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import javax.swing.SwingWorker.StateValue;
+
+/**
+ * Un modèle de wizard avec des opérations.
+ *
+ * @param <E> le type des étapes.
+ * @author tony
+ * @since 1.3
+ */
+public class WizardOperationModel<E extends WizardOperationStep> extends WizardModel<E> {
+
+ public static final String OPERATIONS_PROPERTY_NAME = "operations";
+ public static final String OPERATION_STATE_PROPERTY_NAME = "operationState";
+ public static final String MODEL_STATE_PROPERTY_NAME = "modelState";
+ public static final String WAS_STARTED_PROPERTY_NAME = "wasStarted";
+
+ /**
+ * La liste des opérations à effectuer
+ */
+ protected Set<E> operations;
+ /**
+ * Pour conserver les états des opérations
+ */
+ protected Map<E, WizardOperationState> operationStates;
+ protected Map<E, WizardOperationAction> operationActions;
+ /**
+ * L'état générale du modèle
+ */
+ protected WizardOperationState modelState;
+ /**
+ * un drapeau pour savoir siune opération a été lancée
+ */
+ protected boolean wasStarted;
+
+ @SuppressWarnings("unchecked")
+ public <T extends Enum<T>> WizardOperationModel(Class<E> stepClass, E... steps) {
+ super(stepClass, steps);
+ Class<T> k = (Class) stepClass;
+ this.operationStates = (Map) new EnumMap(k);
+ this.operations = (Set<E>) EnumSet.noneOf(k);
+ this.operationActions = (Map) new EnumMap(k);
+ }
+
+ public Set<E> getOperations() {
+ return operations;
+ }
+
+ public WizardOperationState getModelState() {
+ return modelState;
+ }
+
+ public boolean isWasStarted() {
+ return wasStarted;
+ }
+
+ @SuppressWarnings("unchecked")
+ public E getOperation() {
+ return getStep() != null && getStep().isOperation() ? getStep() : null;
+ }
+
+ public WizardOperationState getOperationState() {
+ E operation = getOperation();
+ return getOperationState(operation);
+ }
+
+ public WizardOperationState getOperationState(E operation) {
+ return operationStates.get(operation);
+ }
+
+ public WizardOperationAction getOperationAction(E operation) {
+ WizardOperationAction action = operationActions.get(operation);
+ if (action == null) {
+ try {
+ action = operation.getActionClass().newInstance();
+ operationActions.put(operation, action);
+ } catch (Exception ex) {
+ throw new RuntimeException(ex);
+ }
+ }
+ return action;
+ }
+
+ public void setOperationState(WizardOperationState operationState) {
+ E operation = getOperation();
+ setOperationState(operation, operationState);
+ }
+
+ public void setOperationState(E operation, WizardOperationState operationState) {
+ WizardOperationState oldValue = getOperationState(operation);
+ this.operationStates.put(operation, operationState);
+ fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, getSteps().indexOf(operation), oldValue, operationState);
+ updateModelState(operation, operationState);
+ validate();
+ }
+
+ public boolean[] getAccessibleSteps() {
+ boolean[] result = new boolean[getSteps().size()];
+ int index = getSteps().indexOf(getStep());
+ if (index != -1) {
+
+ for (int i = 0, j = steps.size(); i < j; i++) {
+ if (i <= index) {
+ // tous les onglets inferieur ou egal au courant sont accessibles
+ result[i] = true;
+ continue;
+ }
+ // les onglets au dela de l'onglet sélectionné sont accessibles
+ // uniquement si l'onglet precedent est accessible, valide et son etat est a SUCCESSED
+ E previousStep = steps.get(i - 1);
+ result[i] = modelState == WizardOperationState.SUCCESSED ||
+ (result[i - 1] &&
+ validate(previousStep) &&
+ (!previousStep.isOperation() || getOperationState(previousStep) == WizardOperationState.SUCCESSED));
+ }
+ }
+ //System.out.println("accessibles steps -------- " + java.util.Arrays.toString(result));
+ return result;
+ }
+
+ @Override
+ public void start() {
+ super.start();
+ updateUniverse();
+ //setSteps(steps.toArray((E[]) Array.newInstance(stepClass, steps.size())));
+
+ // le modèle n'est pas démarré
+ setModelState(WizardOperationState.PENDING);
+ }
+
+ public void cancel() {
+
+ for (E op : operations) {
+ if (getOperationState(op) == WizardOperationState.PENDING) {
+ // on annule l'opération à venir
+ setOperationState(op, WizardOperationState.CANCELED);
+ }
+ }
+ setModelState(WizardOperationState.CANCELED);
+ if (getStep() != null && getStep().isOperation()) {
+ WizardOperationAction action = getOperationAction(getStep());
+ if (action != null) {
+ if (!action.isCancelled() && !action.isDone() && action.getState() == StateValue.STARTED) {
+ System.out.println("cancel action " + action);
+ // on annule l'action
+ action.cancel(true);
+ }
+ }
+ }
+ }
+
+ public WizardOperationModel<E> addOperation(E operation) {
+ operations.add(operation);
+ // mis a jour de l'univers des etapes et operations
+ updateUniverse();
+ // validation
+ validate();
+ return this;
+ }
+
+ public void removeOperation(E operation) {
+ operations.remove(operation);
+
+ // mis a jour de l'univers des etapes et operations
+ updateUniverse();
+ // validation
+ validate();
+ }
+
+ @Override
+ public void setSteps(E... steps) {
+ super.setSteps(steps);
+ // on force la propagation de la nouvelle liste
+ firePropertyChange(OPERATIONS_PROPERTY_NAME, null, operations);
+ updateOperationStates(Arrays.asList(steps));
+ }
+
+ public void updateOperationStates(List<E> steps) {
+ int index = 0;
+ for (E e : steps) {
+ fireIndexedPropertyChange(OPERATION_STATE_PROPERTY_NAME, index++, null, getOperationState(e));
+ }
+ firePropertyChange(MODEL_STATE_PROPERTY_NAME, null, modelState);
+ }
+
+ protected void setModelState(WizardOperationState modelState) {
+ WizardOperationState oldValue = this.modelState;
+ this.modelState = modelState;
+ firePropertyChange(MODEL_STATE_PROPERTY_NAME, oldValue, modelState);
+ if (!wasStarted) {
+ if ((oldValue == null || oldValue == WizardOperationState.PENDING) && modelState == WizardOperationState.RUNNING) {
+ this.wasStarted = true;
+ firePropertyChange(WAS_STARTED_PROPERTY_NAME, false, true);
+ }
+ }
+ }
+
+ protected void updateModelState(E operation, WizardOperationState operationState) {
+
+ switch (operationState) {
+ case RUNNING:
+ //le modele est occupé
+ setModelState(WizardOperationState.RUNNING);
+ break;
+ case FAILED:
+ //le modele est en erreur
+ setModelState(WizardOperationState.FAILED);
+ break;
+ case CANCELED:
+ //le modele devient annulé
+ setModelState(WizardOperationState.CANCELED);
+ return;
+ case PENDING:
+ //le modele est en attente
+ setModelState(WizardOperationState.PENDING);
+ break;
+ case NEED_FIX:
+ //le modele est en attente
+ setModelState(WizardOperationState.PENDING);
+ break;
+ case SUCCESSED:
+ // on regarde si on peut passer le model a l'état success
+ boolean valid = true;
+ for (E o : operations) {
+ if (getOperationState(o) != WizardOperationState.SUCCESSED) {
+ valid = false;
+ break;
+ }
+ }
+ if (valid) {
+ setModelState(WizardOperationState.SUCCESSED);
+ } else {
+ setModelState(WizardOperationState.PENDING);
+ }
+ break;
+ }
+ updateOperationStates(steps);
+ }
+
+ @Override
+ protected void updateUniverse() {
+ E[] newSteps = updateStepUniverse();
+ setSteps(newSteps);
+ }
+
+ protected int getOperationIndex(E operation) {
+ int index = 0;
+ for (E o : operations) {
+ if (operation == o) {
+ return index;
+ }
+ index++;
+ }
+ return -1;
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationState.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationState.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationState.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,32 @@
+package jaxx.runtime.gwt.wizard;
+
+/**
+ * Pour caractériser l'état d'une opération.
+ */
+public enum WizardOperationState {
+
+ /**
+ * quand l'opération n'a pas encore été réalisée
+ */
+ PENDING,
+ /**
+ * quand l'opération est en cours
+ */
+ RUNNING,
+ /**
+ * quand l'opération est annulé en cours d'exécution
+ */
+ CANCELED,
+ /**
+ * quand une erreur s'est produite pendant l'exécution
+ */
+ FAILED,
+ /**
+ * quand l'exécution s'est terminée mais requière des corrections
+ */
+ NEED_FIX,
+ /**
+ * quand l'exécution s'est terminée et ne requière pas de correction
+ */
+ SUCCESSED
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationStep.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationStep.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardOperationStep.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,34 @@
+package jaxx.runtime.gwt.wizard;
+
+/**
+ *
+ * Le contrat a implanter pour une etapes dans le modèle de wizard avec
+ * opérations.
+ *
+ * @author tony
+ * @since 1.3
+ */
+public interface WizardOperationStep extends WizardStep {
+
+ /**
+ * @return le label de l'opération
+ */
+ String getOperationLabel();
+
+ /**
+ * @return la description de l'opération
+ */
+ String getOperationDescription();
+
+ /**
+ * @return le type de l'action associée à l'étape ou <code>null</code> si
+ * l'étape n'a pas d'opération associée.
+ */
+ Class<? extends WizardOperationAction> getActionClass();
+
+ /**
+ * @return <code>true</code> si l'étape a une opération associée,
+ * <code>false</code> sinon.
+ */
+ boolean isOperation();
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardStep.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardStep.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardStep.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,20 @@
+package jaxx.runtime.gwt.wizard;
+
+import java.io.Serializable;
+
+/**
+ * le contrat d'une étape d'un wizard.
+ *
+ * @author tony
+ * @since 1.3
+ */
+public interface WizardStep extends Serializable {
+
+ String name();
+
+ int ordinal();
+
+ String getLabel();
+
+ String getDescription();
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardStepUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardStepUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardStepUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,14 @@
+package jaxx.runtime.gwt.wizard;
+
+/**
+ * Le contrat d'une ui d'étape.
+ *
+ * @param <E> le type d'étape
+ * @param <M> le type de modèle
+ * @author tony
+ * @since 1.3
+ */
+public interface WizardStepUI<E extends WizardStep, M extends WizardModel<E>> {
+
+ E getStep();
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,94 @@
+package jaxx.runtime.gwt.wizard;
+
+import javax.swing.JTabbedPane;
+
+/**
+ *
+ * Contrat a respecter pour une ui de wizard.
+ *
+ * @param <E> le type d'etape
+ * @param <M> le type de model
+ *
+ * @author tony
+ * @since 1.3
+ */
+public interface WizardUI<E extends WizardStep, M extends WizardModel<E>> {
+
+ /**
+ * @return le modèle de wizard
+ */
+ M getModel();
+
+ /**
+ *
+ * @return l'étape courante
+ */
+ E getSelectedStep();
+
+ /**
+ *
+ * @return l'ui de l'étape courante
+ */
+ WizardStepUI<E, M> getSelectedStepUI();
+
+ /**
+ *
+ * @param step l'étape donnée
+ * @return l'ui de l'étape donnée
+ */
+ WizardStepUI<E, M> getStepUI(E step);
+
+ /**
+ *
+ * @param stepIndex la position de l'étape
+ * @return l'ui de l'étape donée
+ */
+ WizardStepUI<E, M> getStepUI(int stepIndex);
+
+ /**
+ * démarre le wizard
+ */
+ void start();
+
+ /**
+ * //TODO il faudrait supprimer cette méthode
+ * @return le conteneur d'ui d'étapes
+ */
+ JTabbedPane getTabs();
+
+ /**
+ * Méthode invoqué lorsque la première opération du modèlé a été démarrée.
+ */
+ void onWasStarted();
+
+ /**
+ * Méthode invoquée lorsque l'univers des étapes a été modifié dans le
+ * modèle.
+ *
+ * @param steps les nouvelles étapes
+ */
+ void onStepsChanged(E[] steps);
+
+ /**
+ * Méthode invoquée lorsque l'étape courante a changé dans le modèle.
+ *
+ * @param newStep la nouvelle étape courante
+ */
+ void onStepChanged(E newStep);
+
+ /**
+ * Méthode invoquée lorsque l'état interne du modèle a changé.
+ *
+ * @param newState le nouvelle état du modèle de wizard
+ */
+ void onModelStateChanged(WizardOperationState newState);
+
+ /**
+ * Méthode invoqué lorsque l'état d'une opération a changé.
+ *
+ * @param step l'étape dont l'état a changé
+ * @param newState le nouvel état pour l'étape donné
+ */
+ void onOperationStateChanged(E step,WizardOperationState newState) ;
+
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUILancher.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUILancher.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUILancher.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,162 @@
+package jaxx.runtime.gwt.wizard;
+
+import java.awt.Window;
+import javax.swing.ImageIcon;
+import jaxx.runtime.JAXXContext;
+import jaxx.runtime.JAXXInitialContext;
+import jaxx.runtime.JAXXObject;
+import org.apache.commons.beanutils.ConstructorUtils;
+
+/**
+ *
+ * Une classe pour lancer une ui de wizard.
+ *
+ * @param <E> le type des etapes
+ * @param <M> le type de modele
+ * @param <UI> le type d'ui
+ * @author tony
+ * @since 1.3
+ */
+public abstract class WizardUILancher<E extends WizardStep, M extends WizardModel<E>, UI extends WizardUI<E, M>> {
+
+ protected UI ui;
+
+ public WizardUILancher(JAXXContext context, Class<UI> uiClass, Class<M> modelClass, String title, String tip, ImageIcon icon) {
+ this(context, uiClass, modelClass, null, title, tip, icon);
+ }
+
+ public WizardUILancher(JAXXContext context, Class<UI> uiClass, Class<M> modelClass, M model, String title, String tip, ImageIcon icon) {
+ try {
+ ui = createUI(context, uiClass, modelClass, model, title, tip, icon);
+ } catch (Exception ex) {
+ throw new RuntimeException("could not instanciate launcher for reason " + ex.getMessage(), ex);
+ }
+ }
+
+ public WizardUILancher(JAXXContext context, Window mainUI, Class<UI> uiClass, Class<M> modelClass, M model) {
+ try {
+ ui = createUI(context, mainUI, uiClass, modelClass, model);
+ } catch (Exception ex) {
+ throw new RuntimeException("could not instanciate launcher for reason " + ex.getMessage(), ex);
+ }
+ }
+
+ public WizardUILancher(JAXXContext context, Window mainUI, Class<UI> uiClass, Class<M> modelClass) {
+ this(context, mainUI, uiClass, modelClass, null);
+ }
+
+ public void start() {
+ init(ui);
+ start(ui);
+ }
+
+ protected void start(UI ui) {
+ ui.start();
+ }
+
+ public <T> T getContextValue(Class<T> clazz, String name) {
+ if (ui == null) {
+ throw new NullPointerException("ui can not be null");
+ }
+ if (!(ui instanceof JAXXObject)) {
+ throw new ClassCastException("ui can not be casted to JAXXObject ");
+ }
+
+ return ((JAXXObject) ui).getContextValue(clazz, name);
+ }
+
+ public <T> T getContextValue(Class<T> clazz) {
+ return getContextValue(clazz, null);
+ }
+
+ protected void init(UI ui) {
+ }
+
+ protected void doAction(UI ui) {
+ }
+
+ protected void doCancel(UI ui) {
+ }
+
+ protected void doClose(UI ui, boolean wasCanceld) {
+ }
+
+ @SuppressWarnings("unchecked")
+ protected UI createUI(JAXXContext context, Window mainUI, Class<UI> uiClass, Class<M> modelClass, M model) throws Exception {
+ JAXXInitialContext uiContext = new JAXXInitialContext();
+ uiContext.add(mainUI == null ? context : mainUI);
+ // parent context model
+ uiContext.add(modelClass.newInstance());
+ if (model != null) {
+ uiContext.add("incoming", model);
+ }
+ // apply action
+ uiContext.add("apply", new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ doAction(ui);
+ } finally {
+ doClose(ui,false);
+ }
+ }
+ });
+ // cancel action
+ uiContext.add("cancel", new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ doCancel(ui);
+ } finally {
+ doClose(ui,true);
+ }
+ }
+ });
+
+ // instanciate ui
+
+ UI newUI = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{mainUI, uiContext}, new Class[]{Window.class, JAXXContext.class});
+ return newUI;
+ }
+
+ @SuppressWarnings("unchecked")
+ protected UI createUI(JAXXContext context, Class<UI> uiClass, Class<M> modelClass, M model, String title, String tip, ImageIcon icon) throws Exception {
+ JAXXInitialContext uiContext = new JAXXInitialContext();
+ uiContext.add(context);
+ // parent context model
+ uiContext.add(modelClass.newInstance());
+ if (model != null) {
+ uiContext.add("incoming", model);
+ }
+ // apply action
+ uiContext.add("apply", new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ doAction(ui);
+ } finally {
+ doClose(ui,false);
+ }
+ }
+ });
+ // cancel action
+ uiContext.add("cancel", new Runnable() {
+
+ @Override
+ public void run() {
+ try {
+ doCancel(ui);
+ } finally {
+ doClose(ui,true);
+ }
+ }
+ });
+
+ // instanciate ui
+ UI newUI = (UI) ConstructorUtils.invokeConstructor(uiClass, new Object[]{uiContext, title, tip, icon}, new Class[]{JAXXContext.class, String.class, String.class, ImageIcon.class});
+ return newUI;
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUtil.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/WizardUtil.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,97 @@
+package jaxx.runtime.gwt.wizard;
+
+import java.beans.IndexedPropertyChangeEvent;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.lang.reflect.Array;
+import org.apache.commons.logging.Log;
+
+/**
+ * Classe de méthodes utiles sur les wizard.
+ *
+ * @author tony
+ * @since 1.3
+ */
+public class WizardUtil {
+
+ protected WizardUtil() {
+ }
+
+ public static boolean acceptStates(WizardOperationState state, WizardOperationState... accepted) {
+ for (WizardOperationState s : accepted) {
+ if (s == state) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public static boolean rejectStates(WizardOperationState state, WizardOperationState... rejected) {
+ for (WizardOperationState s : rejected) {
+ if (s == state) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ public static void addDebugLogListener(final Log log, WizardModel model) {
+ if (log.isDebugEnabled()) {
+ model.addPropertyChangeListener(new PropertyChangeListener() {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ log.debug(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
+ }
+ });
+ }
+ }
+
+ public static void addTraceLogListener(final Log log, WizardModel model) {
+ if (log.isTraceEnabled()) {
+ model.addPropertyChangeListener(new PropertyChangeListener() {
+
+ @Override
+ public void propertyChange(PropertyChangeEvent evt) {
+ log.trace(evt.getPropertyName() + " <" + evt.getOldValue() + " - " + evt.getNewValue() + ">");
+ }
+ });
+ }
+ }
+
+ public static <E extends WizardStep, M extends WizardModel<E>> void installWizardUIListeners(final WizardUI<E, M> ui) {
+ ui.getModel().addPropertyChangeListener(new PropertyChangeListener() {
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public void propertyChange(PropertyChangeEvent evt) {
+ String propertyName = evt.getPropertyName();
+ if (WizardOperationModel.WAS_STARTED_PROPERTY_NAME.equals(propertyName)) {
+ ui.onWasStarted();
+ return;
+ }
+ if (WizardModel.STEPS_PROPERTY_NAME.equals(propertyName)) {
+ java.util.List<E> steps = (java.util.List<E>) evt.getNewValue();
+ ui.onStepsChanged(steps.toArray((E[]) Array.newInstance(ui.getModel().stepClass, steps.size())));
+ return;
+ }
+ if (WizardModel.STEP_PROPERTY_NAME.equals(propertyName)) {
+ ui.onStepChanged((E) evt.getNewValue());
+ return;
+ }
+ if (WizardOperationModel.MODEL_STATE_PROPERTY_NAME.equals(propertyName)) {
+ //TODO should be unicast : only for good stepUI ?
+ ui.onModelStateChanged((WizardOperationState) evt.getNewValue());
+ return;
+ }
+ if (WizardOperationModel.OPERATION_STATE_PROPERTY_NAME.equals(propertyName)) {
+ IndexedPropertyChangeEvent e = (IndexedPropertyChangeEvent) evt;
+ int stepIndex = e.getIndex();
+ E step = ui.getModel().getSteps().get(stepIndex);
+ ui.onOperationStateChanged(step, (WizardOperationState) evt.getNewValue());
+ return;
+ }
+ }
+ });
+ }
+}
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/package.html
===================================================================
--- jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/package.html (rev 0)
+++ jaxx/trunk/jaxx-runtime-gwt/src/main/java/jaxx/runtime/gwt/wizard/package.html 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,9 @@
+<html>
+ <body>
+ <h1>JAXX - Wizard framework</h1>
+
+ This package contains all the classes of the wizard framework.
+
+ TODO
+ </body>
+</html>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-config-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-config-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-config.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-config.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-message-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-message-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-message.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-message.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-next-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-next-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-next.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-next.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-pause-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-pause-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-pause.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-pause.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-previous-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-previous-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-previous.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-previous.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-refresh-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-refresh-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-refresh.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-refresh.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-start-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-start-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-start.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-start.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-canceled-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-canceled-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-canceled.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-canceled.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-failed-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-failed-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-failed.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-failed.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-need_fix-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-need_fix-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-need_fix.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-need_fix.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-pending-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-pending-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-pending.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-pending.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-running-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-running-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-running.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-running.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-successed-16.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-successed-16.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-successed.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-gwt/src/main/resources/icons/action-wizard-state-successed.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-validator-gwt/.classpath
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/.classpath (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/.classpath 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,24 @@
+<classpath>
+ <classpathentry kind="src" path="src/main/java"/>
+ <classpathentry kind="src" path="src/main/resources" including="**/*" excluding="**/*~|**/*.java"/>
+ <classpathentry kind="src" path="src/test/java" output="target/test-classes"/>
+ <classpathentry kind="src" path="src/test/resources" output="target/test-classes" excluding="**/*.java"/>
+ <classpathentry kind="output" path="target/classes"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="var" path="M2_REPO/commons-beanutils/commons-beanutils/1.8.0/commons-beanutils-1.8.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-collections/commons-collections/3.2.1/commons-collections-3.2.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-jxpath/commons-jxpath/1.3/commons-jxpath-1.3.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-lang/commons-lang/2.4/commons-lang-2.4.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-logging/commons-logging/1.1.1/commons-logging-1.1.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/commons-primitives/commons-primitives/1.0/commons-primitives-1.0.jar"/>
+ <classpathentry kind="var" path="M2_REPO/javax/help/javahelp/2.0.02/javahelp-2.0.02.jar"/>
+ <classpathentry kind="src" path="/jaxx-runtime-api"/>
+ <classpathentry kind="src" path="/jaxx-runtime-gwt"/>
+ <classpathentry kind="src" path="/jaxx-runtime-validator"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/4.5/junit-4.5.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/swinglabs/jxlayer/3.0.1/jxlayer-3.0.1.jar"/>
+ <classpathentry kind="var" path="M2_REPO/log4j/log4j/1.2.14/log4j-1.2.14.jar"/>
+ <classpathentry kind="var" path="M2_REPO/org/codelutin/lutinutil/1.0.3/lutinutil-1.0.3.jar"/>
+ <classpathentry kind="var" path="M2_REPO/opensymphony/ognl/2.6.11/ognl-2.6.11.jar"/>
+ <classpathentry kind="var" path="M2_REPO/com/opensymphony/xwork/2.1.1-cl_20090130/xwork-2.1.1-cl_20090130.jar"/>
+</classpath>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/.project
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/.project (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/.project 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,17 @@
+<projectDescription>
+ <name>jaxx-runtime-validator-gwt</name>
+ <comment>Jaxx validation swing extension</comment>
+ <projects>
+ <project>jaxx-runtime-api</project>
+ <project>jaxx-runtime-gwt</project>
+ <project>jaxx-runtime-validator</project>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.eclipse.jdt.core.javabuilder</name>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+</projectDescription>
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/.settings/org.eclipse.jdt.core.prefs
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/.settings/org.eclipse.jdt.core.prefs (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/.settings/org.eclipse.jdt.core.prefs 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,5 @@
+#Mon Mar 30 12:41:56 CEST 2009
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.source=1.6
+org.eclipse.jdt.core.compiler.compliance=1.6
Added: jaxx/trunk/jaxx-runtime-validator-gwt/LICENSE.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/LICENSE.txt (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/LICENSE.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,166 @@
+ GNU LESSER GENERAL PUBLIC LICENSE
+ Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+ This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+ 0. Additional Definitions.
+
+ As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+ "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+ An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+ A "Combined Work" is a work produced by combining or linking an
+Application with the Library. The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+ The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+ The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+ 1. Exception to Section 3 of the GNU GPL.
+
+ You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+ 2. Conveying Modified Versions.
+
+ If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+ a) under this License, provided that you make a good faith effort to
+ ensure that, in the event an Application does not supply the
+ function or data, the facility still operates, and performs
+ whatever part of its purpose remains meaningful, or
+
+ b) under the GNU GPL, with none of the additional permissions of
+ this License applicable to that copy.
+
+ 3. Object Code Incorporating Material from Library Header Files.
+
+ The object code form of an Application may incorporate material from
+a header file that is part of the Library. You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+ a) Give prominent notice with each copy of the object code that the
+ Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the object code with a copy of the GNU GPL and this license
+ document.
+
+ 4. Combined Works.
+
+ You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+ a) Give prominent notice with each copy of the Combined Work that
+ the Library is used in it and that the Library and its use are
+ covered by this License.
+
+ b) Accompany the Combined Work with a copy of the GNU GPL and this license
+ document.
+
+ c) For a Combined Work that displays copyright notices during
+ execution, include the copyright notice for the Library among
+ these notices, as well as a reference directing the user to the
+ copies of the GNU GPL and this license document.
+
+ d) Do one of the following:
+
+ 0) Convey the Minimal Corresponding Source under the terms of this
+ License, and the Corresponding Application Code in a form
+ suitable for, and under terms that permit, the user to
+ recombine or relink the Application with a modified version of
+ the Linked Version to produce a modified Combined Work, in the
+ manner specified by section 6 of the GNU GPL for conveying
+ Corresponding Source.
+
+ 1) Use a suitable shared library mechanism for linking with the
+ Library. A suitable mechanism is one that (a) uses at run time
+ a copy of the Library already present on the user's computer
+ system, and (b) will operate properly with a modified version
+ of the Library that is interface-compatible with the Linked
+ Version.
+
+ e) Provide Installation Information, but only if you would otherwise
+ be required to provide such information under section 6 of the
+ GNU GPL, and only to the extent that such information is
+ necessary to install and execute a modified version of the
+ Combined Work produced by recombining or relinking the
+ Application with a modified version of the Linked Version. (If
+ you use option 4d0, the Installation Information must accompany
+ the Minimal Corresponding Source and Corresponding Application
+ Code. If you use option 4d1, you must provide the Installation
+ Information in the manner specified by section 6 of the GNU GPL
+ for conveying Corresponding Source.)
+
+ 5. Combined Libraries.
+
+ You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+ a) Accompany the combined library with a copy of the same work based
+ on the Library, uncombined with any other library facilities,
+ conveyed under the terms of this License.
+
+ b) Give prominent notice with the combined library that part of it
+ is a work based on the Library, and explaining where to find the
+ accompanying uncombined form of the same work.
+
+ 6. Revised Versions of the GNU Lesser General Public License.
+
+ The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+ Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+ If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
+
Added: jaxx/trunk/jaxx-runtime-validator-gwt/README.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/README.txt (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/README.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,2 @@
+To deploy new version of pom: mvn deploy
+To install localy: mvn install
Added: jaxx/trunk/jaxx-runtime-validator-gwt/changelog.txt
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/changelog.txt (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/changelog.txt 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,6 @@
+1.3 chemit 20090321
+ * 20090320 [chemit] - rename and move SwingValidationUtil to jaxx.runtime.SwingValidatorUtil
+ * 20090319 [chemit] - refactor Validator : now can deal with scopes, improve design
+
+1.1 chemit 20090220
+ * 20090203 [chemit] - introduce this module specific to swing
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/pom.xml
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/pom.xml (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/pom.xml 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- ************************************************************* -->
+ <!-- *** POM Relationships *************************************** -->
+ <!-- ************************************************************* -->
+
+ <parent>
+ <groupId>org.codelutin</groupId>
+ <artifactId>jaxx</artifactId>
+ <version>1.3-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.codelutin.jaxx</groupId>
+ <artifactId>jaxx-runtime-validator-gwt</artifactId>
+
+ <repositories>
+ <repository>
+ <id>gwt-maven</id>
+ <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+
+ <!-- sibling dependencies -->
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-validator</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <!-- GWT Dependencies -->
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-servlet</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-user</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}-libs</classifier>
+ <type>zip</type>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}</classifier>
+ <scope>provided</scope>
+ </dependency>
+
+ </dependencies>
+
+ <!-- ************************************************************* -->
+ <!-- *** Project Information ************************************* -->
+ <!-- ************************************************************* -->
+
+ <name>${project.artifactId}</name>
+ <description>Jaxx validation gwt extension</description>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Settings ****************************************** -->
+ <!-- ************************************************************* -->
+ <packaging>jar</packaging>
+
+ <properties>
+
+ <gwtVersion>1.5.3</gwtVersion>
+
+ </properties>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Environment ************************************** -->
+ <!-- ************************************************************* -->
+ <scm>
+ <url>http://labs.libre-entreprise.org/plugins/scmsvn/viewcvs.php/jaxx/trunk/jaxx…</url>
+ <connection>scm:svn:svn://anonymous@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-runtime-validator-gwt</connection>
+ <developerConnection>scm:svn:svn+ssh://sletellier@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-runtime-validator-gwt</developerConnection>
+ </scm>
+
+ <profiles>
+ <profile>
+ <id>gwt-dev-linux</id>
+ <properties>
+ <platform>linux</platform>
+ </properties>
+ <activation>
+ <os>
+ <name>Linux</name>
+ </os>
+ </activation>
+ </profile>
+ </profiles>
+</project>
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/GWTValidatorUtil.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/GWTValidatorUtil.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/GWTValidatorUtil.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,177 @@
+package jaxx.runtime;
+
+import jaxx.runtime.validator.*;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JList;
+import javax.swing.JTable;
+import java.awt.event.MouseListener;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+
+import jaxx.runtime.validator.gwt.GWTValidatorMessage;
+import jaxx.runtime.validator.gwt.GWTValidatorMessageListMouseListener;
+import jaxx.runtime.validator.gwt.GWTValidatorMessageTableMouseListener;
+
+import org.codelutin.i18n.I18n;
+
+/**
+ * The helper class for validation module.
+ *
+ * @author chemit
+ */
+public class GWTValidatorUtil extends BeanValidatorUtil {
+
+ static ImageIcon errorIcon;
+ static ImageIcon warningIcon;
+ static ImageIcon infoIcon;
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(GWTValidatorUtil.class);
+
+ public static ImageIcon getErrorIcon() {
+ if (errorIcon == null) {
+ errorIcon = jaxx.runtime.Util.createImageIcon("error.png");
+ }
+ return errorIcon;
+ }
+
+ public static ImageIcon getInfoIcon() {
+ if (infoIcon == null) {
+ infoIcon = jaxx.runtime.Util.createImageIcon("info.png");
+ }
+ return infoIcon;
+ }
+
+ public static ImageIcon getWarningIcon() {
+ if (warningIcon == null) {
+ warningIcon = jaxx.runtime.Util.createImageIcon("warning.png");
+ }
+ return warningIcon;
+ }
+
+ protected GWTValidatorUtil() {
+ // no instance
+ }
+
+ /**
+ * Register for a given validator list ui a validator mouse listener.
+ *
+ * Note: there is only one listener registred for a given list model, so
+ * invoking this method tiwce or more will have no effect.
+ *
+ * @param list the validation ui list
+ * @return the listener instanciate or found
+ * @see GWTValidatorMessageListMouseListener
+ */
+ public static GWTValidatorMessageListMouseListener registerErrorListMouseListener(JList list) {
+ GWTValidatorMessageListMouseListener listener = getErrorListMouseListener(list);
+
+ if (listener != null) {
+ return listener;
+ }
+ listener = new GWTValidatorMessageListMouseListener();
+ if (log.isDebugEnabled()) {
+ log.debug(listener.toString());
+ }
+ list.addMouseListener(listener);
+ return listener;
+ }
+
+ /**
+ * Register for a given validator table ui a validator mouse listener
+ *
+ * Note: there is onlt one listener registred for a givne table model, so
+ * invokin this method twice or more will have no effect.
+ *
+ * @param table the validator table ui
+ * @return the listener instanciate or found
+ * @see GWTValidatorMessageTableMouseListener
+ */
+ public static GWTValidatorMessageTableMouseListener registerErrorTableMouseListener(JTable table) {
+ GWTValidatorMessageTableMouseListener listener = getErrorTableMouseListener(table);
+
+ if (listener != null) {
+ return listener;
+ }
+ listener = new GWTValidatorMessageTableMouseListener();
+ if (log.isDebugEnabled()) {
+ log.debug(listener.toString());
+ }
+ table.addMouseListener(listener);
+ return listener;
+ }
+
+ /**
+ * @param list the validator list ui
+ * @return the validator list mouse listener, or <code>null</code> if not found
+ * @see GWTValidatorMessageListMouseListener
+ */
+ public static GWTValidatorMessageListMouseListener getErrorListMouseListener(JList list) {
+ if (list != null) {
+ for (MouseListener listener : list.getMouseListeners()) {
+ if (listener instanceof GWTValidatorMessageTableMouseListener) {
+ return (GWTValidatorMessageListMouseListener) listener;
+ }
+ }
+ }
+ return null;
+ }
+
+ /**
+ * @param table the validator table ui
+ * @return the validator table mouse listener, or <code>null</code> if not found
+ * @see GWTValidatorMessageTableMouseListener
+ */
+ public static GWTValidatorMessageTableMouseListener getErrorTableMouseListener(JTable table) {
+ if (table != null) {
+ for (MouseListener listener : table.getMouseListeners()) {
+ if (listener instanceof GWTValidatorMessageTableMouseListener) {
+ return (GWTValidatorMessageTableMouseListener) listener;
+ }
+ }
+ }
+ return null;
+ }
+
+ public static String getMessage(GWTValidatorMessage model) {
+ String text = model.getMessage();
+ if (model.getField() != null) {
+ text = model.getField().getI18nError(text);
+ }
+ return text;
+ }
+
+ public static String getFieldName(GWTValidatorMessage model, String value) {
+ String text = null;
+ JComponent editor = model.getEditor();
+ if (editor != null) {
+ text = (String) editor.getClientProperty("validatorLabel");
+ /*if (l != null) {
+ text = I18n._(l);
+ } else {
+ // TODO should try the text
+ }*/
+ }
+ if (text == null) {
+ text = value;
+ }
+ return text;
+ }
+
+ public static ImageIcon getIcon(BeanValidatorScope scope) {
+ ImageIcon icon = null;
+ switch (scope) {
+ case ERROR:
+ icon = getErrorIcon();
+ break;
+ case WARNING:
+ icon = getWarningIcon();
+ break;
+ case INFO:
+ icon = getInfoIcon();
+ break;
+ }
+ return icon;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidator.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidator.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidator.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,280 @@
+package jaxx.runtime.validator.gwt;
+
+import jaxx.runtime.validator.gwt.ui.AbstractBeanValidatorUI;
+import jaxx.runtime.validator.gwt.ui.IconValidationUI;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jdesktop.jxlayer.JXLayer;
+
+import javax.swing.JComponent;
+import javax.swing.SwingUtilities;
+import java.awt.Container;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+import jaxx.runtime.validator.BeanValidator;
+import jaxx.runtime.validator.BeanValidatorField;
+
+/**
+ * La surcharge de {@link jaxx.runtime.validator.BeanValidator} pour les ui swing
+ * <p/>
+ * /**
+ * <p/>
+ * Permet d'ajouter facilement le support de la validation des champs d'un
+ * bean et de le relier a une interface graphique.
+ * Utilise xwork pour la validation et JXLayer pour la visualisation.
+ * <p/>
+ * <p/>
+ * Le mieux pour son integration dans Jaxx est de faire de la generation pour
+ * force la compilation du code suivant:
+ * <p/>
+ * <pre>
+ * myValidor.getBean().get<field>();
+ * </pre>
+ * <p/>
+ * et ceci pour chaque field ajoute a la map fieldRepresentation. De cette
+ * facon meme si le champs field est en texte on a une verification de son
+ * existance a la compilation.
+ * <p/>
+ * <p/>
+ * La representation en tag pourrait etre
+ * <pre>
+ * <validator id="myValidator" beanClass="{Personne.class}" errorList="$list">
+ * <field name="name" component="$name"/>
+ * <field name="firstName" component="$firstName"/>
+ * <field name="birthDate" component="$birthDate"/>
+ * </validator>
+ * <validator beanClass="{Personne.class}" autoField="true" errorList="$list">
+ * <fieldRepresentation name="name" component="$lastName"/>
+ * </validator>
+ * </pre>
+ * <p/>
+ * dans le premier exemple on fait un mapping explicite des champs, mais on voit
+ * que le nom du composant graphique est le meme que celui du champs. Pour eviter
+ * de longue saisie, il est possible d'utiliser le flag <b>autoField</b>
+ * qui pour chaque champs du ayant une methode get du bean recherche un composant
+ * avec cet Id. Il est aussi possible de surcharge un champs explicitement
+ * comme ici name, dans le cas ou le composant qui porterait ce nom serait
+ * utilise pour autre chose.
+ * <p/>
+ * <p/>
+ * Il faut un handler particulier pour ce composant car les attributs
+ * <b>beanClass</b> et <b>autoField</b> ne sont present que dans le XML jaxx et
+ * servent a la generation. Il faut aussi prendre en compte les elements
+ * fieldRepresentation fils du tag validator.
+ * <p/>
+ * <p/>
+ * Voici ce que pourrait etre le code genere par jaxx
+ * <pre>
+ * // declaration du bean
+ * BeanValidator<beanClass> $myValidator;
+ * // init du bean
+ * protected void createMyValidator() {
+ * $myValidator = new BeanValidator<beanClass>();
+ * // genere seulement si autoField = true
+ * for (Method m : beanClass.getMethod()) {
+ * if (m.getName().startsWith("get")) {
+ * String fieldName = m.getName().substring(3).toLowerCase();
+ * $myValidator.setFieldRepresentation(fieldName, $objectMap.get(fieldName));
+ * }
+ * }
+ * // pour chaque tag fieldRepresentation
+ * myValidator.setFieldRepresentation("name", $lastName);
+ * // si beanClass est specifie et n'est pas Object, on force l'acces au champs
+ * // pour validation a la compilation
+ * $myValidator.getBean().getName();
+ * $objectMap.put("myValidator", $myValidator);
+ * }
+ * </pre>
+ *
+ * @param <B> le type de bean a valider
+ * @author poussin
+ * @author chemit
+ * @version 1.0
+ */
+public class GWTValidator<B> extends BeanValidator<B> {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private final Log log = LogFactory.getLog(GWTValidator.class);
+ static private final Class<? extends AbstractBeanValidatorUI> DEFAULT_UI_CLASS = IconValidationUI.class;
+ /** permet de faire le lien en un champs du bean et l'objet qui permet de l'editer */
+ protected Map<String, JComponent> fieldRepresentation;
+ /** Object servant a contenir la liste des erreurs */
+ protected GWTValidatorMessageListModel errorListModel;
+ /** Object servant a contenir la liste des erreurs */
+ protected GWTValidatorMessageTableModel errorTableModel;
+ /** ui renderer class */
+ protected Class<? extends AbstractBeanValidatorUI> uiClass;
+
+ public GWTValidator(Class<B> beanClass, String contextName) {
+ super(beanClass, contextName);
+ fieldRepresentation = new HashMap<String, JComponent>();
+ }
+
+ /**
+ * To reload a bean in the validator.
+ *
+ * This method is used to reload ui, since some editors
+ * could not exist when validator is init, so some messages
+ * should not be attached to an editor.
+ */
+ public void reloadBean() {
+ B b = getBean();
+ if (b != null) {
+ setBean(null);
+ setBean(b);
+ }
+ }
+
+ public JComponent getFieldRepresentation(String fieldname) {
+ return fieldRepresentation.get(fieldname);
+ }
+
+ public Class<? extends AbstractBeanValidatorUI> getUiClass() {
+ return uiClass;
+ }
+
+ public void setErrorListModel(GWTValidatorMessageListModel errorListModel) {
+ this.errorListModel = errorListModel;
+ if (errorListModel != null) {
+ // register the validator in the model list
+ errorListModel.registerValidator(this);
+ }
+ }
+
+ public void setErrorTableModel(GWTValidatorMessageTableModel errorTableModel) {
+ this.errorTableModel = errorTableModel;
+ if (errorTableModel != null) {
+ // register the validator in the model table
+ errorTableModel.registerValidator(this);
+ }
+ }
+
+ public void setUiClass(Class<? extends AbstractBeanValidatorUI> uiClass) {
+ this.uiClass = uiClass;
+ }
+
+ @Override
+ public void setContextName(String contextName) {
+ /*Map<ValidatorField<B>, List<ValidatorErrorListener>> oldListeners = new HashMap<ValidatorField<B>, List<ValidatorErrorListener>>();
+
+ for (ValidatorField<B> field : fields) {
+ ValidatorErrorListener[] listeners = field.getValidatorErrorListeners();
+ List<ValidatorErrorListener> toReinject = new ArrayList<ValidatorErrorListener>();
+ for (ValidatorErrorListener listener : listeners) {
+ if (listener instanceof AbstractBeanValidatorUI) {
+ // this listener will be reinject via installUIs method
+ continue;
+ }
+ toReinject.add(listener);
+ }
+ oldListeners.put(field, toReinject);
+ }*/
+ super.setContextName(contextName);
+ // must reinstall ui
+ installUIs();
+ // reinject none ui listeners
+ /*for (Entry<ValidatorField<B>, List<ValidatorErrorListener>> entry : oldListeners.entrySet()) {
+ ValidatorField<B> field = getField(entry.getKey().getName());
+ for (ValidatorErrorListener listener : entry.getValue()) {
+ field.addValidatorErrorListener(listener);
+ }
+ }
+ oldListeners.clear();*/
+ }
+
+ /**
+ * Permet d'indiquer le composant graphique responsable de l'affichage
+ * d'un attribut du bean
+ *
+ * @param fieldname the field name in the bean
+ * @param c the editor component for the field
+ */
+ public void setFieldRepresentation(String fieldname, JComponent c) {
+ BeanValidatorField<B> field = getField(fieldname);
+ if (field == null) {
+ // no field registred in the validator
+ log.warn("the field '" + fieldname + "' is not defined in validator (no rules on it)");
+ return;
+ }
+ fieldRepresentation.put(fieldname, c);
+ }
+
+ public void setFieldRepresentation(Map<String, JComponent> fieldRepresentation) {
+ for (Map.Entry<String, JComponent> e : fieldRepresentation.entrySet()) {
+ setFieldRepresentation(e.getKey(), e.getValue());
+ }
+ }
+
+ @Override
+ public GWTValidator<?> getParentValidator() {
+ return (GWTValidator<?>) super.getParentValidator();
+ }
+
+ public void setParentValidator(GWTValidator<?> parentValidator) {
+ super.setParentValidator(parentValidator);
+ }
+
+ /** install ui on required components */
+ public void installUIs() {
+ SwingUtilities.invokeLater(new Runnable() {
+
+ @Override
+ public void run() {
+ if (uiClass == null) {
+ // use the default one
+ uiClass = DEFAULT_UI_CLASS;
+ }
+ for (Entry<String, JComponent> entry : fieldRepresentation.entrySet()) {
+ try {
+ setMessageRepresentation(entry.getKey(), null, entry.getValue(), uiClass);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+ }
+ });
+ }
+
+ protected void setMessageRepresentation(String fieldname, JComponent old, JComponent c, Class<? extends AbstractBeanValidatorUI> uiClass)
+ throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException {
+ if (old == c) {
+ // same component, nothing to do
+ return;
+ }
+ BeanValidatorField<B> field = getField(fieldname);
+
+ if (field == null) {
+ // this case should not appear since fieldName has already been check in method addFieldRepresentation
+ return;
+ }
+ if (old != null) {
+ // suppression du jxlayer sous l'ancien composant
+ Container container = old.getParent();
+ if (container instanceof JXLayer) {
+ JXLayer<?> jx = (JXLayer<?>) container;
+ Object ui = jx.getUI();
+ if (ui != null && ui instanceof AbstractBeanValidatorUI) {
+ removeBeanValidatorListener((AbstractBeanValidatorUI) ui);
+ }
+
+ jx.setUI(null);
+ }
+ }
+ if (c != null) {
+ // ajout du jxlayer sous ce composant
+ Container container = c.getParent();
+ if (container instanceof JXLayer) {
+ Constructor<? extends AbstractBeanValidatorUI> cons = uiClass.getConstructor(BeanValidatorField.class);
+ AbstractBeanValidatorUI ui = cons.newInstance(field);
+ ui.setEnabled(true);
+ JXLayer<JComponent> jx = (JXLayer<JComponent>) container;
+ addBeanValidatorListener(ui);
+ jx.setUI(ui);
+ }
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessage.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessage.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessage.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,66 @@
+package jaxx.runtime.validator.gwt;
+
+import javax.swing.JComponent;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorMessage;
+import jaxx.runtime.validator.BeanValidatorScope;
+
+/**
+ * The object to box a validation message within an u.
+ *
+ * @author chemit
+ * @since 1.3
+ * @see BeanValidatorMessage
+ */
+public class GWTValidatorMessage extends BeanValidatorMessage<GWTValidatorMessage> {
+
+ /**
+ * the optional field's editor
+ */
+ protected JComponent editor;
+ protected String fieldName;
+
+ public GWTValidatorMessage(GWTValidator validator, BeanValidatorField field, String message, BeanValidatorScope scope, JComponent editor) {
+ super(validator, field, message, scope);
+ this.fieldName = field.getName();
+ this.editor = editor;
+ }
+
+ public GWTValidatorMessage(GWTValidator validator, String fieldName, String message, BeanValidatorScope scope, JComponent editor) {
+ super(validator, null, message, scope);
+ this.fieldName = fieldName;
+ this.editor = editor;
+ }
+
+ public JComponent getEditor() {
+ return editor;
+ }
+
+ public String getFieldName() {
+ return fieldName;
+ }
+
+ @Override
+ public int compareTo(GWTValidatorMessage o) {
+ // sort on scope
+ int result = getScope().compareTo(o.getScope());
+ if (result == 0) {
+ // sort on field name
+ result = fieldName.compareTo(o.getFieldName());
+ if (result == 0) {
+ // sort on message
+ result = message.compareTo(o.getMessage());
+ }
+ }
+ return result;
+ }
+
+ @Override
+ public String toString() {
+ String s = scope + " - " + (field == null ? message : field.getI18nError(message));
+ if (editor == null) {
+ return s;
+ }
+ return editor.getName() + " : " + s;
+ }
+}
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListModel.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,142 @@
+package jaxx.runtime.validator.gwt;
+
+import jaxx.runtime.validator.BeanValidatorEvent;
+
+import javax.swing.JComponent;
+import java.util.ArrayList;
+import java.util.List;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorScope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The model of the list of validation's messages
+ *
+ * @author chemit
+ */
+public class GWTValidatorMessageListModel
+ extends javax.swing.AbstractListModel
+ implements jaxx.runtime.validator.BeanValidatorListener {
+
+ private static final long serialVersionUID = 1L;
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static Log log = LogFactory.getLog(GWTValidatorMessageListModel.class);
+ /** list of registred validators */
+ protected transient List<GWTValidator<?>> validators;
+ /** list of messages actual displayed */
+ protected List<GWTValidatorMessage> data;
+
+ public GWTValidatorMessageListModel() {
+ validators = new ArrayList<GWTValidator<?>>();
+ data = new java.util.ArrayList<GWTValidatorMessage>();
+ }
+
+ public boolean isEmpty() {
+ return getSize() == 0;
+ }
+
+ public void registerValidator(GWTValidator<?> validator) {
+ if (validators.contains(validator)) {
+ throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this);
+ }
+ validators.add(validator);
+ validator.addBeanValidatorListener(this);
+ }
+
+ public void clear() {
+ int i = data.size();
+ if (i > 0) {
+ data.clear();
+ fireIntervalRemoved(this, 0, i - 1);
+ }
+ }
+
+ @Override
+ public int getSize() {
+ return data.size();
+ }
+
+ @Override
+ public Object getElementAt(int index) {
+ ensureRowIndex(index);
+ return data.get(index);
+ }
+
+ @Override
+ public void onFieldChanged(BeanValidatorEvent event) {
+ String[] toDelete = event.getMessagesToDelete();
+ String[] toAdd = event.getMessagesToAdd();
+ BeanValidatorField field = event.getField();
+ BeanValidatorScope scope = event.getScope();
+ boolean mustAdd = toAdd != null && toAdd.length > 0;
+ boolean mustDel = toDelete != null && toDelete.length > 0;
+
+ if (log.isTraceEnabled()) {
+ log.trace("----------------------------------------------------------");
+ log.trace(field + " - (" + getSize() + ") toAdd " + mustAdd);
+ log.trace(field + " - (" + getSize() + ") toDelete " + mustDel);
+ }
+
+ GWTValidator validator = (GWTValidator) event.getSource();
+
+ if (mustDel) {
+
+ // removes datas and notify if no messages to add
+ removeMessages(validator, field, scope, !mustAdd, toDelete);
+ }
+
+ if (mustAdd) {
+
+ // add new messages, sort datas and notify
+ addMessages(validator, field, scope, true, toAdd);
+ }
+ }
+
+ protected void ensureRowIndex(int index) throws ArrayIndexOutOfBoundsException {
+ if (index < -1 || index >= getSize()) {
+ throw new ArrayIndexOutOfBoundsException("the rowIndex was " + index + ", but should be int [0," + (getSize() - 1) + "]");
+ }
+ }
+
+ protected void addMessages(GWTValidator validator, BeanValidatorField field, BeanValidatorScope scope, boolean sort, String... messages) {
+
+ JComponent editor = validator.getFieldRepresentation(field.getName());
+ // add new errors
+ for (String error : messages) {
+ GWTValidatorMessage row = new GWTValidatorMessage(validator, field, error, scope, editor);
+ data.add(row);
+ if (!sort) {
+ fireIntervalAdded(this, data.size() - 1, data.size() - 1);
+ }
+ }
+
+ if (sort) {
+
+ // resort datas
+ java.util.Collections.sort(data);
+
+ // notify
+ fireContentsChanged(this, 0, getSize() - 1);
+ }
+ }
+
+ protected void removeMessages(GWTValidator validator, BeanValidatorField field, BeanValidatorScope scope, boolean notify, String... messages) {
+
+ List<String> messagesToDel = new java.util.ArrayList<String>(java.util.Arrays.asList(messages));
+
+ // do it in reverse mode (only one pass in that way since index
+ // will stay coherent while removing them)
+
+ for (int i = getSize() - 1; i > -1; i--) {
+ GWTValidatorMessage error = data.get(i);
+ if (error.getValidator() == validator && error.getScope() == scope && error.getField() == field && messagesToDel.contains(error.getMessage())) {
+ // remove the message
+ data.remove(i);
+ if (notify) {
+ fireIntervalRemoved(this, i, i);
+ }
+ }
+ }
+ }
+}
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListMouseListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListMouseListener.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListMouseListener.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,60 @@
+package jaxx.runtime.validator.gwt;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JComponent;
+import javax.swing.JList;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/**
+ * A mouse listener to put on a {@link javax.swing.JList} with a {@link GWTValidatorMessageListModel} as a model.
+ * <p/>
+ * When a double click occurs, find the selected error in model and then focus to the associated component of error.
+ *
+ * @author chemit
+ */
+public class GWTValidatorMessageListMouseListener extends MouseAdapter {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ static private Log log = LogFactory.getLog(GWTValidatorMessageListMouseListener.class);
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ if (e.getClickCount() == 2) {
+
+ GWTValidatorMessage entry = getSelectedMessage(e);
+ if (entry == null) {
+ // no entry found
+ return;
+ }
+ JComponent component = entry.getEditor();
+ if (component != null) {
+ component.requestFocus();
+ }
+ }
+ }
+
+ protected GWTValidatorMessage getSelectedMessage(MouseEvent e) {
+ JList list = (JList) e.getSource();
+ if (!(list.getModel() instanceof GWTValidatorMessageListModel)) {
+ log.warn("model must be a " + GWTValidatorMessageListModel.class + ", but was " + list.getModel());
+ return null;
+ }
+
+ GWTValidatorMessageListModel model = (GWTValidatorMessageListModel) list.getModel();
+ int index = list.getSelectionModel().getMinSelectionIndex();
+ if (index == -1) {
+ // nothing is selected
+ return null;
+ }
+ GWTValidatorMessage entry = (GWTValidatorMessage) model.getElementAt(index);
+ if (log.isDebugEnabled()) {
+ log.debug("selected index: " + index + " : error: " + entry);
+ }
+ return entry;
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListRenderer.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageListRenderer.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,80 @@
+package jaxx.runtime.validator.gwt;
+
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import java.awt.Component;
+import javax.swing.DefaultListCellRenderer;
+import jaxx.runtime.validator.BeanValidatorScope;
+import jaxx.runtime.GWTValidatorUtil;
+
+/**
+ * A simple render of a table of validator's messages, says a table that use
+ * a {@link GWTValidatorMessageTableModel} model.
+ *
+ * @author chemit
+ * @since 1.3
+ * @see GWTValidatorMessageTableModel
+ */
+public class GWTValidatorMessageListRenderer extends DefaultListCellRenderer {
+
+ private static final long serialVersionUID = 1L;
+ protected String format = "%1$-20s - %2$s";
+
+ public GWTValidatorMessageListRenderer() {
+ }
+
+ public GWTValidatorMessageListRenderer(String format) {
+ this.format = format;
+ }
+
+ public String getFormat() {
+ return format;
+ }
+
+ public void setFormat(String format) {
+ this.format = format;
+ }
+
+ @Override
+ public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+
+ JLabel rendererComponent = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+
+ GWTValidatorMessage model = (GWTValidatorMessage) value;
+
+ // scope
+ ImageIcon icon = GWTValidatorUtil.getIcon(model.getScope());
+
+ // field name
+ String fieldName = getFieldName(list, model.getField().getName(), index);
+
+ // message
+ String message = getMessage(model);
+
+ // text to display
+ String text = String.format(format, fieldName, message);
+
+ rendererComponent.setText(text);
+ rendererComponent.setIcon(icon);
+
+ return rendererComponent;
+ }
+
+ public ImageIcon getIcon(BeanValidatorScope scope) {
+ ImageIcon icon = GWTValidatorUtil.getIcon(scope);
+ return icon;
+ }
+
+ public String getMessage(GWTValidatorMessage model) {
+ String text = GWTValidatorUtil.getMessage(model);
+ return text;
+ }
+
+ public String getFieldName(JList list, String value, int row) {
+ GWTValidatorMessageListModel tableModel = (GWTValidatorMessageListModel) list.getModel();
+ GWTValidatorMessage model = (GWTValidatorMessage) tableModel.getElementAt(row);
+ String fieldName = GWTValidatorUtil.getFieldName(model, value);
+ return fieldName;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableModel.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableModel.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableModel.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,327 @@
+package jaxx.runtime.validator.gwt;
+
+import jaxx.runtime.validator.BeanValidatorEvent;
+
+import javax.swing.JComponent;
+import java.util.ArrayList;
+import java.util.List;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorScope;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ * The model of the table of errors.
+ *
+ * The model listens validators messages and update his internal model from it.
+ *
+ * @author chemit
+ * @since 1.3
+ */
+public class GWTValidatorMessageTableModel
+ extends javax.swing.table.AbstractTableModel
+ implements jaxx.runtime.validator.BeanValidatorListener {
+
+ private static final long serialVersionUID = 1L;
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static Log log = LogFactory.getLog(GWTValidatorMessageTableMouseListener.class);
+ public static final String[] columnNames = {"validator.scope", "validator.field", "validator.message"};
+ public static final Class<?>[] columnClasses = {BeanValidatorScope.class, String.class, String.class};
+ /** list of registred validators */
+ protected transient List<GWTValidator<?>> validators;
+ /** list of messages actual displayed */
+ protected List<GWTValidatorMessage> data;
+
+ public GWTValidatorMessageTableModel() {
+ super();
+ validators = new ArrayList<GWTValidator<?>>();
+ data = new java.util.ArrayList<GWTValidatorMessage>();
+ }
+
+ /**
+ * Register a validator for this model.
+ *
+ *
+ * Note: a validator can not be register twice in the same model.
+ *
+ * @param validator the validator to register
+ */
+ public void registerValidator(GWTValidator<?> validator) {
+ if (validators.contains(validator)) {
+ throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this);
+ }
+ validators.add(validator);
+ validator.addBeanValidatorListener(this);
+ }
+
+ public void addMessages(GWTValidator validator, String fieldName, BeanValidatorScope scope, String... messages) {
+ addMessages(validator, fieldName, scope, true, messages);
+ }
+
+ public void addMessages(JComponent editor, String fieldName, BeanValidatorScope scope, String... messages) {
+ addMessages(editor, fieldName, scope, true, messages);
+ }
+
+ public void addMessages(GWTValidator validator, BeanValidatorField field, BeanValidatorScope scope, String... messages) {
+ addMessages(validator, field, scope, true, messages);
+ }
+
+ public void removeMessages(JComponent editor, BeanValidatorScope scope) {
+
+ // do it in reverse mode (only one pass in that way since index
+ // will stay coherent while removing them)
+
+ for (int i = getRowCount() - 1; i > -1; i--) {
+ GWTValidatorMessage error = data.get(i);
+ if (error.getEditor() == editor && (scope == null || error.getScope() == scope)) {
+ // remove the message
+ data.remove(i);
+ fireTableRowsDeleted(i, i);
+ }
+ }
+ }
+
+ public void removeMessages(GWTValidator validator, String fieldName, BeanValidatorScope scope, String... messages) {
+ removeMessages(validator, fieldName, scope, true, messages);
+ }
+
+ public void removeMessages(JComponent editor, String fieldName, BeanValidatorScope scope) {
+ removeMessages(editor, fieldName, scope, true);
+ }
+
+ public void removeMessages(GWTValidator validator, BeanValidatorField field, BeanValidatorScope scope, String... messages) {
+ removeMessages(validator, field, scope, true, messages);
+ }
+
+ public void clear() {
+ int i = data.size();
+ if (i > 0) {
+ data.clear();
+ fireTableRowsDeleted(0, i - 1);
+ }
+ }
+
+ /**
+ * Obtain the message for a given row.
+ *
+ * @param rowIndex the row index
+ * @return the message for the given row index
+ */
+ public GWTValidatorMessage getRow(int rowIndex) {
+ ensureRowIndex(rowIndex);
+ return data.get(rowIndex);
+ }
+
+ @Override
+ public boolean isCellEditable(int row, int column) {
+ // cells are never editable in this model
+ return false;
+ }
+
+ @Override
+ public Class<?> getColumnClass(int columnIndex) {
+ ensureColumnIndex(columnIndex);
+ return columnClasses[columnIndex];
+ }
+
+ @Override
+ public String getColumnName(int column) {
+ ensureColumnIndex(column);
+ return columnNames[column];
+ }
+
+ @Override
+ public void onFieldChanged(BeanValidatorEvent event) {
+ String[] toDelete = event.getMessagesToDelete();
+ String[] toAdd = event.getMessagesToAdd();
+ BeanValidatorField field = event.getField();
+ BeanValidatorScope scope = event.getScope();
+ boolean mustAdd = toAdd != null && toAdd.length > 0;
+ boolean mustDel = toDelete != null && toDelete.length > 0;
+
+ if (log.isTraceEnabled()) {
+ log.trace("----------------------------------------------------------");
+ log.trace(field + " - (" + getRowCount() + ") toAdd " + mustAdd);
+ log.trace(field + " - (" + getRowCount() + ") toDelete " + mustDel);
+ }
+
+ GWTValidator validator = (GWTValidator) event.getSource();
+
+ if (mustDel) {
+
+ // removes datas and notify if no messages to add
+ removeMessages(validator, field, scope, !mustAdd, toDelete);
+ }
+
+ if (mustAdd) {
+
+ // add new messages, sort datas and notify
+ addMessages(validator, field, scope, true, toAdd);
+ }
+ }
+
+ @Override
+ public int getRowCount() {
+ return data.size();
+ }
+
+ @Override
+ public int getColumnCount() {
+ return columnNames.length;
+ }
+
+ @Override
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ ensureColumnIndex(columnIndex);
+ ensureRowIndex(rowIndex);
+
+ GWTValidatorMessage row = data.get(rowIndex);
+ if (columnIndex == 0) {
+ // the icon
+ return row.getScope();
+ }
+ if (columnIndex == 1) {
+ // the field
+ return row.getFieldName();
+ }
+ if (columnIndex == 2) {
+ // the message
+ return row.getMessage();
+ }
+
+ // should never come here
+ return null;
+ }
+
+ protected void ensureRowIndex(int rowIndex) throws ArrayIndexOutOfBoundsException {
+ if (rowIndex < -1 || rowIndex >= getRowCount()) {
+ throw new ArrayIndexOutOfBoundsException("the rowIndex was " + rowIndex + ", but should be int [0," + (getRowCount() - 1) + "]");
+ }
+ }
+
+ protected void ensureColumnIndex(int index) throws ArrayIndexOutOfBoundsException {
+ if (index < -1 || index >= getColumnCount()) {
+ throw new ArrayIndexOutOfBoundsException("the columnIndex was " + index + ", but should be int [0," + (getColumnCount() - 1) + "]");
+ }
+ }
+
+ protected void addMessages(GWTValidator validator, BeanValidatorField field, BeanValidatorScope scope, boolean sort, String... messages) {
+
+ JComponent editor = validator == null ? null : validator.getFieldRepresentation(field.getName());
+ // add new errors
+ for (String error : messages) {
+ GWTValidatorMessage row = new GWTValidatorMessage(validator, field, error, scope, editor);
+ data.add(row);
+ if (!sort) {
+ fireTableRowsInserted(data.size() - 1, data.size() - 1);
+ }
+ }
+
+ if (sort) {
+
+ // resort datas
+ java.util.Collections.sort(data);
+
+ // notify
+ fireTableDataChanged();
+ }
+ }
+
+ protected void addMessages(GWTValidator validator, String fieldName, BeanValidatorScope scope, boolean sort, String... messages) {
+
+ JComponent editor = validator == null ? null : validator.getFieldRepresentation(fieldName);
+ // add new errors
+ for (String error : messages) {
+ GWTValidatorMessage row = new GWTValidatorMessage(validator, fieldName, error, scope, editor);
+ data.add(row);
+ if (!sort) {
+ fireTableRowsInserted(data.size() - 1, data.size() - 1);
+ }
+ }
+
+ if (sort) {
+
+ // resort datas
+ java.util.Collections.sort(data);
+
+ // notify
+ fireTableDataChanged();
+ }
+ }
+
+ protected void addMessages(JComponent editor, String fieldName, BeanValidatorScope scope, boolean sort, String... messages) {
+
+ // add new errors
+ for (String error : messages) {
+ GWTValidatorMessage row = new GWTValidatorMessage(null, fieldName, error, scope, editor);
+ data.add(row);
+ if (!sort) {
+ fireTableRowsInserted(data.size() - 1, data.size() - 1);
+ }
+ }
+
+ if (sort) {
+
+ // resort datas
+ java.util.Collections.sort(data);
+
+ // notify
+ fireTableDataChanged();
+ }
+ }
+
+ protected void removeMessages(GWTValidator validator, BeanValidatorField field, BeanValidatorScope scope, boolean notify, String... messages) {
+
+ List<String> messagesToDel = new java.util.ArrayList<String>(java.util.Arrays.asList(messages));
+
+ // do it in reverse mode (only one pass in that way since index
+ // will stay coherent while removing them)
+
+ for (int i = getRowCount() - 1; i > -1; i--) {
+ GWTValidatorMessage error = data.get(i);
+ if (error.getValidator() == validator && error.getScope() == scope && error.getFieldName().equals(field.getName()) && messagesToDel.contains(error.getMessage())) {
+ // remove the message
+ data.remove(i);
+ if (notify) {
+ fireTableRowsDeleted(i, i);
+ }
+ }
+ }
+ }
+
+ protected void removeMessages(GWTValidator validator, String fieldName, BeanValidatorScope scope, boolean notify, String... messages) {
+
+ List<String> messagesToDel = new java.util.ArrayList<String>(java.util.Arrays.asList(messages));
+
+ // do it in reverse mode (only one pass in that way since index
+ // will stay coherent while removing them)
+
+ for (int i = getRowCount() - 1; i > -1; i--) {
+ GWTValidatorMessage error = data.get(i);
+ if (error.getValidator() == validator && error.getScope() == scope && error.getFieldName().equals(fieldName) && messagesToDel.contains(error.getMessage())) {
+ // remove the message
+ data.remove(i);
+ if (notify) {
+ fireTableRowsDeleted(i, i);
+ }
+ }
+ }
+ }
+
+ protected void removeMessages(JComponent editor, String fieldName, BeanValidatorScope scope, boolean notify) {
+
+ // do it in reverse mode (only one pass in that way since index
+ // will stay coherent while removing them)
+
+ for (int i = getRowCount() - 1; i > -1; i--) {
+ GWTValidatorMessage error = data.get(i);
+ if (error.getEditor() == editor && (scope == null || error.getScope() == scope) && error.getFieldName().equals(fieldName)) {
+ // remove the message
+ data.remove(i);
+ if (notify) {
+ fireTableRowsDeleted(i, i);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableMouseListener.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableMouseListener.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableMouseListener.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,94 @@
+package jaxx.runtime.validator.gwt;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import javax.swing.JComponent;
+import javax.swing.JTable;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+/**
+ * A mouse listener to put on a {@link javax.swing.JList} with a {@link GWTValidatorMessageTableModel} as a model.
+ * <p/>
+ * When a double click occurs, find the selected error in model and then focus to the associated component of error.
+ *
+ * @author chemit
+ */
+public class GWTValidatorMessageTableMouseListener extends MouseAdapter {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static Log log = LogFactory.getLog(GWTValidatorMessageTableMouseListener.class);
+
+ public static final String HIGHLIGHT_ERROR_PROPERTY = "highlightError";
+
+ /** delgate property change support */
+ protected PropertyChangeSupport pcs;
+
+ public GWTValidatorMessageTableMouseListener() {
+ pcs = new PropertyChangeSupport(this);
+ }
+
+ @Override
+ public void mouseClicked(MouseEvent e) {
+ super.mouseClicked(e);
+ if (e.getClickCount() == 2) {
+
+ GWTValidatorMessage entry = getSelectedMessage(e);
+ if (entry == null) {
+ // no entry found
+ return;
+ }
+ JComponent component = entry.getEditor();
+ if (component != null) {
+ pcs.firePropertyChange(HIGHLIGHT_ERROR_PROPERTY, null, entry);
+ if (component.isVisible()) {
+ component.requestFocus();
+ }
+ }
+ }
+ }
+
+
+ protected GWTValidatorMessage getSelectedMessage(MouseEvent e) {
+ JTable table = (JTable) e.getSource();
+ if (!(table.getModel() instanceof GWTValidatorMessageTableModel)) {
+ log.warn("model must be a " + GWTValidatorMessageTableModel.class + ", but was " + table.getModel());
+ return null;
+ }
+
+ GWTValidatorMessageTableModel model = (GWTValidatorMessageTableModel) table.getModel();
+ int index = table.getSelectionModel().getMinSelectionIndex();
+ if (index == -1) {
+ // nothing is selected
+ return null;
+ }
+ if (table.getRowSorter() != null) {
+ index = table.getRowSorter().convertRowIndexToModel(index);
+ }
+ GWTValidatorMessage entry = model.getRow(index);
+ if (log.isDebugEnabled()) {
+ log.debug("selected index: " + index + " : error: " + entry);
+ }
+ return entry;
+ }
+
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(listener);
+ }
+
+ public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.addPropertyChangeListener(propertyName, listener);
+ }
+
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(listener);
+ }
+
+ public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
+ pcs.removePropertyChangeListener(propertyName, listener);
+ }
+
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableRenderer.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableRenderer.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/GWTValidatorMessageTableRenderer.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,75 @@
+package jaxx.runtime.validator.gwt;
+
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JTable;
+import javax.swing.table.DefaultTableCellRenderer;
+import java.awt.Component;
+import jaxx.runtime.validator.BeanValidatorScope;
+import jaxx.runtime.GWTValidatorUtil;
+
+/**
+ * A simple render of a table of validator's messages, says a table that use
+ * a {@link GWTValidatorMessageTableModel} model.
+ *
+ * @author chemit
+ * @since 1.3
+ * @see GWTValidatorMessageTableModel
+ */
+public class GWTValidatorMessageTableRenderer extends DefaultTableCellRenderer {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ JLabel rendererComponent = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+
+ ImageIcon icon = null;
+ String text = null;
+
+ column = table.convertColumnIndexToModel(column);
+ if (table.getRowSorter() != null) {
+ row = table.getRowSorter().convertRowIndexToModel(row);
+ }
+
+ switch (column) {
+ case 0:
+ // scope
+ icon = GWTValidatorUtil.getIcon((BeanValidatorScope) value);
+ break;
+
+ case 1:
+ // field name
+ text = getFieldName(table, (String) value, row);
+ break;
+
+ case 2:
+ // message
+ text = getMessage(table, (String) value, row);
+ break;
+ }
+
+ rendererComponent.setText(text);
+ rendererComponent.setIcon(icon);
+ return rendererComponent;
+ }
+
+ public ImageIcon getIcon(BeanValidatorScope scope) {
+ ImageIcon icon = GWTValidatorUtil.getIcon(scope);
+ return icon;
+ }
+
+ public String getMessage(JTable table, String value, int row) {
+ GWTValidatorMessageTableModel tableModel = (GWTValidatorMessageTableModel) table.getModel();
+ GWTValidatorMessage model = tableModel.getRow(row);
+ String text = GWTValidatorUtil.getMessage(model);
+ return text;
+ }
+
+ public String getFieldName(JTable table, String value, int row) {
+ GWTValidatorMessageTableModel tableModel = (GWTValidatorMessageTableModel) table.getModel();
+ GWTValidatorMessage model = tableModel.getRow(row);
+ String fieldName = GWTValidatorUtil.getFieldName(model, value);
+ return fieldName;
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/AbstractBeanValidatorUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/AbstractBeanValidatorUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/AbstractBeanValidatorUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,37 @@
+package jaxx.runtime.validator.gwt.ui;
+
+import jaxx.runtime.validator.BeanValidatorEvent;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorListener;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.jdesktop.jxlayer.plaf.AbstractLayerUI;
+
+/**
+ * Abstract renderer
+ *
+ * @author chemit
+ */
+public abstract class AbstractBeanValidatorUI extends AbstractLayerUI<javax.swing.JComponent> implements BeanValidatorListener {
+
+ /** to use log facility, just put in your code: log.info(\"...\"); */
+ private static final Log log = LogFactory.getLog(AbstractBeanValidatorUI.class);
+ /** the field to render */
+ protected BeanValidatorField field;
+
+ public AbstractBeanValidatorUI(BeanValidatorField field) {
+ this.field = field;
+ if (log.isDebugEnabled()) {
+ log.debug("install " + this + "<field:" + field + ">");
+ }
+ }
+
+ @Override
+ public void onFieldChanged(BeanValidatorEvent event) {
+ if (field.equals(event.getField())) {
+ // ask to repaint the layer
+ setDirty(true);
+ }
+ }
+
+}
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/IconValidationUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/IconValidationUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/IconValidationUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,86 @@
+package jaxx.runtime.validator.gwt.ui;
+
+import org.jdesktop.jxlayer.JXLayer;
+
+import javax.swing.BorderFactory;
+import javax.swing.JComponent;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorScope;
+
+/** @author chemit */
+public class IconValidationUI extends AbstractBeanValidatorUI {
+
+ // The icon to be shown at the layer's corner
+ protected static BufferedImage errorIcon;
+ protected static BufferedImage warningIcon;
+ protected static BufferedImage infoIcon;
+
+ public IconValidationUI(BeanValidatorField field) {
+ super(field);
+ if (errorIcon == null) {
+ errorIcon = prepareIcon(Color.RED);
+ }
+ if (warningIcon == null) {
+ warningIcon = prepareIcon(Color.ORANGE);
+ }
+ if (infoIcon == null) {
+ infoIcon = prepareIcon(Color.GREEN);
+ }
+ }
+
+ @Override
+ public void installUI(JComponent c) {
+ super.installUI(c);
+ c.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 3));
+ }
+
+ @Override
+ public void uninstallUI(JComponent c) {
+ super.uninstallUI(c);
+ c.setBorder(null);
+ }
+
+ @Override
+ protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) {
+ super.paintLayer(g2, l);
+ // There is no need to take insets into account for this painter
+ BeanValidatorScope scope = field.getScope();
+ if (scope != null) {
+ BufferedImage icon = null;
+ switch (scope) {
+ case ERROR:
+ icon = errorIcon;
+ break;
+ case WARNING:
+ icon = warningIcon;
+ break;
+ case INFO:
+ icon = infoIcon;
+ break;
+ }
+ if (icon != null) {
+ g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null);
+ }
+ }
+ }
+
+ protected static BufferedImage prepareIcon(Color color) {
+ int width = 7;
+ int height = 8;
+ BufferedImage icon = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2 = (Graphics2D) icon.getGraphics();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g2.setColor(color);
+ g2.fillRect(0, 0, width, height);
+ g2.setColor(Color.WHITE);
+ g2.drawLine(0, 0, width, height);
+ g2.drawLine(0, height, width, 0);
+ g2.dispose();
+ return icon;
+ }
+}
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/ImageValidationUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/ImageValidationUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/ImageValidationUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,78 @@
+package jaxx.runtime.validator.gwt.ui;
+
+import org.jdesktop.jxlayer.JXLayer;
+
+import javax.swing.BorderFactory;
+import javax.swing.ImageIcon;
+import javax.swing.JComponent;
+import java.awt.Graphics2D;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import jaxx.runtime.validator.BeanValidatorField;
+import jaxx.runtime.validator.BeanValidatorScope;
+
+/** @author chemit */
+public class ImageValidationUI extends AbstractBeanValidatorUI {
+
+ protected static BufferedImage errorIcon;
+ protected static BufferedImage warningIcon;
+ protected static BufferedImage infoIcon;
+
+ public ImageValidationUI(BeanValidatorField field) {
+ super(field);
+ if (errorIcon == null) {
+ errorIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("error.png"));
+ }
+ if (warningIcon == null) {
+ warningIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("warning.png"));
+ }
+ if (infoIcon == null) {
+ infoIcon = prepareIcon(jaxx.runtime.Util.createImageIcon("info.png"));
+ }
+ }
+
+ protected static BufferedImage prepareIcon(ImageIcon image) {
+ BufferedImage icon = new BufferedImage(image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g2 = (Graphics2D) icon.getGraphics();
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
+ g2.drawImage(image.getImage(), 0, 0, null);
+ g2.dispose();
+ return icon;
+ }
+
+ @Override
+ public void installUI(JComponent c) {
+ super.installUI(c);
+ c.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 3));
+ }
+
+ @Override
+ public void uninstallUI(JComponent c) {
+ super.uninstallUI(c);
+ c.setBorder(null);
+ }
+
+ @Override
+ protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) {
+ super.paintLayer(g2, l);
+ BeanValidatorScope scope = field.getScope();
+ if (scope != null) {
+ BufferedImage icon = null;
+ switch (scope) {
+ case ERROR:
+ icon = errorIcon;
+ break;
+ case WARNING:
+ icon = warningIcon;
+ break;
+ case INFO:
+ icon = infoIcon;
+ break;
+ }
+ if (icon != null) {
+ g2.drawImage(icon, l.getWidth() - icon.getWidth() - 1, 0, null);
+ }
+ }
+ }
+}
\ No newline at end of file
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/TranslucentValidationUI.java
===================================================================
--- jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/TranslucentValidationUI.java (rev 0)
+++ jaxx/trunk/jaxx-runtime-validator-gwt/src/main/java/jaxx/runtime/validator/gwt/ui/TranslucentValidationUI.java 2009-04-02 12:38:08 UTC (rev 1286)
@@ -0,0 +1,65 @@
+package jaxx.runtime.validator.gwt.ui;
+
+import jaxx.runtime.validator.BeanValidatorScope;
+import org.jdesktop.jxlayer.JXLayer;
+
+import javax.swing.JComponent;
+import java.awt.AlphaComposite;
+import java.awt.Color;
+import java.awt.Graphics2D;
+import java.awt.Insets;
+import java.awt.Rectangle;
+import jaxx.runtime.validator.BeanValidatorField;
+
+/** @author chemit */
+public class TranslucentValidationUI extends AbstractBeanValidatorUI {
+
+ protected Color errorHightlight;
+ protected Color warningHightlight;
+ protected Color infoHightlight;
+
+ public TranslucentValidationUI(BeanValidatorField field) {
+ super(field);
+ errorHightlight = Color.RED;
+ warningHightlight = Color.YELLOW;
+ infoHightlight = Color.GREEN;
+ }
+
+ @Override
+ protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) {
+ // paints the layer as is
+ super.paintLayer(g2, l);
+
+ // to be in sync with the view if the layer has a border
+ Insets layerInsets = l.getInsets();
+ g2.translate(layerInsets.left, layerInsets.top);
+
+ JComponent view = l.getView();
+ // To prevent painting on view's border
+ Insets insets = view.getInsets();
+ g2.clip(new Rectangle(insets.left, insets.top,
+ view.getWidth() - insets.left - insets.right,
+ view.getHeight() - insets.top - insets.bottom));
+
+ BeanValidatorScope scope = field.getScope();
+
+ if (scope == null) {
+ g2.setColor(Color.WHITE);
+ } else {
+ switch (scope) {
+ case ERROR:
+ g2.setColor(errorHightlight);
+ break;
+ case WARNING:
+ g2.setColor(warningHightlight);
+ break;
+ case INFO:
+ g2.setColor(infoHightlight);
+ break;
+ }
+ }
+
+ g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f));
+ g2.fillRect(0, 0, l.getWidth(), l.getHeight());
+ }
+}
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/error.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/error.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/info.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/info.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Added: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/warning.png
===================================================================
(Binary files differ)
Property changes on: jaxx/trunk/jaxx-runtime-validator-gwt/src/main/resources/icons/warning.png
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
1
0
[Buix-commits] r1285 - in jaxx/trunk: . jaxx-compiler-validator jaxx-my-example maven-jaxx-plugin maven-jaxx-plugin/src/main/java/org/codelutin/jaxx
by kmorin@users.labs.libre-entreprise.org 02 Apr '09
by kmorin@users.labs.libre-entreprise.org 02 Apr '09
02 Apr '09
Author: kmorin
Date: 2009-04-02 12:27:34 +0000 (Thu, 02 Apr 2009)
New Revision: 1285
Added:
jaxx/trunk/jaxx-my-example/
jaxx/trunk/jaxx-my-example/pom.xml
Modified:
jaxx/trunk/jaxx-compiler-validator/pom.xml
jaxx/trunk/maven-jaxx-plugin/pom.xml
jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java
jaxx/trunk/pom.xml
Log:
Modified: jaxx/trunk/jaxx-compiler-validator/pom.xml
===================================================================
--- jaxx/trunk/jaxx-compiler-validator/pom.xml 2009-04-02 12:21:55 UTC (rev 1284)
+++ jaxx/trunk/jaxx-compiler-validator/pom.xml 2009-04-02 12:27:34 UTC (rev 1285)
@@ -32,12 +32,24 @@
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jaxx-runtime-validator-swing</artifactId>
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-validator-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<dependency>
<groupId>${project.groupId}</groupId>
<artifactId>jaxx-compiler-api</artifactId>
Added: jaxx/trunk/jaxx-my-example/pom.xml
===================================================================
--- jaxx/trunk/jaxx-my-example/pom.xml (rev 0)
+++ jaxx/trunk/jaxx-my-example/pom.xml 2009-04-02 12:27:34 UTC (rev 1285)
@@ -0,0 +1,324 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+
+ <modelVersion>4.0.0</modelVersion>
+
+ <!-- ************************************************************* -->
+ <!-- *** POM Relationships *************************************** -->
+ <!-- ************************************************************* -->
+
+ <parent>
+ <groupId>org.codelutin</groupId>
+ <artifactId>jaxx</artifactId>
+ <version>1.3-SNAPSHOT</version>
+ </parent>
+
+ <groupId>org.codelutin.jaxx</groupId>
+ <artifactId>jaxx-my-example</artifactId>
+
+<repositories>
+ <repository>
+ <id>gwt-maven</id>
+ <url>http://gwt-maven.googlecode.com/svn/trunk/mavenrepo/</url>
+ </repository>
+ </repositories>
+
+ <dependencies>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-servlet</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>runtime</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-user</artifactId>
+ <version>${gwtVersion}</version>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}-libs</classifier>
+ <type>zip</type>
+ <scope>provided</scope>
+ </dependency>
+ <dependency>
+ <groupId>com.google.gwt</groupId>
+ <artifactId>gwt-dev</artifactId>
+ <version>${gwtVersion}</version>
+ <classifier>${platform}</classifier>
+ <scope>provided</scope>
+ </dependency>
+ <!-- sibiling dependencies -->
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-runtime-validator-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ </dependencies>
+
+ <!-- ************************************************************* -->
+ <!-- *** Project Information ************************************* -->
+ <!-- ************************************************************* -->
+
+ <name>${project.artifactId}</name>
+ <description>Jaxx My Examples</description>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Settings ****************************************** -->
+ <!-- ************************************************************* -->
+
+ <packaging>jar</packaging>
+
+ <properties>
+<gwtVersion>1.5.3</gwtVersion>
+ <maven.jar.main.class>jaxx.demo.JAXXMyDemo</maven.jar.main.class>
+
+ <!-- jnlp -->
+ <keystorepath>${codelutin.keystorepath}</keystorepath>
+ <keystorealias>CodeLutin</keystorealias>
+ <keystorepass>codelutin</keystorepass>
+
+ <jnlp.build.directory>${project.build.directory}/jnlp</jnlp.build.directory>
+
+ </properties>
+
+ <build>
+
+ <resources>
+ <resource>
+ <directory>src/main/java</directory>
+ <includes>
+ <include>**/*.jaxx</include>
+ </includes>
+ </resource>
+ <resource>
+ <directory>src/main/resources</directory>
+ <includes>
+ <include>**/*</include>
+ </includes>
+ </resource>
+ </resources>
+
+ <pluginManagement>
+ <plugins>
+
+ <plugin>
+ <artifactId>maven-jar-plugin</artifactId>
+ <configuration>
+ <archive>
+ <manifest>
+ <addClasspath>true</addClasspath>
+ <classpathPrefix>./lib/</classpathPrefix>
+ </manifest>
+ </archive>
+ </configuration>
+ </plugin>
+
+ </plugins>
+
+ </pluginManagement>
+
+ <plugins>
+
+ <plugin>
+ <groupId>org.codelutin.jaxx</groupId>
+ <artifactId>maven-jaxx-plugin</artifactId>
+ <version>${project.version}</version>
+ <executions>
+ <execution>
+ <goals>
+ <goal>generate</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <groupId>org.codelutin</groupId>
+ <artifactId>maven-i18n-plugin</artifactId>
+ <configuration>
+ <entries>
+ <entry>
+ <basedir>${maven.gen.dir}/java/</basedir>
+ <includes>
+ <param>**\/**.java</param>
+ </includes>
+ </entry>
+ </entries>
+ </configuration>
+ <executions>
+ <execution>
+ <goals>
+ <goal>parserJava</goal>
+ <goal>gen</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+
+ <plugin>
+ <artifactId>maven-dependency-plugin</artifactId>
+ <configuration>
+ <outputDirectory>${project.build.directory}/lib</outputDirectory>
+ </configuration>
+ </plugin>
+
+ </plugins>
+ </build>
+
+ <!-- ************************************************************* -->
+ <!-- *** Build Environment ************************************** -->
+ <!-- ************************************************************* -->
+
+ <scm>
+ <url>http://labs.libre-entreprise.org/plugins/scmsvn/viewcvs.php/jaxx/trunk/jaxx…</url>
+ <connection>scm:svn:svn://anonymous@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-example</connection>
+ <developerConnection>scm:svn:svn+ssh://sletellier@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/jaxx-example</developerConnection>
+ </scm>
+
+ <profiles>
+ <profile>
+ <id>gwt-dev-linux</id>
+ <properties>
+ <platform>linux</platform>
+ </properties>
+ <activation>
+ <os>
+ <name>Linux</name>
+ </os>
+ </activation>
+ </profile>
+ <!-- by default jnlp is only perform on a release stage when using the maven-release-plugin -->
+ <profile>
+ <id>release-profile</id>
+ <activation>
+ <property>
+ <name>performRelease</name>
+ <value>true</value>
+ </property>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+
+ <artifactId>maven-antrun-plugin</artifactId>
+ <executions>
+ <!-- Ajout des libs signe par Sun dans un fichier jnlp separe -->
+ <execution>
+ <id>JnlpSun</id>
+ <phase>verify</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="${jnlp.build.directory}" />
+ <copy file="${project.basedir}/src/main/jnlp/sun.jnlp" verbose="${maven.verbose}" todir="${jnlp.build.directory}" failonerror="false">
+ <filterset>
+ <filter token="lib" value="javahelp-2.0.02.jar" />
+ <filter token="url" value="${project.url}" />
+ </filterset>
+ </copy>
+ <copy file="${project.basedir}/src/main/jnlp/jxlayer.jnlp" verbose="${maven.verbose}" todir="${jnlp.build.directory}" failonerror="false">
+ <filterset>
+ <filter token="lib" value="jxlayer-3.0.1.jar" />
+ <filter token="url" value="${project.url}" />
+ </filterset>
+ </copy>
+ <copy file="${project.build.directory}/lib/javahelp-2.0.02.jar" verbose="${maven.verbose}" todir="${jnlp.build.directory}/lib" failonerror="false" />
+ <copy file="${project.build.directory}/lib/jxlayer-3.0.1.jar" verbose="${maven.verbose}" todir="${jnlp.build.directory}/lib" failonerror="false" />
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+
+ <execution>
+ <id>JnlpToSite</id>
+ <phase>pre-site</phase>
+ <configuration>
+ <tasks>
+ <mkdir dir="${maven.site.gen.dir}/resources" />
+ <copy todir="${maven.site.gen.dir}/resources" verbose="${maven.verbose}" failonerror="false" overwrite="false">
+ <fileset dir="${jnlp.build.directory}">
+ <include name="**" />
+ </fileset>
+ </copy>
+ </tasks>
+ </configuration>
+ <goals>
+ <goal>run</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.codehaus.mojo.webstart</groupId>
+ <artifactId>webstart-maven-plugin</artifactId>
+ <version>1.0-alpha-2-cl_20081018</version>
+ <executions>
+ <execution>
+ <phase>package</phase>
+ <goals>
+ <goal>jnlp-inline</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <force>false</force>
+ <dependencies>
+ <excludes>
+ <exclude>javax.help:javahelp</exclude>
+ <exclude>org.swinglabs:jxlayer</exclude>
+ </excludes>
+ </dependencies>
+ <libPath>lib</libPath>
+ <extensions>
+ <sun>sun.jnlp</sun>
+ <jxlayer>jxlayer.jnlp</jxlayer>
+ </extensions>
+ <jnlp>
+ <outputFile>launch-demo.jnlp</outputFile>
+ <mainClass>${maven.jar.main.class}</mainClass>
+ <allPermissions>true</allPermissions>
+ <offlineAllowed>true</offlineAllowed>
+ </jnlp>
+
+ <sign>
+ <keystore>${keystorepath}</keystore>
+ <keypass />
+ <storepass>${keystorepass}</storepass>
+ <storetype />
+ <alias>${keystorealias}</alias>
+ <validity />
+ <dnameCn />
+ <dnameOu />
+ <dnameO />
+ <dnameL />
+ <dnameSt />
+ <dnameC />
+ <verify>true</verify>
+ <keystoreConfig>
+ <delete>false</delete>
+ <gen>false</gen>
+ </keystoreConfig>
+ </sign>
+
+ <pack200>false</pack200>
+ <gzip>true</gzip>
+ <verbose>false</verbose>
+ </configuration>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ </profiles>
+
+</project>
Modified: jaxx/trunk/maven-jaxx-plugin/pom.xml
===================================================================
--- jaxx/trunk/maven-jaxx-plugin/pom.xml 2009-04-02 12:21:55 UTC (rev 1284)
+++ jaxx/trunk/maven-jaxx-plugin/pom.xml 2009-04-02 12:27:34 UTC (rev 1285)
@@ -44,6 +44,18 @@
<version>${project.version}</version>
</dependency>
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-compiler-gwt</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
+ <dependency>
+ <groupId>${project.groupId}</groupId>
+ <artifactId>jaxx-gwt-action</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+
<!-- maven plugin project dependencies -->
<dependency>
@@ -150,4 +162,4 @@
<developerConnection>scm:svn:svn+ssh://sletellier@labs.libre-entreprise.org/svnroot/buix/jaxx/trunk/maven-jaxx-plugin</developerConnection>
</scm>
-</project>
\ No newline at end of file
+</project>
Modified: jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java
===================================================================
--- jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2009-04-02 12:21:55 UTC (rev 1284)
+++ jaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2009-04-02 12:27:34 UTC (rev 1285)
@@ -61,13 +61,13 @@
/**
* Le compilateur à utiliser (par défaut celui de Swing)
*
- * @parameter expression="${jaxx.compilerFQN}" default-value="jaxx.compiler.SwingCompiler"
+ * @parameter expression="${jaxx.compilerFQN}" default-value="jaxx.compiler.GWTCompiler"
*/
protected String compilerFQN;
/**
* Le compilateur à utiliser (par défaut celui de Swing)
*
- * @parameter expression="${jaxx.validatorFQN}" default-value="jaxx.runtime.validator.swing.SwingValidator"
+ * @parameter expression="${jaxx.validatorFQN}" default-value="jaxx.runtime.validator.gwt.GWTValidator"
*/
protected String validatorFQN;
/**
Modified: jaxx/trunk/pom.xml
===================================================================
--- jaxx/trunk/pom.xml 2009-04-02 12:21:55 UTC (rev 1284)
+++ jaxx/trunk/pom.xml 2009-04-02 12:27:34 UTC (rev 1285)
@@ -14,22 +14,26 @@
<groupId>org.codelutin</groupId>
<artifactId>jaxx</artifactId>
- <version>1.3-SNAPSHOT</version>
+ <version>2.0-SNAPSHOT</version>
<modules>
<module>jaxx-runtime-api</module>
<module>jaxx-runtime-swing</module>
+ <module>jaxx-runtime-gwt</module>
<module>jaxx-runtime-validator</module>
<module>jaxx-runtime-validator-swing</module>
+ <module>jaxx-runtime-validator-gwt</module>
<module>jaxx-compiler-api</module>
<module>jaxx-compiler-swing</module>
+ <module>jaxx-compiler-gwt</module>
<module>jaxx-compiler-validator</module>
<module>jaxx-swing-action</module>
+ <module>jaxx-gwt-action</module>
<module>maven-jaxx-plugin</module>
- <module>jaxx-example</module>
+ <module>jaxx-my-example</module>
</modules>
<dependencies>
@@ -262,4 +266,4 @@
</profile>
</profiles>
-</project>
\ No newline at end of file
+</project>
1
0