Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4189026

Dragging Unicode into Word leaves bad character

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Cannot Reproduce
    • Icon: P3 P3
    • None
    • 1.2.0, 1.2.1, 1.2.2, 1.3.0
    • client-libs
    • generic, x86, sparc
    • generic, solaris_2.6, windows_98, windows_nt



      Name: tb29552 Date: 11/11/98


      In bug 4094987, it is pointed out that
      drag-and-drop from Word to JDK 1.2rc1 Java apps
      causes an exception due to a lack of a byte order
      flag. The opposite problem also exists, however,
      namely that if one drags from such a Java app
      into Word (as text/plain;charset=unicode), then
      one gets an extra character in Word (the byte
      ordering flag?) at the beginning of the text.

      If one drags this entire text from Word back
      into Java then the original text is produced!
      If the garbage character is not part of the text
      dragged from Word into Java, then bug 4094987's
      exception stack is reproduced.

      It appears that the converter needs to produce
      this flag when dragging from native apps and
      consume it when dragging to native apps and that
      neither is currently done!

      This is a serious problem for Drag-and-Drop in
      JDK 1.2 (which is already hampered by a complete
      lack of examples and documentation on how
      encodings should be handled).

      Source for this problem (with tabstop of 2) follows:

      package ptc;

      // Simple drag and drop test harness

      import java.awt.*;
      import java.awt.datatransfer.*;
      import java.awt.event.*;
      import java.awt.dnd.*;
      import java.io.*;
      import java.util.*;
      import java.util.List;
      import javax.swing.*;


      class SampleFrame extends JFrame
      {
       private static Vector compsNotToRmv = new Vector();
       
       public static Vector getCompsNotToRmv()
       {
         return ( compsNotToRmv );
       }
       
       public JComponent makeLabel( String str )
       {
         if ( str == null )
           return ( null );
         
         JButton label = new JButton( str );
         getContentPane().add( label );
         label.setSize( 75, 16 );
         label.setLocation( 50, 50 );
         
         Transferable labelData = new JLabelTransferable( label );
         DragSourceListener dsl = new LabelDragListener( label );
         DragGestureListener dgl = new SimpleDragGestureListener( labelData, dsl );
         DragSource ds = DragSource.getDefaultDragSource();
         DragGestureRecognizer dgRecog =
                     ds.createDefaultDragGestureRecognizer(
                          label, DnDConstants.ACTION_COPY_OR_MOVE, dgl );
         
         return ( label );
       }
       
       public SampleFrame( String title, String str )
       {
         super( title );
         getContentPane().setLayout( null );
         setSize( new Dimension( 200, 200 ) );
         
         JButton label = new JButton( str );
         getContentPane().add( label );
         label.setLocation( 50, 50 );

         // add drag/droppable label component
         makeLabel( str );
         
         // add drop target stuff to content pane
         DropTargetListener dtl = new LabelDropListener( this );
         DropTarget dt = new DropTarget( getContentPane(), dtl );
       }
      }

      public class MyApp
      {
        public static void main( String args[] )
        {
           SampleFrame frm;
           String suffix = ( args.length > 0 ? args[0] : "" );
           frm = new SampleFrame( "Foo" + suffix, "bar" );
           frm.setVisible( true );
           frm = new SampleFrame( "low" + suffix, "mar" );
           frm.setVisible( true );
        }
      }


      class JLabelTransferable implements Transferable, Serializable
      {
       private static final DataFlavor[] flavors =
       {
         new DataFlavor( DataFlavor.javaJVMLocalObjectMimeType +
                         "; class=" + JButton.class.getName(), "Live JButton" ),
         new DataFlavor( DataFlavor.javaJVMLocalObjectMimeType +
                         "; class=" + String.class.getName(), "Live String" ),
         new DataFlavor( JButton.class, "Serialized JButton" ),
         DataFlavor.stringFlavor,
         DataFlavor.plainTextFlavor
       };
       private static final List flavorList = Arrays.asList( flavors );
       
       public JLabelTransferable( JButton jlabel )
       {
         label = jlabel;
       }
       
       public static DataFlavor[] getRegularFlavors()
       {
         return ( flavors );
       }
       
       public DataFlavor[] getTransferDataFlavors()
       {
         return ( flavors );
       }
       public boolean isDataFlavorSupported( DataFlavor flavor )
       {
         return ( flavorList.contains( flavor ) );
       }
       public Object getTransferData( DataFlavor flavor )
                        throws UnsupportedFlavorException,
                               IOException
       {
         System.err.println( "Transferable.getTransferData() called for: " + flavor.getMimeType() );
         if ( flavors[0].equals( flavor ) )
         {
           return ( label );
         }
         else if ( flavors[1].equals( flavor ) )
         {
           return ( label.getText() );
         }
         else if ( flavors[2].equals( flavor ) )
         {
           return ( label );
         }
         else if ( flavors[3].equals( flavor ) )
         {
           return ( label.getText() );
         }
         else if ( flavors[4].equals( flavor ) )
         {
           // return ( new StringReader( label.getText() ) );
           return ( new ByteArrayInputStream( label.getText().getBytes( "Unicode" ) ) );
           // return ( new StringBufferInputStream( label.getText() ) );
         }
         return ( null );
       }
       
       private JButton label;
      }


      class LabelDragListener implements DragSourceListener, Serializable
      {
       public LabelDragListener( JButton label )
       {
         parent = label.getParent(); // update parent
         this.label = label;
       }
       
       public void dragEnter( DragSourceDragEvent dsde )
       {
         parent = label.getParent(); // update parent
         System.err.println( "DragSourceListener.dragEnter() called" );
       }
       public void dragOver( DragSourceDragEvent dsde )
       {
         System.err.println( "DragSourceListener.dragOver() called" );
       }
       public void dropActionChanged( DragSourceDragEvent dsde )
       {
         System.err.println( "DragSourceListener.dropActionChanged() called" );
       }
       public void dragExit( DragSourceEvent dse )
       {
         System.err.println( "DragSourceListener.dragExit() called" );
       }
       public void dragDropEnd( DragSourceDropEvent dsde )
       {
         System.err.println( "DragSourceListener.dragDropEnd() called" );
         if ( !dsde.getDropSuccess() )
         {
           System.err.println( "DragSourceDropEvent.getDropSuccess() returned 'false'" );
           // could do image animation here
           return;
         }
         final int dropAction = dsde.getDropAction();
         System.err.println( "DragSourceDropEvent.getDropAction() returned " + dropAction );
         
         // it is not safe to remove the drag source component from the component
         // hierarchy until after the completion of the drag-and-drop action;
         // SwingUtilities.invokeLater() is therefore used
         Runnable runner = new Runnable()
         {
           public void run()
           {
      if ( dropAction == DnDConstants.ACTION_MOVE )
      {
      if ( !SampleFrame.getCompsNotToRmv().contains( label ) )
      {
      System.err.println( "DragSourceListener.dragDropEnd(): Removing label from parent" );
      if ( parent != null )
      parent.remove( label );
      }
      else
      SampleFrame.getCompsNotToRmv().remove( label );
      if ( parent instanceof JComponent )
      {
      JComponent jparent = (JComponent) parent;
      jparent.revalidate();
      jparent.repaint();
      }
      }
      }
         };
         SwingUtilities.invokeLater( runner );
       }
       private JButton label;
       transient private Container parent;
      }


      class SimpleDragGestureListener implements DragGestureListener, Serializable
      {
       public SimpleDragGestureListener( Transferable labelData, DragSourceListener dsl )
       {
         this.labelData = labelData;
         this.dsl = dsl;
       }
       public void dragGestureRecognized( DragGestureEvent dge )
       {
         System.err.println( "SimpleDragGestureListener.dragGestureRecognized() called" );
         DragSource ds = dge.getDragSource();
         dge.startDrag( ds.DefaultMoveDrop, labelData, dsl );
       }
       private Transferable labelData;
       private DragSourceListener dsl;
      }


      class LabelDropListener implements DropTargetListener, Serializable
      {
        public LabelDropListener( SampleFrame frame )
        {
          this.frame = frame;
        }
      public void dragEnter( DropTargetDragEvent dtde )
      {
      System.err.println( "DropTargetListener.dragEnter() called" );
      if ( !isDragAcceptable( dtde ) )
      dtde.rejectDrag();
      }
      public void dragOver( DropTargetDragEvent dtde )
      {
      System.err.println( "DropTargetListener.dragOver() called" );
      if ( !isDragAcceptable( dtde ) )
      dtde.rejectDrag();
      }
      public void dropActionChanged( DropTargetDragEvent dtde )
      {
      System.err.println( "DropTargetListener.dropActionChanged() called" );
      if ( !isDragAcceptable( dtde ) )
      dtde.rejectDrag();
      }
      public void dragExit( DropTargetEvent dte )
      {
      System.err.println( "DropTargetListener.dragExit() called" );
      }
      public void drop( DropTargetDropEvent dtde )
      {
      System.err.println( "DropTargetListener.drop() called" );
      boolean local = dtde.isLocalTransfer();
      System.err.println( "Local transfer = " + local );
      DataFlavor flavors[] = JLabelTransferable.getRegularFlavors();
      if ( !local )
      flavors = new DataFlavor[] { flavors[4] };
      DataFlavor chosenFlavor = null;
      for ( int ii = 0; ii < flavors.length; ++ii )
      if ( dtde.isDataFlavorSupported( flavors[ii] ) )
      {
      chosenFlavor = flavors[ii];
      break;
      }
      DataFlavor srcFlavors[] = dtde.getCurrentDataFlavors();
      System.err.println( "Source flavors:" );
      for ( int ii = 0; ii < srcFlavors.length; ++ii )
      System.err.println( " " + srcFlavors[ii].getMimeType() );
      if ( chosenFlavor == null )
      {
      System.err.println( "No flavor match found" );
      dtde.dropComplete( false );
      return;
      }
      System.err.println( "Chosen data flavor is " + chosenFlavor.getMimeType() );
      int srcActions = dtde.getSourceActions();
      if ( ( srcActions & DnDConstants.ACTION_MOVE ) == 0 )
      {
      System.err.println( "No action match found" );
      dtde.dropComplete( false );
      return;
      }

      Object trsData;
      try
      {
            dtde.acceptDrop( DnDConstants.ACTION_MOVE );
      trsData = dtde.getTransferable().getTransferData( chosenFlavor );
      if ( trsData == null )
      throw new NullPointerException();
          }
          catch ( Throwable t )
          {
            System.err.println( "Problems in getting transfer data: " + t.getMessage() );
            t.printStackTrace();
      dtde.dropComplete( false );
      return;
          }
          
          Component comp = null;
          if ( trsData instanceof String )
          {
            String str = (String) trsData;
            comp = frame.makeLabel( str );
          }
          else if ( trsData instanceof Component )
          {
            comp = (Component) trsData;
            if ( comp.getParent() != frame.getContentPane() )
              frame.getContentPane().add( comp );
            if ( dtde.isLocalTransfer() )
              SampleFrame.getCompsNotToRmv().add( comp );
          }
          else if ( trsData instanceof InputStream )
          {
            System.err.println( "Drop data is InputStream" );
            
            // it is currently assumed that this data is text/plain as per
            // above; if the code above this changes then this code must be
            // generalized
            InputStream stream = (InputStream) trsData;
            InputStreamReader strmReader;
            try
            {
              strmReader = new InputStreamReader( stream, "Unicode" );
            }
            catch ( Exception e )
            {
              System.err.println( "Requested Encoding Not Found." );
              strmReader = new InputStreamReader( stream );
            }
      System.err.println( "Encoding used is: " + strmReader.getEncoding() );
            StringBuffer strBuffer = new StringBuffer();
            int idata;
            try
            {
      while ( (idata = strmReader.read()) >= 0 )
      if ( idata != 0 )
      strBuffer.append( (char) idata );
      else
      System.err.println( "NULL CHAR FOUND!" );
            }
            catch ( Exception e )
            {
              System.err.println( "Error reading InputStream: " + e.getMessage() );
              e.printStackTrace();
            }
            System.err.println( "Received string is " + strBuffer );
            comp = frame.makeLabel( strBuffer.toString() );
          }
          if ( comp != null )
      comp.setLocation( dtde.getLocation() );
      if ( frame.getContentPane() instanceof JComponent )
      {
      JComponent jcomp = (JComponent) frame.getContentPane();
            jcomp.revalidate();
      jcomp.repaint();
          }
      dtde.dropComplete( true );
      }
      protected boolean isDragAcceptable( DropTargetDragEvent dtde )
      {
      DataFlavor flavors[] = JLabelTransferable.getRegularFlavors();
      DataFlavor bestFlavor = null;
      for ( int ii = 0; ii < flavors.length; ++ii )
      if ( dtde.isDataFlavorSupported( flavors[ii] ) )
      {
      bestFlavor = flavors[ii];
      break;
      }
      if ( bestFlavor == null )
      return ( false );
      int srcActions = dtde.getSourceActions();
      if ( ( srcActions & DnDConstants.ACTION_MOVE ) == 0 )
      return ( false );
      return ( true );
      }
      private SampleFrame frame;
      }
      (Review ID: 42450)
      ======================================================================

            dmendenhsunw David Mendenhall (Inactive)
            tbell Tim Bell
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: