/*
* Copyright (C) 2004 The Concord Consortium, Inc.,
* 10 Concord Crossing, Concord, MA 01742
*
* Web Site: http://www.concord.org
* Email: info@concord.org
*
* 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
*
* END LICENSE */
package org.concord.swing;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.LayoutManager;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import javax.swing.JPanel;
import javax.swing.JViewport;
import org.concord.swing.ViewEditor.SelectionHandle;
public class NullLayoutPane
extends JPanel
implements SelectableContainer
{
/**
*
*/
private static final long serialVersionUID = -3548766787761400582L;
public static final Point ORIGIN = new Point(0, 0);
protected boolean editable = false;
protected SelectionManager selectionManager;
protected Map itemMap = new HashMap();
protected List selectableItemFreeList = new Vector();
protected JPanel cover = new JPanel();
protected JViewport viewport;
protected ComponentAdapter paneListener = new ComponentAdapter()
{
public void componentMoved(ComponentEvent event)
{
setLocation(NullLayoutPane.this.getLocation());
}
public void componentResized(ComponentEvent event)
{
setSize(NullLayoutPane.this.getSize());
}
public void componentHidden(ComponentEvent event)
{
setVisible(false);
}
public void componentShown(ComponentEvent event)
{
setVisible(true);
}
};
public NullLayoutPane()
{
setLayout(null);
setOpaque(false);
cover.setOpaque(false);
setEditable(true);
}
public final void setLayout(LayoutManager manager)
{
}
protected JViewport getViewport()
{
Container parent = getParent();
while (parent != null)
{
if (parent instanceof JViewport)
return (JViewport) parent;
parent = parent.getParent();
}
return null;
}
public Point getOffset()
{
if (viewport instanceof JViewport)
return viewport.getViewPosition();
return ORIGIN;
}
public void addNotify()
{
super.addNotify();
viewport = getViewport();
Rectangle bounds = getBounds();
cover.setBounds(bounds);
}
public boolean isEditable()
{
return editable;
}
public void setEditable(boolean value)
{
editable = value;
if (editable)
{
if (selectionManager == null)
{
selectionManager = new SelectionManager();
selectionManager.setSelectableContainer(this);
}
add(cover, 0);
cover.addComponentListener(paneListener);
cover.addMouseListener(selectionManager);
cover.addMouseMotionListener(selectionManager);
}
else
{
remove(cover);
cover.removeComponentListener(paneListener);
cover.removeMouseListener(selectionManager);
cover.removeMouseMotionListener(selectionManager);
}
}
public Component add(Component item)
{
SelectableItem selectable = (SelectableItem) itemMap.get(item);
if (selectable == null)
{
if (selectableItemFreeList.isEmpty())
{
selectable = new SelectableItem(this);
}
else
{
selectable = (SelectableItem) selectableItemFreeList.get(0);
selectableItemFreeList.remove(selectable);
}
itemMap.put(item, selectable);
}
super.add(item);
selectable.setComponent(item);
repaint();
return item;
}
public void remove(Component item)
{
Selectable selectable = (Selectable) itemMap.get(item);
if (selectable != null)
{
itemMap.remove(item);
super.remove(item);
if (selectable instanceof SelectableItem)
selectableItemFreeList.add(selectable);
repaint();
}
}
protected void paintComponent(Graphics g)
{
Iterator selectables = itemMap.values().iterator();
while (selectables.hasNext())
{
SelectableItem item = (SelectableItem) selectables.next();
item.draw(g);
}
}
/* (non-Javadoc)
* @see org.concord.swing.SelectableContainer#findSelectable(int, int)
*/
public Selectable findSelectable(MouseEvent event, int x, int y)
{
Iterator selectables = itemMap.values().iterator();
while (selectables.hasNext())
{
SelectableItem item = (SelectableItem) selectables.next();
if (item.contains(x, y))
return item;
}
return null;
}
/* (non-Javadoc)
* @see org.concord.swing.Selectable#select(boolean)
*/
public void select(Selectable selectable, boolean multiple)
{
if (! multiple)
{
deselect();
}
selectable.setSelected(true);
repaint();
}
/* (non-Javadoc)
* @see org.concord.swing.SelectableContainer#deselect()
*/
public void deselect()
{
Iterator selectables = itemMap.values().iterator();
while (selectables.hasNext())
{
SelectableItem item = (SelectableItem) selectables.next();
item.setSelected(false);
}
repaint();
}
public void moveAction(int dx, int dy, Selectable selectable)
{
SelectableItem item = (SelectableItem) selectable;
SelectableItem.Boundary boundary = item.getBoundary();
if (selectable.isSelected())
{
Rectangle b = boundary.getBounds();
boundary.setLocation(b.x + dx, b.y + dy);
}
}
/* (non-Javadoc)
* @see org.concord.swing.SelectableContainer#dragAction(int, int, org.concord.swing.Selectable)
*/
public void dragAction(int dx, int dy, Selectable selectable)
{
SelectableItem item = (SelectableItem) selectable;
SelectableItem.Boundary boundary = item.getBoundary();
SelectableItem.Handle handle = boundary.getSelectedHandle();
if ((selectable != null) && (handle != null))
{
if (handle.getPosition() == SelectionHandle.DRAG)
moveAction(dx, dy, selectable);
else
handle.scale(dx, dy);
}
else
{
Iterator selectables = itemMap.values().iterator();
while (selectables.hasNext())
{
moveAction(dx, dy, (Selectable) selectables.next());
}
}
repaint();
}
/* (non-Javadoc)
* @see org.concord.swing.SelectableContainer#dragActionDone(org.concord.swing.Selectable)
*/
public void dragActionDone(Selectable selectable)
{
// TODO Auto-generated method stub
repaint();
}
public Selectable getActiveObject()
{
return selectionManager.getActiveObject();
}
}