# HG changeset patch
# User nolith
# Date 1181571338 -7200
# Branch trunk
# Node ID 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93
# Parent 01ea204f838e41341c40d9090346aad06584a8ae
[svn] Added a very simple an incomplete GUI
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 .project
--- a/.project Mon Jun 11 00:09:04 2007 +0200
+++ b/.project Mon Jun 11 16:15:38 2007 +0200
@@ -12,6 +12,8 @@
+ org.eclipse.jem.workbench.JavaEMFNatureorg.eclipse.jdt.core.javanature
+ org.eclipse.jem.beaninfo.BeanInfoNature
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 README
--- a/README Mon Jun 11 00:09:04 2007 +0200
+++ b/README Mon Jun 11 16:15:38 2007 +0200
@@ -1,3 +1,8 @@
Before starting remember to downaload dependencies libs
- ant download_deps
\ No newline at end of file
+ ant download_deps
+
+This code uses java6 System.console class
+to compile with java5 use
+
+ ant -Djava6=false
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 build.xml
--- a/build.xml Mon Jun 11 00:09:04 2007 +0200
+++ b/build.xml Mon Jun 11 16:15:38 2007 +0200
@@ -4,12 +4,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -25,10 +40,10 @@
just one file at a time.
-->
-
+ source="${source.version}">
@@ -61,6 +76,16 @@
-->
+
+
+
+
+
+
+
+
+
+
@@ -71,6 +96,7 @@
classpath="${build}"
maxmemory="500m">
+
+
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/net/iharder/dnd/DnDList.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/iharder/dnd/DnDList.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,239 @@
+package net.iharder.dnd;
+
+/**
+ * An extension of {@link javax.swing.JList} that supports drag and drop
+ * to rearrange its contents and to move objects in and out of the list.
+ * The objects in the list will be passed either as a String by calling
+ * the object's toString() object, or if your drag and drop target
+ * accepts the {@link TransferableObject#DATA_FLAVOR} data flavor then
+ * the actual object will be passed.
+ *
+ *
I'm releasing this code into the Public Domain. Enjoy.
+ *
+ *
Original author: Robert Harder, rharder@usa.net
+ *
+ * @author Robert Harder
+ * @author rharder@usa.net
+ * @version 1.1
+ */
+public class DnDList
+extends javax.swing.JList
+implements java.awt.dnd.DropTargetListener,
+ java.awt.dnd.DragSourceListener,
+ java.awt.dnd.DragGestureListener
+{
+
+ private java.awt.dnd.DropTarget dropTarget = null;
+
+ private java.awt.dnd.DragSource dragSource = null;
+
+ private int sourceIndex = -1;
+ private int dropIndex = -1;
+ private Object sourceObject;
+
+
+ /**
+ * Constructs a default {@link DnDList} using a
+ * {@link javax.swing.DefaultListModel}.
+ *
+ * @since 1.1
+ */
+ public DnDList()
+ {
+ super( new javax.swing.DefaultListModel() );
+ initComponents();
+ } // end constructor
+
+
+
+ /**
+ * Constructs a {@link DnDList} using the
+ * passed list model that must be extended from
+ * {@link javax.swing.DefaultListModel}.
+ *
+ * @param model The model to use
+ * @since 1.1
+ */
+ public DnDList( javax.swing.DefaultListModel model )
+ { super( model );
+ initComponents();
+ } // end constructor
+
+
+
+ /**
+ * Constructs a {@link DnDList} by
+ * filling in a {@link javax.swing.DefaultListModel}
+ * with the passed array of objects.
+ *
+ * @param data The data from which to construct a list
+ * @since 1.1
+ */
+ public DnDList( Object[] data )
+ { this();
+ ((javax.swing.DefaultListModel)getModel()).copyInto( data );
+ } // end constructor
+
+
+
+
+ /**
+ * Constructs a {@link DnDList} by
+ * filling in a {@link javax.swing.DefaultListModel}
+ * with the passed {@link java.util.Vector} of objects.
+ *
+ * @param data The data from which to construct a list
+ * @since 1.1
+ */
+ public DnDList( java.util.Vector data )
+ { this();
+ ((javax.swing.DefaultListModel)getModel()).copyInto( data.toArray() );
+ } // end constructor
+
+
+
+ private void initComponents()
+ {
+ dropTarget = new java.awt.dnd.DropTarget (this, this);
+ dragSource = new java.awt.dnd.DragSource();
+ dragSource.createDefaultDragGestureRecognizer( this, java.awt.dnd.DnDConstants.ACTION_MOVE, this);
+ } // end initComponents
+
+
+/* ******** D R A G G E S T U R E L I S T E N E R M E T H O D S ******** */
+
+
+
+
+ public void dragGestureRecognized( java.awt.dnd.DragGestureEvent event)
+ { //System.out.println( "DragGestureListener.dragGestureRecognized" );
+ final Object selected = getSelectedValue();
+ if ( selected != null )
+ {
+ sourceIndex = getSelectedIndex();
+ java.awt.datatransfer.Transferable transfer = new TransferableObject( new TransferableObject.Fetcher()
+ { /**
+ * This will be called when the transfer data is requested at the very end.
+ * At this point we can remove the object from its original place in the list.
+ */
+ public Object getObject()
+ {
+ ((javax.swing.DefaultListModel)getModel()).remove( sourceIndex );
+ return selected;
+ } // end getObject
+ }); // end fetcher
+
+ // as the name suggests, starts the dragging
+ dragSource.startDrag (event, java.awt.dnd.DragSource.DefaultLinkDrop, transfer, this);
+ }
+ else
+ {
+ //System.out.println( "nothing was selected");
+ }
+ } // end dragGestureRecognized
+
+
+/* ******** D R A G S O U R C E L I S T E N E R M E T H O D S ******** */
+
+
+ public void dragDropEnd( java.awt.dnd.DragSourceDropEvent evt )
+ { //System.out.println( "DragSourceListener.dragDropEnd" );
+ } // end dragDropEnd
+
+
+ public void dragEnter( java.awt.dnd.DragSourceDragEvent evt )
+ { //System.out.println( "DragSourceListener.dragEnter" );
+ } // end dragEnter
+
+
+ public void dragExit( java.awt.dnd.DragSourceEvent evt )
+ { //System.out.println( "DragSourceListener.dragExit" );
+ } // end dragExit
+
+
+ public void dragOver( java.awt.dnd.DragSourceDragEvent evt )
+ { //System.out.println( "DragSourceListener.dragOver" );
+ } // end dragOver
+
+
+ public void dropActionChanged( java.awt.dnd.DragSourceDragEvent evt )
+ { //System.out.println( "DragSourceListener.dropActionChanged" );
+ } // end dropActionChanged
+
+
+
+/* ******** D R O P T A R G E T L I S T E N E R M E T H O D S ******** */
+
+
+
+ public void dragEnter( java.awt.dnd.DropTargetDragEvent evt )
+ { //System.out.println( "DropTargetListener.dragEnter" );
+ evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_MOVE);
+ } // end dragEnter
+
+ public void dragExit( java.awt.dnd.DropTargetEvent evt )
+ { //System.out.println( "DropTargetListener.dragExit" );
+ } // end dragExit
+
+ public void dragOver( java.awt.dnd.DropTargetDragEvent evt )
+ { //System.out.println( "DropTargetListener.dragOver" );
+ } // end dragOver
+
+ public void dropActionChanged( java.awt.dnd.DropTargetDragEvent evt )
+ { //System.out.println( "DropTargetListener.dropActionChanged" );
+ evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_MOVE);
+ } // end dropActionChanged
+
+
+
+ public void drop( java.awt.dnd.DropTargetDropEvent evt )
+ { //System.out.println( "DropTargetListener.drop" );
+ java.awt.datatransfer.Transferable transferable = evt.getTransferable();
+
+ // If it's our native TransferableObject, use that
+ if( transferable.isDataFlavorSupported( TransferableObject.DATA_FLAVOR ) )
+ {
+ evt.acceptDrop( java.awt.dnd.DnDConstants.ACTION_MOVE );
+ Object obj = null;
+ try
+ {
+ obj = transferable.getTransferData( TransferableObject.DATA_FLAVOR );
+ } // end try
+ catch( java.awt.datatransfer.UnsupportedFlavorException e )
+ { e.printStackTrace();
+ } // end catch
+ catch( java.io.IOException e )
+ { e.printStackTrace();
+ } // end catch
+
+ if( obj != null )
+ {
+ // See where in the list we dropped the element.
+ int dropIndex = locationToIndex( evt.getLocation() );
+ javax.swing.DefaultListModel model = (javax.swing.DefaultListModel)getModel();
+
+ if( dropIndex < 0 )
+ model.addElement( obj );
+
+ // Else is it moving down the list?
+ else if( sourceIndex >= 0 && dropIndex > sourceIndex )
+ model.add( dropIndex-1, obj );
+ else
+ model.add( dropIndex, obj );
+
+ } // end if: we got the object
+
+ // Else there was a problem getting the object
+ else
+ {
+ evt.rejectDrop();
+ } // end else: can't get the object
+ } // end if: it's a native TransferableObject
+
+ // Else we can't handle this
+ else evt.rejectDrop();
+ } // end drop
+
+
+
+} // end class DnDList
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/net/iharder/dnd/FileDrop.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/iharder/dnd/FileDrop.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,595 @@
+package net.iharder.dnd;
+
+/**
+ * This class makes it easy to drag and drop files from the operating
+ * system to a Java program. Any java.awt.Component can be
+ * dropped onto, but only javax.swing.JComponents will indicate
+ * the drop event with a changed border.
+ *
+ * To use this class, construct a new FileDrop by passing
+ * it the target component and a Listener to receive notification
+ * when file(s) have been dropped. Here is an example:
+ *
+ *
+ * JPanel myPanel = new JPanel();
+ * new FileDrop( myPanel, new FileDrop.Listener()
+ * { public void filesDropped( java.io.File[] files )
+ * {
+ * // handle file drop
+ * ...
+ * } // end filesDropped
+ * }); // end FileDrop.Listener
+ *
+ *
+ * You can specify the border that will appear when files are being dragged by
+ * calling the constructor with a javax.swing.border.Border. Only
+ * JComponents will show any indication with a border.
+ *
+ * You can turn on some debugging features by passing a PrintStream
+ * object (such as System.out) into the full constructor. A null
+ * value will result in no extra debugging information being output.
+ *
+ *
+ *
I'm releasing this code into the Public Domain. Enjoy.
+ *
+ *
Original author: Robert Harder, rharder@usa.net
+ *
+ * @author Robert Harder
+ * @author rharder@usa.net
+ * @version 1.0
+ */
+public class FileDrop
+{
+ private transient javax.swing.border.Border normalBorder;
+ private transient java.awt.dnd.DropTargetListener dropListener;
+
+
+ /** Discover if the running JVM is modern enough to have drag and drop. */
+ private static Boolean supportsDnD;
+
+ // Default border color
+ private static java.awt.Color defaultBorderColor = new java.awt.Color( 0f, 0f, 1f, 0.25f );
+
+ /**
+ * Constructs a {@link FileDrop} with a default light-blue border
+ * and, if c is a {@link java.awt.Container}, recursively
+ * sets all elements contained within as drop targets, though only
+ * the top level container will change borders.
+ *
+ * @param c Component on which files will be dropped.
+ * @param listener Listens for filesDropped.
+ * @since 1.0
+ */
+ public FileDrop(
+ final java.awt.Component c,
+ final Listener listener )
+ { this( null, // Logging stream
+ c, // Drop target
+ javax.swing.BorderFactory.createMatteBorder( 2, 2, 2, 2, defaultBorderColor ), // Drag border
+ true, // Recursive
+ listener );
+ } // end constructor
+
+
+
+
+ /**
+ * Constructor with a default border and the option to recursively set drop targets.
+ * If your component is a java.awt.Container, then each of its children
+ * components will also listen for drops, though only the parent will change borders.
+ *
+ * @param c Component on which files will be dropped.
+ * @param recursive Recursively set children as drop targets.
+ * @param listener Listens for filesDropped.
+ * @since 1.0
+ */
+ public FileDrop(
+ final java.awt.Component c,
+ final boolean recursive,
+ final Listener listener )
+ { this( null, // Logging stream
+ c, // Drop target
+ javax.swing.BorderFactory.createMatteBorder( 2, 2, 2, 2, defaultBorderColor ), // Drag border
+ recursive, // Recursive
+ listener );
+ } // end constructor
+
+
+ /**
+ * Constructor with a default border and debugging optionally turned on.
+ * With Debugging turned on, more status messages will be displayed to
+ * out. A common way to use this constructor is with
+ * System.out or System.err. A null value for
+ * the parameter out will result in no debugging output.
+ *
+ * @param out PrintStream to record debugging info or null for no debugging.
+ * @param out
+ * @param c Component on which files will be dropped.
+ * @param listener Listens for filesDropped.
+ * @since 1.0
+ */
+ public FileDrop(
+ final java.io.PrintStream out,
+ final java.awt.Component c,
+ final Listener listener )
+ { this( out, // Logging stream
+ c, // Drop target
+ javax.swing.BorderFactory.createMatteBorder( 2, 2, 2, 2, defaultBorderColor ),
+ false, // Recursive
+ listener );
+ } // end constructor
+
+
+
+ /**
+ * Constructor with a default border, debugging optionally turned on
+ * and the option to recursively set drop targets.
+ * If your component is a java.awt.Container, then each of its children
+ * components will also listen for drops, though only the parent will change borders.
+ * With Debugging turned on, more status messages will be displayed to
+ * out. A common way to use this constructor is with
+ * System.out or System.err. A null value for
+ * the parameter out will result in no debugging output.
+ *
+ * @param out PrintStream to record debugging info or null for no debugging.
+ * @param out
+ * @param c Component on which files will be dropped.
+ * @param recursive Recursively set children as drop targets.
+ * @param listener Listens for filesDropped.
+ * @since 1.0
+ */
+ public FileDrop(
+ final java.io.PrintStream out,
+ final java.awt.Component c,
+ final boolean recursive,
+ final Listener listener)
+ { this( out, // Logging stream
+ c, // Drop target
+ javax.swing.BorderFactory.createMatteBorder( 2, 2, 2, 2, defaultBorderColor ), // Drag border
+ recursive, // Recursive
+ listener );
+ } // end constructor
+
+
+
+
+ /**
+ * Constructor with a specified border
+ *
+ * @param c Component on which files will be dropped.
+ * @param dragBorder Border to use on JComponent when dragging occurs.
+ * @param listener Listens for filesDropped.
+ * @since 1.0
+ */
+ public FileDrop(
+ final java.awt.Component c,
+ final javax.swing.border.Border dragBorder,
+ final Listener listener)
+ { this(
+ null, // Logging stream
+ c, // Drop target
+ dragBorder, // Drag border
+ false, // Recursive
+ listener );
+ } // end constructor
+
+
+
+
+ /**
+ * Constructor with a specified border and the option to recursively set drop targets.
+ * If your component is a java.awt.Container, then each of its children
+ * components will also listen for drops, though only the parent will change borders.
+ *
+ * @param c Component on which files will be dropped.
+ * @param dragBorder Border to use on JComponent when dragging occurs.
+ * @param recursive Recursively set children as drop targets.
+ * @param listener Listens for filesDropped.
+ * @since 1.0
+ */
+ public FileDrop(
+ final java.awt.Component c,
+ final javax.swing.border.Border dragBorder,
+ final boolean recursive,
+ final Listener listener)
+ { this(
+ null,
+ c,
+ dragBorder,
+ recursive,
+ listener );
+ } // end constructor
+
+
+
+ /**
+ * Constructor with a specified border and debugging optionally turned on.
+ * With Debugging turned on, more status messages will be displayed to
+ * out. A common way to use this constructor is with
+ * System.out or System.err. A null value for
+ * the parameter out will result in no debugging output.
+ *
+ * @param out PrintStream to record debugging info or null for no debugging.
+ * @param c Component on which files will be dropped.
+ * @param dragBorder Border to use on JComponent when dragging occurs.
+ * @param listener Listens for filesDropped.
+ * @since 1.0
+ */
+ public FileDrop(
+ final java.io.PrintStream out,
+ final java.awt.Component c,
+ final javax.swing.border.Border dragBorder,
+ final Listener listener)
+ { this(
+ out, // Logging stream
+ c, // Drop target
+ dragBorder, // Drag border
+ false, // Recursive
+ listener );
+ } // end constructor
+
+
+
+
+
+ /**
+ * Full constructor with a specified border and debugging optionally turned on.
+ * With Debugging turned on, more status messages will be displayed to
+ * out. A common way to use this constructor is with
+ * System.out or System.err. A null value for
+ * the parameter out will result in no debugging output.
+ *
+ * @param out PrintStream to record debugging info or null for no debugging.
+ * @param c Component on which files will be dropped.
+ * @param dragBorder Border to use on JComponent when dragging occurs.
+ * @param recursive Recursively set children as drop targets.
+ * @param listener Listens for filesDropped.
+ * @since 1.0
+ */
+ public FileDrop(
+ final java.io.PrintStream out,
+ final java.awt.Component c,
+ final javax.swing.border.Border dragBorder,
+ final boolean recursive,
+ final Listener listener)
+ {
+
+ if( supportsDnD() )
+ { // Make a drop listener
+ dropListener = new java.awt.dnd.DropTargetListener()
+ { public void dragEnter( java.awt.dnd.DropTargetDragEvent evt )
+ { log( out, "FileDrop: dragEnter event." );
+
+ // Is this an acceptable drag event?
+ if( isDragOk( out, evt ) )
+ {
+ // If it's a Swing component, set its border
+ if( c instanceof javax.swing.JComponent )
+ { javax.swing.JComponent jc = (javax.swing.JComponent) c;
+ normalBorder = jc.getBorder();
+ log( out, "FileDrop: normal border saved." );
+ jc.setBorder( dragBorder );
+ log( out, "FileDrop: drag border set." );
+ } // end if: JComponent
+
+ // Acknowledge that it's okay to enter
+ //evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
+ evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY );
+ log( out, "FileDrop: event accepted." );
+ } // end if: drag ok
+ else
+ { // Reject the drag event
+ evt.rejectDrag();
+ log( out, "FileDrop: event rejected." );
+ } // end else: drag not ok
+ } // end dragEnter
+
+ public void dragOver( java.awt.dnd.DropTargetDragEvent evt )
+ { // This is called continually as long as the mouse is
+ // over the drag target.
+ } // end dragOver
+
+ public void drop( java.awt.dnd.DropTargetDropEvent evt )
+ { log( out, "FileDrop: drop event." );
+ try
+ { // Get whatever was dropped
+ java.awt.datatransfer.Transferable tr = evt.getTransferable();
+
+ // Is it a file list?
+ if (tr.isDataFlavorSupported (java.awt.datatransfer.DataFlavor.javaFileListFlavor))
+ {
+ // Say we'll take it.
+ //evt.acceptDrop ( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
+ evt.acceptDrop ( java.awt.dnd.DnDConstants.ACTION_COPY );
+ log( out, "FileDrop: file list accepted." );
+
+ // Get a useful list
+ java.util.List fileList = (java.util.List)
+ tr.getTransferData(java.awt.datatransfer.DataFlavor.javaFileListFlavor);
+ java.util.Iterator iterator = fileList.iterator();
+
+ // Convert list to array
+ java.io.File[] filesTemp = new java.io.File[ fileList.size() ];
+ fileList.toArray( filesTemp );
+ final java.io.File[] files = filesTemp;
+
+ // Alert listener to drop.
+ if( listener != null )
+ listener.filesDropped( files );
+
+ // Mark that drop is completed.
+ evt.getDropTargetContext().dropComplete(true);
+ log( out, "FileDrop: drop complete." );
+ } // end if: file list
+ else
+ { log( out, "FileDrop: not a file list - abort." );
+ evt.rejectDrop();
+ } // end else: not a file list
+ } // end try
+ catch ( java.io.IOException io)
+ { log( out, "FileDrop: IOException - abort:" );
+ io.printStackTrace( out );
+ evt.rejectDrop();
+ } // end catch IOException
+ catch (java.awt.datatransfer.UnsupportedFlavorException ufe)
+ { log( out, "FileDrop: UnsupportedFlavorException - abort:" );
+ ufe.printStackTrace( out );
+ evt.rejectDrop();
+ } // end catch: UnsupportedFlavorException
+ finally
+ {
+ // If it's a Swing component, reset its border
+ if( c instanceof javax.swing.JComponent )
+ { javax.swing.JComponent jc = (javax.swing.JComponent) c;
+ jc.setBorder( normalBorder );
+ log( out, "FileDrop: normal border restored." );
+ } // end if: JComponent
+ } // end finally
+ } // end drop
+
+ public void dragExit( java.awt.dnd.DropTargetEvent evt )
+ { log( out, "FileDrop: dragExit event." );
+ // If it's a Swing component, reset its border
+ if( c instanceof javax.swing.JComponent )
+ { javax.swing.JComponent jc = (javax.swing.JComponent) c;
+ jc.setBorder( normalBorder );
+ log( out, "FileDrop: normal border restored." );
+ } // end if: JComponent
+ } // end dragExit
+
+ public void dropActionChanged( java.awt.dnd.DropTargetDragEvent evt )
+ { log( out, "FileDrop: dropActionChanged event." );
+ // Is this an acceptable drag event?
+ if( isDragOk( out, evt ) )
+ { //evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY_OR_MOVE );
+ evt.acceptDrag( java.awt.dnd.DnDConstants.ACTION_COPY );
+ log( out, "FileDrop: event accepted." );
+ } // end if: drag ok
+ else
+ { evt.rejectDrag();
+ log( out, "FileDrop: event rejected." );
+ } // end else: drag not ok
+ } // end dropActionChanged
+ }; // end DropTargetListener
+
+ // Make the component (and possibly children) drop targets
+ makeDropTarget( out, c, recursive );
+ } // end if: supports dnd
+ else
+ { log( out, "FileDrop: Drag and drop is not supported with this JVM" );
+ } // end else: does not support DnD
+ } // end constructor
+
+
+ private static boolean supportsDnD()
+ { // Static Boolean
+ if( supportsDnD == null )
+ {
+ boolean support = false;
+ try
+ { Class arbitraryDndClass = Class.forName( "java.awt.dnd.DnDConstants" );
+ support = true;
+ } // end try
+ catch( Exception e )
+ { support = false;
+ } // end catch
+ supportsDnD = new Boolean( support );
+ } // end if: first time through
+ return supportsDnD.booleanValue();
+ } // end supportsDnD
+
+
+
+
+
+ private void makeDropTarget( final java.io.PrintStream out, final java.awt.Component c, boolean recursive )
+ {
+ // Make drop target
+ final java.awt.dnd.DropTarget dt = new java.awt.dnd.DropTarget();
+ try
+ { dt.addDropTargetListener( dropListener );
+ } // end try
+ catch( java.util.TooManyListenersException e )
+ { e.printStackTrace();
+ log(out, "FileDrop: Drop will not work due to previous error. Do you have another listener attached?" );
+ } // end catch
+
+ // Listen for hierarchy changes and remove the drop target when the parent gets cleared out.
+ c.addHierarchyListener( new java.awt.event.HierarchyListener()
+ { public void hierarchyChanged( java.awt.event.HierarchyEvent evt )
+ { log( out, "FileDrop: Hierarchy changed." );
+ java.awt.Component parent = c.getParent();
+ if( parent == null )
+ { c.setDropTarget( null );
+ log( out, "FileDrop: Drop target cleared from component." );
+ } // end if: null parent
+ else
+ { new java.awt.dnd.DropTarget(c, dropListener);
+ log( out, "FileDrop: Drop target added to component." );
+ } // end else: parent not null
+ } // end hierarchyChanged
+ }); // end hierarchy listener
+ if( c.getParent() != null )
+ new java.awt.dnd.DropTarget(c, dropListener);
+
+ if( recursive && (c instanceof java.awt.Container ) )
+ {
+ // Get the container
+ java.awt.Container cont = (java.awt.Container) c;
+
+ // Get it's components
+ java.awt.Component[] comps = cont.getComponents();
+
+ // Set it's components as listeners also
+ for( int i = 0; i < comps.length; i++ )
+ makeDropTarget( out, comps[i], recursive );
+ } // end if: recursively set components as listener
+ } // end dropListener
+
+
+
+ /** Determine if the dragged data is a file list. */
+ private boolean isDragOk( final java.io.PrintStream out, final java.awt.dnd.DropTargetDragEvent evt )
+ { boolean ok = false;
+
+ // Get data flavors being dragged
+ java.awt.datatransfer.DataFlavor[] flavors = evt.getCurrentDataFlavors();
+
+ // See if any of the flavors are a file list
+ int i = 0;
+ while( !ok && i < flavors.length )
+ { // Is the flavor a file list?
+ if( flavors[i].equals( java.awt.datatransfer.DataFlavor.javaFileListFlavor ) )
+ ok = true;
+ i++;
+ } // end while: through flavors
+
+ // If logging is enabled, show data flavors
+ if( out != null )
+ { if( flavors.length == 0 )
+ log( out, "FileDrop: no data flavors." );
+ for( i = 0; i < flavors.length; i++ )
+ log( out, flavors[i].toString() );
+ } // end if: logging enabled
+
+ return ok;
+ } // end isDragOk
+
+
+ /** Outputs message to out if it's not null. */
+ private static void log( java.io.PrintStream out, String message )
+ { // Log message if requested
+ if( out != null )
+ out.println( message );
+ } // end log
+
+
+
+
+ /**
+ * Removes the drag-and-drop hooks from the component and optionally
+ * from the all children. You should call this if you add and remove
+ * components after you've set up the drag-and-drop.
+ * This will recursively unregister all components contained within
+ * c if c is a {@link java.awt.Container}.
+ *
+ * @param c The component to unregister as a drop target
+ * @since 1.0
+ */
+ public static boolean remove( java.awt.Component c)
+ { return remove( null, c, true );
+ } // end remove
+
+
+
+ /**
+ * Removes the drag-and-drop hooks from the component and optionally
+ * from the all children. You should call this if you add and remove
+ * components after you've set up the drag-and-drop.
+ *
+ * @param out Optional {@link java.io.PrintStream} for logging drag and drop messages
+ * @param c The component to unregister
+ * @param recursive Recursively unregister components within a container
+ * @since 1.0
+ */
+ public static boolean remove( java.io.PrintStream out, java.awt.Component c, boolean recursive )
+ { // Make sure we support dnd.
+ if( supportsDnD() )
+ { log( out, "FileDrop: Removing drag-and-drop hooks." );
+ c.setDropTarget( null );
+ if( recursive && ( c instanceof java.awt.Container ) )
+ { java.awt.Component[] comps = ((java.awt.Container)c).getComponents();
+ for( int i = 0; i < comps.length; i++ )
+ remove( out, comps[i], recursive );
+ return true;
+ } // end if: recursive
+ else return false;
+ } // end if: supports DnD
+ else return false;
+ } // end remove
+
+
+
+
+
+
+ /** Runs a sample program that shows dropped files */
+ public static void main( String[] args )
+ {
+ javax.swing.JFrame frame = new javax.swing.JFrame( "FileDrop" );
+ //javax.swing.border.TitledBorder dragBorder = new javax.swing.border.TitledBorder( "Drop 'em" );
+ final javax.swing.JTextArea text = new javax.swing.JTextArea();
+ frame.getContentPane().add(
+ new javax.swing.JScrollPane( text ),
+ java.awt.BorderLayout.CENTER );
+
+ new FileDrop( System.out, text, /*dragBorder,*/ new FileDrop.Listener()
+ { public void filesDropped( java.io.File[] files )
+ { for( int i = 0; i < files.length; i++ )
+ { try
+ { text.append( files[i].getCanonicalPath() + "\n" );
+ } // end try
+ catch( java.io.IOException e ) {}
+ } // end for: through each dropped file
+ } // end filesDropped
+ }); // end FileDrop.Listener
+
+ frame.setBounds( 100, 100, 300, 400 );
+ frame.setDefaultCloseOperation( frame.EXIT_ON_CLOSE );
+ frame.show();
+ } // end main
+
+
+
+
+
+/* ******** I N N E R I N T E R F A C E L I S T E N E R ******** */
+
+
+ /**
+ * Implement this inner interface to listen for when files are dropped. For example
+ * your class declaration may begin like this:
+ *
+ * public class MyClass implements FileDrop.Listener
+ * ...
+ * public void filesDropped( java.io.File[] files )
+ * {
+ * ...
+ * } // end filesDropped
+ * ...
+ *
+ *
+ * @since 1.0
+ */
+ public interface Listener
+ {
+ /**
+ * This method is called when files have been successfully dropped.
+ *
+ * @param files An array of Files that were dropped.
+ * @since 1.0
+ */
+ public abstract void filesDropped( java.io.File[] files );
+ } // end inner-interface Listener
+
+} // end class FileDrop
\ No newline at end of file
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/net/iharder/dnd/FileDropBean.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/iharder/dnd/FileDropBean.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,112 @@
+package net.iharder.dnd;
+import java.beans.*;
+
+/**
+ * If you wish to use the FileDrop package as a JavaBean, this class will act as
+ * an interface to the {@link FileDrop} class that handles all the dirty work.
+ * After instantiating the bean, add components as drop targets using the
+ * {@link #addFileDropTarget addFileDropTarget(...)} method. If the component
+ * is a {@link java.awt.Container}, then all elements contained within will be
+ * marked as a drop target as well.
+ * Using the {@link FileDrop} technique manually in your code will give you more options.
+ *
+ *
I'm releasing this code into the Public Domain. Enjoy.
+ *
+ *
Original author: Robert Harder, rharder@usa.net
+ *
+ * @author Robert Harder
+ * @author rharder@usa.net
+ * @version 1.1
+ */
+public class FileDropBean
+implements java.io.Serializable
+{
+
+ private javax.swing.event.EventListenerList listenerList = new javax.swing.event.EventListenerList();
+
+ /** Creates new FileDropBean */
+ public FileDropBean()
+ {
+ }
+
+ /**
+ * Registers a component as a drop target.
+ * If the component is a container, then all elements contained
+ * within will also be registered as drop targets, though only
+ * the outer container will change borders during a drag and drop
+ * operation (and even then, only if the container is a Swing component).
+ *
+ * @param comp The component to register as a drop target
+ * @since 1.1
+ */
+ public void addFileDropTarget( java.awt.Component comp )
+ {
+ FileDrop.Listener listener = new FileDrop.Listener()
+ { public void filesDropped( java.io.File[] files )
+ { fireFileDropHappened( files );
+ } // end filesDropped
+ }; // end listener
+ boolean recursive = true;
+ new FileDrop( comp, recursive, listener );
+ } // end newDropTarget
+
+
+ /**
+ * Unregisters a component as a drop target.
+ *
+ * @param comp The component to unregister
+ * @since 1.1
+ */
+ public boolean removeFileDropTarget( java.awt.Component comp )
+ { return FileDrop.remove( comp );
+ } // end removeFileDropTarget
+
+
+ /**
+ * Register a listener for {@link FileDropEvent}s.
+ *
+ * @param listener The listener to register
+ * @since 1.1
+ */
+ public void addFileDropListener (FileDropListener listener)
+ { listenerList.add( FileDropListener.class, listener );
+ } // end addFileDropListener
+
+
+
+ /**
+ * Unregister a listener for {@link FileDropEvent}s.
+ *
+ * @param listener The listener to unregister
+ * @since 1.1
+ */
+ public void removeFileDropListener (FileDropListener listener)
+ { listenerList.remove( FileDropListener.class, listener );
+ } // end addFileDropListener
+
+
+ /**
+ * Fires a {@link FileDropEvent} with the given non-null
+ * list of dropped files.
+ *
+ * @param files The files that were dropped
+ * @since 1.1
+ */
+ protected void fireFileDropHappened( java.io.File[] files )
+ {
+ FileDropEvent evt = new FileDropEvent( files, this );
+
+ // Guaranteed to return a non-null array
+ Object[] listeners = listenerList.getListenerList();
+
+ // Process the listeners last to first, notifying
+ // those that are interested in this event
+ for (int i = listeners.length-2; i>=0; i-=2)
+ { if (listeners[i]==FileDropListener.class)
+ { ((FileDropListener)listeners[i+1]).filesDropped(evt);
+ } // end if: correct listener type
+ } // end for: each listener
+ } // end fireFileDropHappened
+
+
+} // end clas FileDropBean
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/net/iharder/dnd/FileDropBeanBeanInfo.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/iharder/dnd/FileDropBeanBeanInfo.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,163 @@
+package net.iharder.dnd;
+
+import java.beans.*;
+
+public class FileDropBeanBeanInfo extends SimpleBeanInfo
+{
+
+ // Properties information will be obtained from introspection.//GEN-FIRST:Properties
+ private static PropertyDescriptor[] properties = null;//GEN-HEADEREND:Properties
+
+ // Here you can add code for customizing the properties array.
+
+ //GEN-LAST:Properties
+
+ // Event set information will be obtained from introspection.//GEN-FIRST:Events
+ private static EventSetDescriptor[] eventSets = null;//GEN-HEADEREND:Events
+
+ // Here you can add code for customizing the event sets array.
+
+ //GEN-LAST:Events
+
+ // Method information will be obtained from introspection.//GEN-FIRST:Methods
+ private static MethodDescriptor[] methods = null;//GEN-HEADEREND:Methods
+
+ // Here you can add code for customizing the methods array.
+
+ //GEN-LAST:Methods
+
+ private static java.awt.Image iconColor16 = null; //GEN-BEGIN:IconsDef
+ private static java.awt.Image iconColor32 = null;
+ private static java.awt.Image iconMono16 = null;
+ private static java.awt.Image iconMono32 = null; //GEN-END:IconsDef
+ private static String iconNameC16 = null;//GEN-BEGIN:Icons
+ private static String iconNameC32 = null;
+ private static String iconNameM16 = null;
+ private static String iconNameM32 = null;//GEN-END:Icons
+
+ private static int defaultPropertyIndex = -1;//GEN-BEGIN:Idx
+ private static int defaultEventIndex = -1;//GEN-END:Idx
+
+
+ /**
+ * Gets the bean's PropertyDescriptors.
+ *
+ * @return An array of PropertyDescriptors describing the editable
+ * properties supported by this bean. May return null if the
+ * information should be obtained by automatic analysis.
+ *
+ * If a property is indexed, then its entry in the result array will
+ * belong to the IndexedPropertyDescriptor subclass of PropertyDescriptor.
+ * A client of getPropertyDescriptors can use "instanceof" to check
+ * if a given PropertyDescriptor is an IndexedPropertyDescriptor.
+ */
+ public PropertyDescriptor[] getPropertyDescriptors() {
+ return properties;
+ }
+
+ /**
+ * Gets the bean's EventSetDescriptors.
+ *
+ * @return An array of EventSetDescriptors describing the kinds of
+ * events fired by this bean. May return null if the information
+ * should be obtained by automatic analysis.
+ */
+ public EventSetDescriptor[] getEventSetDescriptors() {
+ return eventSets;
+ }
+
+ /**
+ * Gets the bean's MethodDescriptors.
+ *
+ * @return An array of MethodDescriptors describing the methods
+ * implemented by this bean. May return null if the information
+ * should be obtained by automatic analysis.
+ */
+ public MethodDescriptor[] getMethodDescriptors() {
+ return methods;
+ }
+
+ /**
+ * A bean may have a "default" property that is the property that will
+ * mostly commonly be initially chosen for update by human's who are
+ * customizing the bean.
+ * @return Index of default property in the PropertyDescriptor array
+ * returned by getPropertyDescriptors.
+ *
Returns -1 if there is no default property.
+ */
+ public int getDefaultPropertyIndex() {
+ return defaultPropertyIndex;
+ }
+
+ /**
+ * A bean may have a "default" event that is the event that will
+ * mostly commonly be used by human's when using the bean.
+ * @return Index of default event in the EventSetDescriptor array
+ * returned by getEventSetDescriptors.
+ *
Returns -1 if there is no default event.
+ */
+ public int getDefaultEventIndex() {
+ return defaultPropertyIndex;
+ }
+
+ /**
+ * This method returns an image object that can be used to
+ * represent the bean in toolboxes, toolbars, etc. Icon images
+ * will typically be GIFs, but may in future include other formats.
+ *
+ * Beans aren't required to provide icons and may return null from
+ * this method.
+ *
+ * There are four possible flavors of icons (16x16 color,
+ * 32x32 color, 16x16 mono, 32x32 mono). If a bean choses to only
+ * support a single icon we recommend supporting 16x16 color.
+ *
+ * We recommend that icons have a "transparent" background
+ * so they can be rendered onto an existing background.
+ *
+ * @param iconKind The kind of icon requested. This should be
+ * one of the constant values ICON_COLOR_16x16, ICON_COLOR_32x32,
+ * ICON_MONO_16x16, or ICON_MONO_32x32.
+ * @return An image object representing the requested icon. May
+ * return null if no suitable icon is available.
+ */
+ public java.awt.Image getIcon(int iconKind) {
+ switch ( iconKind ) {
+ case ICON_COLOR_16x16:
+ if ( iconNameC16 == null )
+ return null;
+ else {
+ if( iconColor16 == null )
+ iconColor16 = loadImage( iconNameC16 );
+ return iconColor16;
+ }
+ case ICON_COLOR_32x32:
+ if ( iconNameC32 == null )
+ return null;
+ else {
+ if( iconColor32 == null )
+ iconColor32 = loadImage( iconNameC32 );
+ return iconColor32;
+ }
+ case ICON_MONO_16x16:
+ if ( iconNameM16 == null )
+ return null;
+ else {
+ if( iconMono16 == null )
+ iconMono16 = loadImage( iconNameM16 );
+ return iconMono16;
+ }
+ case ICON_MONO_32x32:
+ if ( iconNameM32 == null )
+ return null;
+ else {
+ if( iconNameM32 == null )
+ iconMono32 = loadImage( iconNameM32 );
+ return iconMono32;
+ }
+ }
+ return null;
+ }
+
+}
+
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/net/iharder/dnd/FileDropEvent.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/iharder/dnd/FileDropEvent.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,47 @@
+package net.iharder.dnd;
+
+/**
+ * This is the event that is passed to the
+ * {@link FileDropListener#filesDropped filesDropped(...)} method in
+ * your {@link FileDropListener} when files are dropped onto
+ * a registered drop target.
+ *
+ *
I'm releasing this code into the Public Domain. Enjoy.
+ *
+ *
Original author: Robert Harder, rharder@usa.net
+ *
+ * @author Robert Harder
+ * @author rharder@usa.net
+ * @version 1.1
+ */
+public class FileDropEvent extends java.util.EventObject
+{
+
+ private java.io.File[] files;
+
+ /**
+ * Constructs a {@link FileDropEvent} with the array
+ * of files that were dropped and the
+ * {@link FileDropBean} that initiated the event.
+ *
+ * @param files The array of files that were dropped
+ * @source The event source
+ * @since 1.1
+ */
+ public FileDropEvent( java.io.File[] files, Object source )
+ { super( source );
+ this.files = files;
+ } // end constructor
+
+ /**
+ * Returns an array of files that were dropped on a
+ * registered drop target.
+ *
+ * @return array of files that were dropped
+ * @since 1.1
+ */
+ public java.io.File[] getFiles()
+ { return files;
+ } // end getFiles
+
+} // end class FileDropEvent
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/net/iharder/dnd/FileDropListener.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/iharder/dnd/FileDropListener.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,30 @@
+package net.iharder.dnd;
+
+/**
+ * When using the FileDrop package in its JavaBean form,
+ * this listener will receive events when files are dropped
+ * onto registered targets.
+ *
+ *
+ *
I'm releasing this code into the Public Domain. Enjoy.
+ *
+ *
Original author: Robert Harder, rharder@usa.net
+ *
+ * @author Robert Harder
+ * @author rharder@usa.net
+ * @version 1.1
+ */
+public interface FileDropListener extends java.util.EventListener
+{
+
+ /**
+ * Fired by the {@link FileDropBean} when files are dropped
+ * onto a drop target.
+ *
+ * @param evt The {@link FileDropEvent} associated with this event
+ * @since 1.1
+ */
+ public abstract void filesDropped( FileDropEvent evt );
+
+
+} // end interface FileDropListener
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/net/iharder/dnd/TransferableObject.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/net/iharder/dnd/TransferableObject.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,261 @@
+package net.iharder.dnd;
+
+
+/**
+ * At last an easy way to encapsulate your custom objects for dragging and dropping
+ * in your Java programs!
+ * When you need to create a {@link java.awt.datatransfer.Transferable} object,
+ * use this class to wrap your object.
+ * For example:
+ *
+ * Or if you need to know when the data was actually dropped, like when you're
+ * moving data out of a list, say, you can use the {@link TransferableObject.Fetcher}
+ * inner class to return your object Just in Time.
+ * For example:
+ *
+ * ...
+ * final MyCoolClass myObj = new MyCoolClass();
+ *
+ * TransferableObject.Fetcher fetcher = new TransferableObject.Fetcher()
+ * { public Object getObject(){ return myObj; }
+ * }; // end fetcher
+ *
+ * Transferable xfer = new TransferableObject( fetcher );
+ * ...
+ *
+ *
+ * The {@link java.awt.datatransfer.DataFlavor} associated with
+ * {@link TransferableObject} has the representation class
+ * net.iharder.dnd.TransferableObject.class and MIME type
+ * application/x-net.iharder.dnd.TransferableObject.
+ * This data flavor is accessible via the static
+ * {@link #DATA_FLAVOR} property.
+ *
+ *
+ *
This code is licensed for public use under the Common Public License version 0.5.
+ * The Common Public License, developed by IBM and modeled after their industry-friendly IBM Public License,
+ * differs from other common open source licenses in several important ways:
+ *
+ *
You may include this software with other software that uses a different (even non-open source) license.
+ *
You may use this software to make for-profit software.
+ *
Your patent rights, should you generate patents, are protected.
+ *
+ * @author Robert.Harder
+ * @copyright 2001
+ * @version 1.1
+ */
+public class TransferableObject implements java.awt.datatransfer.Transferable
+{
+ /**
+ * The MIME type for {@link #DATA_FLAVOR} is
+ * application/x-net.iharder.dnd.TransferableObject.
+ *
+ * @since 1.1
+ */
+ public final static String MIME_TYPE = "application/x-net.iharder.dnd.TransferableObject";
+
+
+ /**
+ * The default {@link java.awt.datatransfer.DataFlavor} for
+ * {@link TransferableObject} has the representation class
+ * net.iharder.dnd.TransferableObject.class
+ * and the MIME type
+ * application/x-net.iharder.dnd.TransferableObject.
+ *
+ * @since 1.1
+ */
+ public final static java.awt.datatransfer.DataFlavor DATA_FLAVOR =
+ new java.awt.datatransfer.DataFlavor( net.iharder.dnd.TransferableObject.class, MIME_TYPE );
+
+
+ private Fetcher fetcher;
+ private Object data;
+
+ private java.awt.datatransfer.DataFlavor customFlavor;
+
+
+
+ /**
+ * Creates a new {@link TransferableObject} that wraps data.
+ * Along with the {@link #DATA_FLAVOR} associated with this class,
+ * this creates a custom data flavor with a representation class
+ * determined from data.getClass() and the MIME type
+ * application/x-net.iharder.dnd.TransferableObject.
+ *
+ * @param data The data to transfer
+ * @since 1.1
+ */
+ public TransferableObject( Object data )
+ { this.data = data;
+ this.customFlavor = new java.awt.datatransfer.DataFlavor( data.getClass(), MIME_TYPE );
+ } // end constructor
+
+
+
+ /**
+ * Creates a new {@link TransferableObject} that will return the
+ * object that is returned by fetcher.
+ * No custom data flavor is set other than the default
+ * {@link #DATA_FLAVOR}.
+ *
+ * @see Fetcher
+ * @param fetcher The {@link Fetcher} that will return the data object
+ * @since 1.1
+ */
+ public TransferableObject( Fetcher fetcher )
+ { this.fetcher = fetcher;
+ } // end constructor
+
+
+
+ /**
+ * Creates a new {@link TransferableObject} that will return the
+ * object that is returned by fetcher.
+ * Along with the {@link #DATA_FLAVOR} associated with this class,
+ * this creates a custom data flavor with a representation class dataClass
+ * and the MIME type
+ * application/x-net.iharder.dnd.TransferableObject.
+ *
+ * @see Fetcher
+ * @param dataClass The {@link java.lang.Class} to use in the custom data flavor
+ * @param fetcher The {@link Fetcher} that will return the data object
+ * @since 1.1
+ */
+ public TransferableObject( Class dataClass, Fetcher fetcher )
+ { this.fetcher = fetcher;
+ this.customFlavor = new java.awt.datatransfer.DataFlavor( dataClass, MIME_TYPE );
+ } // end constructor
+
+ /**
+ * Returns the custom {@link java.awt.datatransfer.DataFlavor} associated
+ * with the encapsulated object or null if the {@link Fetcher}
+ * constructor was used without passing a {@link java.lang.Class}.
+ *
+ * @return The custom data flavor for the encapsulated object
+ * @since 1.1
+ */
+ public java.awt.datatransfer.DataFlavor getCustomDataFlavor()
+ { return customFlavor;
+ } // end getCustomDataFlavor
+
+
+/* ******** T R A N S F E R A B L E M E T H O D S ******** */
+
+
+ /**
+ * Returns a two- or three-element array containing first
+ * the custom data flavor, if one was created in the constructors,
+ * second the default {@link #DATA_FLAVOR} associated with
+ * {@link TransferableObject}, and third the
+ * {@link java.awt.datatransfer.DataFlavor.stringFlavor}.
+ *
+ * @return An array of supported data flavors
+ * @since 1.1
+ */
+ public java.awt.datatransfer.DataFlavor[] getTransferDataFlavors()
+ {
+ if( customFlavor != null )
+ return new java.awt.datatransfer.DataFlavor[]
+ { customFlavor,
+ DATA_FLAVOR,
+ java.awt.datatransfer.DataFlavor.stringFlavor
+ }; // end flavors array
+ else
+ return new java.awt.datatransfer.DataFlavor[]
+ { DATA_FLAVOR,
+ java.awt.datatransfer.DataFlavor.stringFlavor
+ }; // end flavors array
+ } // end getTransferDataFlavors
+
+
+
+ /**
+ * Returns the data encapsulated in this {@link TransferableObject}.
+ * If the {@link Fetcher} constructor was used, then this is when
+ * the {@link Fetcher#getObject getObject()} method will be called.
+ * If the requested data flavor is not supported, then the
+ * {@link Fetcher#getObject getObject()} method will not be called.
+ *
+ * @param flavor The data flavor for the data to return
+ * @return The dropped data
+ * @since 1.1
+ */
+ public Object getTransferData( java.awt.datatransfer.DataFlavor flavor )
+ throws java.awt.datatransfer.UnsupportedFlavorException, java.io.IOException
+ {
+ // Native object
+ if( flavor.equals( DATA_FLAVOR ) )
+ return fetcher == null ? data : fetcher.getObject();
+
+ // String
+ if( flavor.equals( java.awt.datatransfer.DataFlavor.stringFlavor ) )
+ return fetcher == null ? data.toString() : fetcher.getObject().toString();
+
+ // We can't do anything else
+ throw new java.awt.datatransfer.UnsupportedFlavorException(flavor);
+ } // end getTransferData
+
+
+
+
+ /**
+ * Returns true if flavor is one of the supported
+ * flavors. Flavors are supported using the equals(...) method.
+ *
+ * @param flavor The data flavor to check
+ * @return Whether or not the flavor is supported
+ * @since 1.1
+ */
+ public boolean isDataFlavorSupported( java.awt.datatransfer.DataFlavor flavor )
+ {
+ // Native object
+ if( flavor.equals( DATA_FLAVOR ) )
+ return true;
+
+ // String
+ if( flavor.equals( java.awt.datatransfer.DataFlavor.stringFlavor ) )
+ return true;
+
+ // We can't do anything else
+ return false;
+ } // end isDataFlavorSupported
+
+
+/* ******** I N N E R I N T E R F A C E F E T C H E R ******** */
+
+ /**
+ * Instead of passing your data directly to the {@link TransferableObject}
+ * constructor, you may want to know exactly when your data was received
+ * in case you need to remove it from its source (or do anyting else to it).
+ * When the {@link #getTransferData getTransferData(...)} method is called
+ * on the {@link TransferableObject}, the {@link Fetcher}'s
+ * {@link #getObject getObject()} method will be called.
+ *
+ * @author Robert Harder
+ * @copyright 2001
+ * @version 1.1
+ * @since 1.1
+ */
+ public static interface Fetcher
+ {
+ /**
+ * Return the object being encapsulated in the
+ * {@link TransferableObject}.
+ *
+ * @return The dropped object
+ * @since 1.1
+ */
+ public abstract Object getObject();
+ } // end inner interface Fetcher
+
+
+
+} // end class TransferableObject
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/org/abisso/PortableNotary/GUI/ImagePanel.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/abisso/PortableNotary/GUI/ImagePanel.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,45 @@
+package org.abisso.PortableNotary.GUI;
+
+
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.MediaTracker;
+import java.awt.Toolkit;
+
+import javax.swing.JPanel;
+
+public class ImagePanel extends JPanel
+{
+
+
+ private static final long serialVersionUID = -7945419760047704730L;
+ private Image image;
+
+ public ImagePanel(String path)
+ {
+ image = Toolkit.getDefaultToolkit().getImage(path);
+ MediaTracker tracker = new MediaTracker(this);
+ tracker.addImage(image, 0);
+ try
+ {
+ tracker.waitForID(0);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ Dimension d = new Dimension(image.getWidth(this),image.getHeight(this));
+ setPreferredSize(d);
+ setMaximumSize(d);
+ setMinimumSize(d);
+
+ }
+
+ public void paintComponent(Graphics g)
+ {
+ super.paintComponent(g);
+ g.drawImage(image, 0, 0, this);
+
+ }//end paintComponent
+}//end class
+
diff -r 01ea204f838e41341c40d9090346aad06584a8ae -r 776821e4f4ba1d16ab1fc7c4611bd1be43fd8c93 src/org/abisso/PortableNotary/GUI/MainFrame.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/org/abisso/PortableNotary/GUI/MainFrame.java Mon Jun 11 16:15:38 2007 +0200
@@ -0,0 +1,88 @@
+package org.abisso.PortableNotary.GUI;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.GridBagLayout;
+
+import javax.swing.JFrame;
+import javax.swing.JPanel;
+
+import org.abisso.PortableNotary.Notary;
+
+
+import net.iharder.dnd.FileDrop;
+
+public class MainFrame extends JFrame {
+
+ private static final long serialVersionUID = 1L;
+
+ private JPanel jContentPane = null;
+
+ private JPanel Image = null;
+
+ //private Preferences pref = Preferences.getIstance();
+
+ /**
+ * This is the default constructor
+ */
+ public MainFrame() {
+ super();
+ initialize();
+ }
+
+ /**
+ * This method initializes this
+ *
+ * @return void
+ */
+ private void initialize() {
+ //this.setSize(300, 200);
+ this.setContentPane(getJContentPane());
+ this.setTitle("PortableNotary");
+ Dimension d = getImage().getPreferredSize();
+ d.height += 25;
+ this.setSize(d);
+ new FileDrop( getImage(), new FileDrop.Listener(){
+ public void filesDropped( java.io.File[] files )
+ {
+ MyFrameWithConsole sign;
+
+ for( int i=0; i