我正在做一项学校作业,要求我能够拿起一块瓷砖,将其拖到某个位置,然后放到那里。我可以使用TransferHandler
和dnd包中的一堆东西使它正常工作,但是根据教授的说法,这不是执行此任务的动作的可接受方法。因此,我正在尝试使用MouseListener
接口实现相同的效果。
基本设置是这样的:我有一个JPanel
派生的类,称为LocationView
,其中包含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());
}
最佳答案
尽管有可能让mouseReleased
提供释放鼠标的实际组件作为其来源,但这将带来更多的麻烦,而不是值得的。
以下内容可用于标识释放鼠标的组件。
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());
}