All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.datacleaner.panels.fuse.StreamColumnListPanel 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.panels.fuse;

import java.awt.Component;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;

import org.apache.metamodel.schema.Table;
import org.apache.metamodel.util.CollectionUtils;
import org.datacleaner.actions.ReorderColumnsActionListener;
import org.datacleaner.api.InputColumn;
import org.datacleaner.job.builder.AnalysisJobBuilder;
import org.datacleaner.panels.DCPanel;
import org.datacleaner.util.IconUtils;
import org.datacleaner.util.WidgetFactory;
import org.datacleaner.util.WidgetUtils;
import org.datacleaner.widgets.DCCheckBox;
import org.datacleaner.widgets.DCLabel;
import org.jdesktop.swingx.HorizontalLayout;
import org.jdesktop.swingx.VerticalLayout;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

class StreamColumnListPanel extends DCPanel implements ReorderColumnsActionListener.ReorderColumnsCallback {

    public interface Listener {
        void onValueChanged(StreamColumnListPanel panel);
    }

    private static final long serialVersionUID = 1L;
    private static final Logger logger = LoggerFactory.getLogger(StreamColumnListPanel.class);
    private final Table _table;
    private final List _listeners;
    private final DCPanel _selectedCheckboxesPanel;
    private final DCPanel _availableCheckboxesPanel;

    private DCPanel _buttonPanelForSelected;

    public StreamColumnListPanel(final AnalysisJobBuilder rootAnalysisJobBuilder, final Table table,
            final Listener listener) {
        super();
        _table = table;
        _listeners = new ArrayList<>();
        _listeners.add(listener);

        setLayout(new VerticalLayout(0));

        _selectedCheckboxesPanel = new DCPanel();
        _selectedCheckboxesPanel.setLayout(new VerticalLayout(0));
        _selectedCheckboxesPanel.setBorder(WidgetUtils.BORDER_LIST_ITEM);
        _selectedCheckboxesPanel.setVisible(false);

        _availableCheckboxesPanel = new DCPanel();
        _availableCheckboxesPanel.setLayout(new VerticalLayout(0));

        final DCLabel streamHeader = DCLabel.dark(table.getName());
        streamHeader.setFont(WidgetUtils.FONT_SMALL.deriveFont(Font.BOLD));
        streamHeader.setBorder(WidgetUtils.BORDER_CHECKBOX_LIST_INDENTATION);
        add(streamHeader);

        final JButton reorderColumnsButton = WidgetFactory.createSmallButton(IconUtils.ACTION_REORDER_COLUMNS);
        reorderColumnsButton.setToolTipText("Reorder columns");
        reorderColumnsButton.addActionListener(new ReorderColumnsActionListener(this));

        final JButton selectAllButton = WidgetFactory.createDefaultButton("Select all");
        selectAllButton.setFont(WidgetUtils.FONT_SMALL);
        selectAllButton.addActionListener(e -> {
            for (final DCCheckBox> checkBox : getAvailableInputColumnCheckBoxes()) {
                checkBox.setSelected(true);
            }
            fireValueChanged();
        });

        final JButton selectNoneButton = WidgetFactory.createDefaultButton("Select none");
        selectNoneButton.setFont(WidgetUtils.FONT_SMALL);
        selectNoneButton.addActionListener(e -> {
            for (final DCCheckBox> checkBox : getSelectedInputColumnCheckBoxes()) {
                checkBox.setSelected(false);
            }
            fireValueChanged();
        });

        _buttonPanelForSelected = createButtonPanel();
        _buttonPanelForSelected.setVisible(false);
        _buttonPanelForSelected.add(reorderColumnsButton);
        _buttonPanelForSelected.add(selectNoneButton);

        // only show the "selected" button panel when there are any selections
        addListener(panel -> refresh());

        final DCPanel buttonPanelForAvailable = createButtonPanel();
        buttonPanelForAvailable.add(selectAllButton);

        add(_buttonPanelForSelected);
        add(_selectedCheckboxesPanel);

        add(buttonPanelForAvailable);
        add(_availableCheckboxesPanel);
    }

