将带有JPanel的鼠标监听器添加到包含地球地图的JFrame中(Java)



我正试图通过JPanel将鼠标侦听器添加到我的JFrame中。当我添加侦听器时,地图会消失,但当我删除侦听器的代码时,它可以正常工作(显示地球地图(。监听器的目的是打印坐标,将坐标添加到地图中,并计算两点之间的距离。坐标由一个文本文件提供,有近200万个坐标。它没有显示任何错误。我还有另一门课,用来绘制地图和计算距离,它们都能正常工作。如果没有绘制地图的鼠标侦听器代码,地图就可以正常工作,而有了鼠标侦听器,地图就会消失,但侦听器的工作方式应该是这样的。感谢您提前提供的所有帮助。

这是主类中的代码:

public static void main(String[] args) throws FileNotFoundException {
Map<Integer, Integer> mapC = new TreeMap<>();
JFrame frame = new JFrame("Earth Map");
JPanel panel = new JPanel();
panel.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e){
if (SwingUtilities.isLeftMouseButton(e) && e.getClickCount() == 1) {
int lon = e.getX();
int lat = e.getY();
if(mapC.get(lon) == null){
mapC.put(lon, lat);
}
for (Map.Entry<Integer, Integer> entry : mapC.entrySet()) {
System.out.println("Coordinate clicked: " + entry.getKey() + "," + entry.getValue().toString());
}
if(mapC.size() > 1 && mapC.size() == 2){
MapCoordinate obj = new MapCoordinate();
int count = 0;
int lon1 = 0, lon2 = 0, lat1 = 0, lat2 = 0;
for (Map.Entry<Integer, Integer> entry : mapC.entrySet()) {
if(count == 0){
lon1 = entry.getKey();
lat1 = entry.getValue();
count++;
}else if(count == 1){
lon2 = entry.getKey();
lat2 = entry.getValue();
}
}
obj.distance(lat1, lat2, lon1, lon2);
}else{
System.out.println("Click to another coordinate or click right to delete last clicked coordinate");
}
}else if(SwingUtilities.isRightMouseButton(e) && e.getClickCount() == 1){
if(mapC.size() >= 1){
int lastK = (int) mapC.keySet().toArray()[mapC.size() - 1];
int lastV = (int) mapC.values().toArray()[mapC.size() - 1];
System.out.println("You deleted last clicked coordinate: " + lastK + "," + lastV);
mapC.remove(lastK);
}else{
System.out.println("Perform a left click to add some coordinates, there is no coordinates to delete.");
}
}
}
});
frame.getContentPane().setPreferredSize(new Dimension(600, 600));
DrawEarth draw = new DrawEarth("src//assignment//earth.txt");
frame.add(draw);
frame.add(panel);
frame.pack();
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int height = screenSize.height;
int width = screenSize.width;
frame.setSize(width / 2, height / 2);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}

这是扩展JComponent的代码(DrawEarth是构造函数(:

protected Earth e;
public Map<Integer, Integer> mapC = new TreeMap<>();
public DrawEarth(String filename) throws FileNotFoundException {
e = new Earth();
e.readDataArray("src//assignment//earth.txt");
}
@Override
public void paintComponent(Graphics g) {
Graphics2D dr = (Graphics2D) g;
for (int i = 0; i < e.arrayOfEarth.length; i++) {
double longitude = e.arrayOfEarth[i][0];
double latitude = e.arrayOfEarth[i][1];
double altitude = e.arrayOfEarth[i][2];
if (altitude <= -4000) {
dr.setColor(new Color(32, 3, 252));
} else if (altitude > -4000 && altitude < -3000) {
dr.setColor(new Color(3, 40, 252));
} else if (altitude > -3000 && altitude < -2000) {
dr.setColor(new Color(3, 80, 252));
} else if (altitude > -2000 && altitude < -1000) {
dr.setColor(new Color(3, 150, 252));
} else if (altitude > -1000 && altitude < 0) {
dr.setColor(new Color(3, 200, 252));
} else if (altitude > 0 && altitude < 200) {
dr.setColor(new Color(2, 230, 48));
} else if (altitude > 200 && altitude < 300) {
dr.setColor(new Color(0, 130, 30));
} else if (altitude > 300 && altitude < 2000) {
dr.setColor(new Color(194, 147, 60));
} else if (altitude > 2000 && altitude < 3000) {
dr.setColor(new Color(101, 67, 33));
} else if (altitude > 3000 && altitude < 4000) {
dr.setColor(new Color(255, 255, 255));
} else if (altitude > 4000) {
dr.setColor(new Color(180, 177, 167));
}
dr.fillRect((int) longitude + 50, ((int) latitude * -1) + 100, 1, 1);
int seaLevel = (int) e.shiftLevel;
String label = "The Earth after sea levels rose by " + seaLevel + " metres";
if (seaLevel != 0) {
dr.drawString(label, 110, 220);
}
}
}

我没有提供计算坐标之间距离的代码,因为它工作正常。

代码不多,这是解决问题所必需的两个类,第二类中的大多数代码只是根据海拔值编辑颜色。如果你正确地阅读了整个代码,你会意识到你不需要在第一类中查看整个代码来解决问题。提供所有需要的代码是非常有用的。错误可能在代码中的某个位置。更重要的是,这个问题并不是其他问题的重复。在这个问题的情况下,没有太多的代码,它很容易阅读,不需要更多的信息。这个问题的答案是在Graphics2D对象之前使用paintComponent方法中的super关键字。它看起来是这样的:

...
@Override 
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D dr = (Graphics2D) g;
for (int i = 0; i < e.arrayOfEarth.length; i++) {
...

这将解决整个问题,程序将按照应有的方式运行。此外,不需要使用JPhannel。如果您将鼠标侦听器直接添加到JFrame,它将再次以相同的方式工作,如下所示:

...
frame.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e){
...

感谢大家没有正确地查看我的代码,只是写了更多需要的信息,或者有很多代码等等。感谢大家让我解决自己的问题,没有正确地使用这个平台。

最新更新