-
Bug
-
Resolution: Cannot Reproduce
-
P3
-
None
-
1.2.0, 1.2.1, 1.2.2, 1.3.0
-
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)
======================================================================
- duplicates
-
JDK-4250264 Kestrel-I:Appends extra character to text after dnd
-
- Closed
-
-
JDK-4253439 Junk characters in data transferred to native app
-
- Closed
-
- relates to
-
JDK-4254186 RFE: JDK should support utf-16le
-
- Closed
-
-
JDK-4094987 sun.io.MalformedInputException : Converter malfunction (Unicode)
-
- Closed
-