/*
 This file is part of the software framework JStatCom, 
 a library for building applications for data based analysis.

 Copyright (C) 2000-2005  Markus Kraetzig

 This library 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 library 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 library; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
 USA
 */

package com.jstatcom.project;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.util.Arrays;
import java.util.Comparator;

import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JOptionPane;

/**
 * Singleton list for holding output nodes. It is used as an overview of all
 * computation results that have been generated in textual form.
 * 
 * @author Markus Kraetzig 
 */
public final class OutputList extends JList {

    private boolean isOutputHistory = true;

    private static final OutputList INSTANCE = new OutputList();

    private final DefaultListModel model = new DefaultListModel();

    private boolean sortByTime = true;

    private JFrame parent = null;

    /**
     * Comparator enumeration used by this list.
     *  
     */
    private static abstract class OutputListComparators implements Comparator {

        /**
         * Compares elements by name.
         */
        public static final OutputListComparators ByNameComparator = new OutputListComparators() {

            public int compare(Object a, Object b) {
                if (!(a instanceof OutputData) || !(b instanceof OutputData))
                    throw new IllegalArgumentException(
                            "Wrong argument for OutputListComparators");

                return ((OutputData) a).name.compareTo(((OutputData) b).name);
            }
        };

        /**
         * Compares elements by time.
         */
        public static final OutputListComparators ByTimeComparator = new OutputListComparators() {

            public int compare(Object a, Object b) {
                if (!(a instanceof OutputData) || !(b instanceof OutputData))
                    throw new IllegalArgumentException(
                            "Wrong argument for OutputListComparators");

                return ((OutputData) a).date.compareTo(((OutputData) b).date);
            }
        };

        public abstract int compare(Object a, Object b);

    }

    /**
     * Adds an output element to this list. The list will remain sorted after
     * the add operation depending on the current sort mode (name/time). This
     * method does nothing if isOutputHistory returns
     * false.
     * 
     * @param dataObject
     *            holds output information
     * @throws IllegalArgumentException
     *             if (dataObject == null)
     */
    public void addOutput(OutputData dataObject) {
        if (dataObject == null)
            throw new IllegalArgumentException("Argument was null.");
        if (!isOutputHistory)
            return;
        if (sortByTime)
            model.addElement(dataObject);
        else { // add sorted by name
            boolean inserted = false;
            for (int i = 0; i < model.size(); i++) {
                Object item = model.elementAt(i);
                if (item instanceof OutputData) {
                    OutputData data = (OutputData) item;
                    int compare = data.name.compareTo(dataObject.name);
                    if (compare >= 0) {
                        if (compare == 0)
                            if (i + 1 < model.size())
                                model.add(i + 1, dataObject);
                            else
                                model.addElement(dataObject);
                        else
                            model.add(i, dataObject);
                        inserted = true;
                        break;
                    }

                }
            }
            // was not yet added
            if (!inserted)
                model.addElement(dataObject);
        }
    }

    /**
     * Removes all selected elements from this list.
     */
    public void removeSelected() {
        int index[] = getSelectedIndices();
        Arrays.sort(index);
        for (int i = index.length - 1; i >= 0; i--)
            model.remove(index[i]);
    }

    /**
     * Removes all elements from this list.
     */
    public void removeAll() {
        model.clear();
    }

    /**
     * Sorts elements while keeping the current selection.
     * 
     * @param comparator
     *            instance of Comparable to be applied for the
     *            sort operation
     */
    private void sortKeepSelection(Comparator< ? super Object> comparator) {
        Object[] listElements = new Object[model.size()];
        model.copyInto(listElements);
        // remember selection
        for (int i = 0; i < model.size(); i++)
            ((OutputData) listElements[i]).selected = isSelectedIndex(i);
        // sort elements
        Arrays.sort(listElements, comparator);
        int[] selection = getSelectedIndices();
        model.clear();
        // put elements back, get new indices of previously selected items
        for (int i = 0, k = 0; i < listElements.length; i++) {
            if (((OutputData) listElements[i]).selected)
                selection[k++] = i;
            model.addElement(listElements[i]);
        }
        // set selection again
        setSelectedIndices(selection);
    }

