68650


以下のプログラムで、インスタンスメソッド

[code]

    public void hito(int x, int y) {
        double a= x+y ;
        System.out.println(a);
        
    }
    
[/code]

を定義し、外側クラスで

[code]

    circles[3].hito(evt.getX(), evt.getY());
    
[/code]

と書きました。これは、3つ目の円をクリックした際に、x座標の値と、y座標の値の合計を表示させようという意図です。  
しかし、実際に実行してみると、パネル内のどこをクリックしても、座標値の合計が出てしまいます。つまり、3つ目の円以外の箇所どこでもクリックしても、表示されてしまい、circles[3]と指定した意味がなくなっています。  
なぜこのようなことが起こるのでしょうか？  

[code]

      import java.awt.*;
      import javax.swing.*;
      import java.awt.event.*;
    
      public class Sample91ex3 extends JPanel {
        Circle[] circles = new Circle[20];
        //Circle sel = null;
    
        public Sample91ex3() {
          setOpaque(false);
          int x = 30;
          for (int i = 0; i<20 ; ++ i) {
            circles[i] = new Circle(Color.black, x, 100, 15);
            x = x + 40;  
          }
    
          addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent evt) {
              for (int i = 0; i<20 ; ++ i) {
                if(circles[i].hit(evt.getX(), evt.getY())) {
                 // sel = circles[i];
                  circles[i].changeColor();
                  circles[i].moveBy(10, 10);
                  
                  repaint();
                }
                
    
              }
            circles[3].hito(evt.getX(), evt.getY());
            }
          });
        }
    
        public void paintComponent(Graphics g) {
          for (int i = 0; i < 20; ++i) {circles[i].draw(g); }
        }
    
        public static void main(String[] args) {
          JFrame app = new JFrame();
          app.add(new Sample91ex3());
          app.setSize(800, 300);
          app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          app.setVisible(true);
        }
    
    
        static class Circle {
          int xpos, ypos, rad;
          Color col;
          public Circle(Color c, int x, int y, int r) {
            col = c ; xpos = x; ypos = y; rad = r;
          }
          public void draw(Graphics g) {
            g.setColor(col);
            g.fillOval(xpos-rad, ypos-rad, rad*2, rad*2);
          }
          public void moveBy(int x, int y) {
            xpos = xpos + x ; ypos = ypos + y;
          }
    
          public void moveTo(int x, int y) {
            xpos = x; ypos = y;
          }
          public boolean hit(int x, int y) {
            return (xpos-x)*(xpos-x) + (ypos-y)*(ypos-y) <= rad*rad;
          }
    
          public void hito(int x, int y) {
            double a= x+y ;
            System.out.println(a);
            
          }
          public void setColor(Color c) {
            col = c;
          }
          public void changeColor() {
            col = new Color((int)(Math.random()*255),(int)(Math.random()*255),
                            (int)(Math.random()*255));
          }
        }
      }
    
[/code]


CC BY-SA 4.0
2020-07-16T03:31:44.723
68633
2020-07-16T15:15:26.127
2020-07-16T15:15:26.127
2808
39688
question
java
特定の箇所をクリックした場合のみ実行する意図の処理が、それ以外をクリックしても実行されてしまう


> 3つ目の円以外の箇所どこでもクリックしても、表示されてしまい、circles[3]と指定した意味がなくなっています。  
>  なぜこのようなことが起こるのでしょうか？

引数で渡しているのはクリックした座標ですが、その座標が円の中であるかを判定する必要があります。

[code]

    public void hito(int x, int y) {
        if (hit(x, y)) {
            double a = x + y;
            System.out.println(a);
        }
    }
    
[/code]

* * *

なお、

[code]

    addMouseListener(new MouseAdapter() {
        public void mousePressed(MouseEvent evt) {
            for (int i = 0; i < 20; ++i) {
                if (circles[i].hit(evt.getX(), evt.getY())) {
                    // ...
                    repaint();
                }
    
            }
            circles[3].hito(evt.getX(), evt.getY());
        }
    });
    
[/code]

の `circles[3].hito(evt.getX(), evt.getY());` についてですが、

  * このタイミングでは既に円は移動済み。つまり判定することになるのは、「移動済みの円の中にクリックした座標が含まれるか」になります。それが意図した挙動でないのなら、forループの前に実行することになると思います。
  * 配列の添字は`0`始まりなので、`circles[3]`というのは実際には4つめの円であることに注意してください。(質問文を見る限り、意図しているのは `circles[2]` ではないかという気もします)


CC BY-SA 4.0
2020-07-16T14:40:07.947
68650
2020-07-16T14:40:07.947
2808
68633
answer