com.diversityarrays.kdxplore.curate.MarkerPanelManager.java Source code

Java tutorial

Introduction

Here is the source code for com.diversityarrays.kdxplore.curate.MarkerPanelManager.java

Source

/*
KDXplore provides KDDart Data Exploration and Management
Copyright (C) 2015,2016,2017  Diversity Arrays Technology, Pty Ltd.
    
KDXplore may be redistributed and may be modified 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.
    
KDXplore 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 KDXplore.  If not, see <http://www.gnu.org/licenses/>.
*/
package com.diversityarrays.kdxplore.curate;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

import net.pearcan.ui.marker.AbstractMarkerGroup;
import net.pearcan.ui.marker.MarkerGroup;
import net.pearcan.ui.marker.MarkerMouseClickHandler;
import net.pearcan.ui.marker.MarkerPanel;

import org.apache.commons.collections15.Transformer;

import com.diversityarrays.kdsmart.db.entities.TraitInstance;
import com.diversityarrays.kdsmart.db.entities.TraitNameStyle;
import com.diversityarrays.kdsmart.db.entities.Trial;
import com.diversityarrays.kdxplore.TitledTablePanelWithResizeControls;

public class MarkerPanelManager {

    private static final String TAG = MarkerPanelManager.class.getSimpleName();

    private boolean debugGetIndexName = Boolean.getBoolean("DEBUG_MARKER_GET_INDEX_NAME");
    private boolean debugProposals = Boolean.getBoolean("DEBUG_MARKER_PROPOSALS");
    private boolean debugRightClick = Boolean.getBoolean("DEBUG_MARKER_RIGHT_CLICK");

    private class TableSelectionMarkerGroup extends AbstractMarkerGroup {

        TableSelectionMarkerGroup(JTable table, Color fill) {
            super(0 /* always before TraitInstances */, "Selection", fill, fill.darker(), USES_VIEW_INDICES);

            ListSelectionModel lsm = table.getSelectionModel();

            lsm.addListSelectionListener(new ListSelectionListener() {
                @Override
                public void valueChanged(ListSelectionEvent e) {
                    if (!e.getValueIsAdjusting()) {
                        int[] rows = table.getSelectedRows();
                        List<Integer> indices = new ArrayList<Integer>(rows.length);
                        if (rows != null) {
                            for (int r : rows) {
                                indices.add(r);
                            }
                        }
                        setMarkers(indices);
                    }
                }
            });
        }

        @Override
        public String getIndexName(Integer row) {
            String result = curationTableModel.getPlotName(row);
            return result;
        }
    }

    private class TraitInstanceMarkerGroup extends AbstractMarkerGroup {

        private final TraitInstance traitInstance;

        private Transformer<Integer, String> rowIndexToNameTransformer = new Transformer<Integer, String>() {
            @Override
            public String transform(Integer row) {
                String result = curationTableModel.getPlotName(row) + "[" + getGroupName() + "]";
                System.out.println("indexToName: " + result);
                return result;
            }
        };

        TraitInstanceMarkerGroup(TraitInstance ti, int displayOrder, String name, Color fillColor,
                Color borderColor) {
            super(displayOrder, name, fillColor, borderColor, USES_MODEL_INDICES);
            this.traitInstance = ti;

            setIndexNameTransformer(rowIndexToNameTransformer);
        }

        @Override
        public String toString() {
            return "TraitInstanceMarkerGroup: " + traitInstance.trait.getAliasOrName() + "_"
                    + traitInstance.getInstanceNumber();
        }

        @Override
        public String getIndexName(Integer row) {
            String result = "";
            if (getMarkers().contains(row)) {
                result = rowIndexToNameTransformer.transform(row);
            }
            if (debugGetIndexName) {
                System.out.println(getGroupName() + ".getIndexName=" + result);
            }
            return result;
        }

    }

    private final MarkerPanel markerPanel;

    private final List<MarkerGroup> markerGroups = new ArrayList<>();

    private final MarkerMouseClickHandler mmch = new MarkerMouseClickHandler() {

        @Override
        public void mouseClickedOn(MouseEvent me, MarkerGroup mg, List<Integer> indices, JScrollBar scrollBar,
                int proposedScrollBarValue) {
            String groupName = mg == null ? "<nogroup>" : mg.getGroupName();

            if (debugProposals) {
                StringBuilder sb = new StringBuilder(groupName);
                sb.append(" ").append(indices.size()).append(" indexes:");
                for (Integer i : indices) {
                    sb.append(' ').append(i);
                }
                sb.append(", propose=").append(proposedScrollBarValue);
                System.out.println(sb);
            }

            if (me.getClickCount() == 1) {
                if (SwingUtilities.isLeftMouseButton(me)) {
                    if (scrollBar != null && proposedScrollBarValue >= 0) {
                        scrollBar.setValue(proposedScrollBarValue);
                    }
                } else if (SwingUtilities.isRightMouseButton(me)) {
                    // perhaps support a right click menu

                    if (debugRightClick) {
                        StringBuilder sb = new StringBuilder("mouseClicked: ");
                        if (indices.isEmpty()) {
                            sb.append("No markers");
                        } else {
                            String sep = "";
                            if (indices.size() > 1) {
                                sb.append(indices.size()).append(" markers:");
                                sep = "\n";
                            }

                            if (mg == null) {
                                for (Integer row : indices) {
                                    sb.append(sep).append("row#").append(row);
                                    sep = "\n";
                                }
                            } else {
                                for (Integer row : indices) {
                                    sb.append(sep).append(mg.getIndexName(row));
                                    sep = "\n";
                                }
                            }
                        }
                        android.util.Log.d(TAG, sb.toString());
                    }
                }
            }
        }
    };

