-
Bug
-
Resolution: Fixed
-
P4
-
1.3.0, 1.4.0
-
tiger
-
generic, x86
-
generic, windows_nt
Name: jk109818 Date: 07/11/2000
java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)
Application still dead locks when displaying a JOptionPane whilst performing
drag and drop. Interstingly when run from the command line control-c no longer
kills the application - it now enters a tight loop consuming all of the CPU!
(On 1.2.2_05a at least control-c ends the app!).
Run the following app:
java DNDLock lock - will kill it
java DNDLock - works round it
////////////////////////////
// code starts
import java.awt.*;
import java.awt.datatransfer.*;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.awt.dnd.*;
import javax.swing.*;
import javax.swing.border.*;
/** Deadlock within 1.3. JOptionPane within DND method = death.<p>
** Workround use SwingUtilities.invokeLater.
**/
public class DNDLock extends JFrame
{
private static boolean m_showingDialog = false;
private static boolean m_performLockup = false;
public static void main(String[] args)
{
DNDLock application = new DNDLock("SERVICEPower DND Lock-up
Application: Displaying Dialogs");
if(args.length == 1)
{
if(args[0].equals("lock"))
{
m_performLockup = true;
}
}
application.show();
return;
}
/** Ctor sets up the basic dialog **/
public DNDLock(final String title)
{
super(title);
getContentPane().add(m_mainPanel);
m_mainPanel.add(m_centrePanel, BorderLayout.CENTER);
// handle the frame's close button being pressed
java.awt.event.WindowListener l = new java.awt.event.WindowAdapter()
{
public void windowClosing(java.awt.event.WindowEvent event)
{
System.err.println("DNDLock ended");
System.exit(0);
}
};
addWindowListener(l);
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setSize(500, 250);
m_centrePanel.add(m_fifthObject);
}
private JPanel m_mainPanel = new JPanel(new BorderLayout());
private DropPanel m_centrePanel = new DropPanel(Color.black, "Centre");
private DraggableObject m_fifthObject = new DraggableObject("DRAG OBJECT
5", m_centrePanel);
/**************************************************************************
** DropPanel <p>
** Instances of this are available as drop targets, in this application
** they simply display some text to state where they are up to.
**************************************************************************/
public class DropPanel extends JPanel implements DropTargetListener
{
public DropPanel(final Color color, final String name)
{
m_name = name;
setBorder(BorderFactory.createLineBorder(color));
m_dropTarget = new DropTarget(this, this);
}
///////////////////////////////////////////////////////////////////////
// DropTargetListener implementation
public void dragEnter(DropTargetDragEvent dtde)
{
System.err.println(m_name + " - dragEnter");
m_draggingHere = true;
setCurrentDragBounds(dtde.getLocation());
dtde.acceptDrag(dtde.getSourceActions());
}
/** This processing as invokeLater works with 1.3, and 1.2.2_05a but
not with 1.2.2-W **/
public void dragOver(DropTargetDragEvent dtde)
{
System.err.println(m_name + " - dragOver");
setCurrentDragBounds(dtde.getLocation());
dtde.acceptDrag(dtde.getSourceActions());
if(m_performLockup)
{
JOptionPane.showMessageDialog(null, "Has this locked the
application?", "Are we locked", JOptionPane.QUESTION_MESSAGE);
}
else
{
if(!DNDLock.m_showingDialog)
{
DNDLock.m_showingDialog = true;
SwingUtilities.invokeLater(new Runnable()
{
public void run()
{
JOptionPane.showMessageDialog(null, "Has this
locked the application?", "Are we locked", JOptionPane.QUESTION_MESSAGE);
DNDLock.m_showingDialog = false;
}
});
}
}
repaint();
}
public void dropActionChanged(DropTargetDragEvent dtde)
{
System.err.println(m_name + " - dropActionChanged");
setCurrentDragBounds(dtde.getLocation());
}
public void dragExit(DropTargetEvent dte)
{
System.err.println(m_name + " - dragExit");
m_draggingHere = false;
}
public void drop(DropTargetDropEvent dtde)
{
System.err.println(m_name + " - drop");
setCurrentDragBounds(dtde.getLocation());
dtde.rejectDrop();
dtde.dropComplete(true);
m_draggingHere = false;
}
/** It is not necessary to include any of your own drawing code to get
the application to lock.
** This code is included because it is similar in spirit to our core
application. **/
public void paintComponent(Graphics g)
{
super.paintComponent(g);
paintDrag(g, m_draggingHere);
}
/** As for paintComponent, this is not needed to hang the application.
**/
public void paintDrag(Graphics g, boolean dragging)
{
Rectangle rect = (Rectangle)m_repaintRect.clone();
Graphics2D g2 = (Graphics2D) g;
Color oldColor = g.getColor();
if(dragging)
{
g2.setColor(Color.yellow);
}
else
{
g2.setColor(Color.lightGray);
}
Stroke s = g2.getStroke();
g2.setStroke(m_rectStroke);
g2.draw(rect);
g2.setColor(oldColor);
g2.setStroke(s);
}
private void setCurrentDragBounds(final Point location)
{
// repaint rectangle
m_repaintRect.x = location.x;
m_repaintRect.y = location.y;
m_repaintRect.width = 100;
m_repaintRect.height = 50;
}
private Rectangle m_repaintRect = new Rectangle();
private boolean m_draggingHere = false;
private final String m_name;
private DropTarget m_dropTarget;
private final float[] dash1 = {10.0f};
private BasicStroke m_rectStroke = new BasicStroke(3.0f,
BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash1, 0.0f);
}
/**************************************************************************
** DraggableObject <p>
** Instances of this JComponent derivations are used as draggable objects
** within the core application. Here I use a JLabel for simplicity.
**************************************************************************/
public class DraggableObject extends JLabel
implements DragSourceListener,
DragGestureListener, Transferable
{
public DraggableObject(final String name, JPanel owner)
{
setText(name);
setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
m_owner = owner;
m_name = name;
m_dragSource = DragSource.getDefaultDragSource();
m_dragComponent = this;
m_gestureRecogniser =
m_dragSource.createDefaultDragGestureRecognizer(m_dragComponent,
DnDConstants.ACTION_COPY_OR_MOVE, this);
}
///////////////////////////////////////////////////////////////////////
// DragSourceListener implementation
public void dragDropEnd(DragSourceDropEvent dsde)
{
System.err.println(m_name + " - dragDropEnd: " + dsde.getDropSuccess
());
m_owner.repaint();
m_owner.revalidate();
}
public void dragEnter(DragSourceDragEvent dsde)
{
System.err.println(m_name + " - dragEnter");
}
public void dragExit(DragSourceEvent dse)
{
System.err.println(m_name + " - dragExit");
}
public void dragOver(DragSourceDragEvent dsde)
{
System.err.println(m_name + " - dragOver");
}
/** It is not necessary to include any of your own drawing code to get
the application to lock.
** This code is included because it is similar in spirit to our core
application. **/
public void paintComponent1(Graphics g)
{
super.paintComponent(g);
m_owner.repaint();
}
public void dropActionChanged(DragSourceDragEvent dsde)
{
System.err.println(m_name + " - dropActionChanged");
}
///////////////////////////////////////////////////////////////////////
// DragGestureListener implementation
public void dragGestureRecognized(DragGestureEvent dge)
{
System.err.println(m_name + " - dragGestureRecognized");
// we're in a valid drag situation
dge.startDrag(DragSource.DefaultMoveDrop, this, this);
}
///////////////////////////////////////////////////////////////////////
// Transferable implementation
public DataFlavor[] getTransferDataFlavors()
{
DataFlavor[] flavours = { DRAG_FLAVOUR };
return flavours;
}
public boolean isDataFlavorSupported(DataFlavor flavour)
{
return flavour.equals(DRAG_FLAVOUR);
}
public Object getTransferData(DataFlavor flavor) throws
UnsupportedFlavorException, IOException
{
return new String(m_name + " transferData");
}
private JPanel m_owner;
private String m_name;
private DragSource m_dragSource;
private DragGestureRecognizer m_gestureRecogniser;
private JComponent m_dragComponent;
}
///////////////////////////////////////////////////////////////////////////
// DataFlavor stuff for DragGesture implementation
public static DataFlavor DRAG_FLAVOUR = new DataFlavor
(DragFlavour.class, "DragFlavor");
public class DragFlavour
{
public DragFlavour()
{
}
}
}
// code ends
////////////////////////////
(Review ID: 107069)
======================================================================
- relates to
-
JDK-4484572 Modal JOptionPane.showMessageDialog locks if called during Drag-N-Drop
-
- Closed
-
-
JDK-4633417 JVM completely locks up when dragging to an app that has a modal dialog showing.
-
- Closed
-
-
JDK-4645584 Invoking modal dialog while performing DnD freezes application.
-
- Closed
-