ListArea.java :  » IDE-Netbeans » etl.project » org » netbeans » modules » sql » framework » ui » graph » impl » Java Open Source

Java Open Source » IDE Netbeans » etl.project 
etl.project » org » netbeans » modules » sql » framework » ui » graph » impl » ListArea.java
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common
 * Development and Distribution License("CDDL") (collectively, the
 * "License"). You may not use this file except in compliance with the
 * License. You can obtain a copy of the License at
 * http://www.netbeans.org/cddl-gplv2.html
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
 * specific language governing permissions and limitations under the
 * License.  When distributing the software, include this License Header
 * Notice in each file and include the License file at
 * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the GPL Version 2 section of the License file that
 * accompanied this code. If applicable, add the following below the
 * License Header, with the fields enclosed by brackets [] replaced by
 * your own identifying information:
 * "Portions Copyrighted [year] [name of copyright owner]"
 *
 * Contributor(s):
 *
 * The Original Software is NetBeans. The Initial Developer of the Original
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
 * Microsystems, Inc. All Rights Reserved.
 *
 * If you wish your version of this file to be governed by only the CDDL
 * or only the GPL Version 2, indicate your decision by adding
 * "[Contributor] elects to include this software in this distribution
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
 * single choice of license, a recipient has the option to distribute
 * your version of this file under either the CDDL, the GPL Version 2 or
 * to extend the choice of license to its licensees as provided above.
 * However, if you add GPL Version 2 code and therefore, elected the GPL
 * Version 2 license, then the option applies only if the new code is
 * made subject to such option by the copyright holder.
 */

package org.netbeans.modules.sql.framework.ui.graph.impl;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.ArrayList;

import javax.swing.DefaultListModel;
import javax.swing.ListModel;
import javax.swing.event.ListDataEvent;
import javax.swing.event.ListDataListener;

import org.netbeans.modules.sql.framework.ui.graph.ListAreaCellRenderer;

import com.nwoods.jgo.JGoBrush;
import com.nwoods.jgo.JGoDrawable;
import com.nwoods.jgo.JGoObject;
import com.nwoods.jgo.JGoPen;
import com.nwoods.jgo.JGoRectangle;
import com.nwoods.jgo.JGoScrollBar;
import com.nwoods.jgo.JGoView;

/**
 * @author Ritesh Adval
 * @version $Revision$
 */
public class ListArea extends CanvasArea {

    private static final JGoPen DEFAULT_PEN = JGoPen.makeStockPen(Color.lightGray);
    
    private ListModel dataModel;

    private ListAreaCellRenderer cellRenderer;

    private ListDataAdapter listDataAdapter;

    private ArrayList cells;

    private JGoRectangle columnRect;

    private int vSpacing = 1;
    
    private JGoPen linePen = null;

    //constants for first , last visible row
    //by default set to 0 so that first row is visible
    private int firstVisibleRow = 0;
    private int lastVisibleRow = -1;
    //vertical scrollbar
    private JGoScrollBar vScrollBar;
    private int vScrollBarGap = 0;

    //this is the size of the scrollbar
    private static int scrollBarSize = 14;
    private int prefferedWidth = -1;

    private ArrayList areaList = new ArrayList();

    private boolean drawBoundingRect = true;

    private boolean drawLines = true;

    private boolean showScrollBar = true;

    /** Creates a new instance of BasicListArea */
    public ListArea() {

        listDataAdapter = new ListDataAdapter();
        if (drawBoundingRect) {
            columnRect = new JGoRectangle();
            columnRect.setSelectable(false);
            columnRect.setResizable(false);
            columnRect.setPen(JGoPen.lightGray);
            columnRect.setBrush(JGoBrush.makeStockBrush(Color.WHITE));
            addObjectAtTail(columnRect);
        }
        //add scrollbar
        vScrollBar = new JGoScrollBar();
        vScrollBar.setVertical(true);
        vScrollBar.setSelectable(false);
        addObjectAtTail(vScrollBar);

        this.setSelectable(false);
        this.setResizable(false);
        this.setDraggable(true);

        //set the insets around column
        //this.insets = new Insets(1, 5, 0, 10);

        // have a default cell renderer
        cellRenderer = new DefaultListAreaRenderer();

    }

