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

huangapple go评论64阅读模式
英文:

Adding mouse listener with JPanel to JFrame containing an Earth map (Java)

问题

这是主类中的代码:

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];

        // 根据海拔高度设置颜色

        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);
        }
    }
}
英文:

I am trying to add a mouse listener by JPanel to my JFrame. When I add the listener, the map dissapears but it is working properly (shows the Earth map) when i delete the code for the listener. The purpose of the listener is to print the coordinates, add the coordinates to a map and calculate the distance between two points. Coordinates are provided with a text file and there are nearly 2 million coordinates. It does not show any errors. I have another class for drawing the map and calculating the distance and they are working properly. Without mouse listener code for drawing the map is working properly and with the mouse listener the map dissapears but listener works the way it should be. Thanks for all helps in advance.

This is the code in main class:

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

This is the code which extends JComponent (DrawEarth is the constructor):

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

I did not provide the code for calculating distanece between the coordinates as it works properly.

答案1

得分: 0

以下是翻译好的内容:

这里没有太多的代码,以下是解决问题所需的两个必要类,第二个类中的大部分代码只是根据高度值进行颜色编辑。如果您仔细阅读整个代码,您会认识到您不需要完整查看第一个类中的所有代码来解决问题。提供所有所需的代码非常有用。错误可能在代码的某个地方。更重要的是,这个问题不是任何其他问题的副本。在这个问题的情况下,代码不多,易于阅读,不需要更多信息。这个问题的答案是在paintComponent方法中的Graphics2D对象之前使用super关键字。代码如下所示:

...

@Override 
public void paintComponent(Graphics g){
        super.paintComponent(g);
        Graphics2D dr = (Graphics2D) g;

        for (int i = 0; i < e.arrayOfEarth.length; i++) {

...

这将解决整个问题,程序将按预期运行。同时,无需使用JPannel。如果您将鼠标监听器直接添加到JFrame中,它将以相同的方式工作,代码如下所示:

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

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

英文:

There is not a lot of code, these are the two necessary classes for solving the problem and most of the code in the second class is just for editing the color according to the value of altitude. If you read the whole code properly, you will recognize that you don't need to look the whole code in first class as well for solving the problem. It is very very useful to provide the all needed code. The error may be in somewhere in the code. More importantly, this question is not a duplicate of any other question. In case of this question, there is not a lot of code and it is easy to read and no more information is needed. The answer for this question is to use super keyword in paintComponent method right before the Graphics2D object. it will look like this:

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

This will solve the whole problem and the program will just run how it should be. Also there is no need to use JPannel. If you add your mouse listener to JFrame directly, it will work the same way again, which will look like this:

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

Thank you all for not looking through my code properly and just writing more information needed or there is a lot of code etc. and thank you all for making me to solve my own question and not using this platform properly.

huangapple
  • 本文由 发表于 2020年4月8日 22:18:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/61102914.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定