68718


以下のプログラムで質問があります。

  1. MouseMotionAdapterクラスのメソッドであるMouseDraggedの、「isShiftDown」メソッドはCircleクラスでインスタンスメソッドとして定義しなくても使えます。対してMouseAdapterクラスのメソッドである「hit()」メソッドはCircleクラスでインスタンスメソッドとして自分で定義しないと使えません。なぜhit()メソッドは定義しないといけないのでしょうか？  
この両者の違いを教えて下さい。

  2. このプログラムを実行すると、青色の円をドラッグすると、赤い円が消えてしまいます。その後再び青い円をドラッグすると赤い円が表れます。これはどのコードが原因でこうなるのでしょうか？  
出来れば青い円をドラッグしても、赤い円が消えずにそのまま残るようにしたいです。

[code]

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class Sample91ex2 extends JPanel {
        Circle c1 = new Circle(Color.RED, 100, 50, 30);
        Circle c2 = new Circle(Color.BLUE, 150, 90, 40);
        Circle sel;
    
        public Sample91ex2() {
            setOpaque(false);
    
            addMouseListener(new MouseAdapter() {
                public void mousePressed(MouseEvent evt) {
                    requestFocus();
                    if(c1.hit(evt.getX(), evt.getY())) {
                        sel = c1;
                    } else if(c2.hit(evt.getX(), evt.getY())) {
                        sel = c2;
                    }
                    else sel=null;
                }
            });
    
            addMouseMotionListener(new MouseMotionAdapter() {
                public void mouseDragged(MouseEvent evt) {
                    if(sel == null) { return; }
    
                        sel.moveTo(evt.getX(), evt.getY()); repaint();
    
                    }
            });
    
            addMouseMotionListener(new MouseMotionAdapter() {
                public void mouseDragged(MouseEvent evt) {
                    if(evt.isShiftDown()) {
                        c2.moveTo(evt.getX(), evt.getY()); repaint();
                    } else {
                        c1.moveTo(evt.getX(), evt.getY()); repaint();
                    }
                }
            });
    
        }
        public void paintComponent(Graphics g) {
            c1.draw(g); c2.draw(g);
        }
        public static void main(String[] args) {
            JFrame app = new JFrame();
            app.add(new Sample91ex2());
            app.setSize(400, 300);
            app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            app.setVisible(true);
        }
        static class Circle {
            Color col;
            int xpos, ypos, rad;
            public Circle(Color c, int x, int y, int r) {
                col = c; xpos = x; ypos = y; rad = r;
            }
            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 draw(Graphics g) {
                g.setColor(col);
                g.fillOval(xpos-rad, ypos-rad, rad*2, rad*2);
            }
        }
    }
    
[/code]


CC BY-SA 4.0
2020-07-18T10:11:57.487
68699
2020-07-18T19:46:08.203
2020-07-18T12:05:19.623
3060
39688
question
java
インターフェスの実装クラスのメソッドについて


  1. 

  * `mouseDragged`メソッドは [`MouseMotionAdapter`クラス](https://docs.oracle.com/javase/jp/11/docs/api/java.desktop/java/awt/event/MouseMotionAdapter.html#mouseDragged\(java.awt.event.MouseEvent\))のメソッドです。
  * `isShiftDown`メソッドは [`MouseEvent`クラス](https://docs.oracle.com/javase/jp/11/docs/api/java.desktop/java/awt/event/MouseEvent.html)のメソッドです。

`MouseMotionAdapter`クラス、`MouseEvent`クラスは共にJDKの中で定義されており、それを参照し利用している形です。

他方、`Circle`クラスはユーザ定義クラスであり、それらのように事前に定義されたものを利用しているわけではありません(ので全て自分で定義する必要があります)。

* * *

  2. 

[code]

    addMouseMotionListener(new MouseMotionAdapter() {
        public void mouseDragged(MouseEvent evt) {
            if(evt.isShiftDown()) {
                System.out.println("mv c2");
                c2.moveTo(evt.getX(), evt.getY()); repaint();
            } else {
                c1.moveTo(evt.getX(), evt.getY()); repaint();
            }
        }
    });
    
[/code]

`Shift`を押していなければ `c1.moveTo()` が実行されます。  
つまり、消えているわけではなく、青色と同じところに描画されています。  
このとき、

[code]

    public void paintComponent(Graphics g) {
        c1.draw(g); c2.draw(g);
    }
    
[/code]

赤円 -> 青円 の順に描画しているので、青円の方が全面に来ており、赤円が隠れてしまっています。

赤円の半径を青円より大きくすると、どういう挙動になっているのかわかりやすいと思います。


CC BY-SA 4.0
2020-07-18T19:46:08.203
68718
2020-07-18T19:46:08.203
2808
68699
answer