AWT Drag Events Not Registering

Note: I couldn’t find a reasonable forum to post this here. I normally am active in this section so I choose here. You may move it if you wish :). I also posted this on the Sun forums but it has garnered no replies.

Hi all,

I have written up a small program (code is at the bottom) that uses the getToolkit().addAWTEventListener(new AWTEventListener() code. In it, it will listen for drag events. If it detects one, it will update a variable called currentPoint. Then I have a subclassed JPanel that everytime it paints, will display a rectangle at the current point.

I then run the program and drag my mouse around for maybe 30 seconds. Things work 100% correct. After that though, it seems the AWTEventListener begins missing the events and the currentpoint doesn’t update. This means the block that is following my mouse stops as my mouse cursor moves away during the drag. The point updates about a second later. So for example: If I am moving along the x-axis, the block follows me until say (10, 5) and then stops. My mouse then continues to move and it gets to (15,5) and then the block updates and jumps to that point. During this period, the AWT listener does not receive any mouse events. These actions steadily get worse and worse as I run the program.

Does anyone have any idea what is occuring? I haven’t given much thought but maybe the GC? You can also look at the output and there are no events processed during that time…

Thanks,
day

Code:


 
package main;
 
import java.awt.AWTEvent;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.AWTEventListener;
import java.awt.event.MouseEvent;
import java.io.BufferedWriter;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.Writer;
 
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
 
 
 
 
public class DragWindow extends JFrame
{
	private Point currentPoint = null;
	private PaintPanel paintPanel;
	private boolean dragging = false;
 
	public DragWindow()
	{
		super("Drag Test");
		paintPanel = new PaintPanel(this);
		
		this.getContentPane().add(paintPanel);
		
		try
		{
			 final PrintWriter out
			   = new PrintWriter(new BufferedWriter(new FileWriter("dragData.txt")));
			
			addWindowListener(new ExitListener(out));
			setSize(1280, 1024);
			setLocation(0, 0);
			setVisible(true);
			
			
			getToolkit().addAWTEventListener(new AWTEventListener()
	   		{
	   			public void eventDispatched ( AWTEvent e )
	   			{
 
	   				Point point = ((MouseEvent)e).getPoint();
	   				currentPoint = point;
	   				
	   				System.out.println("Parsed this: X: " + point.x + ". Y: " + point.y);
	   				
	   				out.write("Parsed this: X: " + point.x + ". Y: " + point.y + "\n");
	   				out.flush();
	   				if(e.getID() == MouseEvent.MOUSE_DRAGGED)
	   				{
	   					String data = "MOUSE_DRAGGED: Event: " + e.paramString();
	   					System.out.println(data);
	   					out.write(data);
	   					out.flush();
	   					dragging = true;
	   				
	   				}
	   				else if(e.getID() == MouseEvent.MOUSE_RELEASED)
	   				{
	   					String data = "MOUSE_RELEASED: Event: " + e.paramString();
	   					System.out.println(data);
	   					out.write(data);
	   					out.flush();
	   					dragging = false;
	   				}
	   				
	   				repaint();
	   			}
	 
		   	
	   		}, AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK
 
	   		);
		}
		catch (FileNotFoundException e1)
		{
			e1.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		
		
	}
 
	/**
	 * @return Returns the currentPoint.
	 */
	public Point getCurrentPoint ()
	{
		return currentPoint;
	}
 
	/**
	 * @param currentPoint The currentPoint to set.
	 */
	public void setCurrentPoint ( Point currentPoint )
	{
		this.currentPoint = currentPoint;
	}
 
	/**
	 * @return Returns the dragging.
	 */
	public boolean isDragging ()
	{
		return dragging;
	}
 
	/**
	 * @param dragging The dragging to set.
	 */
	public void setDragging ( boolean dragging )
	{
		this.dragging = dragging;
	}
	
	
}
 
 
package main;
 
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
 
import javax.swing.JPanel;
 
public class PaintPanel extends JPanel
{
	DragWindow window;
	public PaintPanel ( DragWindow window )
	{
		this.window = window;
	}
	public void paintComponent(Graphics g)
	{
		super.paintComponents(g);
		
		Graphics2D g2d = (Graphics2D)g;
		
		
		if(window.getCurrentPoint() != null && window.isDragging())
		{
			Rectangle rectPoint = new Rectangle(window.getCurrentPoint().x, window.getCurrentPoint().y, 20, 20);
			g2d.fill(rectPoint);
		}
	}
}
 
package main;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.PrintWriter;
 
import javax.swing.JFrame;
 
/** A listener that you attach to the top-level Frame or JFrame of
 *  your application, so quitting the frame exits the application.
 *  1998 Marty Hall, http://www.apl.jhu.edu/~hall/java/
 */
 
public class ExitListener extends WindowAdapter 
{
	private JFrame frame;
	private PrintWriter outi;
	
	public ExitListener(PrintWriter o)
	{
		outi = o;
	}
	
	/**
	 * @return Returns the frame.
	 */
	public JFrame getFrame ()
	{
		return frame;
	}
 
	/**
	 * @param frame The frame to set.
	 */
	public void setFrame ( JFrame frame )
	{
		this.frame = frame;
		
	}
 
	
	public void windowClosing(WindowEvent event) 
	{
		outi.close();
		System.exit(0);	
	}
}
 

	
 

I’d suggest you to use MouseEvent’s that extend the AWTEvent you’re impl, because AWTEvent is declared abstract. BTW, abstract means not to be used as instance but for clearier Class struct. in Java, of course. :wink:

Thanks for your reply.

I originally tried to use the mouse event and mouse listener concept, but I have far too many windows and components on the screen that I want to use drag and drop on. It turned out to be a big mess and was buggy. The above works 99% of the time WHEN it’s getting the drag events. I guess I could subclass the event listener and use that instead, but, I don’t think it would fix my problem - but it may.

Any other ideas or thoughts?

Edit: More on what I am trying to do: Get the global mouse position everytime it changes and if its dragging. I need the absolute coordinates regardless of where the cursor is.

Well, I was playing around with things…I removed the debug statements I had in parts of my main code (not the demo) and the missing events stopped occuring. I put it back in and they reappeared…

So - does Java skip events if the processor/I/O is really busy or something?

It really shouldn’t skip events, regardless of I/O or CPU-usage.

Maybe this is a nice alternative:
Point p = MouseInfo.getPointerInfo().getLocation();

Although that’s only the mouse-position.

the main issue about Swing Events is that if they 're registered as EventListeners, the Thread that will dispatch the event is the SwingEDT which is meaningwhile set at a fixed rate. Hence each refresh would occur at a fixed time which isn’t the case in one Game Pattern that gets to more quicker reactivity.
For those simple reasons, it is quite the best thing to use another registry, the AWTEventDispatcher, as the KeyboardFocusManager does hold one. That brings on-time events and does not affect your Threads TimeLines, as we’d call those Game Pattern behaviours. What’s your point? ::slight_smile: ::slight_smile: ::slight_smile: