org.rdv.ui.DataPanelContainer.java Source code

Java tutorial

Introduction

Here is the source code for org.rdv.ui.DataPanelContainer.java

Source

/*
 * RDV
 * Real-time Data Viewer
 * http://rdv.googlecode.com/
 * 
 * Copyright (c) 2005-2007 University at Buffalo
 * Copyright (c) 2005-2007 NEES Cyberinfrastructure Center
 * Copyright (c) 2008 Palta Software
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * $URL$
 * $Revision$
 * $Date$
 * $Author$
 */

package org.rdv.ui;

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.datatransfer.StringSelection;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DragGestureEvent;
import java.awt.dnd.DragGestureListener;
import java.awt.dnd.DragGestureRecognizer;
import java.awt.dnd.DragSource;
import java.awt.dnd.DragSourceDragEvent;
import java.awt.dnd.DragSourceDropEvent;
import java.awt.dnd.DragSourceEvent;
import java.awt.dnd.DragSourceListener;
import java.util.ArrayList;
import java.util.HashMap;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;

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

/**
 * A container to hold the UI components for the data panels. They may add and
 * remove UI components as needed.
 * 
 * @author  Jason P. Hanley
 * @since   1.1
 */
public class DataPanelContainer extends JPanel implements DragGestureListener, DragSourceListener {

    /** serialization version identifier */
    private static final long serialVersionUID = -2496258563984574021L;

    /**
     * The logger for this class.
     * 
     * @since  1.1
     */
    static Log log = LogFactory.getLog(DataPanelContainer.class.getName());

    /**
     * A list of docked UI components.
     * 
     * @since  1.1
     */
    ArrayList<Component> dataPanels;

    /**
     * Display the data panels horizontally.
     * 
     * @since  1.1
     */
    public static int HORIZONTAL_LAYOUT = 0;

    /**
     * Display the data panels vertically.
     * 
     * @since  1.1
     */
    public static int VERTICAL_LAYOUT = 1;

    /**
     * The current layout.
     * 
     * @since  1.1
     */
    private int layout;

    /**
     * The layout manager.
     * 
     * @since  1.3
     */
    private GridLayout gridLayout;

    /**
     * The drag gesture recognizers for the components.
     * 
     * @since  1.3
     */
    private HashMap<Component, DragGestureRecognizer> dragGestures;

    /**
     * The position of components that were in this container.
     */
    private HashMap<JComponent, Integer> previousPositions;

    /** 
     * Create the container and set the default layout to horizontal.
     * 
     * @since  1.1
     */
    public DataPanelContainer() {
        super();

        setBorder(null);

        gridLayout = new GridLayout(1, 1, 8, 8);
        setLayout(gridLayout);

        initLogo();

        dataPanels = new ArrayList<Component>();
        dragGestures = new HashMap<Component, DragGestureRecognizer>();

        layout = HORIZONTAL_LAYOUT;

        previousPositions = new HashMap<JComponent, Integer>();
    }

    /**
     * Add the NEESit and UB logo as the initial background.
     */
    private void initLogo() {
        JLabel backgroundImage = new JLabel(DataViewer.getIcon("icons/neesitandub.gif"));
        backgroundImage.setPreferredSize(new Dimension(1, 1));
        backgroundImage.setMinimumSize(new Dimension(1, 1));
        add(backgroundImage);
    }

    /**
     * Add a data panel UI component to this container.
     * 
     * @param component  the UI component to add
     * @since            1.1
     */
    public void addDataPanel(JComponent component) {
        Integer position = previousPositions.get(component);
        if (position == null || position < 0 || position > dataPanels.size()) {
            dataPanels.add(component);
        } else {
            dataPanels.add(position, component);
        }

        DragSource dragSource = DragSource.getDefaultDragSource();
        DragGestureRecognizer dragGesture = dragSource.createDefaultDragGestureRecognizer(component,
                DnDConstants.ACTION_MOVE, this);
        dragGestures.put(component, dragGesture);

        layoutDataPanels();

        log.info("Added data panel to container (total=" + dataPanels.size() + ").");
    }

    /**
     * Remove the data panel UI component from this container.
     * 
     * @param component  the UI component to remove.
     * @since            1.1
     */
    public void removeDataPanel(JComponent component) {
        DragGestureRecognizer dragGesture = (DragGestureRecognizer) dragGestures.remove(component);
        dragGesture.setComponent(null);

        previousPositions.put(component, new Integer(dataPanels.indexOf(component)));

        dataPanels.remove(component);
        layoutDataPanels();

        log.info("Removed data panel container (total=" + dataPanels.size() + ").");
    }

    /**
     * Set the layout for the data panels.
     * 
     * @param layout  the layout to use
     * @since         1.1
     */
    public void setLayout(int layout) {
        if (this.layout != layout) {
            this.layout = layout;
            layoutDataPanels();
        }
    }

    /**
     * Layout the data panel acording the layout setting and in the order in which
     * they were added to the container.
     * 
     * @since  1.1
     */
    private void layoutDataPanels() {
        int numberOfDataPanels = dataPanels.size();
        if (numberOfDataPanels > 0) {
            int gridDimension = (int) Math.ceil(Math.sqrt(numberOfDataPanels));
            int rows = gridDimension;

            int columns;
            if (numberOfDataPanels > Math.pow(gridDimension, 2) * (gridDimension - 1) / gridDimension) {
                columns = gridDimension;
            } else {
                columns = gridDimension - 1;
            }

            if (layout == HORIZONTAL_LAYOUT) {
                gridLayout.setRows(columns);
                gridLayout.setColumns(rows);
            } else {
                gridLayout.setRows(rows);
                gridLayout.setColumns(columns);
            }
        }

        removeAll();
        JComponent component;
        for (int i = 0; i < numberOfDataPanels; i++) {
            component = (JComponent) dataPanels.get(i);
            add(component);
        }

        validate();
        repaint();
    }

    private void moveBefore(Component moveComponent, Component beforeComponent) {
        int beforeComponentIndex = getComponentIndex(beforeComponent);
        if (beforeComponentIndex != -1) {
            dataPanels.remove(moveComponent);
            dataPanels.add(beforeComponentIndex, moveComponent);
            layoutDataPanels();
        }
    }

    private int getComponentIndex(Component c) {
        for (int i = 0; i < dataPanels.size(); i++) {
            Component component = (Component) dataPanels.get(i);
            if (c == component) {
                return i;
            }
        }
        return -1;
    }

    public void dragGestureRecognized(DragGestureEvent e) {
        e.startDrag(DragSource.DefaultMoveDrop, new StringSelection(""), this);
    }

    public void dragEnter(DragSourceDragEvent e) {
    }

    public void dragOver(DragSourceDragEvent e) {
        Point dragPoint = e.getLocation();
        Point containerLocation = getLocationOnScreen();
        dragPoint.translate(-containerLocation.x, -containerLocation.y);

        Component overComponent = getComponentAt(dragPoint);
        Component dragComponent = e.getDragSourceContext().getComponent();

        if (overComponent != null && overComponent != dragComponent) {
            moveBefore(dragComponent, overComponent);
        }
    }

    public void dropActionChanged(DragSourceDragEvent dsde) {
    }

    public void dragExit(DragSourceEvent dse) {
    }

    public void dragDropEnd(DragSourceDropEvent dsde) {
    }
}