    public void addListener(final Listener listener) {
        _listeners.add(listener);
    }

    private void fireValueChanged() {
        for (final Listener listener : _listeners) {
            listener.onValueChanged(this);
        }
    }

    private DCPanel createButtonPanel() {
        final DCPanel buttonPanel = new DCPanel();
        buttonPanel.setLayout(new HorizontalLayout(2));
        buttonPanel.setBorder(
                new CompoundBorder(new EmptyBorder(4, 0, 0, 0), WidgetUtils.BORDER_CHECKBOX_LIST_INDENTATION));
        return buttonPanel;
    }

    protected List>> getSelectedInputColumnCheckBoxes() {
        return getInputColumnCheckBoxes(_selectedCheckboxesPanel);
    }

    protected List>> getAvailableInputColumnCheckBoxes() {
        return getInputColumnCheckBoxes(_availableCheckboxesPanel);
    }

    @SuppressWarnings("unchecked")
    private List>> getInputColumnCheckBoxes(final DCPanel panel) {
        final Component[] components = panel.getComponents();
        return CollectionUtils.map(components, component -> (DCCheckBox>) component);
    }

    public void addInputColumn(final InputColumn inputColumn, final boolean coalesced) {
        final DCCheckBox> checkBox = new DCCheckBox<>(inputColumn.getName(), coalesced);
        checkBox.addListener((item, selected) -> {
            if (selected) {
                _availableCheckboxesPanel.remove(checkBox);
                _selectedCheckboxesPanel.add(checkBox);
            } else {
                _selectedCheckboxesPanel.remove(checkBox);
                _availableCheckboxesPanel.add(checkBox);
            }
            fireValueChanged();
        });
        checkBox.setValue(inputColumn);

        if (coalesced) {
            _selectedCheckboxesPanel.add(checkBox);
        } else {
            _availableCheckboxesPanel.add(checkBox);
        }
    }

    public List> getAllInputColumns() {
        final List> result = new ArrayList<>();
        for (final DCCheckBox> checkBox : getSelectedInputColumnCheckBoxes()) {
            result.add(checkBox.getValue());
        }
        for (final DCCheckBox> checkBox : getAvailableInputColumnCheckBoxes()) {
            result.add(checkBox.getValue());
        }
        return result;
    }

    public List> getCoalescedInputColumns() {
        final List> result = new ArrayList<>();
        for (final DCCheckBox> checkBox : getSelectedInputColumnCheckBoxes()) {
            result.add(checkBox.getValue());
        }
        return result;
    }

    public Table getTable() {
        return _table;
    }

    @Override
    public InputColumn[] getColumns() {
        return getCoalescedInputColumns().toArray(new InputColumn[0]);
    }

    @Override
    public void reorderColumns(final InputColumn[] newValue) {
        final List>> selectedInputColumnCheckBoxes = getSelectedInputColumnCheckBoxes();

        _selectedCheckboxesPanel.removeAll();
        for (final InputColumn inputColumn : newValue) {
            // find the corresponding checkbox and add it
            boolean found = false;
            for (int i = 0; i < selectedInputColumnCheckBoxes.size(); i++) {
                final DCCheckBox> checkBox = selectedInputColumnCheckBoxes.get(i);
                if (checkBox.getValue().equals(inputColumn)) {
                    found = true;
                    _selectedCheckboxesPanel.add(checkBox);
                    break;
                }
            }
            if (!found) {
                logger.warn("Failed to find reordered column: {}", inputColumn);
            }
        }

        fireValueChanged();
    }

    public boolean hasSelectedInputColumns() {
        return _selectedCheckboxesPanel.getComponentCount() > 0;
    }

    public void refresh() {
        final boolean hasSelectedInputColumns = hasSelectedInputColumns();
        _buttonPanelForSelected.setVisible(hasSelectedInputColumns);
        _selectedCheckboxesPanel.setVisible(hasSelectedInputColumns);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy