javaswingmouseeventmouselistenermousepress

Why is the mousedrag and mousepress being used together in the same time ? I want to stop the mouse drag when I'm using mouse press and vice versa


When I press the free button I can draw in the bottom pane but when I press the rectangle button I can draw a rectangle in the panel but I can also draw anything in the same time. My goal is that when I press one of the functions I want the other to stop functioning.


public class MyFrame extends JFrame implements ActionListener, MouseListener , MouseMotionListener{
    
    JPanel top;
    JPanel bottom ;
    JButton btn1,btn4;
    int freebtn,rectanglebtn; 
    Graphics g;
    
    public MyFrame(){
        this.setTitle("car");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setSize(700,700);
        this.setLayout(null);
        this.setResizable(false);
        
        top = new JPanel(); 
        bottom = new JPanel();
        
        top.setBounds(0, 0, 700, 100);
        top.setBackground(Color.blue);
        
        bottom.setBounds(0, 100, 700, 600);
        bottom.setBackground(Color.white);
        
        btn1 = new JButton("free");
        btn4 = new JButton("rectangle");
        
        
        btn1.addActionListener(this);
        btn4.addActionListener(this);
    
        top.add(btn1);top.add(btn4);
        
        
        this.add(top);
        this.add(bottom);
        bottom.addMouseMotionListener(this);
        bottom.addMouseListener(this);
        this.setVisible(true);
        g=bottom.getGraphics();
        
        
    }
    
    // action listener-------------------------------

    @Override
    public void actionPerformed(ActionEvent e) {
        
        // TODO Auto-generated method stub
        if(e.getActionCommand() =="free") {
            System.out.println("free button");
            
            freebtn=11;
        }
        else if(e.getActionCommand() =="rectangle") {
            System.out.println("rectangle button");
            rectanglebtn=12;
        }
    
    }
    // mouse listener-----------------------------

    @Override
    public void mouseClicked(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void mousePressed(MouseEvent e) {
        // TODO Auto-generated method stub
        System.out.println(rectanglebtn);
        if(rectanglebtn==12) {
            
            g.setColor(Color.BLUE);  
            g.drawRect(e.getX(),e.getY(), 100, 50); 
        }
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void mouseEntered(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }

    @Override
    public void mouseExited(MouseEvent e) {
        // TODO Auto-generated method stub
        
    }
    
    // mouse motion listener---------------------------
    
        
        @Override
        public void mouseDragged(MouseEvent e) {
            // TODO Auto-generated method stub
            System.out.println(freebtn);
            if(freebtn==11) {
                
                g.setColor(Color.BLUE);  
                g.fillOval(e.getX(),e.getY(),20,20); 
            }
            
        }

        @Override
        public void mouseMoved(MouseEvent e) {
            // TODO Auto-generated method stub
            
        }

    
}

I tried to to set one of them to null when I'm using the other but it didnt work


Solution

  • Let's start with...

    @Override
    public void actionPerformed(ActionEvent e) {
        
        // TODO Auto-generated method stub
        if(e.getActionCommand() =="free") {
            System.out.println("free button");
            
            freebtn=11;
        }
        else if(e.getActionCommand() =="rectangle") {
            System.out.println("rectangle button");
            rectanglebtn=12;
        }
    
    }
    

    Apart from the fact that you are using e.getActionCommand() =="rectangle" instead of "rectangle".equals(e.getActionCommand()) (see How do I compare strings in Java?, for more details) , once either freebtn or rectanglebtn are actioned, the values they set never change.

    So, for example, if I press the rectangle button, rectanglebtn is set to 12. If I then press free button, rectanglebtn is still 12

    Instead of using two different (and somewhat unrelated) variables, you should be using a single "state" variable. Now, if you have more than two states, I would use a enum, for example...

    enum State {
        FREE, RECTANGLE, CIRCLE
    }
    

    And then update the action handler to something like...

        private State state = null;
    
        // action listener-------------------------------
        @Override
        public void actionPerformed(ActionEvent e) {
    
            // TODO Auto-generated method stub
            if ("free".equals(e.getActionCommand())) {
                System.out.println("free button");
    
                state = State.FREE;
            } else if ("rectangle".equals(e.getActionCommand())) {
                System.out.println("rectangle button");
                state = State.RECTANGLE;
            }
    
        }
    

    Now, whenever either button is actioned, the state is changed to a single state.

    Then your mouse listener begins to look something more like...

        @Override
        public void mousePressed(MouseEvent e) {
            // TODO Auto-generated method stub
            
            System.out.println(state);
            if (state == State.RECTANGLE) {
    
                g.setColor(Color.BLUE);
                g.drawRect(e.getX(), e.getY(), 100, 50);
            }
        }
    
        // mouse motion listener---------------------------
        @Override
        public void mouseDragged(MouseEvent e) {
            // TODO Auto-generated method stub
            System.out.println(state);
            if (state == State.FREE) {
    
                g.setColor(Color.BLUE);
                g.fillOval(e.getX(), e.getY(), 20, 20);
            }
    
        }
    

    and there is no way that they could become cross wired.

    Now, onto the "other" issues... g = bottom.getGraphics(); is NOT how custom painting works. At best, this will return a "snapshot" of what was last painted and at worst, it will return null.

    You need to look at Painting in AWT and Swing and Performing Custom Painting to get a better understanding of how painting in Swing works and how you should work with it.