/* * Copyright (C) 2014 GG-Net GmbH - Oliver Günther * * 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/>. */ package eu.ggnet.dwoss.util; import java.text.MessageFormat; import javax.swing.JComponent; import org.jdesktop.beansbinding.AutoBinding; import org.jdesktop.beansbinding.Converter; import org.metawidget.inspector.annotation.MetawidgetAnnotationInspector; import org.metawidget.inspector.beanvalidation.BeanValidationInspector; import org.metawidget.inspector.composite.CompositeInspector; import org.metawidget.inspector.composite.CompositeInspectorConfig; import org.metawidget.inspector.impl.BaseObjectInspectorConfig; import org.metawidget.inspector.impl.propertystyle.javabean.JavaBeanPropertyStyleConfig; import org.metawidget.inspector.impl.propertystyle.javassist.JavassistPropertyStyle; import org.metawidget.inspector.jpa.JpaInspector; import org.metawidget.inspector.propertytype.PropertyTypeInspector; import org.metawidget.swing.SwingMetawidget; import org.metawidget.swing.layout.*; import org.metawidget.swing.widgetbuilder.*; import org.metawidget.swing.widgetbuilder.swingx.SwingXWidgetBuilder; import org.metawidget.swing.widgetprocessor.binding.beansbinding.BeansBindingProcessor; import org.metawidget.swing.widgetprocessor.binding.beansbinding.BeansBindingProcessorConfig; import org.metawidget.widgetbuilder.composite.CompositeWidgetBuilder; import org.metawidget.widgetbuilder.composite.CompositeWidgetBuilderConfig; import javassist.ClassClassPath; import javassist.ClassPool; import lombok.RequiredArgsConstructor; import lombok.experimental.Builder; /** * Default config for Metawidget. * Default for SwingMetawidget is: * <ul> * <li>private field inspection</li> * <li>PropertyTypeInspector</li> * <li>JpaInspector</li> * <li>BeanValidationInspector</li> * <li>MetawidgetAnnotationInspector</li> * <li>SwingXWidgetBuilder</li> * <li>SwingWidgetBuilder</li> * <li>BeansBindingProcessor</li> * </ul> * <p/> * @author oliver.guenther */ public class MetawidgetConfig { @RequiredArgsConstructor public static class EnumConverter<T extends Enum<T>> extends Converter<T, String> { private final Class<T> enumClass; @Override public String convertForward(T anEnum) { // The enum will have been converted to its '.name' by PropertyTypeInspector when // it creates lookup values and labels. This means we must also convert the // enum to its '.name' during binding. // // The alternative to this is to have the Metawidgets deal with enums directly, but // that is less desirable because it ties the Metawidgets to a Java 5 platform return anEnum.name(); } @Override public T convertReverse(String name) { return Enum.valueOf(enumClass, name); } } /** * Enhances the default ClassPool of Javassist to work with a JavaFX Application starter. The ClassPool of javassist * is used to load the Classes in javaassist. This is used in Metawidget. This classpool will not find any classes * if called from a java fx application. So we need to give in some magic to let it work. The alogrithm works simply * * @param classes classes as reference for the classpath */ // TODO: Verify, if this is still needed in Java 8 public static void enhancedMetawidget(Class<?>... classes) { ClassPool cp = ClassPool.getDefault(); for (Class<?> clazz : classes) { cp.appendClassPath(new ClassClassPath(clazz)); } } /** * Returns a new SwingMetawidget with GG-Net defaults and optional enum clazzes beeing in use. * <p/> * @param clazzes optional enum classes to be converted. * @return a new SwingMetawidget with GG-Net defaults and optional enum clazzes beeing in use. */ public static SwingMetawidget newSwingMetaWidget(Class<? extends Enum>... clazzes) { return newSwingMetaWidget(false, 1, clazzes); } /** * Returns a new SwingMetawidget with GG-Net defaults, in a gridbagLayout, and optional enum clazzes beeing in use. * <p/> * @param clazzes optional enum classes to be converted. * @param numberOfColums the number of columns to use. Bigger than 1 activates GridBagLayoutConfig. * @param useTabbes if true, use the TabbedLayout for Sections. * @return a new SwingMetawidget with GG-Net defaults and optional enum clazzes beeing in use. */ public static SwingMetawidget newSwingMetaWidget(boolean useTabbes, int numberOfColums, Class<? extends Enum>... clazzes) { return newSwingMetaWidget(useTabbes, false, numberOfColums, null, null, clazzes); } @Builder private static SwingMetawidget newSwingMetaWidget(boolean useTabbes, boolean readOnly, int numberOfColums, AutoBinding.UpdateStrategy updateStrategy, Object inspect, Class<? extends Enum>... clazzes) { SwingMetawidget metawidget = new SwingMetawidget(); BaseObjectInspectorConfig inspectorConfig = new BaseObjectInspectorConfig() .setPropertyStyle(new JavassistPropertyStyle(new JavaBeanPropertyStyleConfig().setPrivateFieldConvention(new MessageFormat("{0}")))); metawidget.setInspector(new CompositeInspector(new CompositeInspectorConfig().setInspectors( new PropertyTypeInspector(inspectorConfig), new JpaInspector(), new BeanValidationInspector(inspectorConfig), new MetawidgetAnnotationInspector(inspectorConfig)))); if ( numberOfColums > 0 ) { if ( useTabbes ) { metawidget.setMetawidgetLayout(new TabbedPaneLayoutDecorator(new TabbedPaneLayoutDecoratorConfig().setLayout( new GridBagLayout(new GridBagLayoutConfig().setNumberOfColumns(numberOfColums))))); } else { metawidget.setMetawidgetLayout(new SeparatorLayoutDecorator(new SeparatorLayoutDecoratorConfig().setLayout( new GridBagLayout(new GridBagLayoutConfig().setNumberOfColumns(numberOfColums))))); } } CompositeWidgetBuilderConfig<JComponent, SwingMetawidget> builderConfig = new CompositeWidgetBuilderConfig<>(); builderConfig.setWidgetBuilders(new OverriddenWidgetBuilder(), new ReadOnlyWidgetBuilder(), new SwingXWidgetBuilder(), new SwingWidgetBuilder()); metawidget.setWidgetBuilder(new CompositeWidgetBuilder<>(builderConfig)); BeansBindingProcessorConfig beansBindingProcessorConfig = new BeansBindingProcessorConfig(); if ( updateStrategy != null ) beansBindingProcessorConfig.setUpdateStrategy(updateStrategy); if ( clazzes != null ) { for (Class<? extends Enum> clazz : clazzes) { beansBindingProcessorConfig.setConverter(clazz, String.class, new EnumConverter(clazz)); } } metawidget.addWidgetProcessor(new BeansBindingProcessor(beansBindingProcessorConfig)); metawidget.setReadOnly(readOnly); if ( inspect != null ) metawidget.setToInspect(inspect); return metawidget; } }