javaswingeventsjlabelmousemotionlistener

Mouse Listener Event for different JPanels


Is is possible to have a global mouse motion listener that has different effects depending on what JPanel is clicked (with only using one mouse motion listener)?

For example: I have a JFrame with two added JPanels and a mouse motion listener added to the JFrame. I want the screen to resize when I click on one JPanel, but I want the JFrame to be dragged around when I click the other. I think this can be done using JLabels using the text of the JLabel to check against, same with a JButton.

EDIT: yes this is definitly not the proper way to do things but just wondering if it is possible, if so, how?

EDIT: Just to make things a bit more clearer, I have one class that extends ActionListener, MouseMotionListener, MouseListener. is it possible to have this one class handle all events of a JFrame that has lots of different JPanels attached to it and do something different based off of which JPanel was pressed? (such as having an ID attached to JPanels that I can compare the event.getSource() with)


Solution

  • First of all, a "global" listener, that does different things for different components, is a bad idea, it places too much logic into a single place, couples the code and becomes a maintenance nightmare.

    Having said that, you could use a single MouseListener added to each component, for example...

    import java.awt.Color;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.GridLayout;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class Test {
    
        public static void main(String[] args) {
            new Test();
        }
    
        public Test() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JPanel left = new TestPane();
                    JPanel right = new TestPane();
    
                    left.setBackground(Color.RED);
                    right.setBackground(Color.BLUE);
    
                    left.setName("left");
                    right.setName("right");
    
                    MouseListener listener = new MouseAdapter() {
                        @Override
                        public void mouseClicked(MouseEvent e) {
                            System.out.println(((JPanel)e.getSource()).getName());
                        }
                    };
    
                    left.addMouseListener(listener);
                    right.addMouseListener(listener);
    
                    JFrame frame = new JFrame("Testing");
                    frame.setLayout(new GridLayout(0, 2));
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(left);
                    frame.add(right);
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            public TestPane() {
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
        }
    
    }
    

    Then you could simple use MouseEvent#getSource to determine which component triggered the event. For simplicity, I've supplied a name for each panel and displayed that, I would use some other way to identify the component before making a decision about what to do.

    The better solution would be to provide a specific MouseListener which did a specific job to the each panel as required, this becomes much easier to manage, isolates responsibility, decouples the code and becomes easier to maintain and manage