Author: tchemit Date: 2012-12-30 14:24:10 +0100 (Sun, 30 Dec 2012) New Revision: 2542 Url: http://nuiton.org/projects/jaxx/repository/revisions/2542 Log: fixes #2493: [BeanComboBox] Use widget with no model fixes #2494: Use the genericType to fill the beanType property on BeanTypeAware widgets Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/bean/ trunk/jaxx-runtime/src/main/java/jaxx/runtime/bean/BeanTypeAware.java Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanComboBox.jaxx trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanComboBoxHandler.java trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanDoubleList.jaxx trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanListHeader.jaxx Modified: trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java =================================================================== --- trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java 2012-12-29 13:29:17 UTC (rev 2541) +++ trunk/jaxx-compiler/src/main/java/jaxx/compiler/tags/DefaultObjectHandler.java 2012-12-30 13:24:10 UTC (rev 2542) @@ -45,8 +45,11 @@ import jaxx.runtime.ComponentDescriptor; import jaxx.runtime.JAXXObject; import jaxx.runtime.JAXXObjectDescriptor; +import jaxx.runtime.bean.BeanTypeAware; import jaxx.runtime.css.Stylesheet; import org.apache.commons.lang3.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; import org.w3c.dom.Attr; import org.w3c.dom.Element; import org.w3c.dom.NamedNodeMap; @@ -81,6 +84,9 @@ */ public class DefaultObjectHandler implements TagHandler { + /** Logger. */ + private static final Log log = LogFactory.getLog(DefaultObjectHandler.class); + public static final String ABSTRACT_ATTRIBUTE = "abstract"; public static final String CONSTRAINTS_ATTRIBUTE = "constraints"; @@ -93,7 +99,7 @@ public static final String DISPLAYED_MNEMONIC_INDEX_ATTRIBUTE = "displayedMnemonicIndex"; - public static final String GENERICTYPE_ATTRIBUTE = "genericType"; + public static final String GENERIC_TYPE_ATTRIBUTE = "genericType"; public static final String ID_ATTRIBUTE = "id"; @@ -611,11 +617,15 @@ JAXXCompiler compiler) { List<Attr> attributes = new ArrayList<Attr>(); NamedNodeMap children = tag.getAttributes(); + for (int i = 0; i < children.getLength(); i++) { attributes.add((Attr) children.item(i)); } Collections.sort(attributes, getAttributeComparator()); + CompiledObject rootObject = compiler.getRootObject(); + + Attr genericTypeAttribute = null; for (Attr attribute : attributes) { String name = attribute.getName(); String value = attribute.getValue().trim(); @@ -643,7 +653,7 @@ } continue; } - CompiledObject rootObject = compiler.getRootObject(); + if (name.equals(IMPLEMENTS_ATTRIBUTE)) { if (object != rootObject) { // can ony be apply to root object @@ -667,18 +677,9 @@ continue; } - if (name.equals(GENERICTYPE_ATTRIBUTE)) { - //TC-20090313 check after all atributes been processed - if (object == rootObject) { - compiler.setGenericType(value); - } else { - object.setGenericTypes(value.split(",")); - if (object.getSimpleType() != null) { - - // reload the simpleType - object.setSimpleType(object.getSimpleType() + "<" + value + ">"); - } - } + if (name.equals(GENERIC_TYPE_ATTRIBUTE)) { + //TC-20090313 check after all attributes been processed + genericTypeAttribute = attribute; continue; } @@ -716,6 +717,29 @@ // simple property setAttribute(object, name, value, true, compiler); } + + if (genericTypeAttribute != null) { + String name = genericTypeAttribute.getName(); + String value = genericTypeAttribute.getValue().trim(); + if (object == rootObject) { + compiler.setGenericType(value); + } else { + object.setGenericTypes(value.split(",")); + if (object.getSimpleType() != null) { + + // reload the simpleType + object.setSimpleType(object.getSimpleType() + "<" + value + ">"); + } + } + if (ClassDescriptorHelper.getClassDescriptor(BeanTypeAware.class).isAssignableFrom(object.getObjectClass())) { + // add beanType from genericType + if (log.isDebugEnabled()) { + log.debug("Add beanType property: " + value + " to " + object); + } + setAttribute(object, BeanTypeAware.PROPERTY_BEAN_TYPE, "{" + value + ".class}", true, compiler); + } + } + } /** Added: trunk/jaxx-runtime/src/main/java/jaxx/runtime/bean/BeanTypeAware.java =================================================================== --- trunk/jaxx-runtime/src/main/java/jaxx/runtime/bean/BeanTypeAware.java (rev 0) +++ trunk/jaxx-runtime/src/main/java/jaxx/runtime/bean/BeanTypeAware.java 2012-12-30 13:24:10 UTC (rev 2542) @@ -0,0 +1,43 @@ +package jaxx.runtime.bean; + +/* + * #%L + * JAXX :: Runtime + * $Id$ + * $HeadURL$ + * %% + * Copyright (C) 2008 - 2012 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% + */ + +/** + * Contract for ui which contains a {@code beanType} property. + * <p/> + * In a jaxx file, if an object has a genericType and implementsthis contract + * then the {@code beanType} will be automaticly setted. + * + * @author tchemit <chemit@codelutin.com> + * @since 2.5.9 + */ +public interface BeanTypeAware<O> { + + String PROPERTY_BEAN_TYPE= "beanType"; + + Class<O> getBeanType(); + + void setBeanType(Class<O> beanType); +} Property changes on: trunk/jaxx-runtime/src/main/java/jaxx/runtime/bean/BeanTypeAware.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanComboBox.jaxx =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanComboBox.jaxx 2012-12-29 13:29:17 UTC (rev 2541) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanComboBox.jaxx 2012-12-30 13:24:10 UTC (rev 2542) @@ -24,20 +24,23 @@ --> <Table fill='both' insets='0' genericType='O' - onFocusGained='combobox.requestFocus()' - onFocusLost='hidePopup()'> + implements='jaxx.runtime.bean.BeanTypeAware<O>' + onFocusGained='combobox.requestFocus()' onFocusLost='hidePopup()'> <import> org.nuiton.util.decorator.JXPathDecorator javax.swing.border.TitledBorder </import> - + + <!-- bean type --> + <Class id='beanType' genericType='O' javaBean='null'/> + <!-- auto complete property --> <Boolean id='autoComplete' javaBean='false'/> <!-- flag to reverse the sort --> <Boolean id='reverseSort' javaBean='false'/> - + <!-- show reset property --> <Boolean id='showReset' javaBean='false'/> @@ -50,7 +53,7 @@ <!-- bean property linked state --> <String id='property' javaBean='""'/> - <!-- bean property --> + <!-- model property --> <Object id='bean' javaBean='null'/> <!-- selectedItem property --> @@ -68,7 +71,7 @@ <ButtonGroup id='sortGroup' onStateChanged='setReverseSort((Boolean)sortGroup.getSelectedValue())'/> - + <!-- ui handler --> <BeanComboBoxHandler id='handler' genericType='O' constructorParams='this'/> Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanComboBoxHandler.java =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanComboBoxHandler.java 2012-12-29 13:29:17 UTC (rev 2541) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanComboBoxHandler.java 2012-12-30 13:24:10 UTC (rev 2542) @@ -57,7 +57,7 @@ * @author tchemit <chemit@codelutin.com> * @see BeanComboBox */ -public class BeanComboBoxHandler<O> implements PropertyChangeListener {//}, ListDataListener { +public class BeanComboBoxHandler<O> implements PropertyChangeListener { public static final Log log = LogFactory.getLog(BeanComboBoxHandler.class); @@ -123,6 +123,10 @@ } init = true; + if (decorator == null) { + throw new NullPointerException("decorator can not be null"); + } + JAXXButtonGroup indexes = ui.getIndexes(); this.decorator = BeanUIUtil.createDecorator(decorator); @@ -152,8 +156,6 @@ ui.autoComplete = true; -// combobox.getModel().addListDataListener(this); - ui.addPropertyChangeListener(this); // set datas @@ -168,11 +170,25 @@ popupHandler.togglePopup(); } + /** + * @return {@code true} if there is no data in comboBox, + * {@code false} otherwise. + * @since 2.5.9 + */ public boolean isEmpty() { boolean result = CollectionUtils.isEmpty(ui.getData()); return result; } + /** + * Add the given item into the comboBox. + * <p/> + * <strong>Note:</strong> The item will be inserted at his correct following + * the selected ordering. + * + * @param item item to add in comboBox. + * @since 2.5.9 + */ public void addItem(O item) { List<O> data = ui.getData(); @@ -184,6 +200,15 @@ fireEmpty(wasEmpty); } + /** + * Remove the given item from the comboBox model. + * <p/> + * <strong>Note:</strong> If this item was selected, then selection will + * be cleared. + * + * @param item the item to remove from the comboBox model + * @since 2.5.9 + */ public void removeItem(O item) { List<O> data = ui.getData(); @@ -340,7 +365,7 @@ } } if (log.isDebugEnabled()) { - log.debug(ui.getProperty() + " on " + ui.getBean().getClass() + " :: " + oldValue + " to " + newValue); + log.debug(ui.getProperty() + " on " + getBeanType() + " :: " + oldValue + " to " + newValue); } try { @@ -362,6 +387,25 @@ return decorator; } + /** + * @return get the type of objects contained in the comboBox model. + * @since 2.5.9 + */ + public Class<O> getBeanType() { + Class<O> result = ui.getBeanType(); + if (result == null) { + result = decorator == null ? null : decorator.getType(); + } + return result; + } + + /** + * Obtain the type of objects contained in the comboBox using the model mutator. + * + * @return get the type of objects contained in the comboBox model. + * @deprecated since 2.5.9 (use now method {@link #getBeanType()}) + */ + @Deprecated public Class<?> getTargetClass() { Method m = getMutator(); return m == null ? null : m.getParameterTypes()[0]; @@ -369,7 +413,7 @@ /** @return le mutateur a utiliser pour modifier le bean associé. */ protected Method getMutator() { - if (mutator == null) { + if (mutator == null && ui.getBean() != null && ui.getProperty() != null) { mutator = BeanUIUtil.getMutator(ui.getBean(), ui.getProperty()); } return mutator; @@ -386,7 +430,8 @@ if (BeanComboBox.PROPERTY_AUTO_COMPLETE.equals(propertyName)) { - setAutoComplete((Boolean) evt.getOldValue(), (Boolean) evt.getNewValue()); + setAutoComplete((Boolean) evt.getOldValue(), + (Boolean) evt.getNewValue()); return; } @@ -418,7 +463,8 @@ } protected void fireEmpty(boolean wasEmpty) { - ui.firePropertyChange(BeanComboBox.PROPERTY_EMPTY, wasEmpty, isEmpty()); + ui.firePropertyChange(BeanComboBox.PROPERTY_EMPTY, wasEmpty, + isEmpty()); } } Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanDoubleList.jaxx =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanDoubleList.jaxx 2012-12-29 13:29:17 UTC (rev 2541) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanDoubleList.jaxx 2012-12-30 13:24:10 UTC (rev 2542) @@ -21,7 +21,7 @@ <http://www.gnu.org/licenses/lgpl-3.0.html>. #L% --> -<Table genericType='O'> +<Table genericType='O' implements='jaxx.runtime.bean.BeanTypeAware<O>'> <import> org.nuiton.util.decorator.JXPathDecorator @@ -29,7 +29,7 @@ </import> <!-- bean type --> - <Class genericType='O' id='beanType' javaBean='null'/> + <Class id='beanType' genericType='O' javaBean='null'/> <!-- label --> <String id='labelText' javaBean='null'/> Modified: trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanListHeader.jaxx =================================================================== --- trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanListHeader.jaxx 2012-12-29 13:29:17 UTC (rev 2541) +++ trunk/jaxx-widgets/src/main/java/jaxx/runtime/swing/editor/bean/BeanListHeader.jaxx 2012-12-30 13:24:10 UTC (rev 2542) @@ -23,7 +23,8 @@ #L% --> -<JPanel id='top' layout='{new BorderLayout()}' genericType='O'> +<JPanel id='top' layout='{new BorderLayout()}' genericType='O' + implements='jaxx.runtime.bean.BeanTypeAware<O>'> <import> org.nuiton.util.decorator.JXPathDecorator @@ -42,8 +43,8 @@ <!-- editable combo property --> <Boolean id='editable' javaBean='true'/> - <!-- bean property --> - <Class genericType='O' id='beanType' javaBean='null'/> + <!-- bean type --> + <Class id='beanType' genericType='O' javaBean='null'/> <!-- label --> <String id='labelText' javaBean='null'/>