0

I have a combobox in my program, with three options CIRCLE, RECTANGLE, FREEHAND. Each option is connected to a mouselistener. If I swich between the three options the mouselisteners are causing me some problems. Therefore I would like to add a mouselistener only once (for example in the constructor or in the beginning of the method, or somewhere else). Is it even possible, and how would the code look like? If it is not possible, is there any other way I can solve it?

public void actionPerformed(ActionEvent e) {      

         if (e.getSource().equals(comboBox)) {            

            JComboBox cb = (JComboBox)e.getSource();

                if (cb.getSelectedItem().equals("Rectangle")) {                
                contentPane.addMouseListener(new MouseAdapter() {       //First mouseListener     
                    @Override
                    public void mousePressed(MouseEvent e) {  
                        startX = e.getX();     
                        startY = e.getY(); 
                    }
                    @Override
                    public void mouseReleased(MouseEvent e) {
                        endX = e.getX();
                        endY = e.getY();

                        int width = startX - endX;
                        int height = startY - endY;
                        w = Math.abs(width);
                        h = Math.abs(height);

                        Rectangle r =  new Rectangle(startX, startY, w, h, pickedColor, thickness);
                        shapeList.add(r);
                        repaint(); 
                    }                    
                });   

            }
            else if (cb.getSelectedItem().equals("Circle")) {

                contentPane.addMouseListener(new MouseAdapter() {            //Second
                    @Override
                    public void mousePressed(MouseEvent e) {  
                        startX = e.getX();     
                        startY = e.getY();
                    }
                    @Override
                    public void mouseReleased(MouseEvent e) {
                        endX = e.getX();
                        endY = e.getY();

                        int width = startX - endX;
                        int height = startY - endY;
                        w = Math.abs(width);
                        h = Math.abs(height);

                        Circle c =  new Circle(startX, startY, w, h, pickedColor, thickness);

                        shapeList.add(c);
                        repaint();
                    }
                });  
            }
            else if (cb.getSelectedItem().equals("Freehand")) {   

                contentPane.addMouseListener(new MouseAdapter() {            //Third
                    @Override
                    public void mousePressed(MouseEvent e) {            
                        startX = e.getX();
                        startY = e.getY();
                    }
                    @Override
                    public void mouseDragged(MouseEvent e) {                       

                        FreeHand fh =  new FreeHand(startX, startY, e.getX(), e.getY(), pickedColor, thickness);

                        shapeList.add(fh);
                        repaint();                       
                    }
                });    
            }                    

        }
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
user2939293
  • 793
  • 5
  • 16
  • 41
  • As outlined in your [previous question](http://stackoverflow.com/questions/26662768/how-to-get-rid-of-circle-inside-rectangle-when-switching-between-objects), you should add a SINGLE `MouseListener`, probably within the constructor, which had the capacity to know how to deal with the currently selected shape. This could be achieved by using a factory of some kind, but that might be complicating the issues before you're ready for them... – MadProgrammer Nov 01 '14 at 00:52

2 Answers2

2

Instead of adding a different listener to the panel each time a selection is made in the combo box, you should add a single mouse listener to the panel, in the constructor. And this listener, when one of its methods is called, should first check which option is selected, and act accordingly (i.e. draw a rectangle, or a circle, or by free hand depending on the selection).

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1

The simplest solution would be to store the last listener and remove that before adding a new one:

            private MouseListener lastListener;
            // ...

            JComboBox cb = (JComboBox)e.getSource();

            if (cb.getSelectedItem().equals("Rectangle")) {         
            if (lastListener != null)
                contentPane.removeMouseListener(lastListener);
            lastListener = new MouseAdapter() {       //First mouseListener     
                // ...
            };
            contentPane.addMouseListener(lastListener);
Yogu
  • 9,165
  • 5
  • 37
  • 58
  • What is "lastListener"? How do I declare it? Thank you for your help – user2939293 Oct 31 '14 at 23:23
  • It's just an attribute you should declare in the class, besides the methods you already defined. – Yogu Oct 31 '14 at 23:24
  • The simplest solution would be to maintain a single `MouseListener` which just knew how to do all the work, maybe using a factory of same kind. IMHO - this introduces more complexity for little to no gain... – MadProgrammer Nov 01 '14 at 00:50
  • @MadProgrammer By simplest I meant the solution with the least structural modification. One class per drawing tool is a good thing. I agree it would be better to use a custom interface for this and select the approtiate implementation on demand, though. – Yogu Nov 01 '14 at 08:00