r728 - in trunk/lutinjaxx: . jaxx-swing-action jaxx-swing-action/src jaxx-swing-action/src/main jaxx-swing-action/src/main/java jaxx-swing-action/src/main/java/org jaxx-swing-action/src/main/java/org/codelutin jaxx-swing-action/src/main/java/org/codelutin/jaxx jaxx-swing-action/src/main/java/org/codelutin/jaxx/action jaxx-swing-action/src/site jaxx-swing-action/src/test jaxx-swing-action/src/test/java jaxx-swing-action/src/test/java/jaxx jaxx-swing-action/src/test/java/jaxx/runtime
Author: tchemit Date: 2008-07-20 19:22:41 +0000 (Sun, 20 Jul 2008) New Revision: 728 Added: trunk/lutinjaxx/jaxx-swing-action/ trunk/lutinjaxx/jaxx-swing-action/pom.xml trunk/lutinjaxx/jaxx-swing-action/src/ trunk/lutinjaxx/jaxx-swing-action/src/main/ trunk/lutinjaxx/jaxx-swing-action/src/main/java/ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/AbstractActionProvider.java trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionConfig.java trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionProvider.java trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfig.java trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/SimpleActionFactoryImpl.java trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfig.java trunk/lutinjaxx/jaxx-swing-action/src/main/resources/ trunk/lutinjaxx/jaxx-swing-action/src/site/ trunk/lutinjaxx/jaxx-swing-action/src/site/site.xml trunk/lutinjaxx/jaxx-swing-action/src/test/ trunk/lutinjaxx/jaxx-swing-action/src/test/java/ trunk/lutinjaxx/jaxx-swing-action/src/test/java/jaxx/ trunk/lutinjaxx/jaxx-swing-action/src/test/java/jaxx/runtime/ trunk/lutinjaxx/jaxx-swing-action/src/test/java/jaxx/runtime/UtilTest.java trunk/lutinjaxx/jaxx-swing-action/src/test/resources/ Log: creation module jaxx-swing-action pour le mini framework d'actions swing Property changes on: trunk/lutinjaxx/jaxx-swing-action ___________________________________________________________________ Name: svn:ignore + target Added: trunk/lutinjaxx/jaxx-swing-action/pom.xml =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/pom.xml (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/pom.xml 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,35 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<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> + + <parent> + <groupId>org.codelutin.jaxx</groupId> + <artifactId>pom</artifactId> + <version>0.2-SNAPSHOT</version> + </parent> + + <artifactId>jaxx-swing-action</artifactId> + <name>jaxx-swing-action</name> + + <packaging>jar</packaging> + <version>0.2-SNAPSHOT</version> + <description>Jaxx lutin library swing actions extension</description> + + <build> + <plugins> + + </plugins> + </build> + + <dependencies> + + <dependency> + <groupId>org.codelutin.jaxx</groupId> + <artifactId>runtime</artifactId> + <scope>compile</scope> + </dependency> + + </dependencies> +</project> Added: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/AbstractActionProvider.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/AbstractActionProvider.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/AbstractActionProvider.java 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,66 @@ +/** + * # #% 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.AbstractAction; +import java.util.Map; + +/** @author chemit */ +public abstract class AbstractActionProvider<A extends AbstractAction> implements ActionProvider<A> { + + protected final String name; + + protected final Class<A> baseClass; + + protected Map<String, Class<? extends A>> actions; + + protected abstract Map<String, Class<? extends A>> initCache(); + + protected AbstractActionProvider(String name, Class<A> baseClass) { + this.name = name; + this.baseClass = baseClass; + this.actions = initCache(); + } + + public String getName() { + return name; + } + + public Class<A> getBaseClass() { + return baseClass; + } + + public Map<String, Class<? extends A>> getClasses() { + return actions; + } + + @Override + public String toString() { + return super.toString() + "<name:" + name + ", baseClass:" + baseClass.getSimpleName() + ">"; + } + + protected void clearCache() { + if (actions != null) { + actions.clear(); + actions = null; + } + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + clearCache(); + } +} Added: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionConfig.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionConfig.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionConfig.java 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,114 @@ +/* +* ##% 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.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 + */ +@Retention(RetentionPolicy.RUNTIME) + +@Target(ElementType.TYPE) + +public @interface ActionConfig { + + /** + * @return la clef de la commande (doit �tre unique) + * @see javax.swing.Action#ACTION_COMMAND_KEY + */ + public abstract String actionCommand(); + + /** + * @return la clef i18n du texte de l'action, si vide ignor� + * @see javax.swing.Action#NAME + */ + public abstract String name() default ""; + + /** + * @return la clef i18n du tooltip de l'action, si vide ignor� + * @see javax.swing.Action#SHORT_DESCRIPTION + */ + public abstract String shortDescription() default ""; + + /** + * @return la clef i18n du texte de l'action, si vide ignor� + * @see javax.swing.Action#LONG_DESCRIPTION + */ + public abstract String longDescription() default ""; + + /** + * @return le nom de l'icone associ�, si vide ignor� + * @see javax.swing.Action#SMALL_ICON + */ + public abstract String smallIcon() default ""; + + /** + * @return le nom du grande icone associ�, si vide ignor� + * @see javax.swing.Action#LARGE_ICON_KEY + */ + public abstract String largeIcon() default ""; + + /** + * @return + * @see javax.swing.Action#ACCELERATOR_KEY + */ + public abstract String accelerator() default ""; + + /** + * @return + * @see javax.swing.Action#MNEMONIC_KEY + */ + public abstract int mnemonic() default '\0'; + + /** + * @return + * @see javax.swing.Action#DISPLAYED_MNEMONIC_INDEX_KEY + */ + public abstract int displayedMnemonicIndex() default '\0'; + + /** + * @return la valeur par d�faut pour les component selectable + * @see javax.swing.Action#SELECTED_KEY + */ + public abstract boolean selected() default false; + + /** + * @return + * @see javax.swing.Action#isEnabled() + */ + public abstract boolean enabled() default true; + + /** + * @return + * @see javax.swing.Action#isEnabled() + */ + public abstract boolean hideActionText() default false; + + +} \ No newline at end of file Added: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionFactory.java 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,387 @@ +/* +* ##% 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.action; + +import jaxx.runtime.JAXXObject; +import jaxx.runtime.swing.JAXXToggleButton; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import static org.codelutin.i18n.I18n._; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JComboBox; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +/** + * Action factory using the ActionConfig annotations to configure the action. + * <p/> + * The factory is abstract, implements method {@link #init()} to fill the + * dictonary of known action implementations. + * <p/> + * Use after the {@link #loadActions(jaxx.runtime.JAXXObject)} to instanciate + * actions in ui with id equals a known action... + * <p/> + * TODO Finish doc + * + * @author chemit + */ +public abstract class ActionFactory { + + protected static Log log = LogFactory.getLog(ActionFactory.class); + + /** dictionary of known actions implementations */ + private Map<String, Class<? extends AbstractAction>> impls; + /** dictionary of instanciated actions */ + private Map<String, AbstractAction> cache; + + /** + * Method to init the dictionary of knwon action implementations. + * + * @return the dictionary of known action implementations + */ + protected abstract Map<String, Class<? extends AbstractAction>> init(); + + protected ActionFactory() { + impls = init(); + cache = new TreeMap<String, AbstractAction>(); + } + + public void resetCache() { + cache.clear(); + } + + @Override + protected void finalize() throws Throwable { + super.finalize(); + resetCache(); + impls.clear(); + } + + public AbstractAction get(String actionKey) { + return cache.get(actionKey); + } + + public AbstractAction[] loadActions(JAXXObject ui) { + List<AbstractAction> result = new ArrayList<AbstractAction>(); + for (Map.Entry<String, Class<? extends AbstractAction>> 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 (comp instanceof AbstractButton) { + AbstractButton component = (AbstractButton) comp; + AbstractAction 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); + result.add(action); + continue; + } + + if (comp instanceof JComboBox) { + JComboBox component = (JComboBox) comp; + AbstractAction 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); + } + result.add(action); + } + } + return result.toArray(new AbstractAction[result.size()]); + } + + public AbstractAction newAction0(String actionKey) { + // on v�rifie que l'action existe bien + checkRegistredAction(actionKey); + + // try in cache + if (cache.containsKey(actionKey)) { + // use cached action + AbstractAction action = cache.get(actionKey); + if (log.isDebugEnabled()) { + log.debug("use cache action " + action); + } + return action; + } + return null; + } + + /** + * @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 AbstractAction newAction(String actionKey, AbstractButton component) { + + // try first in cache + AbstractAction result = newAction0(actionKey); + if (result != null) { + return result; + } + // on r�cup�re la classe d'implantation de l'action + Class<? extends AbstractAction> klazz = impls.get(actionKey); + + try { + result = klazz.getConstructor(String.class).newInstance(actionKey); + result.putValue(Action.ACTION_COMMAND_KEY, actionKey); + + if (log.isDebugEnabled()) { + log.debug("create action " + actionKey + " : " + result); + } + // recherche de l'annotation de configuration + ActionConfig anno = initActionConfig(component, result); + + if (anno == null) { + ToggleActionConfig anno2 = initToggleActionConfig(component, result); + if (anno2 == null && component != null) { + result.putValue(Action.ACTION_COMMAND_KEY, component.getName()); + result.putValue(Action.SHORT_DESCRIPTION, component.getToolTipText()); + result.putValue(Action.SMALL_ICON, component.getIcon()); + result.putValue(Action.NAME, component.getText()); + result.putValue(Action.MNEMONIC_KEY, component.getMnemonic()); + result.putValue("hideActionText", component.getHideActionText()); + if (component instanceof JAXXToggleButton) { + JAXXToggleButton glueComponent = (JAXXToggleButton) component; + result.putValue(Action.SHORT_DESCRIPTION, glueComponent.getNormalTooltipText()); + result.putValue(Action.NAME, glueComponent.getNormalText()); + result.putValue(Action.SMALL_ICON, glueComponent.getIcon()); + result.putValue(Action.MNEMONIC_KEY, glueComponent.getNormalMnemonic()); + result.putValue(Action.SHORT_DESCRIPTION + 2, glueComponent.getGlueTooltipText()); + result.putValue(Action.NAME + 2, glueComponent.getGlueText()); + result.putValue(Action.SMALL_ICON + 2, glueComponent.getSelectedIcon()); + result.putValue(Action.MNEMONIC_KEY + 2, glueComponent.getGlueMnemonic()); + } + } + } + + String text = (String) result.getValue(Action.NAME); + Integer mnemo = (Integer) result.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())); + } + result.putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY, pos); + } + cache.put(actionKey, result); + return result; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + /** + * @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 AbstractAction newAction(String actionKey, JComboBox component) { + + // try first in cache + AbstractAction result = newAction0(actionKey); + if (result != null) { + return result; + } + + // on r�cup�re la classe d'implantation de l'action + Class<? extends AbstractAction> klazz = impls.get(actionKey); + + try { + result = klazz.getConstructor(String.class).newInstance(actionKey); + result.putValue(Action.ACTION_COMMAND_KEY, actionKey); + + log.debug(actionKey + " : " + result); + // recherche de l'annotation de configuration + SelectActionConfig anno = initSelectActionConfig(component, result); + if (anno == null) { + result.putValue(Action.ACTION_COMMAND_KEY, component.getName()); + result.putValue(Action.SHORT_DESCRIPTION, component.getToolTipText()); + //result.putValue("selectedIndex", component.getSelectedIndex()); + } + cache.put(actionKey, result); + return result; + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + public static ToggleActionConfig initToggleActionConfig(AbstractButton component, AbstractAction result) { + ToggleActionConfig anno = result.getClass().getAnnotation(ToggleActionConfig.class); + if (anno != null) { + // inject les donn�es + if (!anno.name().isEmpty()) { + //System.out.println("found action with name : " + anno.name()); + result.putValue(Action.NAME, _(anno.name())); + } + if (!anno.name2().isEmpty()) { + //System.out.println("found action with name2 : " + anno.name2()); + result.putValue(Action.NAME + "2", _(anno.name2())); + } + + if (!anno.shortDescription().isEmpty()) { + result.putValue(Action.SHORT_DESCRIPTION, _(anno.shortDescription())); + } + if (!anno.shortDescription2().isEmpty()) { + result.putValue(Action.SHORT_DESCRIPTION + "2", _(anno.shortDescription2())); + } + + if (!anno.smallIcon().isEmpty()) { + result.putValue(Action.SMALL_ICON, createImageIcon(anno.smallIcon())); + } + if (!anno.smallIcon2().isEmpty()) { + result.putValue(Action.SMALL_ICON + "2", createImageIcon(anno.smallIcon2())); + } + + if (anno.mnemonic() != '\0') { + result.putValue(Action.MNEMONIC_KEY, anno.mnemonic()); + } else if (component != null) { + result.putValue(Action.MNEMONIC_KEY, component.getMnemonic()); + } + if (anno.mnemonic2() != '\0') { + result.putValue(Action.MNEMONIC_KEY + "2", anno.mnemonic2()); + } + //TODO Convert it from String result.putValue(Action.ACCELERATOR_KEY, anno.accelerator()); + + + result.putValue("hideActionText", anno.hideActionText()); + result.putValue(Action.SELECTED_KEY, anno.selected()); + result.setEnabled(anno.enabled()); + } + return anno; + } + + public static ActionConfig initActionConfig(AbstractButton component, AbstractAction result) { + ActionConfig anno = result.getClass().getAnnotation(ActionConfig.class); + if (anno != null) { + // inject les donn�es + if (!anno.name().isEmpty()) { + //System.out.println("found action with name : " + anno.name()); + result.putValue(Action.NAME, _(anno.name())); + } + //if (!anno.shortDescription().isEmpty()) { + result.putValue(Action.SHORT_DESCRIPTION, _(anno.shortDescription())); + //} + if (!anno.smallIcon().isEmpty()) { + result.putValue(Action.SMALL_ICON, createImageIcon(anno.smallIcon())); + } + if (anno.mnemonic() != '\0') { + result.putValue(Action.MNEMONIC_KEY, anno.mnemonic()); + } else if (component != null) { + result.putValue(Action.MNEMONIC_KEY, component.getMnemonic()); + } + //TODO Convert it from String result.putValue(Action.ACCELERATOR_KEY, anno.accelerator()); + + if (component == null) { + result.putValue("hideActionText", anno.hideActionText()); + } else { + boolean actionText = component.getHideActionText(); + result.putValue("hideActionText", anno.hideActionText() || actionText); + } + result.putValue(Action.SELECTED_KEY, anno.selected()); + result.setEnabled(anno.enabled()); + + } + return anno; + } + + public static SelectActionConfig initSelectActionConfig(JComboBox component, AbstractAction result) { + SelectActionConfig anno = result.getClass().getAnnotation(SelectActionConfig.class); + if (anno != null) { + // inject les donn�es + if (!anno.name().isEmpty()) { + result.putValue(Action.NAME, _(anno.name())); + } + if (!anno.shortDescription().isEmpty()) { + result.putValue(Action.SHORT_DESCRIPTION, _(anno.shortDescription())); + } else { + result.putValue(Action.SHORT_DESCRIPTION, _(component.getToolTipText())); + } + result.putValue("selectedIndex", anno.selectedIndex()); + //TODO Convert it from String result.putValue(Action.ACCELERATOR_KEY, anno.accelerator()); + result.setEnabled(anno.enabled()); + } + return anno; + } + + + protected void checkRegistredAction(String actionKey) { + if (!impls.containsKey(actionKey)) { + throw new IllegalStateException("can not find a registered action for key " + actionKey); + } + } + + public String[] getActionNames() { + return impls.keySet().toArray(new String[impls.size()]); + } + + public Set<Map.Entry<String, Class<? extends AbstractAction>>> implsEntrySet() { + return impls.entrySet(); + } + + public Set<Map.Entry<String, AbstractAction>> cacheEntrySet() { + return cache.entrySet(); + } + + public static ImageIcon createImageIcon(String path) { + java.net.URL imgURL = org.codelutin.jaxx.action.ActionFactory.class.getResource("/icons/" + path); + if (imgURL != null) { + return new ImageIcon(imgURL); + } else { + throw new RuntimeException("could not find icon " + path); + } + } +} \ No newline at end of file Added: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionProvider.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionProvider.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ActionProvider.java 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,33 @@ +/** + * # #% 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 + * + * @author chemit + */ +public interface ActionProvider<A extends javax.swing.AbstractAction> { + + /** @return the name of the provider */ + String getName(); + + /** @return the base classe of provided actions */ + Class<A> getBaseClass(); + + /** @return the provided actions classes */ + java.util.Map<String, Class<? extends A>> getClasses(); + +} Added: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfig.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfig.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/SelectActionConfig.java 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,83 @@ +/* +* ##% 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.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 + */ +@Retention(RetentionPolicy.RUNTIME) + +@Target(ElementType.TYPE) + +public @interface SelectActionConfig { + + /** + * @return la clef de la commande (doit �tre unique) + * @see javax.swing.Action#ACTION_COMMAND_KEY + */ + public abstract String actionCommand(); + + /** + * @return la clef i18n du texte de l'action, si vide ignor� + * @see javax.swing.Action#NAME + */ + public abstract String name() default ""; + + /** + * @return la clef i18n du tooltip de l'action, si vide ignor� + * @see javax.swing.Action#SHORT_DESCRIPTION + */ + public abstract String shortDescription() default ""; + + /** + * @return la clef i18n du texte de l'action, si vide ignor� + * @see javax.swing.Action#LONG_DESCRIPTION + */ + public abstract String longDescription() default ""; + + /** + * @return + * @see javax.swing.Action#ACCELERATOR_KEY + */ + public abstract String accelerator() default ""; + + /** + * @return la valeur par d�faut pour les component selectable + * @see javax.swing.Action#SELECTED_KEY + */ + public abstract int selectedIndex() default 0; + + /** + * @return + * @see javax.swing.Action#isEnabled() + */ + public abstract boolean enabled() default true; + +} \ No newline at end of file Added: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/SimpleActionFactoryImpl.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/SimpleActionFactoryImpl.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/SimpleActionFactoryImpl.java 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,115 @@ +/* +* ##% 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 static org.codelutin.i18n.I18n._; +import org.codelutin.util.Resource; + +import javax.swing.AbstractAction; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.ServiceLoader; +import java.util.TreeMap; + +/** + * A simple implementation of {@link org.codelutin.jaxx.action.ActionFactory} using a properties file to + * load action mapping. + * <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. + * + * @author chemit + */ +public class SimpleActionFactoryImpl extends ActionFactory { + /** default file where to load action mapping */ + protected static final String ACTIONS_FILE_PATH = "/actions.properties"; + + /** default prefix for an entryin mapping file. */ + protected static final String ACTION_KEY_PREFIX = "action."; + + /** real file where to load actions mapping */ + protected String actionFilePath; + + public SimpleActionFactoryImpl() { + this(ACTIONS_FILE_PATH); + } + + public SimpleActionFactoryImpl(String actionFilePath) { + this.actionFilePath = actionFilePath; + } + + @SuppressWarnings({"unchecked"}) + protected Map<String, Class<? extends AbstractAction>> init() { + ServiceLoader<ActionProvider> loader = ServiceLoader.load(ActionProvider.class); + Map<String, Class<? extends AbstractAction>> cache = new TreeMap<String, Class<? extends AbstractAction>>(); + + for (ActionProvider<? extends AbstractAction> actionProvider : loader) { + log.info("load action provider " + actionProvider); + cache.putAll(actionProvider.getClasses()); + } + return cache; + } + + @SuppressWarnings({"unchecked"}) + protected Map<String, Class<? extends AbstractAction>> initOld() { + Properties properties = new Properties(); + List<URL> urls = Resource.getURLs(".*jaxx/.+-actions\\.properties"); + for (URL url : urls) { + InputStream inputStream = null; + try { + inputStream = url.openStream(); + log.info("load " + url); + properties.load(inputStream); + } catch (IOException e) { + log.warn(_("jaxx.error.load.actions.file", e.getMessage())); + //throw new RuntimeException(_("jaxx.error.load.actions.file", e.getMessage())); + } 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 AbstractAction>> cache = new TreeMap<String, Class<? extends AbstractAction>>(); + int prefix = ACTION_KEY_PREFIX.length(); + for (Map.Entry<Object, Object> objectObjectEntry : properties.entrySet()) { + String key = objectObjectEntry.getKey() + ""; + String qfn = objectObjectEntry.getValue() + ""; + try { + Class<? extends AbstractAction> implCass; + implCass = (Class<? extends AbstractAction>) Class.forName(qfn); + log.debug("found action " + implCass); + cache.put(key.substring(prefix), implCass); + } catch (ClassNotFoundException e) { + throw new RuntimeException(_("jaxx.error.load.actions.class", key, qfn)); + } + } + return cache; + } + +} \ No newline at end of file Added: trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfig.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfig.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/main/java/org/codelutin/jaxx/action/ToggleActionConfig.java 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,148 @@ +/* +* ##% 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.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 + */ +@Retention(RetentionPolicy.RUNTIME) + +@Target(ElementType.TYPE) + +public @interface ToggleActionConfig { + /** + * @return la clef de la commande (doit �tre unique) + * @see javax.swing.Action#ACTION_COMMAND_KEY + */ + public abstract String actionCommand(); + + /** + * @return la clef i18n du texte de l'action, si vide ignor� + * @see javax.swing.Action#NAME + */ + public abstract String name() default ""; + + /** + * @return la clef i18n du tooltip de l'action, si vide ignor� + * @see javax.swing.Action#SHORT_DESCRIPTION + */ + public abstract String shortDescription() default ""; + + /** + * @return la clef i18n du texte de l'action, si vide ignor� + * @see javax.swing.Action#LONG_DESCRIPTION + */ + public abstract String longDescription() default ""; + + /** + * @return le nom de l'icone associ�, si vide ignor� + * @see javax.swing.Action#SMALL_ICON + */ + public abstract String smallIcon() default ""; + + /** + * @return le nom du grande icone associ�, si vide ignor� + * @see javax.swing.Action#LARGE_ICON_KEY + */ + public abstract String largeIcon() default ""; + + /** + * @return + * @see javax.swing.Action#ACCELERATOR_KEY + */ + public abstract String accelerator() default ""; + + /** + * @return + * @see javax.swing.Action#MNEMONIC_KEY + */ + public abstract int mnemonic() default '\0'; + + /** + * @return la clef i18n du texte de l'action, si vide ignor� + * @see javax.swing.Action#NAME + */ + public abstract String name2() default ""; + + /** + * @return la clef i18n du tooltip de l'action, si vide ignor� + * @see javax.swing.Action#SHORT_DESCRIPTION + */ + public abstract String shortDescription2() default ""; + + /** + * @return la clef i18n du texte de l'action, si vide ignor� + * @see javax.swing.Action#LONG_DESCRIPTION + */ + public abstract String longDescription2() default ""; + + /** + * @return le nom de l'icone associ�, si vide ignor� + * @see javax.swing.Action#SMALL_ICON + */ + public abstract String smallIcon2() default ""; + + /** + * @return le nom du grande icone associ�, si vide ignor� + * @see javax.swing.Action#LARGE_ICON_KEY + */ + public abstract String largeIcon2() default ""; + + /** + * @return + * @see javax.swing.Action#ACCELERATOR_KEY + */ + public abstract String accelerator2() default ""; + + /** + * @return + * @see javax.swing.Action#MNEMONIC_KEY + */ + public abstract int mnemonic2() default '\0'; + + /** + * @return la valeur par d�faut pour les component selectable + * @see javax.swing.Action#SELECTED_KEY + */ + public abstract boolean selected() default false; + + /** + * @return + * @see javax.swing.Action#isEnabled() + */ + public abstract boolean enabled() default true; + + /** + * @return + * @see javax.swing.Action#isEnabled() + */ + public abstract boolean hideActionText() default false; + +} \ No newline at end of file Added: trunk/lutinjaxx/jaxx-swing-action/src/site/site.xml =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/site/site.xml (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/site/site.xml 2008-07-20 19:22:41 UTC (rev 728) @@ -0,0 +1,44 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<project name="LutinUtil"> + + <skin> + <groupId>lutinlib</groupId> + <artifactId>lutin-site-skin</artifactId> + <version>0.1</version> + </skin> + + <bannerLeft> + <name>Lutin Buix Jaxx</name> + </bannerLeft> + + <bannerRight> + <src>http://www.codelutin.com/images/lutinorange-codelutin.png</src> + <href>http://www.codelutin.com</href> + </bannerRight> + + <poweredBy> + <logo href="http://maven.apache.org" name="Maven" img="images/logos/maven-feather.png"/> + <logo href="http://jrst.labs.libre-entreprise.org" name="JRst" img="images/jrst-logo.png"/> + <logo href="http://docutils.sourceforge.net/rst.html" name="ReStructuredText" + img="images/restructuredtext-logo.png"/> + </poweredBy> + + <body> + <links> + <item name="Labs" href="http://labs.libre-entreprise.org/"/> + <item name="Code Lutin" href="http://www.codelutin.com/"/> + </links> + + <menu name="Utilisateur"> + <item name="Accueil" href="index.html"/> + <item href="http://lutinbuilder.labs.libre-entreprise.org/maven2/buix/jaxx" name="T�l�chargement"/> + </menu> + + <menu name="D�veloppeur"> + <item name="A faire" href="Todo.html"/> + </menu> + + ${reports} + + </body> +</project> Added: trunk/lutinjaxx/jaxx-swing-action/src/test/java/jaxx/runtime/UtilTest.java =================================================================== --- trunk/lutinjaxx/jaxx-swing-action/src/test/java/jaxx/runtime/UtilTest.java (rev 0) +++ trunk/lutinjaxx/jaxx-swing-action/src/test/java/jaxx/runtime/UtilTest.java 2008-07-20 19:22:41 UTC (rev 728) @@ -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
participants (1)
-
tchemit@users.labs.libre-entreprise.org