org.ut.biolab.medsavant.client.view.list.ListView.java Source code

Java tutorial

Introduction

Here is the source code for org.ut.biolab.medsavant.client.view.list.ListView.java

Source

/**
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it under the
 * terms of the GNU Lesser General Public License as published by the Free
 * Software Foundation; either version 2.1 of the License, or (at your option)
 * any later version.
 *
 * This software 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 software; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA, or see the FSF
 * site: http://www.fsf.org.
 */
package org.ut.biolab.medsavant.client.view.list;

import com.explodingpixels.macwidgets.MacIcons;
import com.explodingpixels.macwidgets.SourceListControlBar;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import net.miginfocom.swing.MigLayout;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.ut.biolab.medsavant.client.view.login.LoginController;
import org.ut.biolab.medsavant.shared.model.ProgressStatus;
import org.ut.biolab.medsavant.client.util.ClientMiscUtils;
import org.ut.biolab.medsavant.client.util.MedSavantWorker;
import org.ut.biolab.medsavant.client.view.images.IconFactory;
import org.ut.biolab.medsavant.client.view.util.DialogUtils;
import org.ut.biolab.medsavant.client.view.util.ViewUtil;
import org.ut.biolab.medsavant.client.view.component.WaitPanel;
import org.ut.biolab.medsavant.client.view.util.list.NiceList;
import org.ut.biolab.medsavant.client.view.util.list.NiceListColorScheme;
import org.ut.biolab.medsavant.client.view.util.list.NiceListItem;

/**
 *
 * @author tarkvara
 */
public class ListView extends JPanel {

    private static final Log LOG = LogFactory.getLog(ListView.class);
    //TODO: handle limits better!
    static final int LIMIT = 10000;
    private static final String CARD_WAIT = "wait";
    private static final String CARD_SHOW = "show";
    private static final String CARD_ERROR = "error";
    private final String pageName;
    private final DetailedListModel detailedModel;
    private final DetailedView detailedView;
    private final DetailedListEditor detailedEditor;

    Object[][] data;

    private final JPanel showCard;
    private final JLabel errorMessage;

    private NiceList list;

    //private JPanel buttonPanel;
    private final SourceListControlBar controlBar;
    private boolean searchBarEnabled = false;
    private final WaitPanel wp;
    private NiceListColorScheme listColorScheme;