    /**
     * create an instance of list area
     * 
     * @param listData list data values
     */
    public ListArea(Object[] listData) {
        this();

        DefaultListModel model = new DefaultListModel();

        for (int i = 0; i < listData.length; i++) {
            model.addElement(listData[i]);
        }
        setModel(model);

    }

    /**
     * set the list model
     * 
     * @param model list model
     */
    public void setModel(ListModel model) {
        ListModel oldModel = dataModel;
        this.dataModel = model;
        if (oldModel != null) {
            oldModel.removeListDataListener(listDataAdapter);
        }
        dataModel.addListDataListener(listDataAdapter);

        //by setting the model we need to also set the renderer for objects
        //in the model
        for (int i = 0; i < dataModel.getSize(); i++) {
            Object val = dataModel.getElementAt(i);
            ListAreaCellRenderer listCellRenderer = getCellRenderer(i);
            JGoObject cell = listCellRenderer.getListAreaCellRenderer(this, val, i, false, false);

            areaList.add(cell);
            this.addObjectAtTail(cell);
        }

    }

    /**
     * get the list model
     * 
     * @return list model
     */
    public ListModel getModel() {
        return dataModel;
    }

    /**
     * set the default cell renderer
     * 
     * @param cellRenderer cell renderer
     */
    public void setCellRenderer(ListAreaCellRenderer cellRenderer) {
        this.cellRenderer = cellRenderer;
    }

    /**
     * get the default cell renderer
     * 
     * @return cell renderer
     */
    public ListAreaCellRenderer getCellRenderer() {
        return cellRenderer;
    }

    /**
     * get cell renderer at an index
     * 
     * @param row row index
     * @return cell renderer
     */
    protected ListAreaCellRenderer getCellRenderer(int row) {
        return getCellRenderer();
    }

    /**
     * get the cell renderer component at an index
     * 
     * @param row row index
     * @return cell renderer
     */
    public JGoObject getCellRendererComponent(int row) {
        if ((row >= areaList.size()) || row < 0) {
            return null;
        }
        return (JGoObject) areaList.get(row);
    }

    /**
     * set whether to draw lines after each cell in this list
     * 
     * @param drawLines whether to draw lines
     */
    public void setDrawLines(boolean drawLines) {
        this.drawLines = drawLines;
    }

    /**
     * get whether list draws line after each cell
     * 
     * @return drawlines
     */
    public boolean isDrawLines() {
        return this.drawLines;
    }

    /**
     * get value at a particular point
     * 
     * @param loc location
     * @return cell value
     */
    public Object getValueAt(Point loc) {
        ListModel model = getModel();

        if (model == null) {
            return null;
        }

        for (int i = 0; i < model.getSize(); i++) {
            Object val = model.getElementAt(i);
            JGoObject renderer = getCellRendererComponent(i);
            if (renderer != null && renderer.getBoundingRect().contains(loc)) {
                return val;
            }
        }

        return null;
    }

    /**
     * get the vertical scrollbar
     * 
     * @return vertical scroll bar
     */
    public JGoScrollBar getVerticalScrollBar() {
        return vScrollBar;
    }

    /**
     * set the gap of vertical scrollbar from the edge of this area
     * 
     * @param gap gap
     */
    public void setVerticalScrollBarGapFromEdge(int gap) {
        vScrollBarGap = gap;
    }

    public void setShowScrollBar(boolean showScrollBar) {
        this.showScrollBar = showScrollBar;
    }

    public boolean isShowScrollBar() {
        return this.showScrollBar;
    }

