68734


以下のプログラムで質問です。

[code]

    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;
        }
    });
    
[/code]

上記のコードで、マウスが円の中をクリックしないと円を動かさない、としているにもかかわらず、円の外をクリックしても円が動いてしまいます。  
おそらく、この後のisShiftDownメソッドが効いているからだと思いますが、このプログラムでは最初にmousePressedメソッドのプログラムを作っても、のちのisShiftDownメソッドによって上書きされてしまっているのでしょうか？（つまり、mousePressedメソッドが無効になっているのでしょうか？なぜなら円の外をクリックしても円が動くからです。）

[code]

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class Sample91ex2 extends JPanel {
        Circle c1 = new Circle(Color.RED, 100, 50, 50);
        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-19T05:21:39.240
68724
2020-07-19T15:10:09.423
2020-07-19T12:13:25.270
3060
39688
question
java
isShiftDownメソッドの役割について（Mouse eventクラス）


>
> このプログラムでは最初にmousePressedメソッドのプログラムを作っても、のちのisShiftDownメソッドによって上書きされてしまっているのでしょうか？

いいえ、上書きでなく[追加](https://docs.oracle.com/javase/jp/11/docs/api/java.desktop/java/awt/Component.html#addMouseListener\(java.awt.event.MouseListener\))です。

Java標準APIの命名慣例として、`setXXX`という名前のメソッドは、いわゆる上書きですが、`addXXX`は重ねがけになり、両方有効です。

追加したものを削除するためには削除用のメソッドを呼ぶ必要があり、今回の場合で言うと[`removeMouseListener`メソッド](https://docs.oracle.com/javase/jp/11/docs/api/java.desktop/java/awt/Component.html#removeMouseListener\(java.awt.event.MouseListener\))がそれに当たります。


CC BY-SA 4.0
2020-07-19T12:51:15.207
68732
2020-07-19T12:51:15.207
2808
68724
answer


> マウスが円の中をクリックしないと円を動かさない、としているにもかかわらず

いえ、そうはなっていません。  
2つ目のMouseMotionListenerにより、ShiftDownの有無によってC1もしくはC2は移動します。  
Shiftを押していない場合、青い円をドラッグすると、1つ目のMouseMotionListenerも有効になり、赤と青両方の円が一緒に移動します。

MousePressedメソッドはちゃんと有効になっています。  
2つ目のMouseMotionListenerがc1,c2を直接操作してるため、MosePressメソッドが無視されているだけです。（無視するコードを書いているだけ）


CC BY-SA 4.0
2020-07-19T15:10:09.423
68734
2020-07-19T15:10:09.423
40962
68724
answer