JMapViewer,MouseListener调用了2次

使用JMapViewer,可以识别组件的奇怪行为。 我使用DefaultMapController来获取地图位置(lat,lon)。

import java.awt.Graphics; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import javax.swing.JFrame; import org.openstreetmap.gui.jmapviewer.DefaultMapController; import org.openstreetmap.gui.jmapviewer.JMapViewer; public class Test extends JMapViewer{ public Test() { addMouseListener(new DefaultMapController(this) { public void mouseClicked(MouseEvent e){ Point start = e.getPoint(); System.out.println(e.getPoint()); } }); } protected void paintComponent(Graphics g){super.paintComponent(g);} public static void main (String [] args){ JFrame jf = new JFrame(); jf.setSize(800, 600); Test t= new Test(); jf.add(t); jf.setVisible(true); } } 

运行代码,在按下鼠标左键后,方法mouseClicked()被多次调用(2x)。 更换后

  addMouseListener(new DefaultMapController(this) { 

  addMouseListener(new MouseAdapter() { 

代码正常工作,该方法只被调用1次。 哪里有问题? 它是库中的错误还是语法错误或不安全? 如何避免这个问题? 谢谢你的帮助。

您的Test扩展了JMapViewer ,在实例初始化程序块中添加了MouseListener 。 因此 ,“默认构造函数将调用超类的无参数构造函数。” 超类JMapController添加了你的MouseListener – 你第二次猜到了它。

 public JMapController(JMapViewer map) { this.map = map; if (this instanceof MouseListener) map.addMouseListener((MouseListener) this); … } 

相反,创建一个新的JMapControllerDefaultMapController ,如此处所示,并使用它来构造您的JMapViewer

 import java.awt.EventQueue; import java.awt.event.MouseEvent; import javax.swing.JFrame; import org.openstreetmap.gui.jmapviewer.DefaultMapController; import org.openstreetmap.gui.jmapviewer.JMapViewer; /** * @see https://stackoverflow.com/a/39461854/230513 */ public class TestMapController { private void display() { JFrame f = new JFrame("TestMapController"); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JMapViewer map = new JMapViewer(); new DefaultMapController(map) { @Override public void mouseClicked(MouseEvent e) { System.out.println(e.getPoint()); } }; f.add(map); f.pack(); f.setLocationRelativeTo(null); f.setVisible(true); } public static void main(String[] args) { EventQueue.invokeLater(new TestMapController()::display); } }