如何让MouseHandler在DrawPanel中生效并实现鼠标位置显示标签?
问题原因与解决办法
你遇到的问题核心是:你在DrawPanel里嵌套的mousePanel是空的,默认FlowLayout布局下,空JPanel的尺寸是0×0,鼠标根本碰不到这个面板,所以事件监听器完全触发不了。
解决方案一:直接给DrawPanel加监听器(推荐)
没必要额外嵌套一个JPanel,直接把鼠标监听器绑定到DrawPanel本身:
private class DrawPanel extends JPanel { public DrawPanel() { MouseHandler handler = new MouseHandler(); this.addMouseListener(handler); this.addMouseMotionListener(handler); // 可以加个背景色方便看到面板范围 this.setBackground(Color.WHITE); } @Override public void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; } private class MouseHandler extends MouseAdapter implements MouseMotionListener { @Override public void mousePressed(MouseEvent event) { System.out.print("Pressed"); } @Override public void mouseReleased(MouseEvent event) { System.out.print("Released"); } @Override public void mouseDragged(MouseEvent event) { System.out.print("Dragged"); // lblStatus.setText(String.format("(%d,%d)",event.getX(),event.getY())); } @Override public void mouseMoved(MouseEvent event) { System.out.print("Moved"); // System.out.print("("+event.getX()+","+event.getY()+")"); // lblStatus.setText(String.format("(%d,%d)",event.getX(),event.getY())); } } }
解决方案二:保留mousePanel,让它占满空间
如果一定要用内部的mousePanel,需要修改DrawPanel的布局,让mousePanel填满整个DrawPanel:
private class DrawPanel extends JPanel { public DrawPanel() { // 把DrawPanel的布局改成BorderLayout,让内部组件占满空间 this.setLayout(new BorderLayout()); JPanel mousePanel = new JPanel(); // 加背景色方便观察mousePanel的范围 mousePanel.setBackground(Color.LIGHT_GRAY); this.add(mousePanel, BorderLayout.CENTER); MouseHandler handler = new MouseHandler(); mousePanel.addMouseListener(handler); mousePanel.addMouseMotionListener(handler); } // paintComponent和MouseHandler代码不变 }
补充:关于状态标签lblStatus
如果要启用lblStatus.setText(...)的代码,需要确保lblStatus能被MouseHandler访问到:
- 在DrawPanel类中添加成员变量
private JLabel lblStatus; - 在DrawPanel的构造方法中传入这个标签,比如:
public DrawPanel(JLabel statusLabel) { this.lblStatus = statusLabel; // 后续监听器代码就可以正常调用lblStatus的方法了 }
内容的提问来源于stack exchange,提问作者JTD28
相关产品推荐
相关产品推荐

