I am working on a school assignment that requires me to be able to pick up a tile, drag it to a location, then drop it there. I was able to get this working using TransferHandler
and a bunch of stuff from the dnd package, but this is not an acceptable way to perform this action for this assignment according to the professor. So, I am trying to achieve the same effect using the MouseListener
interface.
The basic setup is this: I have a JPanel
-derived class called LocationView
that contains JLabel
-dervived instances of TileView
. I need to get events that give me the LocationView
that has the mouse pressed on and the LocationView
that has the mouse released on. I am proxying mouse events through the TileView
to its containing LocationView
so that I can properly handle the mousePressed
event.
I added System.out.println()
's to the mouse listeners for mousePressed
and mouseReleased
to both LocationView
and TileView
so that I could observe the events that were being generated. To my surprise, pressing the mouse on Tile A in Location A, then dragging to Location B and releasing would generate a mouse released event for both Tile A and Location A, but not for Location B. I need the mouse released event triggered for only Location B.
开发者_StackOverflow中文版To try to work around this, I tried implementing a glass pane based off of the FinalGlassPane
found at http://weblogs.java.net/blog/2006/09/20/well-behaved-glasspane. After adding the glass pane and adding an event listener for it, I can see that the mouse events are indeed filtering through the glass pane, but the mouse released event is still only being called on the item the mouse was clicked on.
Is there a way to have mousePressed
and mouseReleased
events associated with the same drag action be called on separate components?
EDIT: Here is the solution that I arrived at, based off of the answer by lins314159
public void mouseReleased(MouseEvent e) {
Point p = SwingUtilities.convertPoint(LocationView.this, ((Component)e.getSource()).getLocation(), LocationView.this.wsa.getGameView());
e.translatePoint((int) p.getX(), (int) p.getY());
Component tile = SwingUtilities.getDeepestComponentAt(LocationView.this.wsa.getGameView(), e.getX(), e.getY());
}
While it's likely possible to have mouseReleased
give the actual component the mouse was released on as its source, it would be more trouble than it's worth.
The following can be used to identify the component that the mouse was released on.
public void mouseReleased(MouseEvent evt) {
Point p = ((Component) evt.getSource()).getLocation();
evt.translatePoint((int) p.getX(), (int) p.getY());
Component tile = f.getContentPane().getComponentAt(evt.getX(), evt.getY());
}
精彩评论