Max Segal
Max Segal

Reputation: 2045

removeMouseListener() won't work (Java)

I have a problem in what supposed to be a simple task. the following class represents a JPanel with a picture. After every time I draw a shape with drag and release I want the mouse be unresponsive in regards to the frame/panel/component. I am trying to do that by removing the mouselisteners in every possible way as you can see in the method mouseReleased(...) What happens however is that when I finish drawing the shape, the mouse continues to be responsive and every time I press the the button on the frame it continues to draw shapes(with some flawed logic).

How do I remove the mouselistener so I can click and do whatever I want with the mouse when the addShape() method is complete? Thanks! package question2;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.event.MouseMotionListener;

import javax.swing.JButton;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

@SuppressWarnings("serial")
public class PicturePanel extends JPanel { // TODO
    static final int NONE = -1,
            LINES_ONLY = 0, BOUNDED_SHAPES = 1, ALL_SHAPES = 2,
            RECTANGLE = 0, OVAL = 1, LINE = 2,
            DELETION = 11;

    private int shapesMode;
    private int actionMode;
    private Picture<Shape> picture;
    private JPanel controls;
    private JButton addShapeBtn, removeShapeBtn;

    private Shape tempShape; // for drawing the picture by dragging
    private question2.Point startDrag, endDrag;


    public PicturePanel(int shapesMode) {
        this.shapesMode = shapesMode;
        picture = new Picture<Shape>();

        addShapeBtn = new JButton("Add shape");
        removeShapeBtn = new JButton("Remove shape");

        ControlsListener l = new ControlsListener();
        addShapeBtn.addActionListener(l);
        removeShapeBtn.addActionListener(l);

        controls = new JPanel();
        controls.add(addShapeBtn);
        controls.add(removeShapeBtn);

        this.setLayout(new BorderLayout());
        this.add(controls, BorderLayout.SOUTH);
        tempShape = new Line(0, 0, 1000, 100, Color.black);
        picture.add(tempShape);

    }

    private class MouseListener extends MouseAdapter implements MouseMotionListener {
        public void mouseClicked(MouseEvent e) {
            switch (actionMode) {
                case DELETION:
                    question2.Point clickPosition = new question2.Point(e.getX(), e.getY());
                    picture.remove(clickPosition);
                    PicturePanel.this.removeMouseListener(this);

                    repaint();
                    actionMode = NONE;
                    break;

            }
            question2.Point clickPosition = new question2.Point(e.getX(), e.getY());
            picture.remove(clickPosition);
            PicturePanel.this.removeMouseListener(this);

            repaint();
        }

    }
    private class ControlsListener implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            if (e.getSource() == addShapeBtn) {
                if (shapesMode == LINES_ONLY) {
                    addShape(LINE);
                } else if (shapesMode == BOUNDED_SHAPES) {
                    addShape(chooseBoundedShape(PicturePanel.this));
                } else {
                    addShape(chooseAnyShape(PicturePanel.this));
                }

            } else if (e.getSource() == removeShapeBtn) {
                removeShape();
            }

        }
    }

    private void addShape(int shapeType) {

        this.addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                startDrag = new question2.Point(e.getX(), e.getY());
                endDrag = startDrag;
                repaint();

            }

            public void mouseReleased(MouseEvent e) {
                picture.add(tempShape);

                removeMouseMotionListener(this);
                for (java.awt.event.MouseListener m: PicturePanel.this.getMouseListeners()){
                    PicturePanel.this.removeMouseListener(m);
                }
                repaint();
            }

        });

        this.addMouseMotionListener(new MouseMotionAdapter() {
            public void mouseDragged(MouseEvent e) {
                PicturePanel.this.repaint();

                endDrag = new question2.Point(e.getX(), e.getY());
                switch (shapeType) {
                    case LINE:
                        tempShape =
                                new Line(startDrag.getX(), startDrag.getY(), endDrag.getX(),
                                        endDrag.getY(), new Color(((int) (Math.random() * 255)), ((int) (Math.random() * 255)),
                                                ((int) (Math.random() * 255))));

                        break;
                    case OVAL:
                        tempShape =
                                new Oval(Math.min(startDrag.getX(), endDrag.getX()),
                                        Math.min(startDrag.getY(), endDrag.getY()),
                                        Math.abs(endDrag.getX() - startDrag.getX()),
                                        Math.abs(endDrag.getY() - startDrag.getY()),
                                        new Color(((int) (Math.random() * 255)), ((int) (Math.random() * 255)), ((int) (Math.random() * 255))), false);
                        break;
                    case RECTANGLE:
                        tempShape =
                                new Rectangle(Math.min(startDrag.getX(), endDrag.getX()),
                                        Math.min(startDrag.getY(), endDrag.getY()),
                                        Math.abs(endDrag.getX() - startDrag.getX()),
                                        Math.abs(endDrag.getY() - startDrag.getY()),
                                        new Color(((int) (Math.random() * 255)), ((int) (Math.random() * 255)), ((int) (Math.random() * 255))), false);
                        break;
                }
                repaint();
            }
        });

    }

    private void removeShape() {
        System.out.println("click on shape to remove");
        MouseListener ml = new MouseListener();
        PicturePanel.this.addMouseListener(ml);

    }

    public Picture<Shape> getPicture() {
        return picture;
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        picture.show(g);
        tempShape.draw(g);
    }

    public static int chooseShapesType(Component parent) {
        int choice = JOptionPane.showOptionDialog(parent, "Choose shape type", null, 0, JOptionPane.QUESTION_MESSAGE
                , null, new String[] {"Lines only", "Bounded shapes", "All shapes"}, null);
        if (choice == 0)
            return LINES_ONLY;
        else if (choice == 1)
            return BOUNDED_SHAPES;
        else if (choice == 2)
            return ALL_SHAPES;

        return NONE;

    }

    private static int chooseBoundedShape(Component parent) {
        int choice = JOptionPane.showOptionDialog(parent, "Choose shape type", null, 0, JOptionPane.QUESTION_MESSAGE
                , null, new String[] {"Rectangle", "Oval"}, null);
        if (choice == 0)
            return RECTANGLE;
        else if (choice == 1)
            return OVAL;

        return NONE;
    }

    private static int chooseAnyShape(Component parent) {
        int choice = JOptionPane.showOptionDialog(parent, "Choose shape type", null, 0, JOptionPane.QUESTION_MESSAGE
                , null, new String[] {"Rectangle", "Oval", "Line"}, null);
        if (choice == 0)
            return RECTANGLE;
        else if (choice == 1)
            return OVAL;
        else if (choice == 2)
            return LINE;

        return NONE;
    }


}

Upvotes: 0

Views: 870

Answers (1)

Mordechai
Mordechai

Reputation: 16234

Let's not talk if your solution is a good practice, but just solve your problem.

I noticed that, you implement 2 listener classes. 1) MouseListener 2) ControlsListener. The listener removal is only done in the MouseListener implementation, but not in the ControlsListener.

In PicturePanel though you use the ControlsListener but never the MouseListener, that never removes itself, as mentioned above.

Upvotes: 1

Related Questions