-
Bug
-
Resolution: Duplicate
-
P3
-
None
-
1.4.0
-
x86
-
linux
Name: rmT116609 Date: 10/29/2001
java version "1.4.0-beta2"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0-beta2-b77)
Java HotSpot(TM) Client VM (build 1.4.0-beta2-b77, mixed mode)
The following code is based off of the autoscrolling implementation found in http://forum.java.sun.com/thread.jsp?forum=57&thread=167661.
It is primarily used for Drag and Drop implementation. However, it also can be used for other JPanel functionality.
The code has been used with good results on the following:
Windows NT with Sun's JDK 1.3.1_01
Solaris 2.8 with Sun's JDK 1.3.1_01
Linux Redhat 6.2 with Sun's JDK1.3.1_01
Mandrake 7.0 (build 2.2.14-15) with IBM jdk 1.3
Mandrake 8.0 (build 2.4.3-20) with IBM jdk 1.3
The code breaks on the following:
Mandrake 8.0 (build 2.4.3-20) with Sun jdk 1.4 beta2
Windows 2000 using Sun JDK1.4.0-beta2
Linux, Redhat 6.2 using Sun JDK1.4.0-beta2
Solaris 2.8 using Sun JDK 1.4.0-beta2
When you are draging and dropping the cursor when it is at the right or bottom edges should grow and the Jscrollpane should follow it with the
growth. That happens and it works on all the other platforms I mentioned. When it is at the top and left edges the JScrollPane moves over if it can.
The behavior I get is very crappy. It grows a little bit and then it scrolls back and forth. If you perform a drop, the JScrollpane is still screwed up.
You can move the scrollbar all the way down, but the scroll bar will then move back up.
I'm not sure what the 1.3.1 behavior on Mandrake 8 (see related linux build in my post) is because drag and drop just does not work at all.
Long and short of it: if you are at the right or bottom edge, the underlying Panel (SystemGraph) grows in that direction. JScrollPane will then scroll
down a little. Not very complicated. In beta2, the JPanel grows a little bit and then stops, goes back, goes forward, goes back... and then it has
the other bad behavior once the drop is over.
To reproduce the phenomena:
1) compile the example code
2) drag an item from the JTree to the JPanel
3) place the cursor by the bottom or right edges
4) watch
5) after some time drop the item (it should produce a System.out)
6) then try to move the scroll bar to a set position (the scroll bar will promptly move back)
Source Code
BugExample.java
_________________________________________
import javax.swing.*;
import javax.swing.tree.*;
import java.io.*;
import java.util.*;
import java.lang.*;
import java.awt.*;
import java.awt.event.*;
import java.beans.*;
public class BugExample extends JFrame {
private JScrollPane scrollPane;
private SystemGraph systemGraph;
private JPanel mainPanel;
private ModelToolbox toolbox;
BugExample(){
Container cp = getContentPane();
systemGraph = new SystemGraph(scrollPane);
scrollPane = new JScrollPane(systemGraph);
scrollPane.getVerticalScrollBar().setUnitIncrement(10);
scrollPane.getHorizontalScrollBar().setUnitIncrement(30);
cp.add(scrollPane);
cp.setVisible(true);
toolbox = new ModelToolbox(this);
toolbox.setSize(260,500);
toolbox.setVisible(true);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
setLocation(261,40);
setSize(600,500);
super.show();
}
public static void main(String argv[]) {
System.out.println("Hello world.");
BugExample bugExample = new BugExample();
System.out.println("Hello again.");
}
}
___________________________________________________
ModelToolbox.java
___________________________________________________
import javax.swing.tree.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
public class ModelToolbox extends JFrame {
private DnDTree tree;
private BugExample bugExample;
public ModelToolbox(BugExample bde) {
super("Model Toolbox");
createTree();
tree.setRootVisible(true);
tree.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent me) {
}
});
JScrollPane scroll_p = new JScrollPane();
scroll_p.setViewportView(tree);
// consider adding these to a panel & adding panel to frame
getContentPane().setLayout(new BorderLayout());
getContentPane().add(scroll_p, BorderLayout.CENTER);
}
public JTree getTree() {
return tree;
}
private void createTree() {
DefaultMutableTreeNode rootNode=new DefaultMutableTreeNode("Model Toolbox");
DefaultMutableTreeNode ctrlNodes =
new DefaultMutableTreeNode("Controlled Models");
ctrlNodes.add(new DefaultMutableTreeNode("Example1"));
ctrlNodes.add(new DefaultMutableTreeNode("Example2"));
ctrlNodes.add(new DefaultMutableTreeNode("Example3"));
rootNode.add(ctrlNodes);
tree = new DnDTree(rootNode, this);
tree.expandRow(1);
}
}
______________________________________________________
DnDTree.java
_______________________________________________________
import javax.swing.tree.*;
import javax.swing.*;
import javax.swing.event.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.util.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
import java.awt.image.*;
public class DnDTree extends JTree implements DragGestureListener, DragSourceListener {
eDragSource dragSource = null;
private ModelToolbox modelToolbox;
private Cursor cursor;
public DnDTree(DefaultMutableTreeNode node, ModelToolbox toolbox)
{
super(node);
// giving a handle to ModelToolbox so we can access its private values
modelToolbox = toolbox;
dragSource = new eDragSource();
dragSource.createDefaultDragGestureRecognizer(this, DnDConstants.ACTION_MOVE, this);
cursor = getCursor(); // hold onto original cursor
}
// implementation DragSourceListener
public void dragDropEnd(DragSourceDropEvent dsde)
{
System.out.println("I am in dragDropEnd.");
}
public void dragEnter(DragSourceDragEvent dsde)
{
}
public void dragExit(DragSourceEvent dse)
{}
public void dragOver(DragSourceDragEvent dsde)
{
}
public void dropActionChanged(DragSourceDragEvent dsde)
{}
// implementation of DragGestureListener
public void dragGestureRecognized(DragGestureEvent event)
{
String tree_path = getSelectionPath().toString();
if (((TreeNode)(getSelectionPath().getLastPathComponent())).isLeaf())
{
StringTokenizer st = new StringTokenizer(tree_path, ",");
StringSelection text = new StringSelection(st.toString());
dragSource.startDrag(event, DragSource.DefaultMoveDrop, text, this);
}
}
class eDragSource extends DragSource {
public DragSourceContext createDragSourceContext(
java.awt.dnd.peer.DragSourceContextPeer dscp,
DragGestureEvent dgl,
Cursor myCursor,
Image img,
Point offset,
Transferable t,
DragSourceListener dsl) {
return new eDragSourceContext(dscp,dgl,myCursor,img,offset,t,dsl);
}
}
class eDragSourceContext extends DragSourceContext {
public eDragSourceContext(java.awt.dnd.peer.DragSourceContextPeer dscp, DragGestureEvent dgl, Cursor cursor, Image img, Point offset, Transferable t,
DragSourceListener dsl) {
super(dscp,dgl,cursor,img,offset,t,dsl);
}
}
}
_____________________________________________________________________
SystemGraph.java
_____________________________________________________________________
import java.awt.*;
import javax.swing.*;
import java.io.*;
import java.awt.event.*;
import java.util.*;
import java.beans.*;
import java.lang.reflect.*;
import java.awt.dnd.*;
import java.awt.datatransfer.*;
public class SystemGraph extends JPanel implements DropTargetListener, Autoscroll{
private int gridSpacing;
private int width;
private int height;
// this all supports drag and drop
static int autoscrollMargin = 20;
Insets autoscrollInsets = new Insets(0,0,0,0);
DropTarget dropTarget = null;
private Cursor cursor;
private Cursor myCursor;
private JScrollPane scrollPane;
public SystemGraph(JScrollPane jsp) {
scrollPane = jsp;
setLayout(null);
setForeground(Color.black);
setBackground(Color.white);
setCanvasSize(new Dimension(600,400));
width = 600;
height = 400;
gridSpacing = 20;
dropTarget = new DropTarget (this, this);
setAutoscrolls(true);
cursor = getCursor();
setVisible(true);
}
public void setCanvasSize(int w, int h)
{
width = w;
height = h;
setCanvasSize(new Dimension(width, height));
}
public void setCanvasSize(Dimension size)
{
computeMaximumSize(size);
setPreferredSize(size);
setSize(size);
}
private void computeMaximumSize(Dimension size)
{
if(size.width >= getWidth() && size.height >= getHeight())
return;
Component[] elements = getComponents();
for(int i=0; i<elements.length; i++){
size.width = Math.max(size.width, elements[i].getX() + elements[i].getWidth());
size.height = Math.max(size.height, elements[i].getY() + elements[i].getHeight());
}
size.width = Math.max(size.width, getScrollPaneWidth());
size.height = Math.max(size.height, getScrollPaneHeight());
}
public int getGridSpacing()
{
return gridSpacing;
}
public void changeBackgroundColor()
{
Color backgroundColor = JColorChooser.showDialog(getParent(), "Select Background Color", getBackground());
if (backgroundColor != null)
setBackground(backgroundColor);
}
public void add(JComponent jc){
super.add(jc);
updateUI();
}
public void setBackground(Color c) {
Color oldColor = getBackground();
super.setBackground(c);
}
public void resizeCanvas() {
Dimension d = getSize();
setCanvasSize(d);
}
public Point point2grid(int x, int y, int width, int height){
// x and y are new desired location which will be converted
// to the nearest grid point
x = x - (x % gridSpacing);
y = y - (y % gridSpacing);
if (x<0) {
x = 0;
}
if (y<0) {
y = 0;
}
if (x > getWidth() - width) {
// increase width if going off the right edge
setCanvasSize(x+width, getHeight());
}
if (y > getHeight() - height) {
// increase height if going off the bottom edge
setCanvasSize(getWidth(), y+height);
}
return(new Point(x,y));
}
// implementation of DropTargetListener
public void dragEnter(DropTargetDragEvent event)
{
}
public void dragExit(DropTargetEvent event)
{
// System.out.println("I am in dragExit.");
}
public void dragOver(DropTargetDragEvent event)
{
}
public void drop(DropTargetDropEvent event)
{
try {
Transferable transferable = event.getTransferable();
// we accept only Strings
if (transferable.isDataFlavorSupported (DataFlavor.stringFlavor)){
event.acceptDrop(DnDConstants.ACTION_COPY);
String path = (String)transferable.getTransferData ( DataFlavor.stringFlavor);
System.out.println("drop target got data: " + path);
event.getDropTargetContext().dropComplete(true);
// put in logic to turn back cursor
setCursor(cursor);
}
else{
event.rejectDrop();
// put in logic to turn back cursor
setCursor(cursor);
}
}
catch(Exception e){
System.out.println(e.toString());
e.printStackTrace();
}
}
public void dropActionChanged(DropTargetDragEvent event)
{}
//implement Autoscroll
public Insets getAutoscrollInsets()
{
Dimension size = getSize();
Rectangle rect = getVisibleRect();
autoscrollInsets.top = rect.y + autoscrollMargin;
autoscrollInsets.left = rect.x + autoscrollMargin;
autoscrollInsets.bottom = size.height - (rect.y + rect.height) + autoscrollMargin;
autoscrollInsets.right = size.width - (rect.x + rect.width) + autoscrollMargin;
return autoscrollInsets;
}
public void autoscroll(Point location)
{
int top = 0, left = 0, bottom = 0, right = 0;
Dimension size = getSize();
Rectangle rect = getVisibleRect();
int bottomEdge = rect.y + rect.height;
int rightEdge = rect.x + rect.width;
if (location.y - rect.y <= autoscrollMargin && rect.y > 0)
top = autoscrollMargin;
if (location.x - rect.x <= autoscrollMargin && rect.x > 0)
left = autoscrollMargin;
if (bottomEdge - location.y <= autoscrollMargin && bottomEdge < size.height)
bottom = autoscrollMargin;
if (rightEdge - location.x <= autoscrollMargin && rightEdge < size.width)
right = autoscrollMargin;
rect.x += right - left;
rect.y += bottom - top;
scrollRectToVisible(rect);
// increase width or height if
if ((location.x + gridSpacing) > getWidth() )
{
setCanvasSize(getWidth()+gridSpacing, getHeight());
}
if ((location.y + gridSpacing) > getHeight())
{
setCanvasSize(getWidth(), getHeight()+gridSpacing);
}
}
public int getAutoscrollMargin()
{ return autoscrollMargin; }
public int getScrollPaneWidth(){
if(scrollPane == null)
return 0;
else
return scrollPane.getViewport().getExtentSize().width;
}
public int getScrollPaneHeight(){
if(scrollPane == null)
return 0;
else
return scrollPane.getViewport().getExtentSize().height;
}
}
(Review ID: 134307)
======================================================================
- duplicates
-
JDK-4516490 REGRESSION: DropTarget causes autoscroll method to enter into infinite loop
-
- Closed
-