    /**
     * since setVisible() doesn't automatically call setVisible() on all the children, we
     * need to do this manually to handle the scroll bar
     * 
     * @param bFlag boolean
     */
    public void setVisible(boolean bFlag) {
        super.setVisible(bFlag);
        if (getVerticalScrollBar() != null && isShowScrollBar()) {
            getVerticalScrollBar().setVisible(bFlag);
            if (bFlag) {
                this.addObjectAtTail(getVerticalScrollBar());
            } else {
                this.removeObject(getVerticalScrollBar());
            }
        }
    }

    /**
     * updates the vertical scroll bar
     */
    public void updateVerticalScrollBar() {
        JGoScrollBar bar = getVerticalScrollBar();
        if (bar != null) {

            if (!this.isShowScrollBar()) {
                bar.setVisible(false);
                return;
            }

            if (getFirstVisibleRow() == 0 && getLastVisibleRow() == getRowCount() - 1) {
                bar.setVisible(false);
                scrollBarSize = 0;
            } else {
                bar.setVisible(true);
                bar.setValues(getFirstVisibleRow(), getLastVisibleRow() - getFirstVisibleRow() + 1, 0, getRowCount(), 1, Math.max(getLastVisibleRow()
                    - getFirstVisibleRow(), 1));

                scrollBarSize = 14;
                //set the height so that only visible rows can be dispalced
                //this avoids extra space at the end of scroll bar
                //any parent should listen to change in child geometry
                if (this.getParent() instanceof BasicListArea) {
                    ((BasicListArea) this.getParent()).adjustHeight(this);
                }
            }
        }
    }

    /**
     * this gets the notification from the JGoScrollBar when the scroll bar value,
     * representing the first visible index, has changed
     * 
     * @param hint event hint
     * @param prevInt previous integer value
     * @param prevVal previous object value
     */
    public void update(int hint, int prevInt, Object prevVal) {
        if (hint == JGoScrollBar.ChangedScrollBarValue) {
            if (getVerticalScrollBar() != null) {
                // optimization: assume area doesn't change when scrolling items
                setFirstVisibleRow(getVerticalScrollBar().getValue());
            }
        } else {
            super.update(hint, prevInt, prevVal);
        }
    }

    /**
     * get the graph rectangle
     * 
     * @return graph rectangle
     */
    public JGoObject getRect() {
        return columnRect;
    }

    /**
     * get the number of rows in this column area
     * 
     * @return number of rows in this column
     */
    public int getRowCount() {
        if (dataModel == null) {
            return -1;
        }
        return dataModel.getSize();
    }

    /**
     * add a new cell in the column area int val value to represent in a cell
     * 
     * @param row row
     * @param val value
     */
    public void addItem(int row, Object val) {
    }

    /**
     * get the cell at an index
     * 
     * @param row row
     * @return cell area
     */
    public CellArea getCellAt(int row) {
        if (row <= cells.size() - 1) {
            return (CellArea) cells.get(row);
        }

        return null;
    }

    /**
     * set the preffered width
     * 
     * @param width preffered width
     */
    public void setPrefferedWidth(int width) {
        this.prefferedWidth = width;
    }

    /**
     * get the preffered width
     * 
     * @return preffered width
     */
    public int getPrefferedWidth() {
        return prefferedWidth;
    }

    /**
     * get maximum width of this area
     * 
     * @return max width
     */
    public int getMaximumWidth() {
        int maxWidth = getInsets().left + getInsets().right;

        int w = 0;

        for (int i = 0; i < getModel().getSize(); i++) {
            JGoObject renderer = getCellRendererComponent(i);
            if (renderer != null) {
                int rendererWidth = renderer.getWidth();
                if (w < rendererWidth) {
                    w = rendererWidth;
                }
            }
        }

        maxWidth += w;

        return maxWidth;
    }

    /**
     * get the maximum height of this area
     * 
     * @return max height
     */
    public int getMaximumHeight() {
        int maxHeight = getInsets().top + getInsets().bottom;

        for (int i = 0; i < getModel().getSize(); i++) {
            JGoObject renderer = getCellRendererComponent(i);
            if (renderer != null) {
                int rendererHeight = renderer.getHeight();
                maxHeight += rendererHeight;
                maxHeight += vSpacing;
            }
        }
        //remove one extra vspace
        maxHeight -= vSpacing;

        return maxHeight;
    }

