package org.openswing.swing.pivottable.client;
import javax.swing.*;
import java.awt.dnd.*;
import java.awt.Toolkit;
import org.openswing.swing.util.client.ClientUtils;
import org.openswing.swing.util.client.ClientSettings;
import java.awt.Point;
import java.awt.Cursor;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.DataFlavor;
import java.util.ArrayList;
/**
* <p>Title: OpenSwing Framework</p>
* <p>Description: Draggable button used within pivot table.</p>
* <p>Copyright: Copyright (C) 2006 Mauro Carniel</p>
*
* <p> This file is part of OpenSwing Framework.
* This library is free software; you can redistribute it and/or
* modify it under the terms of the (LGPL) Lesser General Public
* License as published by the Free Software Foundation;
*
* GNU LESSER GENERAL PUBLIC LICENSE
* Version 2.1, February 1999
*
* 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* The author may be contacted at:
* maurocarniel@tin.it</p>
*
* @author Mauro Carniel
* @version 1.0
*/
public class DraggableButton extends JPanel implements DragSourceListener, DropTargetListener {
/** drag source */
private DragSource dragSource = new DragSource();
/** panel identifier, used for DnD */
private String panelId = null;
/** drop gestures */
private DropTarget dropTarget = null;
/** cursor to show on dragging */
private Cursor dragCursor = null;
/** component position */
private int pos;
/** list of DraggableButtonListener elements */
private ArrayList draggableButtonListeners = new ArrayList();
public DraggableButton(String panelId,int pos) {
this.panelId = panelId;
this.pos = pos;
try {
dragSource.createDefaultDragGestureRecognizer(
this,
DnDConstants.ACTION_MOVE,
new DragGestureAdapter(this)
);
dropTarget = new DropTarget(this, this);
dragCursor = Toolkit.getDefaultToolkit().createCustomCursor(
ClientUtils.getImage("column.gif"),
new Point(15, 10),
ClientSettings.getInstance().getResources().getResource("drag")
);
}
catch (Exception ex) {
ex.printStackTrace();
}
}
public final void addDraggableButtonListener(DraggableButtonListener listener) {
draggableButtonListeners.add(listener);
}
public final void removeDraggableButtonListener(DraggableButtonListener listener) {
draggableButtonListeners.remove(listener);
}
/********************************************************************
*
* DRAG 'N DROP MANAGEMENTS METHODS
*
********************************************************************/
/************************************************************
* DRAG MANAGEMENT
************************************************************/
class DragGestureAdapter implements DragGestureListener {
private DragSourceListener dragListener = null;
public DragGestureAdapter(DragSourceListener dragListener) {
this.dragListener = dragListener;
}
/**
* A drag gesture has been initiated.
*/
public final void dragGestureRecognized( DragGestureEvent event) {
setCursor(dragCursor);
try {
dragSource.startDrag(event, DragSource.DefaultMoveDrop,
new StringSelection(panelId + "_" + pos),
dragListener);
}
catch (InvalidDnDOperationException ex) {
}
}
}
/**
* This message goes to DragSourceListener, informing it that the dragging has entered the DropSite
*/
public final void dragEnter (DragSourceDragEvent event) {
setCursor(Cursor.getDefaultCursor());
}
/**
* This message goes to DragSourceListener, informing it that the dragging has exited the DropSite.
*/
public final void dragExit (DragSourceEvent event) {
setCursor(Cursor.getDefaultCursor());
}
/**
* This message goes to DragSourceListener, informing it that the dragging is currently ocurring over the DropSite.
*/
public final void dragOver (DragSourceDragEvent event) {
setCursor(dragCursor);
}
/**
* This method is invoked when the user changes the dropAction.
*/
public final void dropActionChanged ( DragSourceDragEvent event) { }
/**
* This message goes to DragSourceListener, informing it that the dragging has ended.
*/
public final void dragDropEnd (DragSourceDropEvent event) {
}
/************************************************************
* DROP MANAGEMENT
************************************************************/
/**
* This method is invoked when you are dragging over the DropSite.
*/
public final void dragEnter (DropTargetDragEvent event) {
event.acceptDrag (DnDConstants.ACTION_MOVE);
}
/**
* This method is invoked when you are exit the DropSite without dropping.
*/
public final void dragExit (DropTargetEvent event) {
}
/**
* This method is invoked when a drag operation is going on.
*/
public final void dragOver (DropTargetDragEvent event) {
}
/**
* This method is invoked when a drop event has occurred.
*/
public final void drop(DropTargetDropEvent event) {
try {
setCursor(Cursor.getDefaultCursor());
Transferable transferable = event.getTransferable();
if (transferable.isDataFlavorSupported (DataFlavor.stringFlavor)){
String id = (String)transferable.getTransferData ( DataFlavor.stringFlavor);
if (id!=null && id.startsWith(panelId)) {
event.acceptDrop(DnDConstants.ACTION_MOVE);
event.getDropTargetContext().dropComplete(true);
String[] tokens = id.split("_");
int draggedCompPos = Integer.parseInt(tokens[tokens.length-1]);
// System.out.println("draggedCompPos:"+draggedCompPos+" pos:"+pos);
if (draggedCompPos!=pos) {
DraggableButtonEvent e = new DraggableButtonEvent(
panelId,
draggedCompPos,
pos
);
for(int i=0;i<draggableButtonListeners.size();i++)
((DraggableButtonListener)draggableButtonListeners.get(i)).dragEventFired(e);
}
}
else
event.rejectDrop();
} else{
event.rejectDrop();
}
}
catch (Exception ex) {
ex.printStackTrace();
event.rejectDrop();
} finally {
try {
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
catch (Exception ex) {
}
}
}
/**
* This method is invoked if the use modifies the current drop gesture.
*/
public final void dropActionChanged ( DropTargetDragEvent event ) {
}
}