    public ListView(String page, DetailedListModel model, DetailedView view, DetailedListEditor editor) {
        pageName = page;
        detailedModel = model;
        detailedView = view;
        detailedEditor = editor;

        setLayout(new CardLayout());

        wp = new WaitPanel("Getting list");
        add(wp, CARD_WAIT);

        showCard = new JPanel();
        add(showCard, CARD_SHOW);

        JPanel errorPanel = new JPanel();
        errorPanel.setLayout(new BorderLayout());
        errorMessage = new JLabel("An error occurred:");
        errorPanel.add(errorMessage, BorderLayout.NORTH);

        add(errorPanel, CARD_ERROR);

        controlBar = new SourceListControlBar();

        if (detailedEditor.doesImplementAdding()) {

            controlBar.createAndAddButton(MacIcons.PLUS, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    detailedEditor.addItems();
                    if (detailedEditor.doesRefreshAfterAdding()) {
                        refreshList();
                    }
                }

            });
        }

        if (detailedEditor.doesImplementImporting()) {

            controlBar.createAndAddButton(IconFactory.getInstance().getIcon(IconFactory.StandardIcon.IMPORT),
                    new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            detailedEditor.importItems();
                            if (detailedEditor.doesImplementImporting()) {
                                refreshList();
                            }
                        }

                    });
        }

        if (detailedEditor.doesImplementExporting()) {

            controlBar.createAndAddButton(IconFactory.getInstance().getIcon(IconFactory.StandardIcon.EXPORT),
                    new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            detailedEditor.exportItems();
                            refreshList();
                        }

                    });
        }

        if (detailedEditor.doesImplementDeleting()) {

            controlBar.createAndAddButton(MacIcons.MINUS, new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    detailedEditor.deleteItems(getSelectedRows());
                    // In some cases, such as removing/publishing variants, the deleteItems() method may have logged us out.

                    if (detailedEditor.doesRefreshAfterDeleting()) {
                        refreshList();
                    }
                }

            });
        }

        if (detailedEditor.doesImplementEditing()) {

            controlBar.createAndAddButton(IconFactory.getInstance().getIcon(IconFactory.StandardIcon.GEAR),
                    new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            if (getSelectedRows().size() > 0) {
                                detailedEditor.editItem(getSelectedRows().get(0));
                                if (detailedEditor.doesRefreshAfterEditing()) {
                                    refreshList();
                                }
                            } else {
                                DialogUtils.displayMessage("Please choose one item to edit.");
                            }
                        }

                    });
        }

        // Only for SavedFiltersPanel
        if (detailedEditor.doesImplementLoading()) {

            controlBar.createAndAddButton(
                    IconFactory.getInstance().getIcon(IconFactory.StandardIcon.LOAD_ON_TOOLBAR),
                    new ActionListener() {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            detailedEditor.loadItems(getSelectedRows());
                        }

                    });

        }

        showWaitCard();
        fetchList();
    }

    public SourceListControlBar getControlBar() {
        return this.controlBar;
    }

    private List<Object[]> getSelectedRows() {
        List<NiceListItem> items = list.getSelectedItems();
        List<Object[]> selectedRows = new ArrayList<Object[]>();
        for (NiceListItem item : items) {
            selectedRows.add((Object[]) item.getItem());
        }
        return selectedRows;
    }

    private void showWaitCard() {
        //((CardLayout) getLayout()).show(this, CARD_WAIT);
    }

    private void showShowCard() {
        ((CardLayout) getLayout()).show(this, CARD_SHOW);
        this.updateUI();
    }

    private void showErrorCard(String message) {
        errorMessage.setText(String.format(
                "<html><font color=\"#ff0000\">An error occurred:<br><font size=\"-2\">%s</font></font></html>",
                message));
        ((CardLayout) getLayout()).show(this, CARD_ERROR);
    }

    private synchronized void setList(Object[][] list) {
        data = list;
        try {
            updateShowCard();
            showShowCard();
        } catch (Exception ex) {
            LOG.error("Unable to load list.", ex);
            showErrorCard(ClientMiscUtils.getMessage(ex));
        }
    }

    void refreshList() {
        showWaitCard();
        fetchList();
    }

    boolean isFetching = false;
    final Object fetch = new Object();

    private void fetchList() {

        isFetching = true;
        new MedSavantWorker<Object[][]>(pageName) {
            @Override
            protected Object[][] doInBackground() throws Exception {
                try {
                    Object[][] result = detailedModel.getList(LIMIT);
                    return result;
                } catch (Throwable t) {
                    t.printStackTrace();
                    return null;
                }
            }

            @Override
            protected void showProgress(double ignored) {
            }

            @Override
            protected void showSuccess(Object[][] result) {
                //System.out.println("Fetched new list");
                setList(result);
                isFetching = false;
                synchronized (fetch) {
                    fetch.notifyAll();
                }
                if (result.length == 0) {
                    detailedView.setSelectedItem(new Object[] {});
                }
            }

            @Override
            protected ProgressStatus checkProgress() {
                return new ProgressStatus("Working", 0.5);
            }
        }.execute();
    }

    private void updateShowCard() {
        showCard.removeAll();

        showCard.setLayout(new BorderLayout());

        String[] columnNames = detailedModel.getColumnNames();
        Class[] columnClasses = detailedModel.getColumnClasses();
        int[] columnVisibility = detailedModel.getHiddenColumns();

        int firstVisibleColumn = 0;
        while (columnVisibility.length > 0 && firstVisibleColumn == columnVisibility[firstVisibleColumn]) {
            firstVisibleColumn++;
        }

        Set<NiceListItem> selectedItems;
        if (list != null) {
            selectedItems = new HashSet<NiceListItem>(list.getSelectedItems());
        } else {
            selectedItems = new HashSet<NiceListItem>(); // empty set, for simplicity of not having to null check later on
        }

        list = new NiceList();
        if (listColorScheme != null) {
            list.setColorScheme(listColorScheme);
        }
        list.startTransaction();

        List<Integer> selectedIndicies = new ArrayList<Integer>();

        int counter = 0;
        for (Object[] row : data) {
            NiceListItem nli = new NiceListItem(row[firstVisibleColumn].toString(), row);
            list.addItem(nli);

            if (selectedItems.contains(nli)) {
                selectedIndicies.add(counter);
            }
            counter++;
        }

        /*
         int[] selectedIndiciesArray = new int[selectedIndicies.size()];
            
         System.out.println("Reselecting "  + selectedIndicies.size() + " items");
         for (int i = 0; i < selectedIndicies.size();i++) {
         System.out.println("Reselecting "  + list.getItem(selectedIndicies.get(i)).toString() + " at index " + selectedIndicies.get(i));
         selectedIndiciesArray[i] = selectedIndicies.get(i);
         }*/
        list.endTransaction();

        wp.setBackground(list.getColorScheme().getBackgroundColor());

        if (detailedView != null) {
            list.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
                @Override
                public void valueChanged(ListSelectionEvent e) {

                    if (!e.getValueIsAdjusting()) {
                        List<Object[]> selectedItems = getSelectedRows();
                        if (selectedItems.size() == 1) {
                            detailedView.setSelectedItem(selectedItems.get(0));
                        } else {
                            detailedView.setMultipleSelections(selectedItems);
                        }
                    }
                }
            });

            list.addMouseListener(new MouseAdapter() {
                @Override
                public void mousePressed(MouseEvent e) {
                    if (SwingUtilities.isRightMouseButton(e)) {
                        JPopupMenu popup = detailedView.createPopup();
                        if (popup != null) {
                            popup.show(e.getComponent(), e.getX(), e.getY());
                        }
                    }
                }
            });
        }

        if (selectedIndicies.isEmpty()) {
            list.selectItemAtIndex(0);
        } else {
            list.selectItemsAtIndicies(selectedIndicies);
        }

        JScrollPane jsp = ViewUtil.getClearBorderlessScrollPane(list);
        jsp.setHorizontalScrollBar(null);

        JPanel topPanel = new JPanel();
        topPanel.setLayout(new MigLayout("wrap, fillx"));

        topPanel.add(ViewUtil.getEmphasizedLabel(pageName.toUpperCase()));
        topPanel.setBackground(list.getColorScheme().getBackgroundColor());

        if (searchBarEnabled) {
            topPanel.add(list.getSearchBar(), "growx 1.0");
        }
        showCard.add(topPanel, BorderLayout.NORTH);

        showCard.add(jsp, BorderLayout.CENTER);

        showCard.add(controlBar.getComponent(), BorderLayout.SOUTH);

    }

    public void setSearchBarEnabled(boolean b) {
        searchBarEnabled = b;
    }

    void selectItemWithKey(final String key) {

        System.out.println("Selecting item with key " + key);

        new Thread(new Runnable() {

            @Override
            public void run() {
                if (isFetching) {
                    try {
                        synchronized (fetch) {
                            fetch.wait();
                        }
                    } catch (InterruptedException ex) {
                    }
                }
                list.selectItemWithKey(key);
            }

        }).start();
    }

    void selectItemAtIndex(final int i) {
        //System.out.println("Selecting item at index " + i);
        new Thread(new Runnable() {

            @Override
            public void run() {
                if (isFetching) {
                    try {
                        synchronized (fetch) {
                            fetch.wait();
                        }
                    } catch (InterruptedException ex) {
                    }
                }
                list.selectItemAtIndex(i);
            }

        }).start();

    }

    public void setSelectedItemText(String text) {
        NiceListItem item = list.getSelectedItems().get(0);
        item.setLabel(text);
        list.updateUI();
    }

    void setColorScheme(NiceListColorScheme cs) {
        listColorScheme = cs;
        if (list != null) {
            updateShowCard();
        }
    }
}