    /**
     * get first visible row index
     * 
     * @return first visible row index
     */
    public int getFirstVisibleRow() {
        return firstVisibleRow;
    }

    /**
     * set the first visible row
     * 
     * @param rowIdx index of first visible row
     */
    public void setFirstVisibleRow(int rowIdx) {
        int oldIndex = firstVisibleRow;

        if (rowIdx >= 0 && rowIdx <= getRowCount() && oldIndex != rowIdx) {
            firstVisibleRow = rowIdx;
        }
    }

    /**
     * get the height of all visible rows in this column
     * 
     * @return height of visible rows
     */
    public int getVisibleRowHeights() {
        int rowHeights = 0;
        for (int i = this.getFirstVisibleRow(); i <= this.getLastVisibleRow(); i++) {
            JGoObject renderer = getCellRendererComponent(i);
            if (renderer != null) {
                rowHeights += renderer.getHeight() + getVerticalSpacing();
            }
        }

        rowHeights += insets.top + insets.bottom - getVerticalSpacing();

        return rowHeights;
    }

    /**
     * get the last visible row of this list area
     * 
     * @return list visible row
     */
    public int getLastVisibleRow() {
        return lastVisibleRow;
    }

    /**
     * set the last visible row
     * 
     * @param rowIdx index of first visible row
     */
    public void setLastVisibleRow(int rowIdx) {
        int oldIndex = lastVisibleRow;

        if (rowIdx >= 0 && rowIdx <= getRowCount() && oldIndex != rowIdx) {
            lastVisibleRow = rowIdx;
        }
    }

    /**
     * get the vertical spacing
     * 
     * @return vertical spacing
     */
    public int getVerticalSpacing() {
        return vSpacing;
    }

    /**
     * set the vertical spacing between cells of this list area
     * 
     * @param newspace new vertical space
     */
    public void setVerticalSpacing(int newspace) {
        int oldSpacing = vSpacing;
        if (oldSpacing != newspace) {
            vSpacing = newspace;
        }
    }

    /**
     * get the line pen
     * 
     * @return line pen
     */
    public JGoPen getLinePen() {
        return (linePen != null) ? linePen : DEFAULT_PEN;
    }

    /**
     * set line pen for drawing border
     * 
     * @param pen pen
     */
    public void setLinePen(JGoPen pen) {
        JGoPen oldPen = linePen;
        if (oldPen != pen) {
            linePen = pen;
            layoutChildren();
        }
    }

    /**
     * set the out of scroll cell bounds
     * 
     * @param rect rect
     */
    public void setOutOfScrollCellBounds(Rectangle rect) {
    }

    /**
     * paint this area
     * 
     * @param g Graphics2D
     * @param view view
     */
    public void paint(Graphics2D g, JGoView view) {
        super.paint(g, view);

        if (!drawLines) {
            return;
        }

        int penwidth = 0;
        if (getLinePen() != null) {
            penwidth = getLinePen().getWidth();
        }
        if (penwidth == 0) {
            return;
        }
        JGoObject r = getRect();
        if (r == null) {
            return; // not yet initialized
        }
        Insets insets1 = getInsets();

        int rectleft = r.getLeft();
        int recttop = r.getTop();
        int rectwidth = r.getWidth();
        int rectheight = r.getHeight();

        int top = recttop + insets1.top;
        int height = rectheight - insets1.top - insets1.bottom;

        int limit = 0;
        limit = height;

        int s = 0; // height/width of visible items so far
        for (int i = getFirstVisibleRow(); i < getLastVisibleRow(); i++) {

            JGoObject cell = this.getCellRendererComponent(i);
            int h = cell.getHeight();
            s += h;
            int sep = Math.max(penwidth, getVerticalSpacing());
            if (s + sep <= limit) {
                JGoDrawable.drawLine(g, getLinePen(), rectleft, top + s + sep / 2, rectleft + rectwidth, top + s + sep / 2);
            }
            s += sep;
        }

    }

