MouseListener in separate class not working

后端 未结 1 1359
醉酒成梦
醉酒成梦 2021-01-26 11:56

I have separate class to handle mouse listener. But it not working when I use it from another class and I don\'t know yet how to solve this. Here my Handler class:



        
相关标签:
1条回答
  • 2021-01-26 12:29

    Recommendations:

    • Yes, make Handler a completely separate independent class.
    • Yes, get your listened-to component via the MouseEvent's getSource() method. You can check if it's the right type of object before casting by using the instanceof operator but if you always and only add it to one type of object, then this isn't an issue.
    • Yes, as Camickr and others suggests, don't use AWT's Canvas but rather Swing's JPanel. There are traps that can happen if you mix AWT and Swing components together, you lose a lot of functionality if you use AWT instead of Swing, and there's no need to use Canvas.
    • I would have the MouseListener (in my code, I used a MouseAdapter since it can allow slightly more compact code with less unnecessary code such as empty methods) change the state of the listened to component by calling a setter method.
    • I've had this work well by having that setter method change the state of a "bound" property, one that notifies any PropertyChangeListeners that are interested in its change.
    • And I'd do just that -- add a PropertyChangeListener to the JPanel with the MouseListener and in it change the state of the status JPanel if mouse events occur.

    For example:

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    import java.awt.FlowLayout;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    
    import javax.swing.*;
    
    @SuppressWarnings("serial")
    public class HandlerTester extends JPanel {
       public HandlerTester() {
          Handler handler = new Handler();
          final MyPanel myPanel = new MyPanel();
          myPanel.addMouseListener(handler);
          myPanel.addMouseMotionListener(handler);
    
          final StatusPanel statusPanel = new StatusPanel();
    
          myPanel.addPropertyChangeListener(new PropertyChangeListener() {
    
             @Override
             public void propertyChange(PropertyChangeEvent pcEvt) {
                if (MyPanel.MOUSE_PRESSED.equals(pcEvt.getPropertyName())) {
                   statusPanel.setMousePressed(((Boolean)pcEvt.getNewValue()).booleanValue());
                }
             }
          });
    
          setLayout(new BorderLayout());
          add(myPanel, BorderLayout.CENTER);
          add(statusPanel, BorderLayout.PAGE_END);
       }
    
       private static void createAndShowGUI() {
          HandlerTester handlerTester = new HandlerTester();
    
          JFrame frame = new JFrame("HandlerTester");
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.getContentPane().add(handlerTester);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(new Runnable() {
             public void run() {
                createAndShowGUI();
             }
          });
       }
    }
    
    class Handler extends MouseAdapter {
       @Override
       public void mousePressed(MouseEvent mEvt) {
          Object src = mEvt.getSource();
          if (src instanceof MyPanel) {
             MyPanel myPanel = (MyPanel) src;
             myPanel.setMousePressed(true);         
          }
       }
    
       @Override
       public void mouseReleased(MouseEvent mEvt) {
          Object src = mEvt.getSource();
          if (src instanceof MyPanel) {
             MyPanel myPanel = (MyPanel) src;
             myPanel.setMousePressed(false);         
          }
       }
    }
    
    @SuppressWarnings("serial")
    class MyPanel extends JPanel {
       public static final String MOUSE_PRESSED = "mouse pressed";
       private static final int PREF_W = 600;
       private static final int PREF_H = 400;
       private boolean mousePressed = false;
    
       public boolean isMousePressed() {
          return mousePressed;
       }
    
       public void setMousePressed(boolean mousePressed) {
          boolean oldValue = this.mousePressed;
          boolean newValue = mousePressed;
          this.mousePressed = mousePressed;
          firePropertyChange(MOUSE_PRESSED, oldValue, newValue);
       }
    
       public Dimension getPreferredSize() {
          return new Dimension(PREF_W, PREF_H);
       }
    }
    
    @SuppressWarnings("serial")
    class StatusPanel extends JPanel {
       private static final String MOUSE_PRESSED = "Mouse Pressed";
       private static final String MOUSE_NOT_PRESSED = "Mouse Not Pressed";
       private JLabel label = new JLabel(MOUSE_NOT_PRESSED);
    
       public StatusPanel() {
          setLayout(new FlowLayout(FlowLayout.LEADING));
          add(label);
          setBorder(BorderFactory.createEtchedBorder());
       }
    
       public void setMousePressed(boolean mousePressed) {
          String text = mousePressed ? MOUSE_PRESSED : MOUSE_NOT_PRESSED;
          label.setText(text);
       }
    }
    
    0 讨论(0)
提交回复
热议问题