我有单独的类来处理鼠标侦听器。但是当我在另一个类中使用它时,它不起作用,并且我还不知道如何解决这个问题。这是我的Handler类:
some import stuff public class Handler implements MouseListener, MouseMotionListener { private final Canvas canvas; public Handler(Canvas targetCanvas) { this.canvas = targetCanvas; } // recasting exception public Canvas getTargetCanvas() { return canvas; } ... ... @Override public void mouseDragged(MouseEvent e) { // recasting exception DrawingCanvas dC = (DrawingCanvas) getTargetCanvas(); dC.setMouseDragged(true); } @Override public void mouseMoved(MouseEvent e) { // recasting exception DrawingCanvas dCanvas = (DrawingCanvas) getTargetCanvas(); dCanvas.setMouseClicked(true); dCanvas.setMouseCoordinates(e.getPoint()); } }
DrawingCanvas类:
some import stuff public class DrawingCanvas extends Canvas { private boolean isMouseDragged, isMouseMoved; private Point mouseCoordinates; public DrawingCanvas() { this.setPreferredSize(new Dimension(790, 500)); this.setBackground(Color.WHITE); } public Point getMouseCoordinates() { return mouseCoordinates; } public boolean isIsMouseDragged() { return isMouseDragged; } public boolean isIsMouseMoved() { return isMouseMoved; } ... ... public void setMouseDragged(boolean dragged) { isMouseDragged = dragged; } public void setMouseMoved(boolean moved) { isMouseMoved = moved; } public void setMouseCoordinates(Point coordinates) { mouseCoordinates = coordinates; } }
StatusBar类:
some import stuff public class StatusBar extends JPanel { private JLabel statusBar; public StatusBar() { statusBar = new JLabel(); this.setPreferredSize(new Dimension(500, 30)); this.setBackground(new Color(242,241,240)); this.add(statusBar, new BorderLayout(5,0)); } public JLabel getStatusBar() { return statusBar; } public void setStatusBar(JLabel statusBar) { this.statusBar = statusBar; } }
和MouseEventGUI类:
some import stuff public class MouseEventGUI extends JFrame { private DrawingCanvas drawingCanvas; private StatusBar statusBar; private MenuBar menuBar; public MouseEventGUI() { super("Learn Mouse Event"); drawingCanvas = new DrawingCanvas(); statusBar = new StatusBar(); menuBar = new MenuBar(); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setPreferredSize(new Dimension(750, 560)); this.add(menuBar, BorderLayout.NORTH); this.add(drawingCanvas, BorderLayout.CENTER); this.add(statusBar, BorderLayout.SOUTH); this.addMouseListener(new Handler(drawingCanvas)); this.addMouseMotionListener(new Handler(drawingCanvas)); if(drawingCanvas.isIsMouseMoved()){ statusBar.getStatusBar().setText(String.format("%d, %d", drawingCanvas.getMouseCoordinates().x, drawingCanvas.getMouseCoordinates().y)); } else { statusBar.getStatusBar().setText("Mouse is not listened."); } } }
当我运行该程序时,在状态栏中显示“未监听鼠标”(请参见MouseEventGUI类),希望它在画布中移动时显示鼠标光标的坐标。
[更新]
如果在同一个类中,则 可以 进行一些修改 很好地工作 。这是DrawingCanvas类的代码:
public class DrawingCanvas extends JPanel { private boolean isMouseClicked, isMouseMoved; private Point mouseCoordinates; protected StatusBar statusBar; protected MenuBar menuBar; public DrawingCanvas(StatusBar st) { setPreferredSize(new Dimension(790, 500)); setBackground(Color.WHITE); statusBar = st; Handlers handlers = new Handlers(); addMouseListener(handlers); addMouseMotionListener(handlers); } **// inner class** protected class Handlers extends MouseAdapter implements MouseListener, MouseMotionListener { @Override public void mouseClicked(MouseEvent e) { statusBar.getStatusBar().setText("Mouse clicked."); } @Override public void mouseMoved(MouseEvent e) { statusBar.getStatusBar().setText(String.format("%d, %d", e.getX(),e.getY())); } } }
这里是MouseEventGUI类:
public class MouseEventGUI extends JFrame { private DrawingCanvas drawingCanvas; private StatusBar statusBar; private MenuBar menuBar; public MouseEventGUI() { super("Learn Mouse Event"); statusBar = new StatusBar(); menuBar = new MenuBar(); drawingCanvas = new DrawingCanvas(statusBar); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setPreferredSize(new Dimension(750, 560)); this.add(menuBar, BorderLayout.NORTH); this.add(drawingCanvas, BorderLayout.CENTER); this.add(statusBar, BorderLayout.SOUTH); } }
但是,出于 可重用的 原因,我计划将其放在单独的类中。
建议:
getSource()
instanceof
例如:
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); } }