    /**
     * layout all of this children of this column area
     */
    public void layoutChildren() {
        columnRect.setPen(getLinePen());
        
        if (drawBoundingRect) {
            columnRect.setBoundingRect(this.getBoundingRect());
        }

        //get the bounding rectangle of this column area
        int x = getLeft() + insets.left;
        int y = getTop() + insets.top;
        int width = getWidth() - insets.left - insets.right;
        int height = getHeight() - insets.top - insets.bottom;

        int oldLastVisibleRow = lastVisibleRow;

        int cellWidth = width;

        int nextCellDeltaTop = 0;

        //row count
        int cnt = 0;
        for (int i = 0; i < dataModel.getSize(); i++) {
            JGoObject cell = (JGoObject) areaList.get(i);

            if (cnt < getFirstVisibleRow()) {
                cell.setVisible(false);

                cell.setBoundingRect(x, y + nextCellDeltaTop, cellWidth, cell.getHeight());
                cnt++;
                continue;
            }

            //if cell is going out of the height of this
            //area then we mark it invisible
            //if (nextCellTop > (y + height)) {
            if (nextCellDeltaTop + cell.getHeight() > height) {

                cell.setVisible(false);
                cell.setBoundingRect(x, y + nextCellDeltaTop, cellWidth, cell.getHeight());
            } else {
                cell.setVisible(true);
                lastVisibleRow = cnt;
                cell.setBoundingRect(x, y + nextCellDeltaTop, cellWidth, cell.getHeight());
                nextCellDeltaTop += cell.getHeight() + getVerticalSpacing();

            }
            cnt++;
        }

        //layout vertical scrollbar
        JGoScrollBar sbar = getVerticalScrollBar();

        if (sbar != null) {
            sbar.setBoundingRect(x + width - scrollBarSize - vScrollBarGap, y, scrollBarSize, height);

            if (oldLastVisibleRow != lastVisibleRow) {
                updateVerticalScrollBar();
            }
        }
    }

    class ListDataAdapter implements ListDataListener {

        /**
         * Sent when the contents of the list has changed in a way that's too complex to
         * characterize with the previous methods. For example, this is sent when an item
         * has been replaced. Index0 and index1 bracket the change.
         * 
         * @param e a <code>ListDataEvent</code> encapsulating the event information
         */
        public void contentsChanged(ListDataEvent e) {
        }

        /**
         * Sent after the indices in the index0,index1 interval have been inserted in the
         * data model. The new interval includes both index0 and index1.
         * 
         * @param e a <code>ListDataEvent</code> encapsulating the event information
         */
        public void intervalAdded(ListDataEvent e) {
            //list model has new items so get renderer for them and add it
            for (int i = e.getIndex0(); i <= e.getIndex1(); i++) {
                Object val = getModel().getElementAt(i);

                ListAreaCellRenderer listCellRenderer = getCellRenderer(i);
                JGoObject cell = listCellRenderer.getListAreaCellRenderer(ListArea.this, val, i, false, false);

                //set location of the cell otherwise it will be 0 0 causing
                //width and height of listarea to start from 0,0 till current list
                //are x, y position see computeBoundingRect() for how it is calculated

                cell.setLocation(ListArea.this.getLocation());
                areaList.add(cell);
                addObjectAtTail(cell);
            }
        }

        /**
         * Sent after the indices in the index0,index1 interval have been removed from the
         * data model. The interval includes both index0 and index1.
         * 
         * @param e a <code>ListDataEvent</code> encapsulating the event information
         */
        public void intervalRemoved(ListDataEvent e) {
            //list model has some items removed so remove renderer for them
            for (int i = e.getIndex0(); i <= e.getIndex1(); i++) {
                JGoObject obj = (JGoObject) areaList.get(i);
                areaList.remove(i);
                removeObject(obj);
            }

        }

    }
}

java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.