建议:
- 是的,使Handler成为完全独立的独立类。
- 是的,通过MouseEvent的
getSource()
方法获取您的监听组件。您可以使用instanceof
运算符在投射之前检查它是否是正确的对象类型,但是如果总是将它仅添加到一种类型的对象上,那么这不是问题。 - 是的,正如Camickr和其他人所建议的,不要使用AWT的Canvas,而要使用Swing的JPanel。如果将AWT和Swing组件混合在一起,可能会发生陷阱,如果使用AWT而不是Swing,则会损失很多功能,并且不需要使用Canvas。
- 我将让MouseListener(在我的代码中,我使用MouseAdapter,因为它可以允许使用稍微更紧凑的代码和更少的不必要代码(例如空方法))通过调用setter方法来更改侦听组件的状态。
- 我已经通过使该setter方法更改“绑定”属性的状态来很好地完成了这一工作,该属性会通知对它的更改感兴趣的所有PropertyChangeListener。
- 我只是这样做-使用MouseListener将PropertyChangeListener添加到JPanel,如果发生鼠标事件,它会更改状态JPanel的状态。
例如:
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); }}


