r2779 - in trunk: . jaxx-application-api jaxx-application-api/src jaxx-application-api/src/license jaxx-application-api/src/main jaxx-application-api/src/main/java jaxx-application-api/src/main/java/org jaxx-application-api/src/main/java/org/nuiton jaxx-application-api/src/main/java/org/nuiton/jaxx jaxx-application-api/src/main/java/org/nuiton/jaxx/application jaxx-application-api/src/main/java/org/nuiton/jaxx/application/listener jaxx-application-api/src/main/java/org/nuiton/jaxx/application
Author: tchemit Date: 2014-01-31 11:50:51 +0100 (Fri, 31 Jan 2014) New Revision: 2779 Url: http://nuiton.org/projects/jaxx/repository/revisions/2779 Log: fixes #3017: Introduce a simple jaxx application framework Added: trunk/jaxx-application-api/ trunk/jaxx-application-api/LICENSE.txt trunk/jaxx-application-api/README.txt trunk/jaxx-application-api/pom.xml trunk/jaxx-application-api/src/ trunk/jaxx-application-api/src/license/ trunk/jaxx-application-api/src/license/THIRD-PARTY.properties trunk/jaxx-application-api/src/main/ trunk/jaxx-application-api/src/main/java/ trunk/jaxx-application-api/src/main/java/org/ trunk/jaxx-application-api/src/main/java/org/nuiton/ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationBusinessException.java trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationConfiguration.java trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationContext.java trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationDataUtil.java trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationIOUtil.java trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationTechnicalException.java trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/listener/ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/listener/PropagatePropertyChangeListener.java trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/type/ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/type/ApplicationProgressionModel.java trunk/jaxx-application-api/src/main/resources/ trunk/jaxx-application-swing/ trunk/jaxx-application-swing/LICENSE.txt trunk/jaxx-application-swing/README.txt trunk/jaxx-application-swing/pom.xml trunk/jaxx-application-swing/src/ trunk/jaxx-application-swing/src/license/ trunk/jaxx-application-swing/src/license/THIRD-PARTY.properties trunk/jaxx-application-swing/src/main/ trunk/jaxx-application-swing/src/main/java/ trunk/jaxx-application-swing/src/main/java/org/ trunk/jaxx-application-swing/src/main/java/org/nuiton/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/AbstractApplicationUIHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUI.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUIContext.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/AbstractApplicationAction.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionEngine.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionException.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionFactory.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionSwingWorker.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.css trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.jaxx trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIModel.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationUIAction.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationAction.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEngine.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEvent.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionListener.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractApplicationTableModel.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractSelectTableAction.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/ColumnIdentifier.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableCellAction.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableRowAction.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableCellAction.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableRowAction.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ActionListCellRenderer.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationColorHighlighter.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationErrorHelper.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationExceptionHandler.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/Cancelable.java trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/CloseableUI.java trunk/jaxx-application-swing/src/main/resources/ trunk/jaxx-application-swing/src/main/resources/i18n/ trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties Modified: trunk/jaxx-demo/src/main/resources/jaxxdemo-help-fr.properties trunk/pom.xml Property changes on: trunk/jaxx-application-api ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Added: trunk/jaxx-application-api/LICENSE.txt =================================================================== --- trunk/jaxx-application-api/LICENSE.txt (rev 0) +++ trunk/jaxx-application-api/LICENSE.txt 2014-01-31 10:50:51 UTC (rev 2779) @@ -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. + Property changes on: trunk/jaxx-application-api/LICENSE.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Property changes on: trunk/jaxx-application-api/README.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-api/pom.xml =================================================================== --- trunk/jaxx-application-api/pom.xml (rev 0) +++ trunk/jaxx-application-api/pom.xml 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,92 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Ifremer shared :: Application + %% + Copyright (C) 2013 Ifremer, CodeLutin, 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 3 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, see + <http://www.gnu.org/licenses/gpl-3.0.html>. + #L% + --> + +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.nuiton</groupId> + <artifactId>jaxx</artifactId> + <version>2.8-SNAPSHOT</version> + </parent> + + <groupId>org.nuiton.jaxx</groupId> + <artifactId>jaxx-application-api</artifactId> + <name>JAXX :: Application API</name> + + <dependencies> + + <!-- Commons --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + <dependency> + <groupId>commons-beanutils</groupId> + <artifactId>commons-beanutils</artifactId> + </dependency> + <dependency> + <groupId>commons-io</groupId> + <artifactId>commons-io</artifactId> + </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-vfs2</artifactId> + </dependency> + + <!-- Guava --> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + + <!-- Nuiton --> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-utils</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-config</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton.i18n</groupId> + <artifactId>nuiton-i18n</artifactId> + </dependency> + + <!-- SwingX --> + <dependency> + <groupId>org.swinglabs.swingx</groupId> + <artifactId>swingx-common</artifactId> + </dependency> + + + <!-- Test --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + </dependencies> + +</project> Property changes on: trunk/jaxx-application-api/pom.xml ___________________________________________________________________ Added: svn:mime-type + text/xml Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Property changes on: trunk/jaxx-application-api/src ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Property changes on: trunk/jaxx-application-api/src/license ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Added: trunk/jaxx-application-api/src/license/THIRD-PARTY.properties =================================================================== --- trunk/jaxx-application-api/src/license/THIRD-PARTY.properties (rev 0) +++ trunk/jaxx-application-api/src/license/THIRD-PARTY.properties 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,21 @@ +# Generated by org.codehaus.mojo.license.AddThirdPartyMojo +#------------------------------------------------------------------------------- +# Already used licenses in project : +# - BSD License +# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 +# - Common Public License Version 1.0 +# - GNU Library or Lesser General Public License +# - Indiana University Extreme! Lab Software License, vesion 1.1.1 +# - Lesser General Public License (LGPL) +# - Lesser General Public License (LGPL) v 3.0 +# - Lesser General Public License (LPGL) +# - Lesser General Public License (LPGL) v 2.1 +# - MIT License +# - New BSD License +# - The Apache Software License, Version 2.0 +#------------------------------------------------------------------------------- +# Please fill the missing licenses for dependencies : +# +# +#Sun Nov 24 23:48:15 CET 2013 +commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0 Property changes on: trunk/jaxx-application-api/src/license/THIRD-PARTY.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Property changes on: trunk/jaxx-application-api/src/main ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Property changes on: trunk/jaxx-application-api/src/main/java ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Added: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationBusinessException.java =================================================================== --- trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationBusinessException.java (rev 0) +++ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationBusinessException.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,51 @@ +package org.nuiton.jaxx.application; + +/* + * #%L + * JAXX :: Application API + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * Application business exception, a such exeception should be shown to + * user in application. + * + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationBusinessException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public ApplicationBusinessException(String message) { + super(message); + } + + public ApplicationBusinessException(String message, Throwable cause) { + super(message, cause); + } + + public ApplicationBusinessException(Throwable cause) { + super(cause); + } +} Property changes on: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationBusinessException.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationConfiguration.java =================================================================== --- trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationConfiguration.java (rev 0) +++ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationConfiguration.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,58 @@ +package org.nuiton.jaxx.application; + +/* + * #%L + * JAXX :: Application API + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.config.ApplicationConfig; +import org.nuiton.util.Version; + +import javax.swing.KeyStroke; + +/** + * Created on 11/24/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public abstract class ApplicationConfiguration { + + /** + * Delegate application config. + */ + protected final ApplicationConfig applicationConfig; + + public abstract String getApplicationName(); + + public abstract Version getVersion(); + + public abstract KeyStroke getShortcutClosePopup(); + + public ApplicationConfiguration(ApplicationConfig applicationConfig) { + this.applicationConfig = applicationConfig; + } + + public ApplicationConfig getApplicationConfig() { + return applicationConfig; + } +} Property changes on: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationConfiguration.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationContext.java =================================================================== --- trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationContext.java (rev 0) +++ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationContext.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,41 @@ +package org.nuiton.jaxx.application; + +/* + * #%L + * JAXX :: Application API + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * Context of application, may contains config, data sources, ... + * <p/> + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public interface ApplicationContext { + + /** + * @return the application configuration + */ + ApplicationConfiguration getConfiguration(); +} Property changes on: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationContext.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationDataUtil.java =================================================================== --- trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationDataUtil.java (rev 0) +++ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationDataUtil.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,77 @@ +package org.nuiton.jaxx.application; + +/* + * #%L + * JAXX :: Application API + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.lang3.time.DurationFormatUtils; + +import java.util.Date; + +/** + * Useful methods on data. + * <p/> + * TODO Needs some javadoc. + * <p/> + * Created on 11/24/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationDataUtil { + + public static void setProperty(Object bean, String property, Object value) { + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(property); + try { + PropertyUtils.setSimpleProperty(bean, property, value); + } catch (Exception e) { + throw new ApplicationTechnicalException(String.format("Property %1s not found on object of type %2s", property, bean.getClass().getName()), e); + } + } + + public static Object getProperty(Object bean, String property) { + Preconditions.checkNotNull(bean); + Preconditions.checkNotNull(property); + try { + return PropertyUtils.getSimpleProperty(bean, property); + } catch (Exception e) { + throw new ApplicationTechnicalException(String.format("Property %1s not found on object of type %2s", property, bean.getClass().getName()), e); + } + } + + public static String getDuration(Date startDate, + Date endDate, + String format) { + String duration = ""; + if (startDate != null && endDate != null && !startDate.after(endDate)) { + duration = DurationFormatUtils.formatPeriod( + startDate.getTime(), + endDate.getTime(), + format); + } + return duration; + } +} Property changes on: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationDataUtil.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationIOUtil.java =================================================================== --- trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationIOUtil.java (rev 0) +++ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationIOUtil.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,256 @@ +package org.nuiton.jaxx.application; + +/* + * #%L + * JAXX :: Application API + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Charsets; +import com.google.common.io.Files; +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.FilenameUtils; +import org.apache.commons.vfs2.FileObject; +import org.apache.commons.vfs2.FileSelector; +import org.apache.commons.vfs2.FileSystemManager; +import org.apache.commons.vfs2.FileType; +import org.apache.commons.vfs2.VFS; +import org.nuiton.util.ZipUtil; + +import java.io.Closeable; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.Reader; +import java.io.Writer; +import java.util.List; +import java.util.UUID; + +import static org.nuiton.i18n.I18n._; + +/** + * Useful methods around IO, all method errors are boxes a + * {@link ApplicationTechnicalException}. + * <p/> + * Created on 11/24/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationIOUtil { + + protected ApplicationIOUtil() { + // no instance + } + + public static void close(Closeable toClose, String errorMessage) { + + try { + toClose.close(); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void zip(File source, File archiveFile, String errorMessage) { + try { + ZipUtil.compress(archiveFile, source); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void zip(File source, File archiveFile, List<File> files, String errorMessage) { + try { + ZipUtil.compressFiles(archiveFile, source, files); + } catch (IOException e) { + throw new ApplicationTechnicalException(_(errorMessage, archiveFile), e); + } + } + + public static FileObject resolveFile(String file, String errorMessage) { + try { + FileSystemManager manager = VFS.getManager(); + FileObject targetObject = manager.resolveFile(file); + return targetObject; + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static FileObject[] getChildren(FileObject objectFile, String errorMessage) { + try { + return objectFile.getChildren(); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static FileObject getChild(FileObject objectFile, String name, String errorMessage) { + try { + return objectFile.getChild(name); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + + public static FileType getType(FileObject objectFile, String errorMessage) { + try { + return objectFile.getType(); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void explode(FileObject archiveFile, + File target, + FileSelector fileSelector, String errorMessage) { + try { + FileSystemManager manager = VFS.getManager(); + FileObject targetObject = manager.toFileObject(target); + targetObject.copyFrom(archiveFile, fileSelector); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void forceMkdir(File dir, String errorMessage) { + try { + FileUtils.forceMkdir(dir); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void cleanDirectory(File dir, String errorMessage) { + try { + FileUtils.cleanDirectory(dir); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void deleteDirectory(File dir, String errorMessage) { + try { + FileUtils.deleteDirectory(dir); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void forceDeleteOnExit(File dir, String errorMessage) { + try { + FileUtils.forceDeleteOnExit(dir); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void copyDirectory(File source, File target, String errorMessage) { + try { + FileUtils.copyDirectory(source, target); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void copyFileToDirectory(File source, File target, String errorMessage) { + try { + FileUtils.copyFileToDirectory(source, target); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void copyFile(File source, File target, String errorMessage) { + try { + FileUtils.copyFile(source, target); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void deleteFile(File file, String errorMessage) { + try { + FileUtils.forceDelete(file); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static String getBaseName(String file) { + return FilenameUtils.getBaseName(file); + } + + public static String getExtension(String file) { + return FilenameUtils.getExtension(file); + } + + public static Reader newReader(File file, String errorMessage) { + try { + return Files.newReader(file, Charsets.UTF_8); + + } catch (FileNotFoundException e) { + throw new ApplicationTechnicalException(_(errorMessage, file), e); + } + } + + public static Writer newWriter(File file, String errorMessage + ) { + try { + return Files.newWriter(file, Charsets.UTF_8); + + } catch (FileNotFoundException e) { + throw new ApplicationTechnicalException(_(errorMessage, file), e); + } + } + + public static File explodeZip(File rootDirectory, + File file, + String errorMessage) { + File tempDir = new File(rootDirectory, UUID.randomUUID().toString()); + try { + ZipUtil.uncompress(file, tempDir); + } catch (IOException e) { + throw new ApplicationTechnicalException(_(errorMessage, file), e); + } + return tempDir; + } + + public static String readContent(File file, String errorMessage) { + + try { + return Files.readFirstLine(file, Charsets.UTF_8); + + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } + + public static void writeContent(File file, String content, String errorMessage) { + try { + FileUtils.write(file, content, Charsets.UTF_8); + } catch (IOException e) { + throw new ApplicationTechnicalException(errorMessage, e); + } + } +} Property changes on: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationIOUtil.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationTechnicalException.java =================================================================== --- trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationTechnicalException.java (rev 0) +++ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationTechnicalException.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,50 @@ +package org.nuiton.jaxx.application; + +/* + * #%L + * JAXX :: Application API + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * Application Technical exception. + * + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationTechnicalException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public ApplicationTechnicalException(String message) { + super(message); + } + + public ApplicationTechnicalException(String message, Throwable cause) { + super(message, cause); + } + + public ApplicationTechnicalException(Throwable cause) { + super(cause); + } +} Property changes on: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/ApplicationTechnicalException.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/listener/PropagatePropertyChangeListener.java =================================================================== --- trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/listener/PropagatePropertyChangeListener.java (rev 0) +++ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/listener/PropagatePropertyChangeListener.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,80 @@ +package org.nuiton.jaxx.application.listener; + +/* + * #%L + * JAXX :: Application API + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.jdesktop.beans.AbstractBean; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +/** + * To listen a bean and propagate some of properties. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class PropagatePropertyChangeListener implements PropertyChangeListener { + + public static interface PropagatePropertyChange { + void firePropertyChanged(String propertyName, + Object oldValue, + Object newValue); + } + + public static void listenAndPropagate(AbstractBean producer, + PropagatePropertyChange consumer, + String propertyNameToListen, + String propertyNameToForward) { + PropagatePropertyChangeListener listener = + new PropagatePropertyChangeListener(propertyNameToForward, + consumer); + producer.addPropertyChangeListener(propertyNameToListen, listener); + } + + public static void listenAndPropagateAll(AbstractBean producer, + PropagatePropertyChange consumer) { + PropagatePropertyChangeListener listener = + new PropagatePropertyChangeListener(null, consumer); + producer.addPropertyChangeListener(listener); + } + + private String propertyName; + + private PropagatePropertyChange editor; + + public PropagatePropertyChangeListener(String propertyName, + PropagatePropertyChange editor) { + this.propertyName = propertyName; + this.editor = editor; + } + + @Override + public void propertyChange(PropertyChangeEvent evt) { + String name = propertyName == null ? evt.getPropertyName() : propertyName; + editor.firePropertyChanged(name, + evt.getOldValue(), + evt.getNewValue()); + } +} Property changes on: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/listener/PropagatePropertyChangeListener.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/type/ApplicationProgressionModel.java =================================================================== --- trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/type/ApplicationProgressionModel.java (rev 0) +++ trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/type/ApplicationProgressionModel.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,115 @@ +package org.nuiton.jaxx.application.type; + +/* + * #%L + * JAXX :: Application API + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.jdesktop.beans.AbstractSerializableBean; + +/** + * Simple model for a progression long task. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationProgressionModel extends AbstractSerializableBean { + + private static final long serialVersionUID = 1L; + + public static final String PROPERTY_TOTAL = "total"; + + public static final String PROPERTY_CURRENT = "current"; + + public static final String PROPERTY_RATE = "rate"; + + public static final String PROPERTY_MESSAGE = "message"; + + protected int total; + + protected int current; + + protected float rate; + + protected String message; + + public int getTotal() { + return total; + } + + public void setTotal(int total) { + Object oldValue = getTotal(); + this.total = total; + firePropertyChange(PROPERTY_TOTAL, oldValue, total); + setCurrent(0); + } + + public void adaptTotal(int total) { + int current = getCurrent(); + setTotal(total); + increments(current); + Object oldValue = getTotal(); + this.total = total; + firePropertyChange(PROPERTY_TOTAL, oldValue, total); + setCurrent(current); + } + + public int getCurrent() { + return current; + } + + public void setCurrent(int current) { + Object oldValue = getCurrent(); + this.current = current; + firePropertyChange(PROPERTY_CURRENT, oldValue, current); + } + + public void increments(int nb) { + setCurrent(current + nb); + setRate(getCurrent() / getTotal()); + } + + public float getRate() { + return rate; + } + + public void setRate(float rate) { + Object oldValue = getRate(); + this.rate = rate; + firePropertyChange(PROPERTY_RATE, oldValue, rate); + } + + public String getMessage() { + return message; + } + + public void increments(String message) { + increments(1); + setMessage(message); + } + + public void setMessage(String message) { + Object oldValue = getMessage(); + this.message = message; + firePropertyChange(PROPERTY_MESSAGE, oldValue, message); + } +} Property changes on: trunk/jaxx-application-api/src/main/java/org/nuiton/jaxx/application/type/ApplicationProgressionModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Property changes on: trunk/jaxx-application-api/src/main/resources ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Property changes on: trunk/jaxx-application-swing ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Added: trunk/jaxx-application-swing/LICENSE.txt =================================================================== --- trunk/jaxx-application-swing/LICENSE.txt (rev 0) +++ trunk/jaxx-application-swing/LICENSE.txt 2014-01-31 10:50:51 UTC (rev 2779) @@ -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. + Property changes on: trunk/jaxx-application-swing/LICENSE.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Property changes on: trunk/jaxx-application-swing/README.txt ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/pom.xml =================================================================== --- trunk/jaxx-application-swing/pom.xml (rev 0) +++ trunk/jaxx-application-swing/pom.xml 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,189 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- + #%L + Ifremer shared :: Application Swing + %% + Copyright (C) 2013 Ifremer, CodeLutin, 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 3 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, see + <http://www.gnu.org/licenses/gpl-3.0.html>. + #L% + --> + +<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/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.nuiton</groupId> + <artifactId>jaxx</artifactId> + <version>2.8-SNAPSHOT</version> + </parent> + + <groupId>org.nuiton.jaxx</groupId> + <artifactId>jaxx-application-swing</artifactId> + <name>JAXX :: Application Swing</name> + + <properties> + + <!-- jaxx configuration --> + <jaxx.addProjectClassPath>true</jaxx.addProjectClassPath> + <jaxx.addSourcesToClassPath>true</jaxx.addSourcesToClassPath> + <jaxx.defaultErrorUIFQN> + jaxx.runtime.validator.swing.ui.ImageValidationUI + </jaxx.defaultErrorUIFQN> + <!--<jaxx.useUIManagerForIcon>true</jaxx.useUIManagerForIcon>--> + <jaxx.generateHelp>true</jaxx.generateHelp> + <jaxx.generateSearch>false</jaxx.generateSearch> + <jaxx.autoImportCss>true</jaxx.autoImportCss> + <jaxx.autoRecurseInCss>false</jaxx.autoRecurseInCss> + <jaxx.addAutoHandlerUI>true</jaxx.addAutoHandlerUI> + + <!-- Post Release configuration --> + <skipPostRelease>false</skipPostRelease> + + </properties> + + <dependencies> + + <!-- Sibling --> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>jaxx-application-api</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>jaxx-runtime</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>jaxx-validator</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>jaxx-widgets</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- Commons --> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-lang3</artifactId> + </dependency> + <dependency> + <groupId>commons-logging</groupId> + <artifactId>commons-logging</artifactId> + </dependency> + <dependency> + <groupId>commons-httpclient</groupId> + <artifactId>commons-httpclient</artifactId> + <scope>runtime</scope> + </dependency> + + <!-- Guava --> + <dependency> + <groupId>com.google.guava</groupId> + <artifactId>guava</artifactId> + </dependency> + + <!-- Nuiton --> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-utils</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-decorator</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton.i18n</groupId> + <artifactId>nuiton-i18n</artifactId> + </dependency> + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-csv</artifactId> + </dependency> + + <!-- SwingX --> + <dependency> + <groupId>org.swinglabs.swingx</groupId> + <artifactId>swingx-core</artifactId> + </dependency> + <dependency> + <groupId>org.swinglabs.swingx</groupId> + <artifactId>swingx-common</artifactId> + </dependency> + <dependency> + <groupId>org.swinglabs.swingx</groupId> + <artifactId>swingx-autocomplete</artifactId> + </dependency> + + <!-- Logging --> + <!--dependency> + <groupId>org.slf4j</groupId> + <artifactId>slf4j-jcl</artifactId> + <scope>runtime</scope> + </dependency> + <dependency> + <groupId>log4j</groupId> + <artifactId>log4j</artifactId> + <scope>runtime</scope> + </dependency--> + + <!-- Test --> + <dependency> + <groupId>junit</groupId> + <artifactId>junit</artifactId> + </dependency> + + </dependencies> + + <build> + + <plugins> + + <plugin> + <groupId>org.nuiton.jaxx</groupId> + <artifactId>jaxx-maven-plugin</artifactId> + <version>${project.version}</version> + <executions> + <execution> + <goals> + <goal>generate</goal> + </goals> + </execution> + </executions> + </plugin> + + <plugin> + <groupId>org.nuiton.i18n</groupId> + <artifactId>i18n-maven-plugin</artifactId> + <executions> + <execution> + <id>scan-sources</id> + <goals> + <goal>parserJava</goal> + <goal>gen</goal> + </goals> + </execution> + </executions> + </plugin> + + </plugins> + </build> + +</project> Property changes on: trunk/jaxx-application-swing/pom.xml ___________________________________________________________________ Added: svn:mime-type + text/xml Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Property changes on: trunk/jaxx-application-swing/src ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Property changes on: trunk/jaxx-application-swing/src/license ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Added: trunk/jaxx-application-swing/src/license/THIRD-PARTY.properties =================================================================== --- trunk/jaxx-application-swing/src/license/THIRD-PARTY.properties (rev 0) +++ trunk/jaxx-application-swing/src/license/THIRD-PARTY.properties 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,25 @@ +# Generated by org.codehaus.mojo.license.AddThirdPartyMojo +#------------------------------------------------------------------------------- +# Already used licenses in project : +# - Apache License +# - BSD License +# - COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0 +# - Common Public License Version 1.0 +# - GNU General Public License - Version 2 with the class path exception +# - GNU Library or Lesser General Public License +# - General Public License (GPL) +# - Indiana University Extreme! Lab Software License, vesion 1.1.1 +# - Lesser General Public License (LGPL) +# - Lesser General Public License (LGPL) v 3.0 +# - Lesser General Public License (LPGL) +# - Lesser General Public License (LPGL) v 2.1 +# - MIT License +# - New BSD License +# - The Apache Software License, Version 2.0 +#------------------------------------------------------------------------------- +# Please fill the missing licenses for dependencies : +# +# +#Sun Nov 24 23:54:27 CET 2013 +commons-primitives--commons-primitives--1.0=The Apache Software License, Version 2.0 +javassist--javassist--3.11.0.GA=The Apache Software License, Version 2.0 Property changes on: trunk/jaxx-application-swing/src/license/THIRD-PARTY.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Property changes on: trunk/jaxx-application-swing/src/main ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Property changes on: trunk/jaxx-application-swing/src/main/java ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/AbstractApplicationUIHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/AbstractApplicationUIHandler.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/AbstractApplicationUIHandler.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,1019 @@ +package org.nuiton.jaxx.application.swing; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import jaxx.runtime.JAXXUtil; +import jaxx.runtime.SwingUtil; +import jaxx.runtime.spi.UIHandler; +import jaxx.runtime.swing.JAXXWidgetUtil; +import jaxx.runtime.swing.editor.FileEditor; +import jaxx.runtime.swing.editor.NumberEditor; +import jaxx.runtime.swing.editor.SimpleTimeEditor; +import jaxx.runtime.swing.editor.bean.BeanDoubleList; +import jaxx.runtime.swing.editor.bean.BeanFilterableComboBox; +import jaxx.runtime.swing.editor.bean.BeanUIUtil; +import jaxx.runtime.swing.editor.cell.NumberCellEditor; +import jaxx.runtime.swing.editor.gis.DmdCoordinateEditor; +import jaxx.runtime.swing.editor.gis.DmsCoordinateEditor; +import jaxx.runtime.swing.renderer.DecoratorListCellRenderer; +import jaxx.runtime.swing.renderer.DecoratorTableCellRenderer; +import jaxx.runtime.validator.swing.SwingValidator; +import org.apache.commons.lang3.ArrayUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.swingx.JXDatePicker; +import org.jdesktop.swingx.JXTable; +import org.jdesktop.swingx.autocomplete.ComboBoxCellEditor; +import org.jdesktop.swingx.autocomplete.ObjectToStringConverter; +import org.jdesktop.swingx.table.TableColumnExt; +import org.nuiton.decorator.Decorator; +import org.nuiton.decorator.JXPathDecorator; +import org.nuiton.jaxx.application.ApplicationDataUtil; +import org.nuiton.jaxx.application.swing.action.ApplicationActionUI; +import org.nuiton.jaxx.application.swing.table.ColumnIdentifier; +import org.nuiton.jaxx.application.swing.util.ApplicationUIUtil; +import org.nuiton.jaxx.application.swing.util.Cancelable; +import org.nuiton.jaxx.application.type.ApplicationProgressionModel; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Action; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JComboBox; +import javax.swing.JComponent; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPopupMenu; +import javax.swing.JRootPane; +import javax.swing.JScrollPane; +import javax.swing.JSpinner; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JViewport; +import javax.swing.KeyStroke; +import javax.swing.ListCellRenderer; +import javax.swing.ListSelectionModel; +import javax.swing.ScrollPaneConstants; +import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.border.LineBorder; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumnModel; +import javax.swing.text.JTextComponent; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dialog; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import java.awt.event.ItemEvent; +import java.awt.event.KeyEvent; +import java.awt.event.MouseEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.io.File; +import java.io.Serializable; +import java.text.ParseException; +import java.util.Date; +import java.util.List; +import java.util.Map; + +import static org.nuiton.i18n.I18n._; + +/** + * Handler of any ui. + * <p/> + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public abstract class AbstractApplicationUIHandler<M, UI extends ApplicationUI<M, ?>> implements UIHandler<UI> { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(AbstractApplicationUIHandler.class); + + public abstract void onCloseUI(); + + public abstract SwingValidator<M> getValidator(); + + public abstract Component getTopestUI(); + + public abstract <E> Decorator<E> getDecorator(Class<E> beanType, String decoratorContext); + + /** + * Hook to prepare popup just before showing it. + * <p/> + * The right place to update actions accessibility; a quite better design + * than trying to update each time something change in the table... + * + * @param modelRowIndex selected row index (or lowest selected one) + * @param modelColumnIndex selected column index + * @since 2.6 + */ + protected void beforeOpenPopup(int modelRowIndex, int modelColumnIndex) { + // by default do nothing + } + + /** + * Global application context. + */ + private ApplicationUIContext context; + + /** + * UI handled. + */ + protected UI ui; + + //------------------------------------------------------------------------// + //-- Public methods --// + //------------------------------------------------------------------------// + + public DefaultComboBoxModel newComboModel(Object... items) { + return new DefaultComboBoxModel(items); + } + + public final M getModel() { + return ui.getModel(); + } + + public final UI getUI() { + return ui; + } + + @Override + public void beforeInit(UI ui) { + this.ui = ui; + } + + public ApplicationUIContext getContext() { + if (context == null) { + context = ApplicationUIUtil.getApplicationContext(ui); + } + return context; + } + + public void setText(KeyEvent event, String property) { + JTextComponent field = (JTextComponent) event.getSource(); + String value = field.getText(); + ApplicationDataUtil.setProperty(getModel(), property, value); + } + + public void setFile(ActionEvent event, String property) { + FileEditor field = (FileEditor) event.getSource(); + File value = field.getSelectedFile(); + ApplicationDataUtil.setProperty(getModel(), property, value); + } + + public void setBoolean(ItemEvent event, String property) { + boolean value = event.getStateChange() == ItemEvent.SELECTED; + ApplicationDataUtil.setProperty(getModel(), property, value); + } + + public void setDate(ActionEvent event, String property) { + JXDatePicker field = (JXDatePicker) event.getSource(); + Date value = field.getDate(); + ApplicationDataUtil.setProperty(getModel(), property, value); + } + + public void selectListData(ListSelectionEvent event, String property) { + if (!event.getValueIsAdjusting()) { + JList list = (JList) event.getSource(); + ListSelectionModel selectionModel = list.getSelectionModel(); + + selectionModel.setValueIsAdjusting(true); + try { + List<Object> selectedList = Lists.newLinkedList(); + + for (int index : list.getSelectedIndices()) { + Object o = list.getModel().getElementAt(index); + selectedList.add(o); + } + ApplicationDataUtil.setProperty(getModel(), property, selectedList); + } finally { + selectionModel.setValueIsAdjusting(false); + } + } + } + + public void openDialog(ApplicationUI dialogContent, + String title, Dimension dim) { + Component topestUI = getTopestUI(); + + JDialog result; + if (topestUI instanceof Frame) { + result = new JDialog((Frame) topestUI, title, true); + } else { + result = new JDialog((Dialog) topestUI, title, true); + } + + result.add((Component) dialogContent); + result.setResizable(true); + + result.setSize(dim); + + final AbstractApplicationUIHandler handler = dialogContent.getHandler(); + + if (handler instanceof Cancelable) { + + // add a auto-close action + JRootPane rootPane = result.getRootPane(); + + KeyStroke shortcutClosePopup = getContext().getConfiguration().getShortcutClosePopup(); + + rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put( + shortcutClosePopup, "close"); + rootPane.getActionMap().put("close", new AbstractAction() { + private static final long serialVersionUID = 1L; + + @Override + public void actionPerformed(ActionEvent e) { + ((Cancelable) handler).cancel(); + } + }); + } + + result.addWindowListener(new WindowAdapter() { + + @Override + public void windowClosed(WindowEvent e) { + Component ui = (Component) e.getSource(); + if (log.isDebugEnabled()) { + log.debug("Destroy ui " + ui); + } + JAXXUtil.destroy(ui); + } + }); + SwingUtil.center(getContext().getMainUI(), result); + result.setVisible(true); + } + + public void closeDialog() { + getParentContainer(JDialog.class).setVisible(false); + } + + public <U extends Container> U getParentContainer(Class<U> uiType) { + return SwingUtil.getParentContainer(ui, uiType); + } + + public static final String CONFIRMATION_FORMAT = "<html>%s<hr/><br/>%s</html>"; + + public int askSaveBeforeLeaving(String message) { + String htmlMessage = String.format( + CONFIRMATION_FORMAT, + message, + _("jaxx.application.common.askSaveBeforeLeaving.help")); + int result = JOptionPane.showConfirmDialog( + getTopestUI(), + htmlMessage, + _("jaxx.application.common.askSaveBeforeLeaving.title"), + JOptionPane.YES_NO_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + return result; + } + + public boolean askCancelEditBeforeLeaving(String message) { + String htmlMessage = String.format( + CONFIRMATION_FORMAT, + message, + _("jaxx.application.common.askCancelEditBeforeLeaving.help")); + int i = JOptionPane.showConfirmDialog( + getTopestUI(), + htmlMessage, + _("jaxx.application.common.askCancelEditBeforeLeaving.title"), + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + + boolean result = i == JOptionPane.OK_OPTION; + return result; + } + + public void showSuccessMessage(String title, String message) { + + Component topestUI = getTopestUI(); + boolean alwaysOnTop = false; + + if (topestUI instanceof JDialog) { + alwaysOnTop = ((JDialog) topestUI).isAlwaysOnTop(); + } + + if (alwaysOnTop) { + ((JDialog) topestUI).setAlwaysOnTop(false); + } + try { + + JOptionPane.showMessageDialog( + topestUI, + message, + title, + JOptionPane.INFORMATION_MESSAGE, + UIManager.getIcon("info") + ); + } finally { + if (alwaysOnTop) { + ((JDialog) topestUI).setAlwaysOnTop(true); + } + } + } + + protected void addHighlighters(final JXTable table) { + + } + + public void autoSelectRowInTable(MouseEvent e, JPopupMenu popup) { + + boolean rightClick = SwingUtilities.isRightMouseButton(e); + + if (rightClick || SwingUtilities.isLeftMouseButton(e)) { + + // get the coordinates of the mouse click + Point p = e.getPoint(); + + JXTable source = (JXTable) e.getSource(); + + int[] selectedRows = source.getSelectedRows(); + int[] selectedColumns = source.getSelectedColumns(); + + // get the row index at this point + int rowIndex = source.rowAtPoint(p); + + // get the column index at this point + int columnIndex = source.columnAtPoint(p); + + if (log.isDebugEnabled()) { + log.debug("At point [" + p + "] found Row " + rowIndex + ", Column " + columnIndex); + } + + boolean canContinue = true; + + if (source.isEditing()) { + + // stop editing + boolean stopEdit = source.getCellEditor().stopCellEditing(); + if (!stopEdit) { + if (log.isWarnEnabled()) { + log.warn("Could not stop edit cell..."); + } + canContinue = false; + } + } + + if (canContinue) { + + // select row (could empty selection) + if (rowIndex == -1) { + source.clearSelection(); + } else if (!ArrayUtils.contains(selectedRows, rowIndex)) { + if (ListSelectionModel.MULTIPLE_INTERVAL_SELECTION == source.getSelectionMode()) { + // add to selection + source.addRowSelectionInterval(rowIndex, rowIndex); + } else { + // set selection + source.setRowSelectionInterval(rowIndex, rowIndex); + } + } + + // select column (could empty selection) + if (columnIndex == -1) { + source.clearSelection(); + } else if (!ArrayUtils.contains(selectedColumns, columnIndex)) { + source.setColumnSelectionInterval(columnIndex, columnIndex); + } + + if (rightClick) { + + // use now model coordinate + int modelRowIndex = rowIndex == -1 ? -1 : source.convertRowIndexToModel(rowIndex); + int modelColumnIndex = columnIndex == -1 ? -1 : source.convertColumnIndexToModel(columnIndex); + + beforeOpenPopup(modelRowIndex, modelColumnIndex); + + // on right click show popup + popup.show(source, e.getX(), e.getY()); + } + } + } + } + + public void openRowMenu(KeyEvent e, JPopupMenu popup) { + + if (e.getKeyCode() == KeyEvent.VK_CONTEXT_MENU) { + + JXTable source = (JXTable) e.getSource(); + + // get the lowest selected row + int[] selectedRows = source.getSelectedRows(); + int lowestRow = -1; + for (int row : selectedRows) { + lowestRow = Math.max(lowestRow, row); + } + // get the selected column + int selectedColumn = source.getSelectedColumn(); + Rectangle r = source.getCellRect(lowestRow, selectedColumn, true); + + // get the point in the middle lower of the cell + Point p = new Point(r.x + r.width / 2, r.y + r.height); + + if (log.isDebugEnabled()) { + log.debug("Row " + lowestRow + " found t point [" + p + "]"); + } + + boolean canContinue = true; + + if (source.isEditing()) { + + // stop editing + boolean stopEdit = source.getCellEditor().stopCellEditing(); + if (!stopEdit) { + if (log.isWarnEnabled()) { + log.warn("Could not stop edit cell..."); + } + canContinue = false; + } + } + + if (canContinue) { + + // use now model coordinate + int rowIndex = source.convertRowIndexToModel(lowestRow); + int columnIndex = source.convertColumnIndexToModel(selectedColumn); + beforeOpenPopup(rowIndex, columnIndex); + + popup.show(source, p.x, p.y); + } + } + } + + //------------------------------------------------------------------------// + //-- Init methods --// + //------------------------------------------------------------------------// + + protected void initUIComponent(Object component) { + if (component instanceof NumberEditor) { + + initNumberEditor((NumberEditor) component); + } else if (component instanceof JXDatePicker) { + + initDatePicker((JXDatePicker) component); + } else if (component instanceof SimpleTimeEditor) { + + initTimeEditor((SimpleTimeEditor) component); + } else if (component instanceof JLabel) { + + initLabel((JLabel) component); + } else if (component instanceof JTextField) { + + initTextField((JTextField) component); + } else if (component instanceof AbstractButton) { + + initButton((AbstractButton) component); + } else if (component instanceof JScrollPane) { + + initScrollPane((JScrollPane) component); + } else if (component instanceof DmsCoordinateEditor) { + + initCoordinateDMSEditor((DmsCoordinateEditor) component); + } else if (component instanceof DmdCoordinateEditor) { + + initCoordinateDMDEditor((DmdCoordinateEditor) component); + } + } + + protected void initUI(UI ui) { + + for (Map.Entry<String, Object> entry : ui.get$objectMap().entrySet()) { + Object component = entry.getValue(); + initUIComponent(component); + } + + ((Component) ui).addHierarchyListener(new HierarchyListener() { + @Override + public void hierarchyChanged(HierarchyEvent e) { + JComponent component = getComponentToFocus(); + if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) > 0 + && e.getChanged().isShowing() + && component != null) { + component.requestFocus(); + } + } + }); + } + + protected abstract JComponent getComponentToFocus(); + + protected void initTextField(JTextField jTextField) { + + if (isAutoSelectOnFocus(jTextField)) { + addAutoSelectOnFocus(jTextField); + } + } + + protected void initLabel(JLabel jLabel) { + + // by default do nothing more + } + + protected void initButton(AbstractButton abstractButton) { + + Class actionName = (Class) abstractButton.getClientProperty("applicationAction"); + if (actionName != null) { + Action action = getContext().getActionFactory().createUIAction(this, abstractButton, actionName); + abstractButton.setAction(action); + } + } + + /** + * Prépare un component de choix d'entités pour un type d'entité donné et + * pour un service de persistance donné. + * + * @param comboBox le component graphique à initialiser + */ + protected <E> void initBeanFilterableComboBox( + BeanFilterableComboBox<E> comboBox, + List<E> data, + E selectedData) { + + initBeanFilterableComboBox(comboBox, data, selectedData, null); + } + + protected <E> void initBeanFilterableComboBox( + BeanFilterableComboBox<E> comboBox, + List<E> data, + E selectedData, + String decoratorContext) { + + Preconditions.checkNotNull(comboBox, "No comboBox!"); + + Class<E> beanType = comboBox.getBeanType(); + + Preconditions.checkNotNull(beanType, "No beanType on the combobox!"); + + Decorator<E> decorator = getDecorator(beanType, decoratorContext); + + if (data == null) { + data = Lists.newArrayList(); + } + + if (log.isDebugEnabled()) { + log.debug("entity comboBox list [" + beanType.getName() + "] : " + + (data == null ? 0 : data.size())); + } + + comboBox.setI18nPrefix(getContext().getI18nPrefix()); + + // add data list to combo box + comboBox.init((JXPathDecorator<E>) decorator, data); + + comboBox.setSelectedItem(selectedData); + + if (log.isDebugEnabled()) { + log.debug("combo [" + beanType.getName() + "] : " + + comboBox.getData().size()); + } + } + + /** + * Prépare un component de choix d'entités pour un type d'entité donné et + * pour un service de persistance donné. + * + * @param list le component graphique à initialiser + * @param data la liste des données à mettre dans la liste de gauche + * @param selectedData la liste des données à mettre dans la liste de droite + */ + protected <E> void initBeanList( + BeanDoubleList<E> list, + List<E> data, + List<E> selectedData, + Decorator<E> selectedDecorator) { + + Preconditions.checkNotNull(list, "No list!"); + + Class<E> beanType = list.getBeanType(); + Preconditions.checkNotNull(beanType, "No beanType on the double list!"); + + Decorator<E> decorator = getDecorator(beanType, null); + + if (log.isDebugEnabled()) { + log.debug("entity list [" + beanType.getName() + "] : " + + (data == null ? 0 : data.size())); + } + + list.setI18nPrefix(getContext().getI18nPrefix()); + + // add data list to combo box + list.init((JXPathDecorator<E>) decorator, + (JXPathDecorator<E>) selectedDecorator, + data, + selectedData); + + if (log.isDebugEnabled()) { + log.debug("Jlist [" + beanType.getName() + "] : " + + list.getUniverseList().getModel().getSize()); + } + } + + /** + * Prépare un component de choix d'entités pour un type d'entité donné et + * pour un service de persistance donné. + * + * @param list le component graphique à initialiser + * @param data la liste des données à mettre dans la liste de gauche + * @param selectedData la liste des données à mettre dans la liste de droite + */ + protected <E> void initBeanList( + BeanDoubleList<E> list, + List<E> data, + List<E> selectedData) { + + initBeanList(list, data, selectedData, null); + } + + protected void initNumberEditor(NumberEditor editor) { + if (log.isDebugEnabled()) { + log.debug("init number editor " + editor.getName()); + } + editor.init(); + + // Force binding if value is already in model + Number model = editor.getModel(); + if (model != null) { + editor.setModel(null); + editor.setModel(model); + } + + if (isAutoSelectOnFocus(editor)) { + + addAutoSelectOnFocus(editor.getTextField()); + } + } + + protected void initTimeEditor(SimpleTimeEditor editor) { + if (log.isDebugEnabled()) { + log.debug("init time editor " + editor.getName() + + " for property " + editor.getModel().getProperty()); + } + editor.init(); + + if (isAutoSelectOnFocus(editor)) { + addAutoSelectOnFocus(((JSpinner.DefaultEditor) editor.getHour().getEditor()).getTextField()); + addAutoSelectOnFocus(((JSpinner.DefaultEditor) editor.getMinute().getEditor()).getTextField()); + } + } + + protected void initCoordinateDMSEditor(DmsCoordinateEditor editor) { + Object property = editor.getClientProperty("longitudeEditor"); + boolean longitudeEditor = property != null && Boolean.valueOf(property.toString()); + editor.init(longitudeEditor); + } + + protected void initCoordinateDMDEditor(DmdCoordinateEditor editor) { + Object property = editor.getClientProperty("longitudeEditor"); + boolean longitudeEditor = property != null && Boolean.valueOf(property.toString()); + editor.init(longitudeEditor); + } + + protected void initDatePicker(final JXDatePicker picker) { + + if (log.isDebugEnabled()) { + log.debug("disable JXDatePicker editor" + picker.getName()); + } + String dateFormat = getContext().getDateFormat(); + picker.setFormats(dateFormat); + picker.setToolTipText(_("jaxx.application.common.datefield.tip", dateFormat)); + picker.getEditor().addFocusListener(new FocusAdapter() { + + @Override + public void focusLost(FocusEvent e) { + try { + picker.commitEdit(); + + } catch (ParseException ex) { + if (log.isDebugEnabled()) { + log.debug("format error", ex); + } + picker.requestFocus(); + } + } + }); + + if (isAutoSelectOnFocus(picker)) { + addAutoSelectOnFocus(picker.getEditor()); + } + } + + protected void initScrollPane(JScrollPane scrollPane) { + Boolean onlyVerticalScrollable = (Boolean) scrollPane.getClientProperty("onlyVerticalScrollable"); + if (onlyVerticalScrollable != null && onlyVerticalScrollable) { + scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); + + final JViewport viewport = scrollPane.getViewport(); + viewport.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + Dimension newDimension = new Dimension(viewport.getExtentSize().width, + viewport.getViewSize().height); + viewport.setViewSize(newDimension); + } + }); + } + } + + protected boolean isAutoSelectOnFocus(JComponent comp) { + Object selectOnFocus = comp.getClientProperty("selectOnFocus"); + return selectOnFocus != null && Boolean.valueOf(selectOnFocus.toString()); + } + + protected void addAutoSelectOnFocus(JTextField jTextField) { + jTextField.addFocusListener(new FocusAdapter() { + @Override + public void focusGained(final FocusEvent e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + JTextField source = (JTextField) e.getSource(); + source.selectAll(); + } + }); + + } + }); + } + + protected boolean quitScreen(boolean modelIsValid, + boolean modelIsModify, + String askGiveUpMessage, + String askSaveMessage, + Action saveAction) { + boolean result; + + if (!modelIsValid) { + + // model is not valid + // ask user to qui or not + result = askCancelEditBeforeLeaving(askGiveUpMessage); + + } else if (modelIsModify) { + + // something is modify ask user what to do + int answer = askSaveBeforeLeaving(askSaveMessage); + switch (answer) { + case JOptionPane.YES_OPTION: + + // ok save + saveAction.actionPerformed(null); + result = true; + break; + case JOptionPane.NO_OPTION: + + // do not save but can still quit the screen (so nothing to do) + result = true; + break; + default: + // do not save and stay here (so nothing to do) + result = false; + + } + } else { + + // model is valid and not modify, can safely quit screen + result = true; + } + return result; + } + + //------------------------------------------------------------------------// + //-- Decorator API --// + //------------------------------------------------------------------------// + + protected String decorate(Serializable object) { + return decorate(object, null); + } + + protected String decorate(Serializable object, String context) { + String result = ""; + if (object != null) { + result = getDecorator(object.getClass(), context).toString(object); + } + return result; + } + + //------------------------------------------------------------------------// + //-- List API --// + //------------------------------------------------------------------------// + + protected <O> ListCellRenderer newListCellRender(Class<O> type) { + + return newListCellRender(type, null); + } + + protected <O> ListCellRenderer newListCellRender(Class<O> type, String name) { + + Decorator<O> decorator = getDecorator(type, name); + return newListCellRender(decorator); + } + + protected <O> ListCellRenderer newListCellRender(Decorator<O> decorator) { + + Preconditions.checkNotNull(decorator); + + ListCellRenderer result = new DecoratorListCellRenderer(decorator); + return result; + } + + //FIXME Move this in JAXX + protected <B> void changeValidatorContext(String newContext, + SwingValidator<B> validator) { + B bean = validator.getBean(); + validator.setContext(newContext); + validator.setBean(bean); + } + + //------------------------------------------------------------------------// + //-- Table API --// + //------------------------------------------------------------------------// + + protected <R> TableColumnExt addColumnToModel(TableColumnModel model, + TableCellEditor editor, + TableCellRenderer renderer, + ColumnIdentifier<R> identifier) { + + TableColumnExt col = new TableColumnExt(model.getColumnCount()); + col.setCellEditor(editor); + col.setCellRenderer(renderer); + String label = _(identifier.getHeaderI18nKey()); + + col.setHeaderValue(label); + String tip = _(identifier.getHeaderTipI18nKey()); + + col.setToolTipText(tip); + + col.setIdentifier(identifier); + model.addColumn(col); + // by default no column is sortable, must specify it + col.setSortable(false); + return col; + } + + protected <R> TableColumnExt addColumnToModel(TableColumnModel model, + ColumnIdentifier<R> identifier) { + + return addColumnToModel(model, null, null, identifier); + } + + protected <R> TableColumnExt addFloatColumnToModel(TableColumnModel model, + ColumnIdentifier<R> identifier, + String numberPattern, + JTable table) { + + NumberCellEditor<Float> editor = + JAXXWidgetUtil.newNumberTableCellEditor(Float.class, false); + editor.getNumberEditor().setSelectAllTextOnError(true); + editor.getNumberEditor().getTextField().setBorder(new LineBorder(Color.GRAY, 2)); + editor.getNumberEditor().setNumberPattern(numberPattern); + + TableCellRenderer renderer = + newNumberCellRenderer(table.getDefaultRenderer(Number.class)); + + return addColumnToModel(model, editor, renderer, identifier); + } + + protected <R> TableColumnExt addIntegerColumnToModel(TableColumnModel model, + ColumnIdentifier<R> identifier, + String numberPattern, + JTable table) { + + NumberCellEditor<Integer> editor = + JAXXWidgetUtil.newNumberTableCellEditor(Integer.class, false); + editor.getNumberEditor().setSelectAllTextOnError(true); + editor.getNumberEditor().getTextField().setBorder(new LineBorder(Color.GRAY, 2)); + editor.getNumberEditor().setNumberPattern(numberPattern); + + TableCellRenderer renderer = newNumberCellRenderer(table.getDefaultRenderer(Number.class)); + return addColumnToModel(model, editor, renderer, identifier); + } + + + protected TableCellRenderer newNumberCellRenderer(final TableCellRenderer defaultRenderer) { + TableCellRenderer result = new TableCellRenderer() { + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + Component result = defaultRenderer.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + if (result instanceof JLabel) { + JLabel jLabel = (JLabel) result; + jLabel.setHorizontalTextPosition(SwingConstants.RIGHT); + + } + return result; + } + }; + return result; + } + + + protected <R> TableColumnExt addBooleanColumnToModel(TableColumnModel model, + ColumnIdentifier<R> identifier, + JTable table) { + + return addColumnToModel(model, + table.getDefaultEditor(Boolean.class), + table.getDefaultRenderer(Boolean.class), + identifier); + } + + protected <R, B> TableColumnExt addComboDataColumnToModel(TableColumnModel model, + ColumnIdentifier<R> identifier, + Decorator<B> decorator, + List<B> data) { + JComboBox comboBox = new JComboBox(); + comboBox.setRenderer(newListCellRender(decorator)); + + List<B> dataToList = Lists.newArrayList(data); + + // add a null value at first position + if (!dataToList.isEmpty() && dataToList.get(0) != null) { + dataToList.add(0, null); + } + SwingUtil.fillComboBox(comboBox, dataToList, null); + + ObjectToStringConverter converter = BeanUIUtil.newDecoratedObjectToStringConverter(decorator); + BeanUIUtil.decorate(comboBox, converter); + ComboBoxCellEditor editor = new ComboBoxCellEditor(comboBox); + + return addColumnToModel(model, + editor, + newTableCellRender(decorator), + identifier); + } + + protected <O> TableCellRenderer newTableCellRender(Class<O> type) { + + return newTableCellRender(type, null); + } + + protected <O> TableCellRenderer newTableCellRender(Class<O> type, String name) { + + Decorator<O> decorator = getDecorator(type, name); + + TableCellRenderer result = newTableCellRender(decorator); + return result; + } + + protected <O> TableCellRenderer newTableCellRender(Decorator<O> decorator) { + + Preconditions.checkNotNull(decorator); + + DecoratorTableCellRenderer result = new DecoratorTableCellRenderer(decorator, true); + return result; + } + + protected void incrementsMessage(String message) { + + ApplicationActionUI actionUI = getContext().getActionUI(); + if (actionUI != null) { + ApplicationProgressionModel progressionModel = actionUI.getModel().getProgressionModel(); + if (progressionModel != null) + + progressionModel.increments(message); + } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/AbstractApplicationUIHandler.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUI.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUI.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUI.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,138 @@ +package org.nuiton.jaxx.application.swing; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import jaxx.runtime.JAXXObject; + +/** + * Contract to place on each ui. + * <p/> + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public interface ApplicationUI<M, H extends AbstractApplicationUIHandler<M, ?>> extends JAXXObject { + + M getModel(); + + H getHandler(); + + /** + * Pattern to use for short numeric values in editors with max 1 digits. + * + * @since 0.2 + */ + public static final String INT_1_DIGITS_PATTERN = "\\d{0,1}"; + + /** + * Pattern to use for short numeric values in editors with max 2 digits. + * + * @since 0.1 + */ + public static final String INT_2_DIGITS_PATTERN = "\\d{0,2}"; + + /** + * Pattern to use for signed numeric values in editors with max 2 digits. + * + * @since 2.8 + */ + public static final String SIGNED_INT_2_DIGITS_PATTERN = "-?\\d{0,2}"; + + /** + * Pattern to use for short numeric values in editors with max 3 digits. + * + * @since 0.1 + */ + public static final String INT_3_DIGITS_PATTERN = "\\d{0,3}"; + + /** + * Pattern to use for singed numeric values in editors with max 3 digits. + * + * @since 2.8 + */ + public static final String SIGNED_INT_3_DIGITS_PATTERN = "-?\\d{0,3}"; + + /** + * Pattern to use for short numeric values in editors with max 4 digits. + * + * @since 0.2 + */ + public static final String INT_4_DIGITS_PATTERN = "\\d{0,4}"; + + /** + * Pattern to use for integer numeric values in editors with max 6 digits. + * + * @since 0.1 + */ + public static final String INT_6_DIGITS_PATTERN = "\\d{0,6}"; + + /** + * Pattern to use for integer numeric values in editors with max 7 digits. + * + * @since 0.1 + */ + public static final String INT_7_DIGITS_PATTERN = "\\d{0,7}"; + + /** + * Pattern to use for decimal numeric values with 1 decimal digits in + * editors. + * + * @since 0.1 + */ + public static final String DECIMAL1_PATTERN = "\\d{0,6}(\\.\\d{0,1})?"; + + /** + * Pattern to use for decimal numeric values with 2 decimal digits in + * editors. + * + * @since 0.1 + */ + public static final String DECIMAL2_PATTERN = "\\d{0,6}(\\.\\d{0,2})?"; + + /** + * Pattern to use for decimal numeric values with 3 decimal digits in + * editors. + * + * @since 0.1 + */ + public static final String DECIMAL3_PATTERN = "\\d{0,6}(\\.\\d{0,3})?"; + + /** + * Pattern to use for decimal numeric values with 4 decimal digits in + * editors. + * + * @since 2.6 + */ + public static final String DECIMAL4_PATTERN = "\\d{0,6}(\\.\\d{0,4})?"; + + /** + * Pattern to use for decimal numeric values with 2 digits + 3 decimal digits in + * editors. + * + * @since 2.8 + */ + public static final String DECIMAL2_DIGITS_PATTERN = "\\d{0,2}(\\.\\d*)?"; +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUI.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUIContext.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUIContext.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUIContext.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,84 @@ +package org.nuiton.jaxx.application.swing; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.ApplicationContext; +import org.nuiton.jaxx.application.swing.action.ApplicationActionEngine; +import org.nuiton.jaxx.application.swing.action.ApplicationActionFactory; +import org.nuiton.jaxx.application.swing.action.ApplicationActionUI; +import org.nuiton.jaxx.application.swing.util.ApplicationErrorHelper; + +import java.awt.Color; +import java.awt.Component; + +/** + * Created on 11/24/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public interface ApplicationUIContext extends ApplicationContext { + + /** + * @return the main ui of the application. + */ + Component getMainUI(); + + /** + * @return the ui used to display long action. + */ + ApplicationActionUI getActionUI(); + + /** + * Wait until the action ui is not null and then returns it. + * + * @return the ui used to display long action. + */ + ApplicationActionUI getExistingActionUI(); + + Component getBodyUI(); + + Component getStatusUI(); + + boolean isBusy(); + + void setBusy(boolean busy); + + boolean isHideBody(); + + void setHideBody(boolean b); + + Color getColorBlockingLayer(); + + ApplicationActionFactory getActionFactory(); + + ApplicationActionEngine getActionEngine(); + + ApplicationErrorHelper getErrorHelper(); + + String getI18nPrefix(); + + String getDateFormat(); +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/ApplicationUIContext.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/AbstractApplicationAction.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/AbstractApplicationAction.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/AbstractApplicationAction.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,326 @@ +package org.nuiton.jaxx.application.swing.action; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import jaxx.runtime.FileChooserUtil; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.beans.AbstractBean; +import org.nuiton.decorator.Decorator; +import org.nuiton.jaxx.application.ApplicationConfiguration; +import org.nuiton.jaxx.application.swing.AbstractApplicationUIHandler; +import org.nuiton.jaxx.application.swing.ApplicationUI; +import org.nuiton.jaxx.application.swing.ApplicationUIContext; +import org.nuiton.jaxx.application.type.ApplicationProgressionModel; + +import javax.swing.JOptionPane; +import java.io.File; + +import static org.nuiton.i18n.I18n._; + +/** + * Tutti base action. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public abstract class AbstractApplicationAction<M extends AbstractBean, UI extends ApplicationUI<M, ?>, H extends AbstractApplicationUIHandler<M, UI>> + extends AbstractBean { + + /** Logger. */ + private static final Log log = LogFactory.getLog(AbstractApplicationAction.class); + + public static final String PROPERTY_DONE = "done"; + + protected final H handler; + + protected String actionDescription; + + protected final boolean hideBody; + + protected final Object lock = new Object(); + + public abstract void doAction() throws Exception; + + protected AbstractApplicationAction(H handler, boolean hideBody) { + this.handler = handler; + this.hideBody = hideBody; + } + + public boolean prepareAction() throws Exception { + // by default nothing to prepare + return true; + } + + protected void releaseAction() { + // by default nothing to clean + firePropertyChange(PROPERTY_DONE, null, true); + } + + public void postSuccessAction() { + // by default nothing to do after action + } + + public void postFailedAction(Throwable error) { + // by default nothing to do after action + } + + public H getHandler() { + return handler; + } + + public M getModel() { + return handler.getModel(); + } + + public final UI getUI() { + return handler.getUI(); + } + + public ApplicationUIContext getContext() { + return handler.getContext(); + } + + public String getActionDescription() { + return actionDescription; + } + + public void setActionDescription(String actionDescription) { + this.actionDescription = actionDescription; + } + + public void setProgressionModel(ApplicationProgressionModel progressionModel) { + getContext().getActionUI().getModel().setProgressionModel(progressionModel); + } + + protected ApplicationProgressionModel getProgressionModel() { + return getContext().getActionUI().getModel().getProgressionModel(); + } + + public boolean isHideBody() { + return hideBody; + } + + protected ApplicationConfiguration getConfig() { + return getContext().getConfiguration(); + } + + protected abstract void sendMessage(String message); + + protected <O> Decorator<O> getDecorator(Class<O> type, String name) { + Decorator<O> decorator = handler.getDecorator(type, name); + Preconditions.checkNotNull(decorator); + return decorator; + } + + protected String decorate(Object object) { + return getDecorator(object.getClass(), null).toString(object); + } + + protected String decorate(Object object, String context) { + return getDecorator(object.getClass(), context).toString(object); + } + + /** + * Choisir un fichier via un sélecteur graphique de fichiers. + * + * @param title le titre du dialogue de sélection + * @param buttonLabel le label du boutton d'acceptation + * @param filters les filtres + descriptions sur le sélecteur de + * fichiers + * @return le fichier choisi ou le fichier incoming si l'opération a été + * annulée + */ + protected File chooseFile(String title, + String buttonLabel, + String... filters) { + + File file = FileChooserUtil.getFile(title, + buttonLabel, + getContext().getMainUI(), + filters); + if (log.isDebugEnabled()) { + log.debug(title + " : " + file); + } + if (file != null) { + File newDir = file.isDirectory() ? file : file.getParentFile(); + FileChooserUtil.setCurrentDirectory(newDir); + } + return file; + } + + /** + * Sauver un fichier via un sélecteur graphique de fichiers. + * + * @param title le titre du dialogue de sélection + * @param buttonLabel le label du boutton d'acceptation + * @param filters les filtres + descriptions sur le sélecteur de + * fichiers + * @return le fichier choisi ou {@code null} si pas de fichier choisi ou + * pas voulu écrasé un fichier existant. + */ + protected File saveFile(File defaultFile, + String filename, + String extension, + String title, + String buttonLabel, + String... filters) { + + if (defaultFile != null && FileChooserUtil.isCurrentDirectoryDefault()) { + + // set default directory to this one + FileChooserUtil.setCurrentDirectory(defaultFile); + } + File file = saveFile(filename, extension, title, buttonLabel, filters); + return file; + } + + /** + * Sauver un fichier via un sélecteur graphique de fichiers. + * + * @param title le titre du dialogue de sélection + * @param buttonLabel le label du boutton d'acceptation + * @param filters les filtres + descriptions sur le sélecteur de + * fichiers + * @return le fichier choisi ou {@code null} si pas de fichier choisi ou + * pas voulu écrasé un fichier existant. + */ + protected File saveFile(String filename, + String extension, + String title, + String buttonLabel, + String... filters) { + + boolean withExtension = StringUtils.isNotBlank(extension); + String filenameSuffix = withExtension ? "." + extension : ""; + File file = FileChooserUtil.saveFile(filename + filenameSuffix, title, buttonLabel, getContext().getMainUI(), filters); + if (log.isDebugEnabled()) { + log.debug(title + " : " + file); + } + if (file != null) { + Preconditions.checkState(!file.isDirectory()); + + // add extension if missing + if (withExtension && !file.getName().endsWith(filenameSuffix)) { + file = new File(file.getParentFile(), file.getName() + filenameSuffix); + } + + // ask user to confirm overwrite. + boolean confirm = askOverwriteFile(file); + + if (confirm) { + + // on conserve le répertoire (pour une prochaine utilisation) + FileChooserUtil.setCurrentDirectory(file.getParentFile()); + } else { + + // l'utilisateur n'a pas confirmé l'écrasement + // donc pas de fichier en retour + file = null; + } + } + + return file; + } + + protected boolean askOverwriteFile(File file) { + boolean result; + if (file.exists()) { + + // file exists ask user to overwrite + String htmlMessage = String.format( + AbstractApplicationUIHandler.CONFIRMATION_FORMAT, + _("jaxx.application.common.askOverwriteFile.message", file), + _("jaxx.application.common.askOverwriteFile.help")); + + result = JOptionPane.showConfirmDialog( + getHandler().getTopestUI(), + htmlMessage, + _("jaxx.application.common.askOverwriteFile.title"), + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE) == JOptionPane.OK_OPTION; + } else { + + // file does not exist + result = true; + } + return result; + } + + protected boolean askBeforeDelete(String title, String message) { + String htmlMessage = String.format( + AbstractApplicationUIHandler.CONFIRMATION_FORMAT, + message, + _("jaxx.application.common.askBeforeDelete.help")); + int i = JOptionPane.showConfirmDialog( + getHandler().getTopestUI(), + htmlMessage, + title, + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.QUESTION_MESSAGE); + + boolean result = i == JOptionPane.OK_OPTION; + return result; + } + + protected void displayInfoMessage(String title, String message) { + JOptionPane.showMessageDialog( + getHandler().getTopestUI(), + message, + title, + JOptionPane.INFORMATION_MESSAGE); + } + + protected void displayWarningMessage(String title, String message) { + JOptionPane.showMessageDialog( + getHandler().getTopestUI(), + message, + title, + JOptionPane.WARNING_MESSAGE); + } + + protected void createProgressionModelIfRequired(int total) { + ApplicationProgressionModel progressionModel = getProgressionModel(); + if (progressionModel == null) { + progressionModel = new ApplicationProgressionModel(); + progressionModel.setTotal(total); + progressionModel.setMessage(""); + progressionModel.setCurrent(0); + setProgressionModel(progressionModel); + } else { + progressionModel.adaptTotal(total); + } + } + + public ApplicationActionFactory getActionFactory() { + return getContext().getActionFactory(); + } + + public ApplicationActionEngine getActionEngine() { + return getContext().getActionEngine(); + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/AbstractApplicationAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionEngine.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionEngine.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionEngine.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,101 @@ +package org.nuiton.jaxx.application.swing.action; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.swing.AbstractApplicationUIHandler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.AbstractButton; + +/** + * To create and consume {@link AbstractApplicationAction}. + * Created on 11/24/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationActionEngine { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ApplicationActionEngine.class); + + private final ApplicationActionFactory actionFactory; + + public ApplicationActionEngine(ApplicationActionFactory actionFactory) { + this.actionFactory = actionFactory; + } + + public <A extends AbstractApplicationAction> void runInternalAction(A action) { + Throwable error = null; + + try { + action.doAction(); + action.postSuccessAction(); + } catch (Throwable e) { + error = e; + if (log.isErrorEnabled()) { + log.error("Error in action:", e); + } + throw ApplicationActionException.propagateError(action, e); + } finally { + try { + if (error != null) { + action.postFailedAction(error); + } + } finally { + + action.releaseAction(); + } + } + } + + public <A extends AbstractApplicationAction> void runInternalAction(AbstractApplicationUIHandler handler, + Class<A> actionName) { + A action = actionFactory.createLogicAction(handler, actionName); + runInternalAction(action); + } + + public <A extends AbstractApplicationAction> void runAction(A action) { + ApplicationUIAction<A> uiAction = actionFactory.createUIAction(null, action); + uiAction.actionPerformed(null); + } + + public void runAction(AbstractButton button) { + button.getAction().actionPerformed(null); + } + + public <A extends AbstractApplicationAction> void runActionAndWait(A action) { + ApplicationUIAction<A> uiAction = actionFactory.createUIAction(null, action); + uiAction.launchActionAndWait(); + } + + public <A extends AbstractApplicationAction> void runActionAndWait(AbstractApplicationUIHandler handler, + Class<A> actionName) { + A logicAction = actionFactory.createLogicAction(handler, actionName); + runActionAndWait(logicAction); + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionEngine.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionException.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionException.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionException.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,58 @@ +package org.nuiton.jaxx.application.swing.action; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * To box any error of a {@link AbstractApplicationAction}. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationActionException extends RuntimeException { + + private static final long serialVersionUID = 1L; + + private final AbstractApplicationAction action; + + public ApplicationActionException(AbstractApplicationAction action, Throwable cause) { + super(cause); + this.action = action; + } + + public static ApplicationActionException propagateError(AbstractApplicationAction action, + Throwable cause) { + ApplicationActionException result; + if (cause instanceof ApplicationActionException) { + result = ((ApplicationActionException) cause); + } else { + result = new ApplicationActionException(action, cause); + } + return result; + } + + public AbstractApplicationAction getAction() { + return action; + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionException.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionFactory.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionFactory.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionFactory.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,99 @@ +package org.nuiton.jaxx.application.swing.action; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import org.nuiton.jaxx.application.ApplicationTechnicalException; +import org.nuiton.jaxx.application.swing.AbstractApplicationUIHandler; +import org.apache.commons.lang3.reflect.ConstructorUtils; + +import javax.swing.AbstractButton; +import javax.swing.Action; + +import static org.nuiton.i18n.I18n._; + +/** + * Factory of actions. + * <p/> + * Created on 11/24/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationActionFactory { + + public <A extends AbstractApplicationAction> ApplicationUIAction<A> createUIAction(AbstractApplicationUIHandler handler, + Class<A> actionName) { + return createUIAction(handler, null, actionName); + } + + + public <A extends AbstractApplicationAction> ApplicationUIAction<A> createUIAction(AbstractApplicationUIHandler handler, + AbstractButton abstractButton, + Class<A> actionName) { + try { + + // create logic action + A logicAction = createLogicAction(handler, actionName); + + // create ui action + ApplicationUIAction<A> result = createUIAction(abstractButton, logicAction); + return result; + } catch (Exception e) { + throw new ApplicationTechnicalException(_("jaxx.application.action.create.error", actionName), e); + } + + } + + public <A extends AbstractApplicationAction> ApplicationUIAction<A> createUIAction(AbstractButton abstractButton, + A logicAction) { + + // create ui action + ApplicationUIAction<A> result = new ApplicationUIAction<A>(abstractButton, + logicAction); + return result; + + + } + + public <A extends AbstractApplicationAction> A createLogicAction(AbstractApplicationUIHandler handler, + Class<A> actionName) { + try { + + // create action + A result = ConstructorUtils.invokeConstructor(actionName, handler); + return result; + } catch (Exception e) { + throw new ApplicationTechnicalException(_("jaxx.application.action.create.error", actionName), e); + } + } + + public <A extends AbstractApplicationAction> A getLogicAction(AbstractButton b) { + Action action = b.getAction(); + Preconditions.checkNotNull(action); + Preconditions.checkState(action instanceof ApplicationUIAction); + return ((ApplicationUIAction<A>) action).getLogicAction(); + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionFactory.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionSwingWorker.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionSwingWorker.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionSwingWorker.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,186 @@ +package org.nuiton.jaxx.application.swing.action; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.Timer; +import java.util.TimerTask; + +/** + * Worker to execute logic action. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationActionSwingWorker<A extends AbstractApplicationAction> extends SwingWorker<Void, String> { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ApplicationActionSwingWorker.class); + + /** + * Timer used to launch timerTask (to open load dialog). + * + * @since 2.8.2 + */ + private static final Timer t = new Timer(); + + protected final ApplicationActionUI actionUI; + + protected final A action; + + protected Throwable error; + + protected TimerTask timer; + + protected ApplicationActionSwingWorker(A action) { + + this.action = action; + this.actionUI = action.getContext().getActionUI(); + } + + public Throwable getError() { + return error; + } + + public boolean isFailed() { + return error != null; + } + + @Override + protected Void doInBackground() throws Exception { + + if (!isCancelled()) { + + timer = new TuttiActionTimerTask(); + + t.schedule(timer, 1000); + + try { + + action.doAction(); + + } catch (Throwable e) { + if (log.isErrorEnabled()) { + log.error("Task [" + this + "] Error while doAction: ", e); + } + error = e; + } finally { + if (log.isDebugEnabled()) { + log.debug("Task [" + this + "] done"); + } + } + } + return null; + } + + @Override + protected void done() { + super.done(); + + if (log.isDebugEnabled()) { + log.debug("Task [" + this + "] execute done method after all"); + } + + if (error == null) { + + // success hook + action.postSuccessAction(); + } else { + + // fail hook + action.postFailedAction(error); + } + + action.releaseAction(); + + if (timer != null) { + + timer.cancel(); + } + + actionUI.close(); + + updateBusyState(false); + } + + protected void updateBusyState(boolean busy) { + + boolean hideBody = action.isHideBody(); + + action.getContext().setBusy(busy); + + if (hideBody) { + action.getContext().setHideBody(!busy); + } + + } + + protected class TuttiActionTimerTask extends TimerTask { + + public TuttiActionTimerTask() { + action.addPropertyChangeListener(AbstractApplicationAction.PROPERTY_DONE, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + if (actionUI.isVisible()) { + actionUI.close(); + } + + // we do NOT want the timer to wake up then the actionUI dialog + cancel(); + } + }); + } + + @Override + public void run() { + if (isCancelled() || isDone()) { + + if (log.isDebugEnabled()) { + log.debug("Task [" + action + "] was already canceled or done, do nothing"); + } + } else { + + if (log.isDebugEnabled()) { + log.debug("Task [" + action + "] is started, show waiting dialog"); + } + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + actionUI.open(action); + } + }); + } + } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionSwingWorker.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.css =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.css (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.css 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,68 @@ +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +#busyBlockLayerUI { + useIcon:false; + blockingColor: {handler.getContext().getColorBlockingLayer()}; + block:{true}; +} + +#globalPanel { + border: {new TitledBorder((String) null)}; +} + +#globalActionLabel { + border: {new EmptyBorder(5, 5, 5, 5)}; +} + +#globalProgressBar { + indeterminate: true; +} + +#taskPanel { + visible: false; + border: {new TitledBorder((String) null)}; +} + +#taskProgressBar { + indeterminate: false; +} + +#taskActionLabel { + border: {new EmptyBorder(5, 5, 5, 5)}; +} + +#informationPanel { + visible: false; + border: {new TitledBorder((String) null)}; +} + +#informationLabel { + border: {new EmptyBorder(5, 5, 5, 5)}; +} + +#okAction { + actionIcon: information; + text: "tutti.action.ok"; +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.css ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.jaxx =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.jaxx (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUI.jaxx 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,74 @@ +<!-- + #%L + JAXX :: Application Swing + $Id:$ + $HeadURL:$ + %% + Copyright (C) 2014 Code Lutin, Tony CHEMIT + %% + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + + You should have received a copy of the GNU General Lesser Public + License along with this program. If not, see + <http://www.gnu.org/licenses/lgpl-3.0.html>. + #L% + --> +<JDialog width='300' height='200' modal='true' + undecorated='true' + implements='org.nuiton.jaxx.application.swing.ApplicationUI<ApplicationActionUIModel, ApplicationActionUIHandler>'> + <import> + + org.nuiton.jaxx.application.swing.ApplicationUI + org.nuiton.jaxx.application.swing.ApplicationUIContext + org.nuiton.jaxx.application.swing.util.ApplicationUIUtil + + jaxx.runtime.swing.BlockingLayerUI + + javax.swing.border.EmptyBorder + </import> + + <script><![CDATA[ + + public ApplicationActionUI(JFrame frame, ApplicationUIContext context) { + super(frame, true); + ApplicationUIUtil.setApplicationContext(this, context); + } + + public void open(AbstractApplicationAction action) { + getModel().setAction(action); + } + + public void close() { + getModel().clear(); + } + ]]></script> + + + <BlockingLayerUI id='busyBlockLayerUI'/> + + <ApplicationActionUIModel id='model' + initializer='getContextValue(ApplicationActionUIModel.class)'/> + + <JPanel id='rootPanel' layout='{new BorderLayout()}' + constraints='BorderLayout.CENTER' decorator='boxed'> + <JPanel id='globalPanel' constraints='BorderLayout.NORTH' + layout='{new BorderLayout()}'> + <JLabel id='globalActionLabel' constraints='BorderLayout.CENTER'/> + <JProgressBar id='globalProgressBar' constraints='BorderLayout.SOUTH'/> + </JPanel> + <JPanel id='taskPanel' constraints='BorderLayout.CENTER' + layout='{new BorderLayout()}'> + <JLabel id='taskActionLabel' constraints='BorderLayout.CENTER'/> + <JProgressBar id='taskProgressBar' constraints='BorderLayout.SOUTH'/> + </JPanel> + </JPanel> + +</JDialog> Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIHandler.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIHandler.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,281 @@ +package org.nuiton.jaxx.application.swing.action; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.swing.AbstractApplicationUIHandler; +import org.nuiton.jaxx.application.type.ApplicationProgressionModel; +import jaxx.runtime.SwingUtil; +import jaxx.runtime.validator.swing.SwingValidator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.decorator.Decorator; + +import javax.swing.JComponent; +import java.awt.Component; +import java.awt.Cursor; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.event.ComponentListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import static org.nuiton.i18n.I18n._; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationActionUIHandler extends AbstractApplicationUIHandler<ApplicationActionUIModel, ApplicationActionUI> { + + /** Logger. */ + private static final Log log = + LogFactory.getLog(ApplicationActionUIHandler.class); + + protected PropertyChangeListener progressionListener = new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + String propertyName = evt.getPropertyName(); + if (ApplicationProgressionModel.PROPERTY_MESSAGE.equals(propertyName)) { + + // change message + String newMessage = (String) evt.getNewValue(); + ui.getTaskActionLabel().setText("<html><body>" + newMessage + "</body></html>"); + ui.pack(); + } else if (ApplicationProgressionModel.PROPERTY_TOTAL.equals(propertyName)) { + + // change total progressbar max + ui.getTaskProgressBar().setMaximum((Integer) evt.getNewValue()); + + } else if (ApplicationProgressionModel.PROPERTY_CURRENT.equals(propertyName)) { + + // change value of progress bar + ui.getTaskProgressBar().setValue((Integer) evt.getNewValue()); + } + } + }; + + protected ComponentListener listener = new ComponentAdapter() { + boolean moving; + + boolean resizing; + + @Override + public void componentMoved(ComponentEvent e) { + + Component mainUI = (Component) e.getSource(); + + if (!moving && mainUI.isShowing()) { + + moving = true; + try { + setLocation(mainUI); + } finally { + moving = false; + } + } + } + + @Override + public void componentResized(ComponentEvent e) { + + Component mainUI = (Component) e.getSource(); + + if (!resizing && mainUI.isShowing()) { + + resizing = true; + try { + setSize(mainUI); + } finally { + resizing = false; + } + } + } + }; + + //------------------------------------------------------------------------// + //-- AbstractTuttiUIHandler methods --// + //------------------------------------------------------------------------// + + @Override + public void beforeInit(ApplicationActionUI ui) { + this.ui = ui; + ApplicationActionUIModel model = new ApplicationActionUIModel(); + ui.setContextValue(model); + + model.addPropertyChangeListener(ApplicationActionUIModel.PROPERTY_ACTION, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + // udpate global label + AbstractApplicationAction action = (AbstractApplicationAction) evt.getNewValue(); + + if (log.isDebugEnabled()) { + log.debug("Action to use: " + action); + } + if (action == null) { + + // stoping action + hideAction(); + } else { + + // starting action + showAction(action); + } + } + }); + + model.addPropertyChangeListener(ApplicationActionUIModel.PROPERTY_PROGRESSION_MODEL, new PropertyChangeListener() { + @Override + public void propertyChange(PropertyChangeEvent evt) { + + // change progression model + + ApplicationProgressionModel oldValue = (ApplicationProgressionModel) evt.getOldValue(); + ApplicationProgressionModel newValue = (ApplicationProgressionModel) evt.getNewValue(); + + if (log.isDebugEnabled()) { + log.debug("progression model: " + newValue); + } + if (oldValue != null) { + oldValue.removePropertyChangeListener(progressionListener); + } + + if (newValue == null) { + + // remove progression model + ApplicationActionUIHandler.this.ui.getTaskPanel().setVisible(false); + } else { + + // use progression model + ApplicationActionUIHandler.this.ui.getTaskPanel().setVisible(true); + + newValue.addPropertyChangeListener(progressionListener); + } + } + }); + } + + @Override + public void afterInit(ApplicationActionUI ui) { + + initUI(this.ui); + + // installation layer de blocage en mode busy + SwingUtil.setLayerUI(this.ui.getRootPanel(), this.ui.getBusyBlockLayerUI()); + + this.ui.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR)); + } + + @Override + protected JComponent getComponentToFocus() { + return null; + } + + @Override + public void onCloseUI() { + + } + + @Override + public SwingValidator<ApplicationActionUIModel> getValidator() { + return null; + } + + @Override + public Component getTopestUI() { + return null; + } + + @Override + public <E> Decorator<E> getDecorator(Class<E> beanType, String decoratorContext) { + return null; + } + + //------------------------------------------------------------------------// + //-- Internal methods --// + //------------------------------------------------------------------------// + + protected void hideAction() { + ui.setVisible(false); + } + + protected void showAction(AbstractApplicationAction action) { + ui.setTitle(_("jaxx.application.title.actionUI", + getContext().getConfiguration().getApplicationName(), + getContext().getConfiguration().getVersion(), + action.getActionDescription())); + ui.getGlobalActionLabel().setText( + _("jaxx.application.message.action.running", + action.getActionDescription())); + ui.pack(); + + Component mainUI = getContext().getMainUI(); + if (mainUI != null) { + mainUI.addComponentListener(listener); + + setLocation(mainUI); + setSize(mainUI); + } + try { + ui.setVisible(true); + } finally { + if (mainUI != null) { + mainUI.removeComponentListener(listener); + } + } + } + + protected void setLocation(Component mainUI) { + Component component = getContext().getBodyUI(); + Component status = getContext().getStatusUI(); + int width = component == null ? 0 : component.getWidth(); + int height = component == null ? 0 : component.getHeight() + status.getHeight(); + + int x; + int y; + if (height == 0) { + x = mainUI.getX() + 5; + y = mainUI.getY() + 15; + } else { + x = mainUI.getX() + (mainUI.getWidth() - width); + y = mainUI.getY() + (mainUI.getHeight() - height); + } + ui.setLocation(x, y); + } + + protected void setSize(Component mainUI) { + // Better to let his own size to the action progress bar + // see http://forge.codelutin.com/issues/3263 +// Container component = mainUI.getBody(); +// int width = component == null ? 0 : component.getWidth(); + + ui.pack(); + +// if (width != 0 && ui.getWidth() < width) { +// ui.setSize(width, ui.getHeight()); +// } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIHandler.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIModel.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIModel.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIModel.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,75 @@ +package org.nuiton.jaxx.application.swing.action; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import org.nuiton.jaxx.application.type.ApplicationProgressionModel; +import org.jdesktop.beans.AbstractSerializableBean; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationActionUIModel extends AbstractSerializableBean { + + private static final long serialVersionUID = 1L; + + public static final String PROPERTY_ACTION = "action"; + + public static final String PROPERTY_PROGRESSION_MODEL = "progressionModel"; + + protected AbstractApplicationAction action; + + protected ApplicationProgressionModel progressionModel; + + public ApplicationProgressionModel getProgressionModel() { + return progressionModel; + } + + public void setProgressionModel(ApplicationProgressionModel progressionModel) { + Object oldValue = getProgressionModel(); + this.progressionModel = progressionModel; + firePropertyChange(PROPERTY_PROGRESSION_MODEL, oldValue, progressionModel); + } + + public AbstractApplicationAction getAction() { + return action; + } + + public void setAction(AbstractApplicationAction action) { + Preconditions.checkNotNull(action, "action can not be null"); + Object oldValue = getAction(); + this.action = action; + firePropertyChange(PROPERTY_ACTION, oldValue, action); + } + + public void clear() { + setProgressionModel(null); + + Object oldValue = getAction(); + action = null; + firePropertyChange(PROPERTY_ACTION, oldValue, null); + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationActionUIModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationUIAction.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationUIAction.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationUIAction.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,228 @@ +package org.nuiton.jaxx.application.swing.action; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.TimeLog; + +import javax.swing.AbstractAction; +import javax.swing.AbstractButton; +import javax.swing.Icon; +import javax.swing.SwingUtilities; +import java.awt.event.ActionEvent; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +/** + * Abstract tutti ui action which launch a {@link AbstractApplicationAction}. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8.2 + */ +public class ApplicationUIAction<A extends AbstractApplicationAction> extends AbstractAction { + + private static final long serialVersionUID = 1L; + + /** Logger. */ + private static final Log log = LogFactory.getLog(ApplicationUIAction.class); + + private static final TimeLog TIME_LOG = new TimeLog(ApplicationUIAction.class); + + public static final ExecutorService waitingThread = + Executors.newSingleThreadExecutor(); + + private static final String LOGIC_ACTION = "logicAction"; + + private final Object lock = new Object(); + + private boolean wait; + + private long t0; + + public ApplicationUIAction(AbstractButton button, A action) { + + putValue(LOGIC_ACTION, action); + + // fill the ui action from the button + setActionKey(action.getClass().getName()); + if (button != null) { + setActionIcon(button.getIcon()); + setActionName(button.getText()); + setActionDescription(button.getToolTipText()); + setActionMnemonic(button.getMnemonic()); + } + } + + public void launchActionAndWait() { + wait = true; + actionPerformed(null); + lock(); + } + + + @Override + public final void actionPerformed(final ActionEvent event) { + + t0 = TimeLog.getTime(); + + if (log.isInfoEnabled()) { + log.info("Task [" + getLogicAction().getClass().getSimpleName() + "] starting"); + } + + // prepare action + boolean doAction; + + A action = getLogicAction(); + + // reset status message + action.sendMessage(""); + + try { + doAction = action.prepareAction(); + } catch (Exception e) { + action.releaseAction(); + throw ApplicationActionException.propagateError(action, e); + } + + if (doAction) { + + final ApplicationActionSwingWorker<A> worker = + new ApplicationActionSwingWorker<A>(action); + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + + // make ui busy + worker.updateBusyState(true); + + } + }); + + if (log.isDebugEnabled()) { + log.debug("Before execute of action " + action); + } + + // perform and release action + worker.execute(); + + // wait until action is done + waitingThread.execute( + new Runnable() { + @Override + public void run() { + + A action = getLogicAction(); + try { + try { + worker.get(); + } catch (ExecutionException e) { + // don't care . + } catch (CancellationException e) { + // dont care ? + } catch (InterruptedException e) { + // don't care ? + } + if (log.isDebugEnabled()) { + log.debug("After execute of action " + action + " (worker done? " + worker.isDone() + ")"); + } + + if (worker.isFailed()) { + + throw ApplicationActionException.propagateError(action, worker.getError()); + } + } finally { + unlock(); + } + } + } + ); + + } else { + + try { + // release action + action.releaseAction(); + + } finally { + unlock(); + } + } + } + + public void setActionIcon(Icon actionIcon) { + putValue(SMALL_ICON, actionIcon); + putValue(LARGE_ICON_KEY, actionIcon); + } + + public void setActionKey(String actionKey) { + putValue(ACTION_COMMAND_KEY, actionKey); + } + + public void setActionName(String actionName) { + putValue(NAME, actionName); + } + + public void setActionDescription(String actionDescription) { + putValue(SHORT_DESCRIPTION, actionDescription); + getLogicAction().setActionDescription(actionDescription); + } + + public void setActionMnemonic(int key) { + putValue(MNEMONIC_KEY, key); + } + + public A getLogicAction() { + return (A) getValue(LOGIC_ACTION); + } + + protected void lock() { + if (wait) { + synchronized (lock) { + try { + + lock.wait(); + + } catch (InterruptedException e) { + throw ApplicationActionException.propagateError(getLogicAction(), e); + } finally { + wait = false; + } + } + } + } + + protected void unlock() { + TIME_LOG.log(t0, "Task [" + getLogicAction().getClass().getSimpleName() + "] End"); + if (wait) { + synchronized (lock) { + lock.notifyAll(); + } + } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/action/ApplicationUIAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationAction.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationAction.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationAction.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,60 @@ +package org.nuiton.jaxx.application.swing.actionng; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * Contract of an application action. + * <p/> + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public interface ApplicationAction { + + /** + * Hook to + * + * @return {@code true} if action can be execute, {@code false} otherwise. + */ + boolean prepare(); + + /** + * Real action code. + */ + void action(); + + /** + * Executed when action ended with success. + */ + void done(); + + /** + * Executed when action failed. + * + * @param error failure exception + */ + void fail(Exception error); +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEngine.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEngine.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEngine.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,103 @@ +package org.nuiton.jaxx.application.swing.actionng; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import javax.swing.event.EventListenerList; + +/** + * Engine what consumes incoming actions. + * <p/> + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationActionEngine { + + private final EventListenerList eventList; + + public ApplicationActionEngine() { + eventList = new EventListenerList(); + } + + public void addAction(ApplicationAction action) { + + } + + //------------------------------------------------------------------------// + //--- ApplicationActionListener API ---// + //------------------------------------------------------------------------// + + public void addApplicationEventListener(ApplicationActionListener listener) { + eventList.add(ApplicationActionListener.class, listener); + } + + public void removeApplicationEventListener(ApplicationActionListener listener) { + eventList.remove(ApplicationActionListener.class, listener); + } + + protected void fireInit(ApplicationAction action) { + ApplicationActionEvent event = new ApplicationActionEvent(action, ApplicationActionEvent.EventType.INIT); + + ApplicationActionListener[] listeners = eventList.getListeners(ApplicationActionListener.class); + for (ApplicationActionListener listener : listeners) { + listener.actionStarted(event); + } + } + + protected void fireStart(ApplicationAction action) { + ApplicationActionEvent event = new ApplicationActionEvent(action, ApplicationActionEvent.EventType.START); + + ApplicationActionListener[] listeners = eventList.getListeners(ApplicationActionListener.class); + for (ApplicationActionListener listener : listeners) { + listener.actionStarted(event); + } + } + + protected void fireDone(ApplicationAction action) { + ApplicationActionEvent event = new ApplicationActionEvent(action, ApplicationActionEvent.EventType.DONE); + ApplicationActionListener[] listeners = eventList.getListeners(ApplicationActionListener.class); + for (ApplicationActionListener listener : listeners) { + listener.actionDone(event); + } + } + + protected void fireFail(ApplicationAction action, Exception error) { + ApplicationActionEvent event = new ApplicationActionEvent(action, ApplicationActionEvent.EventType.FAIL); + event.setError(error); + ApplicationActionListener[] listeners = eventList.getListeners(ApplicationActionListener.class); + for (ApplicationActionListener listener : listeners) { + listener.actionFailed(event); + } + } + + protected void fireProgressionChange(ApplicationAction action) { + ApplicationActionEvent event = new ApplicationActionEvent(action, ApplicationActionEvent.EventType.PROGRESSION_CHANGE); + ApplicationActionListener[] listeners = eventList.getListeners(ApplicationActionListener.class); + for (ApplicationActionListener listener : listeners) { + listener.actionProgressionChanged(event); + } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEngine.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEvent.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEvent.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEvent.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,97 @@ +package org.nuiton.jaxx.application.swing.actionng; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import java.util.EventObject; + +/** + * Events... + * + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationActionEvent extends EventObject { + + private static final long serialVersionUID = 1L; + + public enum EventType { + /** + * Before starting action. + */ + INIT, + /** + * When action is started. + */ + START, + /** + * When action end with succes. + */ + DONE, + /** + * When action failed. + */ + FAIL, + /** + * When progression changed. + */ + PROGRESSION_CHANGE + } + + private Exception error; + + private final EventType eventType; + + /** + * Constructs a prototypical Event. + * + * @param source The object on which the Event initially occurred. + * @param eventType The type of event + * @throws IllegalArgumentException if source is null. + */ + public ApplicationActionEvent(ApplicationAction source, + EventType eventType) { + super(source); + this.eventType = eventType; + } + + @Override + public ApplicationAction getSource() { + return (ApplicationAction) super.getSource(); + } + + public Exception getError() { + return error; + } + + public void setError(Exception error) { + this.error = error; + } + + public EventType getEventType() { + return eventType; + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionEvent.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionListener.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionListener.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionListener.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,49 @@ +package org.nuiton.jaxx.application.swing.actionng; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import java.util.EventListener; + +/** + * To listen {@link ApplicationActionEngine} events. + * <p/> + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public interface ApplicationActionListener extends EventListener { + + void actionInit(ApplicationActionEvent event); + + void actionStarted(ApplicationActionEvent event); + + void actionProgressionChanged(ApplicationActionEvent event); + + void actionDone(ApplicationActionEvent event); + + void actionFailed(ApplicationActionEvent event); + +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/actionng/ApplicationActionListener.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,126 @@ +package org.nuiton.jaxx.application.swing.tab; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import jaxx.runtime.SwingUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.nuiton.util.beans.BeanUtil; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.UIManager; +import java.awt.Color; +import java.awt.Font; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +import static org.nuiton.i18n.I18n._; + +/** + * Custom tab component which adds a * in the end of the title + * when the content is modified. + * + * @author kmorin <kmorin@codelutin.com> + * @since 2.8 + */ +public class CustomTab extends JPanel { + + private static final long serialVersionUID = 1L; + + private static final Log log = LogFactory.getLog(CustomTab.class); + + protected TabContentModel model; + + protected JLabel title = new JLabel(); + + public TabContentModel getModel() { + return model; + } + + public CustomTab(TabContentModel model) { + this.model = model; + try { + BeanUtil.addPropertyChangeListener( + new PropertyChangeListener() { + + @Override + public void propertyChange(PropertyChangeEvent evt) { + updateTitle(); + } + }, this.model); + + } catch (Exception ex) { + log.error("Error while adding the listener to the model modifications", ex); + } + + setBackground(null); + + updateTitle(); + String actionIcon = model.getIcon(); + if (actionIcon != null) { + title.setIcon(SwingUtil.createActionIcon(actionIcon)); + } + add(title); + } + + @Override + public void setBackground(Color bg) { + if (bg == null) { + bg = new Color(0, 0, 0, 0); + } + super.setBackground(bg); + revalidate(); + } + + @Override + public void setForeground(Color fg) { + super.setForeground(fg); + if (title != null) { + title.setForeground(fg); + } + } + + protected void updateTitle() { + Font f = UIManager.getDefaults().getFont("Label.font"); + String titleValue = _(model.getTitle()); + + int style; + if (model.isModify()) { + style = Font.BOLD; + titleValue += "*"; + + } else if (model.isEmpty()) { + style = Font.ITALIC; + + } else { + style = Font.PLAIN; + } + + title.setText(titleValue); + title.setFont(f.deriveFont(style)); + } + +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/CustomTab.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,112 @@ +package org.nuiton.jaxx.application.swing.tab; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.swing.AbstractApplicationUIHandler; +import org.nuiton.jaxx.application.swing.ApplicationUI; + +import javax.swing.DefaultSingleSelectionModel; +import javax.swing.JTabbedPane; +import java.awt.Component; + +/** + * Created on 11/25/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class DelegateTabContainerHandler implements TabContainerHandler { + + final JTabbedPane tabbedPane; + + public DelegateTabContainerHandler(JTabbedPane tabbedPane) { + this.tabbedPane = tabbedPane; + } + + @Override + public JTabbedPane getTabPanel() { + return tabbedPane; + } + + @Override + public void init() { + + getTabPanel().setModel(new DefaultSingleSelectionModel() { + + private static final long serialVersionUID = 1L; + + @Override + public void setSelectedIndex(int index) { + int currentIndex = getTabPanel().getSelectedIndex(); + boolean mustChangeTab = onTabChanged(currentIndex, index); + + if (mustChangeTab) { + super.setSelectedIndex(index); + } + } + + }); + } + + + @Override + public boolean onTabChanged(int currentIndex, int newIndex) { + boolean result = true; + if (currentIndex != newIndex) { + TabHandler handler = getTabHandler(currentIndex); + if (handler != null) { + result = handler.onHideTab(currentIndex, newIndex); + } + + handler = getTabHandler(newIndex); + if (handler != null) { + handler.onShowTab(currentIndex, newIndex); + } + } + return result; + } + + @Override + public TabHandler getTabHandler(int index) { + TabHandler tabHandler = null; + JTabbedPane tabPanel = getTabPanel(); + if (index >= 0 && index < tabPanel.getTabCount()) { + Component tab = tabPanel.getComponentAt(index); + if (ApplicationUI.class.isInstance(tab)) { + ApplicationUI tuttiTab = (ApplicationUI) tabPanel.getComponentAt(index); + AbstractApplicationUIHandler handler = tuttiTab.getHandler(); + if (TabHandler.class.isInstance(handler)) { + tabHandler = (TabHandler) handler; + } + } + } + return tabHandler; + } + + @Override + public void setCustomTab(int index, TabContentModel model) { + getTabPanel().setTabComponentAt(index, new CustomTab(model)); + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/DelegateTabContainerHandler.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,68 @@ +package org.nuiton.jaxx.application.swing.tab; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import javax.swing.JTabbedPane; + +/** + * Created on 11/25/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public interface TabContainerHandler { + + JTabbedPane getTabPanel(); + + void init(); + + /** + * Method called when the user selects a tab. + * + * @param currentIndex + * @param newIndex + * @return <code>false</code> if you want to prevent the tab change, + * <code>true</code> otherwise + */ + boolean onTabChanged(int currentIndex, int newIndex); + + /** + * Returns the tab handler of the tab i. + * + * @param index the index of the tab + * @return the tab handler of the index i if the handler implements + * the {@link TabHandler} interface, + * <code>null</code> otherwise + */ + TabHandler getTabHandler(int index); + + /** + * Sets a {@link CustomTab} as tab component. + * + * @param index + * @param model + */ + void setCustomTab(int index, TabContentModel model); +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContainerHandler.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,44 @@ +package org.nuiton.jaxx.application.swing.tab; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * Interface defining the models of the tab content UIs. + * + * @author kmorin <kmorin@codelutin.com> + * @since 2.8 + */ +public interface TabContentModel { + + boolean isEmpty(); + + boolean isValid(); + + boolean isModify(); + + String getTitle(); + + String getIcon(); +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabContentModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,52 @@ +package org.nuiton.jaxx.application.swing.tab; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * Interface describing UI contained in a tab. + * + * @author kmorin <kmorin@codelutin.com> + * @since 2.8 + */ +public interface TabHandler { + + /** + * Method called when the tab is hidden + * + * @param currentIndex + * @param newIndex + * @return <code>false</code> to prevent the tab to be hidden, + * <code>true</code> otherwise. + */ + boolean onHideTab(int currentIndex, int newIndex); + + /** + * Method called when the tab is shown + * + * @param currentIndex + * @param newIndex + */ + void onShowTab(int currentIndex, int newIndex); +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/tab/TabHandler.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractApplicationTableModel.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractApplicationTableModel.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractApplicationTableModel.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,303 @@ +package org.nuiton.jaxx.application.swing.table; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import com.google.common.base.Preconditions; +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import jaxx.runtime.SwingUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.swingx.table.TableColumnModelExt; + +import javax.swing.table.AbstractTableModel; +import javax.swing.table.TableColumn; +import java.io.Serializable; +import java.util.List; +import java.util.Set; + +/** + * Abstract model of a table. + * + * @param <R> type of a row. + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public abstract class AbstractApplicationTableModel<R extends Serializable> extends AbstractTableModel { + + private static final long serialVersionUID = 1L; + + /** Logger. */ + private static final Log log = + LogFactory.getLog(AbstractApplicationTableModel.class); + + /** + * Data in the model. + * + * @since 0.2 + */ + protected List<R> rows; + + /** + * Set of non editable columns. + * + * @since 0.2 + */ + protected Set<ColumnIdentifier<?>> noneEditableCols; + + /** + * Creates a new row when moving to next editable cell / row ? + * + * @since 0.3 + */ + protected final boolean createNewRow; + + /** + * Creates a first empty row when setting a null or empty list of rows ? + * + * @since 0.3 + */ + protected final boolean createEmptyRowIsEmpty; + + /** + * Identifiers of columns (in initial order). + * + * @since 1.1 + */ + protected final List<ColumnIdentifier<R>> identifiers; + + public abstract R createNewRow(); + + protected AbstractApplicationTableModel(TableColumnModelExt columnModel, + boolean createNewRow, + boolean createEmptyRowIsEmpty) { + this.identifiers = Lists.newArrayListWithCapacity(columnModel.getColumnCount()); + for (TableColumn tc : columnModel.getColumns(true)) { + this.identifiers.add((ColumnIdentifier<R>) tc.getIdentifier()); + } + this.createNewRow = createNewRow; + this.createEmptyRowIsEmpty = createEmptyRowIsEmpty; + } + + public final List<R> getRows() { + return rows; + } + + public final void setRows(List<R> data) { + + // can't accept a empty data list + Preconditions.checkNotNull(data, "Data list can not be null."); + + this.rows = null; + if (createEmptyRowIsEmpty && data.isEmpty()) { + + if (log.isDebugEnabled()) { + log.debug("Creates a first empty row on tableModel " + this); + } + // add a first edit line + data.add(createNewRow()); + } + if (log.isDebugEnabled()) { + log.debug("Set " + data.size() + " row(s) in table model " + this); + } + this.rows = data; + onRowsChanged(data); + fireTableDataChanged(); + } + + public boolean isCreateNewRow() { + return createNewRow; + } + + public boolean isCreateEmptyRowIsEmpty() { + return createEmptyRowIsEmpty; + } + + public final void addNewRow() { + R newValue = createNewRow(); + addNewRow(newValue); + } + + public final void addNewRow(R newValue) { + + addNewRow(getRowCount(), newValue); + } + + public final void addNewRow(int rowIndex, R newValue) { + + Preconditions.checkNotNull(newValue, "Row can not be null."); + + List<R> data = getRows(); + Preconditions.checkNotNull(data, "Data list can not be null."); + + data.add(rowIndex, newValue); + + onRowAdded(rowIndex, newValue); + fireTableRowsInserted(rowIndex, rowIndex); + } + + public final void fireTableRowsInserted(R newValue) { + + Preconditions.checkNotNull(newValue, "Row can not be null."); + + int rowIndex = getRowIndex(newValue); + fireTableRowsInserted(rowIndex, rowIndex); + } + + public final int updateRow(R row) { + Preconditions.checkNotNull(row, "Row can not be null."); + + List<R> data = getRows(); + Preconditions.checkNotNull(data, "Data list can not be null."); + + int rowIndex = data.indexOf(row); + + fireTableRowsUpdated(rowIndex, rowIndex); + return rowIndex; + } + + public final R removeRow(int rowIndex) { + SwingUtil.ensureRowIndex(this, rowIndex); + + List<R> data = getRows(); + + R result = data.remove(rowIndex); + + fireTableRowsDeleted(rowIndex, rowIndex); + return result; + } + + protected void onRowsChanged(List<R> data) { + // by default do nothing + } + + protected void onRowAdded(int rowIndex, R newValue) { + // by default do nothing + } + + public final int getRowIndex(R row) { + int result = rows == null ? -1 : rows.indexOf(row); + return result; + } + + public final R getEntry(int rowIndex) { + SwingUtil.ensureRowIndex(this, rowIndex); + List<R> data = getRows(); + R result = data == null ? null : data.get(rowIndex); + return result; + } + + public final void setNoneEditableCols(ColumnIdentifier<?>... noneEditableCols) { + this.noneEditableCols = Sets.newHashSet(noneEditableCols); + } + + @Override + public final int getRowCount() { + return rows == null ? 0 : rows.size(); + } + + @Override + public final int getColumnCount() { + return identifiers.size(); + } + + @Override + public final Object getValueAt(int rowIndex, int columnIndex) { + R entry = getEntry(rowIndex); + ColumnIdentifier<R> identifier = getIdentifier(columnIndex); + if (log.isDebugEnabled()) { + log.debug("columnIndex: " + columnIndex + " :: " + identifier.getPropertyName()); + } + Object result = identifier.getValue(entry); + return result; + } + + @Override + public final void setValueAt(Object aValue, int rowIndex, int columnIndex) { + if (log.isDebugEnabled()) { + log.debug("setValueAt " + aValue); + } + R entry = getEntry(rowIndex); + ColumnIdentifier<R> identifier = getIdentifier(columnIndex); + setValueAt(aValue, rowIndex, columnIndex, identifier, entry); + } + + @Override + public final boolean isCellEditable(int rowIndex, int columnIndex) { + ColumnIdentifier<R> identifier = getIdentifier(columnIndex); + boolean result = isCellEditable(rowIndex, columnIndex, identifier); + return result; + } + + protected void setValueAt(Object aValue, + int rowIndex, + int columnIndex, + ColumnIdentifier<R> propertyName, + R entry) { + if (log.isDebugEnabled()) { + log.debug("setValueAt " + aValue); + } + propertyName.setValue(entry, aValue); + } + + protected boolean isCellEditable(int rowIndex, + int columnIndex, + ColumnIdentifier<R> propertyName) { + boolean result = !noneEditableCols.contains(propertyName); + return result; + } + + public final void fireTableCellUpdated(int rowIndex, + ColumnIdentifier<R>... identifiers) { + for (ColumnIdentifier<R> identifier : identifiers) { + int columnIndex = this.identifiers.indexOf(identifier); + fireTableCellUpdated(rowIndex, columnIndex); + } + } + + public final void fireTableRowUpdatedShell(Set<R> shell) { + + int minRowIndex1 = getColumnCount(); + int maxRowIndex1 = 0; + + for (R r : shell) { + int rowIndex1 = getRowIndex(r); + minRowIndex1 = Math.min(minRowIndex1, rowIndex1); + maxRowIndex1 = Math.max(maxRowIndex1, rowIndex1); + } + fireTableRowsUpdated(minRowIndex1, maxRowIndex1); + } + + protected void collectShell(R row, Set<R> collectedRows) { + + // by default just add the incoming row + collectedRows.add(row); + } + + protected ColumnIdentifier<R> getIdentifier(int columnIndex) { + ColumnIdentifier<R> identifier = identifiers.get(columnIndex); + return identifier; + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractApplicationTableModel.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractSelectTableAction.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractSelectTableAction.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractSelectTableAction.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,102 @@ +package org.nuiton.jaxx.application.swing.table; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.swing.util.ApplicationUIUtil; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.AbstractAction; +import javax.swing.JTable; + +/** + * Abstract action to select a cell in a table. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public abstract class AbstractSelectTableAction<M extends AbstractApplicationTableModel> extends AbstractAction { + + private static final long serialVersionUID = 1L; + + /** Logger. */ + private static final Log log = + LogFactory.getLog(AbstractSelectTableAction.class); + + private final M model; + + private final JTable table; + + public AbstractSelectTableAction(M model, JTable table) { + this.model = model; + this.table = table; + } + + protected void doSelectCell(int rowIndex, int columnIndex) { + + if (log.isDebugEnabled()) { + log.debug("Will select cell at " + + getCellCoordinate(rowIndex, columnIndex)); + } + ApplicationUIUtil.doSelectCell(table, rowIndex, columnIndex); + } + + protected int getSelectedRow() { + int result = table.getSelectedRow(); + return result; + } + + protected int getSelectedColumn() { + int result = table.getSelectedColumn(); + return result; + } + + protected int getRowCount() { + return table.getRowCount(); + } + + protected int getColumnCount() { + return table.getColumnCount(); + } + + protected boolean isCellEditable(int rowIndex, int columnIndex) { + boolean result; + result = rowIndex > -1 && columnIndex > -1 && + table.isCellEditable(rowIndex, columnIndex); + return result; + } + + protected boolean isCreateNewRow() { + return model.isCreateNewRow(); + } + + protected String getCellCoordinate(int rowIndex, int columnIndex) { + return " [" + rowIndex + ", " + columnIndex + "]"; + } + + protected void addNewRow() { + model.addNewRow(); + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/AbstractSelectTableAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/ColumnIdentifier.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/ColumnIdentifier.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/ColumnIdentifier.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,105 @@ +package org.nuiton.jaxx.application.swing.table; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.ApplicationDataUtil; + +import java.io.Serializable; + +/** + * To represent a column of a table. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ColumnIdentifier<R> implements Serializable { + + private static final long serialVersionUID = 1L; + + private final String propertyName; + + private final String headerI18nKey; + + private final String headerTipI18nKey; + + public static <R> ColumnIdentifier<R> newId(String propertyName, + String headerI18nKey, + String headerTipI18nKey) { + return new ColumnIdentifier<R>(propertyName, + headerI18nKey, + headerTipI18nKey); + } + + public static <R> ColumnIdentifier<R> newReadOnlyId(String propertyName, + String headerI18nKey, + String headerTipI18nKey) { + return new ColumnIdentifier<R>(propertyName, + headerI18nKey, + headerTipI18nKey) { + + private static final long serialVersionUID = 1L; + + @Override + public void setValue(R entry, Object value) { + // no set + } + }; + } + + protected ColumnIdentifier(String propertyName, + String headerI18nKey, + String headerTipI18nKey) { + this.propertyName = propertyName; + this.headerI18nKey = headerI18nKey; + this.headerTipI18nKey = headerTipI18nKey; + } + + public String getPropertyName() { + return propertyName; + } + + public String getHeaderI18nKey() { + return headerI18nKey; + } + + public String getHeaderTipI18nKey() { + return headerTipI18nKey; + } + + public Object getValue(R entry) { + Object result = null; + if (propertyName != null && entry != null) { + result = ApplicationDataUtil.getProperty(entry, propertyName); + } + return result; + } + + public void setValue(R entry, Object value) { + if (propertyName != null) { + ApplicationDataUtil.setProperty(entry, propertyName, value); + } + } + +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/ColumnIdentifier.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableCellAction.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableCellAction.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableCellAction.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,102 @@ +package org.nuiton.jaxx.application.swing.table; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JTable; +import java.awt.event.ActionEvent; + +/** + * Action to select next editable cell in a table. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class MoveToNextEditableCellAction<M extends AbstractApplicationTableModel> extends AbstractSelectTableAction<M> { + + private static final long serialVersionUID = 1L; + + /** Logger. */ + private static final Log log = + LogFactory.getLog(MoveToNextEditableCellAction.class); + + public static <M extends AbstractApplicationTableModel> MoveToNextEditableCellAction<M> newAction(M model, JTable table) { + return new MoveToNextEditableCellAction<M>(model, table); + } + + protected MoveToNextEditableCellAction(M model, JTable table) { + super(model, table); + } + + @Override + public void actionPerformed(ActionEvent e) { + + int currentRow = getSelectedRow(); + int currentColumn = getSelectedColumn(); + + if (log.isDebugEnabled()) { + log.debug("Move to previous editable cell " + + getCellCoordinate(currentRow, currentColumn)); + } + + int columnCount = getColumnCount(); + + int rowCount = getRowCount(); + + if (currentRow <= rowCount || currentColumn <= columnCount) { + + // go to next cell + currentColumn++; + boolean canSelect = true; + + // select next cell + if (currentColumn >= columnCount) { + + // no more cell, so will move to next editable column on next row + currentColumn = 0; + currentRow++; + + if (currentRow == rowCount) { + + if (isCreateNewRow()) { + + // create a new row in model + addNewRow(); + } else { + + // can not create new row, so do nothing + canSelect = false; + } + } + } + + if (canSelect) { + doSelectCell(currentRow, currentColumn); + } + } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableCellAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableRowAction.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableRowAction.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableRowAction.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,93 @@ +package org.nuiton.jaxx.application.swing.table; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JTable; +import java.awt.event.ActionEvent; + +/** + * Action to select next editable row in a table. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class MoveToNextEditableRowAction<M extends AbstractApplicationTableModel> extends AbstractSelectTableAction<M> { + + private static final long serialVersionUID = 1L; + + /** Logger. */ + private static final Log log = + LogFactory.getLog(MoveToNextEditableRowAction.class); + + public static <M extends AbstractApplicationTableModel> MoveToNextEditableRowAction<M> newAction(M model, JTable table) { + return new MoveToNextEditableRowAction<M>(model, table); + } + + protected MoveToNextEditableRowAction(M model, JTable table) { + super(model, table); + } + + @Override + public void actionPerformed(ActionEvent e) { + int currentRow = getSelectedRow(); + int currentColumn = getSelectedColumn(); + + if (log.isDebugEnabled()) { + log.debug("Move to next row editable cell " + + getCellCoordinate(currentRow, currentColumn)); + } + + int rowCount = getRowCount(); + + if (currentRow < rowCount) { + // go to next cell + currentRow++; + boolean canSelect = true; + + // select next cell + if (currentRow >= rowCount) { + + if (log.isDebugEnabled()) { + log.debug("No next row"); + } + if (isCreateNewRow()) { + + // create a new row in model + addNewRow(); + + } else { + canSelect = false; + } + } + + if (canSelect) { + doSelectCell(currentRow, currentColumn); + } + } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToNextEditableRowAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableCellAction.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableCellAction.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableCellAction.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,82 @@ +package org.nuiton.jaxx.application.swing.table; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JTable; +import java.awt.event.ActionEvent; + +/** + * Action to select previous editable cell in a table. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class MoveToPreviousEditableCellAction<M extends AbstractApplicationTableModel> extends AbstractSelectTableAction<M> { + + private static final long serialVersionUID = 1L; + + /** Logger. */ + private static final Log log = + LogFactory.getLog(MoveToPreviousEditableCellAction.class); + + public static <M extends AbstractApplicationTableModel> MoveToPreviousEditableCellAction<M> newAction(M model, JTable table) { + return new MoveToPreviousEditableCellAction<M>(model, table); + } + + protected MoveToPreviousEditableCellAction(M model, JTable table) { + super(model, table); + } + + @Override + public void actionPerformed(ActionEvent e) { + int currentRow = getSelectedRow(); + int currentColumn = getSelectedColumn(); + + if (log.isDebugEnabled()) { + log.debug("Move to previous editable cell, " + + getCellCoordinate(currentRow, currentColumn)); + } + + int columnCount = getColumnCount(); + + if (currentRow > 0 || currentColumn > 0) { + + // go to next cell + currentColumn--; + + // select next cell + if (currentColumn < 0) { + + currentColumn = columnCount - 1; + currentRow--; + } + + doSelectCell(currentRow, currentColumn); + } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableCellAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableRowAction.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableRowAction.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableRowAction.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,73 @@ +package org.nuiton.jaxx.application.swing.table; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JTable; +import java.awt.event.ActionEvent; + +/** + * Action to select previous editable row in a table. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class MoveToPreviousEditableRowAction<M extends AbstractApplicationTableModel> extends AbstractSelectTableAction<M> { + + private static final long serialVersionUID = 1L; + + /** Logger. */ + private static final Log log = + LogFactory.getLog(MoveToPreviousEditableRowAction.class); + + public static <M extends AbstractApplicationTableModel> MoveToPreviousEditableRowAction<M> newAction(M model, JTable table) { + return new MoveToPreviousEditableRowAction<M>(model, table); + } + + protected MoveToPreviousEditableRowAction(M model, JTable table) { + super(model, table); + } + + @Override + public void actionPerformed(ActionEvent e) { + + int currentRow = getSelectedRow(); + int currentColumn = getSelectedColumn(); + + if (log.isDebugEnabled()) { + log.debug("Move to previous row editable cell " + + getCellCoordinate(currentRow, currentColumn)); + } + + if (currentRow > 0) { + + // go to next cell + currentRow--; + doSelectCell(currentRow, currentColumn); + } + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/table/MoveToPreviousEditableRowAction.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ActionListCellRenderer.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ActionListCellRenderer.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ActionListCellRenderer.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,61 @@ +package org.nuiton.jaxx.application.swing.util; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import javax.swing.Action; +import javax.swing.DefaultListCellRenderer; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JList; +import javax.swing.border.EmptyBorder; +import java.awt.Component; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ActionListCellRenderer extends DefaultListCellRenderer { + + private static final long serialVersionUID = 1L; + + protected final EmptyBorder border = new EmptyBorder(4, 8, 4, 8); + + @Override + public Component getListCellRendererComponent(JList list, + Object value, + int index, + boolean isSelected, + boolean cellHasFocus) { + + Component result = super.getListCellRendererComponent( + list, value, index, isSelected, cellHasFocus); + Action action = ((JButton) value).getAction(); + setIcon((Icon) action.getValue(Action.LARGE_ICON_KEY)); + setText((String) action.getValue(Action.NAME)); + setToolTipText((String) action.getValue(Action.SHORT_DESCRIPTION)); + setBorder(border); + return result; + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ActionListCellRenderer.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationColorHighlighter.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationColorHighlighter.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationColorHighlighter.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,66 @@ +package org.nuiton.jaxx.application.swing.util; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.jdesktop.swingx.decorator.AbstractHighlighter; +import org.jdesktop.swingx.decorator.ComponentAdapter; +import org.jdesktop.swingx.decorator.HighlightPredicate; +import org.jdesktop.swingx.util.PaintUtils; + +import java.awt.Color; +import java.awt.Component; + +/** + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationColorHighlighter extends AbstractHighlighter { + + protected Color color; + + protected boolean foreground; + + public ApplicationColorHighlighter(HighlightPredicate predicate, Color color, boolean foreground) { + super(predicate); + this.color = color; + this.foreground = foreground; + } + + @Override + protected Component doHighlight(Component component, ComponentAdapter adapter) { + + if (foreground) { + component.setForeground(color); + + } else { + component.setBackground(color); + if (adapter.isSelected()) { + component.setForeground(PaintUtils.computeForeground(color)); + } + } + + return component; + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationColorHighlighter.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationErrorHelper.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationErrorHelper.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationErrorHelper.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,113 @@ +package org.nuiton.jaxx.application.swing.util; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.ApplicationBusinessException; +import org.nuiton.jaxx.application.swing.ApplicationUIContext; +import org.jdesktop.swingx.JXErrorPane; +import org.jdesktop.swingx.error.ErrorInfo; +import org.jdesktop.swingx.error.ErrorReporter; +import org.nuiton.csv.ImportRuntimeException; + +import javax.swing.JOptionPane; + +import static org.nuiton.i18n.I18n._; + +/** + * Helper to display errors. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationErrorHelper implements ErrorReporter { + + protected ApplicationUIContext context; + + public ApplicationErrorHelper(ApplicationUIContext context) { + this.context = context; + } + + /** + * Display a user friendly error frame. + * + * @param message message for user + * @param cause exception cause + */ + public void showErrorDialog(String message, Throwable cause) { + + if (cause == null) { + JOptionPane.showMessageDialog(context.getMainUI(), "<html><body>" + message + "</body></html>", + _("jaxx.application.error.ui.business.error"), + JOptionPane.ERROR_MESSAGE); + } else if (cause instanceof ApplicationBusinessException) { + JOptionPane.showMessageDialog(context.getMainUI(), "<html><body>" + cause.getMessage() + "</body></html>", + _("jaxx.application.error.ui.business.error"), + JOptionPane.ERROR_MESSAGE); + } else if (cause instanceof ImportRuntimeException) { + JOptionPane.showMessageDialog(context.getMainUI(), cause.getMessage(), + _("jaxx.application.error.ui.business.error"), + JOptionPane.ERROR_MESSAGE); + } else { + + JXErrorPane pane = new JXErrorPane(); + ErrorInfo info = new ErrorInfo(_("jaxx.application.error.ui.other.error"), + _("jaxx.application.error.errorpane.htmlmessage", message), null, null, + cause, null, null); + pane.setErrorInfo(info); + pane.setErrorReporter(this); + JXErrorPane.showDialog(context.getActionUI(), pane); + } + + } + + /** + * Display a user friendly error frame. + * + * @param message message for user + */ + public void showErrorDialog(String message) { + showErrorDialog(message, null); + } + + @Override + public void reportError(ErrorInfo errorInfo) throws NullPointerException { + + showErrorDialog(errorInfo.getBasicErrorMessage(), errorInfo.getErrorException()); + } + + /** + * Display a user friendly warning frame. + * + * @param message message for user + */ + public void showWarningDialog(String message) { + + JOptionPane.showMessageDialog(context.getMainUI(), "<html><body>" + message + "</body></html>", + _("jaxx.application.error.ui.business.warning"), + JOptionPane.WARNING_MESSAGE); + + } + +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationErrorHelper.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationExceptionHandler.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationExceptionHandler.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationExceptionHandler.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,91 @@ +package org.nuiton.jaxx.application.swing.util; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.ApplicationTechnicalException; +import jaxx.runtime.swing.JAXXRuntimeException; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * Global exception handler. + * <p/> + * Catch all application uncaught and display it in a custom JoptionPane + * or JXErrorPane. + * <p/> + * See http://stackoverflow.com/a/4448569/1165234 for details. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationExceptionHandler implements Thread.UncaughtExceptionHandler { + + private static final Log log = + LogFactory.getLog(ApplicationExceptionHandler.class); + + final ApplicationErrorHelper errorHelper; + + public ApplicationExceptionHandler(ApplicationErrorHelper errorHelper) { + this.errorHelper = errorHelper; + } + + @Override + public void uncaughtException(Thread t, Throwable ex) { + handleException(t.getName(), ex); + } + + public void handle(Throwable thrown) { + // for EDT exceptions + handleException(Thread.currentThread().getName(), thrown); + } + + protected void handleException(String tname, Throwable ex) { + if (log.isErrorEnabled()) { + log.error("Global application exception [" + tname + "]", ex); + } + + Throwable cause = getCause(ex); + + showErrorDialog(cause.getMessage(), cause); + } + + protected Throwable getCause(Throwable ex) { + + Throwable cause = ex; + + if (cause instanceof ApplicationTechnicalException) { + cause = cause.getCause(); + } + + if (cause instanceof JAXXRuntimeException) { + cause = cause.getCause(); + } + return cause; + } + + public void showErrorDialog(String message, Throwable cause) { + errorHelper.showErrorDialog(message, cause); + } +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationExceptionHandler.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,226 @@ +package org.nuiton.jaxx.application.swing.util; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +import org.nuiton.jaxx.application.ApplicationTechnicalException; +import org.nuiton.jaxx.application.swing.ApplicationUIContext; +import jaxx.runtime.JAXXObject; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.swingx.JXTable; +import org.jdesktop.swingx.decorator.HighlightPredicate; +import org.jdesktop.swingx.decorator.Highlighter; + +import javax.swing.JTable; +import java.awt.Color; +import java.awt.Desktop; +import java.net.URI; +import java.net.URISyntaxException; +import java.net.URL; + +import static org.nuiton.i18n.I18n._; + +/** + * Useful ui methods. + * <p/> + * Created on 11/23/13. + * + * @author Tony Chemit <chemit@codelutin.com> + * @since 2.8 + */ +public class ApplicationUIUtil { + + /** Logger. */ + private static final Log log = LogFactory.getLog(ApplicationUIUtil.class); + + protected ApplicationUIUtil() { + // avoid instanciate util class + } + + public static void setApplicationContext(JAXXObject ui, ApplicationUIContext context) { + ui.setContextValue(context, "applicationContext"); + } + + public static ApplicationUIContext getApplicationContext(JAXXObject ui) { + return ui.getContextValue(ApplicationUIContext.class, "applicationContext"); + } + + public static Highlighter newBackgroundColorHighlighter(HighlightPredicate predicate, Color color) { + return new ApplicationColorHighlighter(predicate, color, false); + } + + public static Highlighter newForegroundColorHighlighter(HighlightPredicate predicate, Color color) { + return new ApplicationColorHighlighter(predicate, color, true); + } + + public static void openLink(URL url) { + try { + openLink(url.toURI()); + } catch (URISyntaxException e) { + throw new ApplicationTechnicalException(_("jaxx.application.error.cannot.open.link", url), e); + } + } + + public static Desktop getDesktopForBrowse() { + + if (!Desktop.isDesktopSupported()) { + throw new ApplicationTechnicalException( + _("jaxx.application.error.desktop.not.supported")); + } + + Desktop desktop = Desktop.getDesktop(); + + if (!desktop.isSupported(Desktop.Action.BROWSE)) { + + throw new ApplicationTechnicalException( + _("jaxx.application.error.desktop.browse.not.supported")); + } + + return desktop; + } + + public static void openLink(URI uri) { + + Desktop desktop = getDesktopForBrowse(); + + try { + + desktop.browse(uri); + } catch (Exception e) { + + throw new ApplicationTechnicalException( + _("jaxx.application.error.cannot.open.link", uri), e); + } + } + + public static Desktop getDesktopForMail() { + + if (!Desktop.isDesktopSupported()) { + throw new ApplicationTechnicalException( + _("jaxx.application.error.desktop.not.supported")); + } + + Desktop desktop = Desktop.getDesktop(); + + if (!desktop.isSupported(Desktop.Action.MAIL)) { + + throw new ApplicationTechnicalException( + _("jaxx.application.error.desktop.mail.not.supported")); + } + + return desktop; + } + + public static void mail(String subject, String body) { + + Desktop desktop = getDesktopForMail(); + + try { + URI mailtoURI = new URI("mailto", null, null, "subject=" + subject + "&body=" + body, null); + desktop.mail(mailtoURI); + + } catch (Exception e) { + + throw new ApplicationTechnicalException( + _("jaxx.application.error.cannot.mail"), e); + } + } + + public static void selectFirstCellOnFirstRowAndStopEditing(JXTable table) { + + // select first cell + doSelectCell(table, 0, 0); + + if (table.isEditing()) { + + // but no edit it + table.getCellEditor().stopCellEditing(); + } + } + + public static void selectFirstCellOnLastRow(JXTable table) { + + // select first cell + doSelectCell(table, table.getRowCount() - 1, 0); + } + + public static void selectFirstCellOnRow(JXTable table, int row, boolean stopEdit) { + + // select first cell + doSelectCell(table, row, 0); + + if (stopEdit && table.isEditing()) { + + table.getCellEditor().stopCellEditing(); + } + } + + public static void doSelectCell(JTable table, + int rowIndex, + int columnIndex) { + + int rowCount = table.getRowCount(); + if (rowCount == 0) { + + // no row, can not selected any cell + if (log.isWarnEnabled()) { + log.warn("No row in table, can not select any cell"); + } + return; + } + int columnCount = table.getColumnCount(); + if (columnCount == 0) { + + // no column, can not selected any cell + if (log.isWarnEnabled()) { + log.warn("No column in table, can not select any cell"); + } + return; + } + if (columnIndex > columnCount) { + if (log.isWarnEnabled()) { + log.warn(String.format("ColumnIndex: %s is more than columnCount %s", columnIndex, columnCount)); + } + columnIndex = columnCount - 1; + } + if (columnIndex < 0) { + columnIndex = 0; + } + if (rowIndex >= rowCount) { + if (log.isWarnEnabled()) { + log.warn(String.format("RowIndex: %s is more than rowCount %s", rowIndex, rowCount)); + } + rowIndex = rowCount - 1; + } + if (rowIndex < 0) { + rowIndex = 0; + } + + table.setColumnSelectionInterval(columnIndex, columnIndex); + table.setRowSelectionInterval(rowIndex, rowIndex); + table.editCellAt(rowIndex, columnIndex); + } + +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/ApplicationUIUtil.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/Cancelable.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/Cancelable.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/Cancelable.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,36 @@ +package org.nuiton.jaxx.application.swing.util; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * To cancel contract. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public interface Cancelable { + + void cancel(); +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/Cancelable.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/CloseableUI.java =================================================================== --- trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/CloseableUI.java (rev 0) +++ trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/CloseableUI.java 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,44 @@ +package org.nuiton.jaxx.application.swing.util; + +/* + * #%L + * JAXX :: Application Swing + * $Id$ + * $HeadURL:$ + * %% + * Copyright (C) 2014 Code Lutin, Tony CHEMIT + * %% + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. + * + * You should have received a copy of the GNU General Lesser Public + * License along with this program. If not, see + * <http://www.gnu.org/licenses/lgpl-3.0.html>. + * #L% + */ + +/** + * Place this contract on any handler of ui that need some check before closing. + * + * Contract to close an ui. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.8 + */ +public interface CloseableUI { + + /** + * Try to quit UI. + * + * @return {@code true} if ui is safe to quit, {@code false} otherwise + * (means must stay on it). + */ + boolean quitUI(); +} Property changes on: trunk/jaxx-application-swing/src/main/java/org/nuiton/jaxx/application/swing/util/CloseableUI.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Property changes on: trunk/jaxx-application-swing/src/main/resources ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Property changes on: trunk/jaxx-application-swing/src/main/resources/i18n ___________________________________________________________________ Added: svn:ignore + target .idea *.ipr *.iws *.iml Added: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties =================================================================== --- trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties (rev 0) +++ trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,21 @@ +jaxx.application.action.create.error= +jaxx.application.common.askBeforeDelete.help= +jaxx.application.common.askCancelEditBeforeLeaving.help= +jaxx.application.common.askCancelEditBeforeLeaving.title= +jaxx.application.common.askOverwriteFile.help= +jaxx.application.common.askOverwriteFile.message= +jaxx.application.common.askOverwriteFile.title= +jaxx.application.common.askSaveBeforeLeaving.help= +jaxx.application.common.askSaveBeforeLeaving.title= +jaxx.application.common.datefield.tip= +jaxx.application.error.cannot.mail= +jaxx.application.error.cannot.open.link= +jaxx.application.error.desktop.browse.not.supported= +jaxx.application.error.desktop.mail.not.supported= +jaxx.application.error.desktop.not.supported= +jaxx.application.error.errorpane.htmlmessage= +jaxx.application.error.ui.business.error= +jaxx.application.error.ui.business.warning= +jaxx.application.error.ui.other.error= +jaxx.application.message.action.running= +jaxx.application.title.actionUI= Property changes on: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_en_GB.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties =================================================================== --- trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties (rev 0) +++ trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,21 @@ +jaxx.application.action.create.error= +jaxx.application.common.askBeforeDelete.help= +jaxx.application.common.askCancelEditBeforeLeaving.help= +jaxx.application.common.askCancelEditBeforeLeaving.title= +jaxx.application.common.askOverwriteFile.help= +jaxx.application.common.askOverwriteFile.message= +jaxx.application.common.askOverwriteFile.title= +jaxx.application.common.askSaveBeforeLeaving.help= +jaxx.application.common.askSaveBeforeLeaving.title= +jaxx.application.common.datefield.tip= +jaxx.application.error.cannot.mail= +jaxx.application.error.cannot.open.link= +jaxx.application.error.desktop.browse.not.supported= +jaxx.application.error.desktop.mail.not.supported= +jaxx.application.error.desktop.not.supported= +jaxx.application.error.errorpane.htmlmessage= +jaxx.application.error.ui.business.error= +jaxx.application.error.ui.business.warning= +jaxx.application.error.ui.other.error= +jaxx.application.message.action.running= +jaxx.application.title.actionUI= Property changes on: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_es_ES.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties =================================================================== --- trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties (rev 0) +++ trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties 2014-01-31 10:50:51 UTC (rev 2779) @@ -0,0 +1,21 @@ +jaxx.application.action.create.error=Erreur à l'instanciation de l'action %s +jaxx.application.common.askBeforeDelete.help=Que voulez-vous faire ?<ul><li><strong>Annuler</strong> pour ne pas supprimer</li><li><strong>OK</strong> pour supprimer l'objet en question</li></ul> +jaxx.application.common.askCancelEditBeforeLeaving.help=Que voulez-vous faire ?<ul><li><strong>Annuler</strong> pour rester sur cet écran</li><li><strong>OK</strong> pour quitter l'écran en abandonnant les modifications</li></ul> +jaxx.application.common.askCancelEditBeforeLeaving.title=Modifications non enregistrées mais invalides +jaxx.application.common.askOverwriteFile.help=Que voulez-vous faire ?<ul><li><strong>Annuler</strong> pour ne pas écraser le fichier et annuler l'opération</li><li><strong>Oui</strong> pour écraser le fichier et continuer l'opération</li></ul> +jaxx.application.common.askOverwriteFile.message=Le fichier %s existe déjà, confirmer pour l'écraser +jaxx.application.common.askOverwriteFile.title=Confirmer l'écrasement d'un fichier... +jaxx.application.common.askSaveBeforeLeaving.help=Que voulez-vous faire?<ul><li><strong>Annuler</strong> pour rester sur cet écran</li><li><strong>Non</strong> pour quitter l'écran en abandonnant les modifications en cours</li><li><strong>Oui</strong> pour quitter l'écran après enregistrement des modifications</li></ul> +jaxx.application.common.askSaveBeforeLeaving.title=Modifications non enregistrées +jaxx.application.common.datefield.tip=Format attendu \: %s +jaxx.application.error.cannot.mail=Erreur lors de l'ouverture du client mail +jaxx.application.error.cannot.open.link=Impossible d'ouvrir le fichier %s +jaxx.application.error.desktop.browse.not.supported=Le navigateur n'a pas pu être ouvert. Vérifiez que vous avez défini un navigateur par défaut dans votre système +jaxx.application.error.desktop.mail.not.supported=Le client mail n'a pas pu être ouvert. Vérifiez que vous avez défini un client mail par défaut dans votre système +jaxx.application.error.desktop.not.supported=Votre système ne permet pas d'ouvrir des liens ou fichiers en dehors de l'application +jaxx.application.error.errorpane.htmlmessage=<html><body><b>Une erreur s'est produite</b>\:<br/>%s</body></html> +jaxx.application.error.ui.business.error=Erreur +jaxx.application.error.ui.business.warning=Avertissement +jaxx.application.error.ui.other.error=Erreur +jaxx.application.message.action.running=<html>Action <strong>%s</strong> en cours d'exécution...</html> +jaxx.application.title.actionUI=%s - v %s [%s] Property changes on: trunk/jaxx-application-swing/src/main/resources/i18n/jaxx-application-swing_fr_FR.properties ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Modified: trunk/jaxx-demo/src/main/resources/jaxxdemo-help-fr.properties =================================================================== --- trunk/jaxx-demo/src/main/resources/jaxxdemo-help-fr.properties 2014-01-31 09:27:15 UTC (rev 2778) +++ trunk/jaxx-demo/src/main/resources/jaxxdemo-help-fr.properties 2014-01-31 10:50:51 UTC (rev 2779) @@ -1,3 +1,26 @@ +### +# #%L +# JAXX :: Demo +# $Id$ +# $HeadURL:$ +# %% +# Copyright (C) 2008 - 2014 CodeLutin +# %% +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation, either version 3 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 Lesser Public License for more details. +# +# You should have received a copy of the GNU General Lesser Public +# License along with this program. If not, see +# <http://www.gnu.org/licenses/lgpl-3.0.html>. +# #L% +### #Generated by org.nuiton.jaxx.plugin.GenerateHelpIdsMojo #Fri Jan 10 13:44:01 CET 2014 ui.component.swing.buttons.JButtonDemo= Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2014-01-31 09:27:15 UTC (rev 2778) +++ trunk/pom.xml 2014-01-31 10:50:51 UTC (rev 2779) @@ -43,6 +43,8 @@ <module>jaxx-maven-plugin</module> <module>jaxx-widgets</module> <module>jaxx-config</module> + <module>jaxx-application-api</module> + <module>jaxx-application-swing</module> </modules> <developers> @@ -118,6 +120,7 @@ <nuitonConfigVersion>3.0-alpha-1</nuitonConfigVersion> <nuitonDecoratorVersion>3.0-alpha-2</nuitonDecoratorVersion> <nuitonI18nVersion>2.5.2</nuitonI18nVersion> + <nuitonCsvVersion>3.0-alpha-1</nuitonCsvVersion> <eugeneVersion>2.7.3</eugeneVersion> <jxLayerVersion>3.0.4</jxLayerVersion> <javaHelpVersion>2.0.05</javaHelpVersion> @@ -190,6 +193,12 @@ </dependency> <dependency> + <groupId>org.nuiton</groupId> + <artifactId>nuiton-csv</artifactId> + <version>${nuitonCsvVersion}</version> + </dependency> + + <dependency> <groupId>org.nuiton.eugene</groupId> <artifactId>eugene</artifactId> <version>${eugeneVersion}</version> @@ -262,6 +271,22 @@ </exclusions> </dependency> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-vfs2</artifactId> + <version>2.0</version> + <exclusions> + <exclusion> + <groupId>org.apache.maven.scm</groupId> + <artifactId>maven-scm-api</artifactId> + </exclusion> + <exclusion> + <groupId>org.apache.maven.scm</groupId> + <artifactId>maven-scm-provider-svnexe</artifactId> + </exclusion> + </exclusions> + </dependency> + <!-- sun dependencies --> <dependency> <groupId>com.sun</groupId>
participants (1)
-
tchemit@users.nuiton.org