    /**
     * Displays all list elements by their date in ascending order. The
     * selection is kept.
     */
    public void sortByTime() {
        if (sortByTime)
            return;
        sortByTime = true;
        sortKeepSelection(OutputListComparators.ByTimeComparator);

    }

    /**
     * Displays all list elements by their name in ascending order. The
     * selection is kept.
     */
    public void sortByName() {
        if (!sortByTime)
            return;
        sortByTime = false;
        sortKeepSelection(OutputListComparators.ByNameComparator);
    }

    /**
     * Not to be invoked.
     */
    private OutputList() {
        setModel(model);
        URL url = getClass().getResource("/images/outputdata.gif");
        if (url == null)
            return;
        final Icon icon = new ImageIcon(url);

        setCellRenderer(new DefaultListCellRenderer() {

            public java.awt.Component getListCellRendererComponent(JList list,
                    Object value, int index, boolean isSelected,
                    boolean cellHasFocus) {

                setIcon(icon);

                if (isSelected) {
                    setBackground(list.getSelectionBackground());
                    setForeground(list.getSelectionForeground());
                } else {
                    setBackground(list.getBackground());
                    setForeground(list.getForeground());
                }
                setText(value.toString());

                setEnabled(list.isEnabled());
                setFont(list.getFont());
                return this;
            }
        });

        addKeyListener(new KeyAdapter() {

            public void keyPressed(KeyEvent keyEvent) {

                Object obj = keyEvent.getSource();
                if (!(obj instanceof OutputList))
                    return;
                OutputList list = (OutputList) obj;

                if (keyEvent.getKeyChar() == KeyEvent.VK_DELETE) {
                    if (JOptionPane.showConfirmDialog(parent,
                            "Remove selected output elements?",
                            "Clear Selected", JOptionPane.YES_NO_OPTION,
                            JOptionPane.QUESTION_MESSAGE) == JOptionPane.NO_OPTION) {
                        return;
                    }
                    list.removeSelected();
                }

                // Ctrl+A KeyEvent, fire selection event as well
                if (keyEvent.getKeyCode() == java.awt.event.KeyEvent.VK_A
                        && keyEvent.getModifiers() == java.awt.event.InputEvent.CTRL_MASK)
                    if (list.getModel().getSize() > 0)
                        list.setSelectedIndex(0);
            }

        });

    }

    /**
     * Gets a reference to the singleton instance of this class.
     * 
     * @return instance of OutputList
     */
    public static OutputList getInstance() {
        return INSTANCE;
    }

    /**
     * Gets whether the elements are sorted by time.
     * 
     * @return true if sorted by time, false if
     *         sorted by name
     */
    public boolean isSortByTime() {
        return sortByTime;
    }

    /**
     * Sets whether the elements are sorted by time. If true then
     * new elements are always appended to the end of the list. If this property
     * is false, then the elements are sorted by their name and
     * new elements are added accordingly.
     * 
     * @param sortByTime
     *            true if sorted by time, false if
     *            sorted by name
     */
    public void setSortByTime(boolean sortByTime) {
        this.sortByTime = sortByTime;
    }

    /**
     * Sets the parent frame that is used by modal dialogs within a frame.
     * 
     * @param parent
     *            JFrame to be used as parent
     */
    public void setParent(JFrame parent) {
        this.parent = parent;
    }

    /**
     * Gets whether output history is on. If this property is false,
     * then addOutput will have no effect. The default is
     * true.
     * 
     * @return true if on, false otherwise
     */
    public boolean isOutputHistory() {
        return isOutputHistory;
    }

    /**
     * Sets whether output history is on. If this property is false,
     * then addOutput will have no effect.
     * 
     * @param isOutputHistory
     *            true to enable output history
     */
    public void setOutputHistory(boolean isOutputHistory) {
        this.isOutputHistory = isOutputHistory;
    }
}
 
 

Ads help maintain this website.