org.datacleaner.widgets.properties.MultipleMappedStringsPropertyWidget Maven / Gradle / Ivy
/**
* DataCleaner (community edition)
* Copyright (C) 2014 Free Software Foundation, Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package org.datacleaner.widgets.properties;
import java.awt.BorderLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.WeakHashMap;
import javax.swing.JComponent;
import javax.swing.event.DocumentEvent;
import org.datacleaner.api.InputColumn;
import org.datacleaner.descriptors.ConfiguredPropertyDescriptor;
import org.datacleaner.job.builder.ComponentBuilder;
import org.datacleaner.panels.DCPanel;
import org.datacleaner.util.DCDocumentListener;
import org.datacleaner.util.StringUtils;
import org.datacleaner.util.WidgetFactory;
import org.datacleaner.widgets.DCCheckBox;
import org.jdesktop.swingx.JXTextField;
/**
* A specialized property widget for multiple input columns that are mapped to
* string values. This widget looks like the
* {@link MultipleInputColumnsPropertyWidget}, but is enhanced with string text
* fields.
*/
public class MultipleMappedStringsPropertyWidget extends MultipleInputColumnsPropertyWidget {
public class MappedStringsPropertyWidget extends MinimalPropertyWidget {
public MappedStringsPropertyWidget(final ComponentBuilder componentBuilder,
final ConfiguredPropertyDescriptor propertyDescriptor) {
super(componentBuilder, propertyDescriptor);
}
@Override
public JComponent getWidget() {
// do not return a visual widget
return null;
}
@Override
public boolean isSet() {
return MultipleMappedStringsPropertyWidget.this.isSet();
}
@Override
public String[] getValue() {
return getMappedStrings();
}
@Override
protected void setValue(final String[] value) {
if (MultipleMappedStringsPropertyWidget.this.isUpdating()) {
return;
}
setMappedStrings(value);
}
}
private final WeakHashMap, JXTextField> _mappedTextFields;
private final ConfiguredPropertyDescriptor _mappedStringsProperty;
private final MappedStringsPropertyWidget _mappedStringsPropertyWidget;
/**
* Constructs the property widget
*
* @param componentBuilder
* the component builder for the table lookup
* @param inputColumnsProperty
* the property representing the columns to use for setting up
* conditional lookup (InputColumn[])
* @param mappedStringsProperty
* the property representing the mapped strings (String[])
*/
public MultipleMappedStringsPropertyWidget(final ComponentBuilder componentBuilder,
final ConfiguredPropertyDescriptor inputColumnsProperty,
final ConfiguredPropertyDescriptor mappedStringsProperty) {
super(componentBuilder, inputColumnsProperty);
_mappedTextFields = new WeakHashMap<>();
_mappedStringsProperty = mappedStringsProperty;
_mappedStringsPropertyWidget = new MappedStringsPropertyWidget(componentBuilder, mappedStringsProperty);
final InputColumn>[] currentValue = getCurrentValue();
final String[] currentMappedStringsValue =
(String[]) componentBuilder.getConfiguredProperty(mappedStringsProperty);
if (currentValue != null && currentMappedStringsValue != null) {
// first create combo's, then set value (so combo is ready before it
// is requested)
_mappedStringsPropertyWidget.setValue(currentMappedStringsValue);
final int minLength = Math.min(currentValue.length, currentMappedStringsValue.length);
for (int i = 0; i < minLength; i++) {
final InputColumn> inputColumn = currentValue[i];
final String mappedString = currentMappedStringsValue[i];
createTextField(inputColumn, mappedString);
}
setValue(currentValue);
}
}
@Override
protected boolean isAllInputColumnsSelectedIfNoValueExist() {
return false;
}
private JXTextField createTextField(final InputColumn> inputColumn, String mappedString) {
final JXTextField textField = WidgetFactory.createTextField();
_mappedTextFields.put(inputColumn, textField);
if (mappedString == null) {
mappedString = getDefaultMappedString(inputColumn);
}
if (mappedString != null) {
textField.setText(mappedString);
}
textField.getDocument().addDocumentListener(new DCDocumentListener() {
@Override
protected void onChange(final DocumentEvent event) {
if (isBatchUpdating()) {
return;
}
fireValueChanged();
_mappedStringsPropertyWidget.fireValueChanged();
}
});
return textField;
}
/**
* Subclasses can override this method to set a default value for a column
* when it is selected.
*
* @param inputColumn
* @return
*/
protected String getDefaultMappedString(final InputColumn> inputColumn) {
return "";
}
@Override
protected JComponent decorateCheckBox(final DCCheckBox> checkBox) {
final JXTextField textField;
if (_mappedTextFields.containsKey(checkBox.getValue())) {
textField = _mappedTextFields.get(checkBox.getValue());
} else {
textField = createTextField(checkBox.getValue(), null);
}
checkBox.addListenerToHead((item, selected) -> {
textField.setVisible(selected);
updateUI();
});
checkBox.addListener(new DCCheckBox.Listener>() {
@Override
public void onItemSelected(InputColumn> item, boolean selected) {
if (isBatchUpdating()) {
return;
}
_mappedStringsPropertyWidget.fireValueChanged();
}
});
textField.setVisible(checkBox.isSelected());
final DCPanel panel = new DCPanel();
panel.setLayout(new BorderLayout());
panel.add(checkBox, BorderLayout.CENTER);
panel.add(textField, BorderLayout.EAST);
return panel;
}
public ConfiguredPropertyDescriptor getMappedStringsProperty() {
return _mappedStringsProperty;
}
public MappedStringsPropertyWidget getMappedStringsPropertyWidget() {
return _mappedStringsPropertyWidget;
}
@Override
public InputColumn>[] getValue() {
final InputColumn>[] checkedInputColumns = super.getValue();
final List> result = new ArrayList<>();
for (final InputColumn> inputColumn : checkedInputColumns) {
// exclude input columns that have not been mapped yet
final JXTextField textField = _mappedTextFields.get(inputColumn);
if (textField != null && textField.isVisible()) {
if (!StringUtils.isNullOrEmpty(textField.getText())) {
result.add(inputColumn);
}
}
}
return result.toArray(new InputColumn[result.size()]);
}
public String[] getMappedStrings() {
final List> inputColumns = MultipleMappedStringsPropertyWidget.this.getSelectedInputColumns();
final List result = new ArrayList<>();
for (final InputColumn> inputColumn : inputColumns) {
final JXTextField textField = _mappedTextFields.get(inputColumn);
if (textField == null) {
result.add(null);
} else {
final String value = textField.getText();
result.add(value);
}
}
return result.toArray(new String[result.size()]);
}
public void setMappedStrings(final String[] value) {
final List> inputColumns = MultipleMappedStringsPropertyWidget.this.getSelectedInputColumns();
for (int i = 0; i < inputColumns.size(); i++) {
final InputColumn> inputColumn = inputColumns.get(i);
final String mappedString;
if (value == null) {
mappedString = getDefaultMappedString(inputColumn);
} else if (i < value.length) {
mappedString = value[i];
} else {
mappedString = getDefaultMappedString(inputColumn);
}
final JXTextField textField = _mappedTextFields.get(inputColumn);
textField.setVisible(true);
final String previousText = textField.getText();
if (!mappedString.equals(previousText)) {
textField.setText(mappedString);
}
}
}
@Override
protected void onValuesBatchSelected(final List> values) {
for (final JXTextField textField : _mappedTextFields.values()) {
textField.setVisible(false);
}
for (final InputColumn> inputColumn : values) {
final JXTextField textField = _mappedTextFields.get(inputColumn);
if (textField != null) {
textField.setVisible(true);
}
}
}
@Override
protected void onBatchFinished() {
super.onBatchFinished();
_mappedStringsPropertyWidget.fireValueChanged();
}
}