    private final PropertyChangeListener traitInstancesPropertyChangeListener = new PropertyChangeListener() {
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            if (CurationTableModel.PROPERTY_TRAIT_INSTANCES.equals(evt.getPropertyName())) {

                //            markerPanel.removeMarkerGroup(tableSelectionMarkerGroup);
                markerPanel.removeMarkerGroups(markerGroups);

                markerGroups.clear();

                List<TraitInstance> traitInstances = curationTableModel.getTraitInstances();
                if (traitInstances.isEmpty()) {
                    markerGroups.add(tableSelectionMarkerGroup);
                } else {
                    int displayOrder = 1;
                    for (TraitInstance ti : traitInstances) {
                        ++displayOrder;
                        String groupName = traitNameStyle.makeTraitInstanceName(ti);
                        Color fillColor = traitInstanceColorProvider.transform(ti);
                        Color borderColor = fillColor.darker();
                        TraitInstanceMarkerGroup timg = new TraitInstanceMarkerGroup(ti, displayOrder, groupName,
                                fillColor, borderColor);

                        markerGroups.add(timg);
                    }
                }

                markerPanel.addMarkerGroups(markerGroups);
            }
        }
    };

    private final TraitNameStyle traitNameStyle;

    @SuppressWarnings("unused")
    private final JTable table;
    private final CurationTableModel curationTableModel;

    private final Transformer<TraitInstance, Color> traitInstanceColorProvider;

    private final CurationTableSelectionModel curationTableSelectionModel;
    private final ChangeListener selectionChangeListener = new ChangeListener() {
        @Override
        public void stateChanged(ChangeEvent e) {
            if (curationTableSelectionModel == e.getSource()) {
                handleSelectionChanges();
            }
        }
    };

    private final TableSelectionMarkerGroup tableSelectionMarkerGroup;

    public MarkerPanelManager(Trial trial, CurationTableModel curationTableModel, JTable curationTable,
            TitledTablePanelWithResizeControls curationTablePanel, Transformer<TraitInstance, Color> ticp,
            CurationTableSelectionModel ctsm) {
        this.table = curationTable;
        this.curationTableModel = curationTableModel;
        this.traitInstanceColorProvider = ticp;
        this.curationTableSelectionModel = ctsm;

        traitNameStyle = trial.getTraitNameStyle();

        curationTablePanel.scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        markerPanel = new MarkerPanel(curationTablePanel.scrollPane, SwingConstants.VERTICAL);
        Component corner = curationTablePanel.scrollPane.getCorner(JScrollPane.UPPER_RIGHT_CORNER);
        if (corner != null) {
            markerPanel.setHeaderComponent(corner);
        }

        markerPanel.addMarkerMouseClickHandler(mmch);

        // Initialise the table selection marker
        Color selfill = curationTable.getSelectionBackground();

        tableSelectionMarkerGroup = new TableSelectionMarkerGroup(curationTable, selfill);
        markerGroups.add(tableSelectionMarkerGroup);
        markerPanel.addMarkerGroup(tableSelectionMarkerGroup);

        // Then amend the UI
        curationTablePanel.add(markerPanel, BorderLayout.EAST);

        curationTableModel.addPropertyChangeListener(CurationTableModel.PROPERTY_TRAIT_INSTANCES,
                traitInstancesPropertyChangeListener);

        curationTableSelectionModel.addChangeListener(selectionChangeListener);
    }

    protected void handleSelectionChanges() {
        int[] modelRows = curationTableSelectionModel.getToolSelectedModelRows();
        int[] modelCols = curationTableSelectionModel.getToolSelectedModelColumns();

        Map<TraitInstance, List<Integer>> viewRowsByTraitInstance = new HashMap<>();
        for (int modelRow : modelRows) {
            if (modelRow < 0) {
                continue; // must have been filtered out?
            }
            for (int modelColumn : modelCols) {
                // Note that these are "selected" in the tools - NOT in the table
                if (modelColumn >= 0) {
                    // ... and it is visible
                    TraitInstance ti = curationTableModel.getTraitInstanceAt(modelColumn);
                    if (ti != null) {
                        // ... and corresponds to a TraitInstance
                        List<Integer> list = viewRowsByTraitInstance.get(ti);
                        if (list == null) {
                            list = new ArrayList<>();
                            viewRowsByTraitInstance.put(ti, list);
                        }
                        list.add(modelRow);
                    }
                }
            }
        }

        for (MarkerGroup markerGroup : markerGroups) {
            if (markerGroup instanceof TraitInstanceMarkerGroup) {
                TraitInstanceMarkerGroup timg = (TraitInstanceMarkerGroup) markerGroup;
                List<Integer> tiViewRows = viewRowsByTraitInstance.get(timg.traitInstance);
                if (tiViewRows == null) {
                    markerGroup.clearMarkers();
                } else {
                    markerGroup.setMarkers(tiViewRows);
                }
            }
        }
    }
}