Changeset 3138


Ignore:
Timestamp:
02/04/12 22:30:55 (4 months ago)
Author:
kasper
Message:

Ticket #754: Fixed UI support for "Select from Map" transformer.

Files:
6 edited

Legend:

Unmodified
Added
Removed
  • AnalyzerBeans/trunk/core/src/main/java/org/eobjects/analyzer/beans/datastructures/SelectFromMapTransformer.java

    r3118 r3138  
    2020package org.eobjects.analyzer.beans.datastructures; 
    2121 
     22import java.util.Arrays; 
    2223import java.util.Map; 
    2324 
     
    8182        @Override 
    8283        public OutputColumns getOutputColumns() { 
     84                String[] keys = this.keys; 
     85                Class<?>[] types = this.types; 
     86                if (keys.length != types.length) { 
     87                        // odd case sometimes encountered with invalid configurations or 
     88                        // while building a job 
     89                        final int length = Math.min(keys.length, types.length); 
     90                        keys = Arrays.copyOf(keys, length); 
     91                        types = Arrays.copyOf(types, length); 
     92                } 
    8393                return new OutputColumns(keys, types); 
    8494        } 
  • DataCleaner/trunk/core/src/main/java/org/eobjects/datacleaner/panels/datastructures/KeysAndTypesPropertyWidget.java

    r3136 r3138  
    2525 
    2626import javax.swing.JComponent; 
     27import javax.swing.SwingUtilities; 
    2728import javax.swing.event.DocumentEvent; 
    2829 
     
    3031import org.eobjects.analyzer.descriptors.ConfiguredPropertyDescriptor; 
    3132import org.eobjects.analyzer.job.builder.AbstractBeanJobBuilder; 
     33import org.eobjects.analyzer.util.StringUtils; 
    3234import org.eobjects.datacleaner.panels.DCPanel; 
    3335import org.eobjects.datacleaner.util.DCDocumentListener; 
     
    4951        private final ConfiguredPropertyDescriptor _typesProperty; 
    5052        private final List<DCComboBox<Class<?>>> _comboBoxes; 
    51         private final MinimalPropertyWidget<Class<?>[]> _typesPropertyWidget; 
    52  
     53 
     54        @SuppressWarnings("rawtypes") 
     55        private final MinimalPropertyWidget<Class[]> _typesPropertyWidget; 
     56 
     57        @SuppressWarnings("rawtypes") 
    5358        public KeysAndTypesPropertyWidget( 
    5459                        ConfiguredPropertyDescriptor keysProperty, 
     
    5863                _comboBoxes = new ArrayList<DCComboBox<Class<?>>>(); 
    5964                _typesProperty = typesProperty; 
    60                 _typesPropertyWidget = new MinimalPropertyWidget<Class<?>[]>( 
     65                _typesPropertyWidget = new MinimalPropertyWidget<Class[]>( 
    6166                                getBeanJobBuilder(), _typesProperty) { 
    6267 
     
    6772 
    6873                        @Override 
    69                         public Class<?>[] getValue() { 
     74                        public Class[] getValue() { 
    7075                                final String[] keys = KeysAndTypesPropertyWidget.this 
    7176                                                .getValue(); 
    72                                 final Class<?>[] result = new Class<?>[keys.length]; 
    73                                 for (int i = 0; i < result.length; i++) { 
    74                                         final DCComboBox<Class<?>> comboBox = _comboBoxes.get(i); 
    75                                         result[i] = comboBox.getSelectedItem(); 
    76                                 } 
    77                                 return result; 
     77                                final List<Class<?>> result = new ArrayList<Class<?>>(); 
     78                                for (int i = 0; i < keys.length; i++) { 
     79                                        if (!StringUtils.isNullOrEmpty(keys[i])) { 
     80                                                final DCComboBox<Class<?>> comboBox = _comboBoxes 
     81                                                                .get(i); 
     82                                                result.add(comboBox.getSelectedItem()); 
     83                                        } 
     84                                } 
     85                                return result.toArray(new Class[result.size()]); 
    7886                        } 
    7987 
     
    92100 
    93101                        @Override 
    94                         protected void setValue(Class<?>[] value) { 
     102                        protected void setValue(Class[] value) { 
    95103                                if (EqualsBuilder.equals(value, getValue())) { 
    96104                                        return; 
     
    116124                }; 
    117125 
    118                 // TODO: Initialize value 
    119         } 
    120  
    121         @Override 
    122         protected JComponent decorateTextField(JXTextField textField) { 
     126                final String[] currentKeysValue = getCurrentValue(); 
     127                final Class[] currentTypesValue = (Class[]) beanJobBuilder 
     128                                .getConfiguredProperty(typesProperty); 
     129                if (currentTypesValue != null) { 
     130                        // first create textfields, then set keys value 
     131 
     132                        for (int i = 0; i < currentTypesValue.length; i++) { 
     133                                final Class<?> type = currentTypesValue[i]; 
     134                                createComboBox(type); 
     135                        } 
     136 
     137                        setValue(currentKeysValue); 
     138                        _typesPropertyWidget.onValueTouched(currentTypesValue); 
     139                } 
     140        } 
     141 
     142        private DCComboBox<Class<?>> createComboBox(Class<?> type) { 
    123143                final DCComboBox<Class<?>> comboBox = SingleClassPropertyWidget 
    124144                                .createClassComboBox(true); 
     145                if (type != null) { 
     146                        comboBox.setSelectedItem(type); 
     147                } 
     148                _comboBoxes.add(comboBox); 
     149                return comboBox; 
     150        } 
     151 
     152        @Override 
     153        protected JComponent decorateTextField(JXTextField textField, int index) { 
     154                final DCComboBox<Class<?>> comboBox; 
     155 
     156                if (index < _comboBoxes.size()) { 
     157                        comboBox = _comboBoxes.get(index); 
     158                } else { 
     159                        comboBox = createComboBox(null); 
     160                } 
     161 
    125162                comboBox.addListener(new Listener<Class<?>>() { 
    126163                        @Override 
     
    133170                        @Override 
    134171                        protected void onChange(DocumentEvent event) { 
    135                                 _typesPropertyWidget.fireValueChanged(); 
     172                                // invoke later, because document events are fired before the 
     173                                // textfield.getText() returns the new value 
     174                                SwingUtilities.invokeLater(new Runnable() { 
     175                                        @Override 
     176                                        public void run() { 
     177                                                setUpdating(true); 
     178                                                _typesPropertyWidget.fireValueChanged(); 
     179                                                setUpdating(false); 
     180                                        } 
     181                                }); 
    136182                        } 
    137183                }); 
    138  
    139                 _comboBoxes.add(comboBox); 
    140184 
    141185                final DCPanel panel = new DCPanel(); 
  • DataCleaner/trunk/core/src/main/java/org/eobjects/datacleaner/widgets/properties/MinimalPropertyWidget.java

    r2843 r3138  
    3131 *  
    3232 * @author Kasper SÞrensen 
    33  * 
     33 *  
    3434 * @param <E> 
    3535 */ 
    3636public abstract class MinimalPropertyWidget<E> implements PropertyWidget<E> { 
    3737 
    38         private static final Logger logger = LoggerFactory.getLogger(AbstractPropertyWidget.class); 
     38        private static final Logger logger = LoggerFactory 
     39                        .getLogger(AbstractPropertyWidget.class); 
    3940 
    4041        private final AbstractBeanJobBuilder<?, ?, ?> _beanJobBuilder; 
    4142        private final ConfiguredPropertyDescriptor _propertyDescriptor; 
    4243 
    43         public MinimalPropertyWidget(AbstractBeanJobBuilder<?, ?, ?> beanJobBuilder, 
     44        private transient volatile int _updating; 
     45 
     46        public MinimalPropertyWidget( 
     47                        AbstractBeanJobBuilder<?, ?, ?> beanJobBuilder, 
    4448                        ConfiguredPropertyDescriptor propertyDescriptor) { 
    4549                _beanJobBuilder = beanJobBuilder; 
    4650                _propertyDescriptor = propertyDescriptor; 
     51                _updating = 0; 
    4752        } 
    4853 
     
    7681        @Override 
    7782        public void onValueTouched(E value) { 
     83                if (isUpdating()) { 
     84                        // prevent update loops from a widget's own configuration change 
     85                        // notification 
     86                        return; 
     87                } 
    7888                E existingValue = getValue(); 
    7989                if (EqualsBuilder.equals(value, existingValue)) { 
     
    8191                } 
    8292                setValue(value); 
     93        } 
     94 
     95        /** 
     96         * Determines whether a property widget is currently updating/setting it's 
     97         * property value. When true, this property will not treat incoming 
     98         * notifications, since they will be triggered by itself. 
     99         *  
     100         * @return 
     101         */ 
     102        protected boolean isUpdating() { 
     103                return _updating == 0; 
     104        } 
     105 
     106        /** 
     107         * Provides a method for setting the "updating" flag (see 
     108         * {@link #isUpdating()}). 
     109         *  
     110         * @param updating 
     111         */ 
     112        protected void setUpdating(boolean updating) { 
     113                if (updating) { 
     114                        _updating++; 
     115                } else { 
     116                        assert _updating > 0; 
     117                        _updating--; 
     118                } 
    83119        } 
    84120 
     
    90126        @SuppressWarnings("unchecked") 
    91127        protected E getCurrentValue() { 
    92                 return (E) getBeanJobBuilder().getConfiguredProperty(getPropertyDescriptor()); 
     128                return (E) getBeanJobBuilder().getConfiguredProperty( 
     129                                getPropertyDescriptor()); 
    93130        } 
    94131 
     
    96133 
    97134        protected final void fireValueChanged(Object newValue) { 
     135                setUpdating(true); 
    98136                try { 
    99                         _beanJobBuilder.setConfiguredProperty(_propertyDescriptor, newValue); 
     137                        _beanJobBuilder 
     138                                        .setConfiguredProperty(_propertyDescriptor, newValue); 
    100139                } catch (Exception e) { 
    101140                        // an exception will be thrown here if setting an invalid property 
     
    103142                        // fuzz about it) 
    104143                        if (logger.isWarnEnabled()) { 
    105                                 logger.warn("Exception thrown when setting configured property " + _propertyDescriptor, e); 
     144                                logger.warn( 
     145                                                "Exception thrown when setting configured property " 
     146                                                                + _propertyDescriptor, e); 
    106147                        } 
     148                } finally { 
     149                        setUpdating(false); 
    107150                } 
    108151        } 
  • DataCleaner/trunk/core/src/main/java/org/eobjects/datacleaner/widgets/properties/MultipleStringPropertyWidget.java

    r3136 r3138  
    2424import java.awt.event.ActionEvent; 
    2525import java.awt.event.ActionListener; 
     26import java.util.ArrayList; 
    2627import java.util.IdentityHashMap; 
     28import java.util.List; 
    2729import java.util.Map; 
    2830 
     
    161163                }); 
    162164 
    163                 JComponent decoration = decorateTextField(textField); 
     165                final int index = _textFieldPanel.getComponentCount(); 
     166                final JComponent decoration = decorateTextField(textField, index); 
    164167                _textFieldDecorations.put(decoration, textField); 
    165168 
     
    170173        } 
    171174 
    172         protected JComponent decorateTextField(JXTextField textField) { 
     175        protected JComponent decorateTextField(JXTextField textField, int index) { 
    173176                return textField; 
    174177        } 
     
    177180        public String[] getValue() { 
    178181                Component[] components = _textFieldPanel.getComponents(); 
    179                 String[] result = new String[components.length]; 
     182                List<String> result = new ArrayList<String>(); 
    180183                for (int i = 0; i < components.length; i++) { 
    181                         Component decoration = components[i]; 
    182                         JXTextField textField = _textFieldDecorations.get(decoration); 
    183                         result[i] = textField.getText(); 
    184                 } 
    185                 return result; 
     184                        final Component decoration = components[i]; 
     185                        final JXTextField textField = _textFieldDecorations.get(decoration); 
     186                        final String text = textField.getText(); 
     187                        if (isEmptyStringValid() || text.length() != 0) { 
     188                                result.add(text); 
     189                        } 
     190                } 
     191                return result.toArray(new String[result.size()]); 
    186192        } 
    187193 
  • DataCleaner/trunk/core/src/main/java/org/eobjects/datacleaner/widgets/properties/PropertyWidgetFactory.java

    r3099 r3138  
    202202         */ 
    203203        public void onConfigurationChanged() { 
    204                 Collection<PropertyWidget<?>> widgets = getWidgets(); 
     204                final Collection<PropertyWidget<?>> widgets = getWidgets(); 
    205205 
    206206                for (PropertyWidget<?> widget : widgets) { 
    207207                        @SuppressWarnings("unchecked") 
    208                         PropertyWidget<Object> objectWidget = (PropertyWidget<Object>) widget; 
    209                         Object value = _beanJobBuilder.getConfiguredProperty(objectWidget.getPropertyDescriptor()); 
     208                        final PropertyWidget<Object> objectWidget = (PropertyWidget<Object>) widget; 
     209                        final ConfiguredPropertyDescriptor propertyDescriptor = objectWidget.getPropertyDescriptor(); 
     210                        final Object value = _beanJobBuilder.getConfiguredProperty(propertyDescriptor); 
    210211                        objectWidget.onValueTouched(value); 
    211212                } 
  • DataCleaner/trunk/core/src/main/java/org/eobjects/datacleaner/widgets/properties/SingleFilePropertyWidget.java

    r2941 r3138  
    4040import org.eobjects.datacleaner.widgets.FilenameTextField; 
    4141 
    42 public final class SingleFilePropertyWidget extends AbstractPropertyWidget<File> { 
     42public final class SingleFilePropertyWidget extends 
     43                AbstractPropertyWidget<File> { 
    4344 
    4445        private final FilenameTextField _filenameField; 
     
    4647 
    4748        @Inject 
    48         public SingleFilePropertyWidget(ConfiguredPropertyDescriptor propertyDescriptor, 
    49                         AbstractBeanJobBuilder<?, ?, ?> beanJobBuilder, UserPreferences userPreferences) { 
     49        public SingleFilePropertyWidget( 
     50                        ConfiguredPropertyDescriptor propertyDescriptor, 
     51                        AbstractBeanJobBuilder<?, ?, ?> beanJobBuilder, 
     52                        UserPreferences userPreferences) { 
    5053                super(beanJobBuilder, propertyDescriptor); 
    5154                _userPreferences = userPreferences; 
     
    5457                String[] extensions = null; 
    5558 
    56                 FileProperty fileProperty = propertyDescriptor.getAnnotation(FileProperty.class); 
     59                FileProperty fileProperty = propertyDescriptor 
     60                                .getAnnotation(FileProperty.class); 
    5761                if (fileProperty != null) { 
    5862                        openFileDialog = fileProperty.accessMode() == FileAccessMode.OPEN; 
     
    6165                } 
    6266 
    63                 _filenameField = new FilenameTextField(_userPreferences.getConfiguredFileDirectory(), openFileDialog); 
     67                _filenameField = new FilenameTextField( 
     68                                _userPreferences.getConfiguredFileDirectory(), openFileDialog); 
    6469 
    6570                if (extensions != null && extensions.length > 0) { 
    66                         List<FileFilter> filters = new ArrayList<FileFilter>(extensions.length); 
     71                        List<FileFilter> filters = new ArrayList<FileFilter>( 
     72                                        extensions.length); 
    6773                        for (String extension : extensions) { 
    68                                 FileFilter filter = new ExtensionFilter(extension.toUpperCase() + " file", "." + extension); 
     74                                FileFilter filter = new ExtensionFilter(extension.toUpperCase() 
     75                                                + " file", "." + extension); 
    6976                                filters.add(filter); 
    7077                                _filenameField.addChoosableFileFilter(filter); 
     
    7380                                _filenameField.setSelectedFileFilter(filters.get(0)); 
    7481                        } else { 
    75                                 FileFilter filter = FileFilters.combined("All suggested file formats", 
     82                                FileFilter filter = FileFilters.combined( 
     83                                                "All suggested file formats", 
    7684                                                filters.toArray(new FileFilter[filters.size()])); 
    7785                                _filenameField.setSelectedFileFilter(filter); 
     
    8694                } 
    8795 
    88                 _filenameField.getTextField().getDocument().addDocumentListener(new DCDocumentListener() { 
     96                _filenameField.getTextField().getDocument() 
     97                                .addDocumentListener(new DCDocumentListener() { 
    8998 
    90                         @Override 
    91                         protected void onChange(DocumentEvent e) { 
    92                                 fireValueChanged(); 
    93                         } 
    94                 }); 
     99                                        @Override 
     100                                        protected void onChange(DocumentEvent e) { 
     101                                                fireValueChanged(); 
     102                                        } 
     103                                }); 
    95104 
    96105                _filenameField.addFileSelectionListener(new FileSelectionListener() { 
    97106                        @Override 
    98                         public void onSelected(FilenameTextField filenameTextField, File file) { 
     107                        public void onSelected(FilenameTextField filenameTextField, 
     108                                        File file) { 
    99109                                File dir = file.getParentFile(); 
    100110                                _userPreferences.setConfiguredFileDirectory(dir); 
     
    104114 
    105115                add(_filenameField); 
     116        } 
     117 
     118        @Override 
     119        public boolean isSet() { 
     120                return _filenameField.getFile() != null; 
    106121        } 
    107122 
     
    128143 
    129144                File existingFile = _filenameField.getFile(); 
    130                 if (existingFile != null && existingFile.getAbsoluteFile().equals(value.getAbsoluteFile())) { 
     145                if (existingFile != null 
     146                                && existingFile.getAbsoluteFile().equals( 
     147                                                value.getAbsoluteFile())) { 
    131148                        return; 
    132149                } 
Note: See TracChangeset for help on using the changeset viewer.