【发布时间】:2010-04-01 10:14:13
【问题描述】:
我正在处理一项学校作业,该作业要求我能够拿起一块瓷砖,将其拖到某个位置,然后将其放在那里。我能够使用TransferHandler 和 dnd 包中的一堆东西来完成这项工作,但根据教授的说法,这不是为这项作业执行此操作的可接受方式。所以,我尝试使用MouseListener 接口来达到同样的效果。
基本设置是这样的:我有一个名为LocationView 的JPanel 派生类,其中包含JLabel 派生的TileView 实例。我需要获取事件,这些事件为我提供按下鼠标的LocationView 和释放鼠标的LocationView。我正在通过TileView 将鼠标事件代理到它包含的LocationView,以便我可以正确处理mousePressed 事件。
我将System.out.println() 添加到mousePressed 和mouseReleased 的鼠标侦听器到LocationView 和TileView,以便我可以观察正在生成的事件。令我惊讶的是,在位置 A 的图块 A 上按下鼠标,然后拖动到位置 B 并释放会为图块 A 和位置 A 生成鼠标释放事件,但不会为位置 B 生成鼠标释放事件。我只需要触发鼠标释放事件位置 B。
为了解决这个问题,我尝试根据http://weblogs.java.net/blog/2006/09/20/well-behaved-glasspane 中的FinalGlassPane 实现一个玻璃窗格。添加玻璃窗格并为其添加事件侦听器后,我可以看到鼠标事件确实是通过玻璃窗格过滤的,但鼠标释放事件仍然只在鼠标单击的项目上被调用。
有没有办法让mousePressed 和mouseReleased 事件关联到相同的拖动动作在不同的组件上被调用?
编辑: 这是我根据 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());
}
【问题讨论】: