如何将自定义的 MouseMotionListener 添加到 JPanel?
Posted
技术标签:
【中文标题】如何将自定义的 MouseMotionListener 添加到 JPanel?【英文标题】:How to add a self-defined MouseMotionListener to a JPanel? 【发布时间】:2022-01-02 13:37:20 【问题描述】:我为JPanel
写了一个MouseMotionListener
,但我对如何使用它感到困惑。
使用aWindow.add(new MouseMotionEvents())
将监听器类添加到框架时效果很好,但是当我尝试使用content.add(new MouseMotionEvents())
将它添加到面板时,它不起作用。我是 Swing 和 JComponent
s 的新手,有人能给我一些提示吗?
public class test
public static void main(String[] args)
JFrame aWindow = new JFrame();
aWindow.setBounds(600, 600, 600, 600);
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel content = new JPanel();
content.add(new MouseMotionEvents());
aWindow.add(content);
aWindow.setVisible(true);
class MouseMotionEvents extends JPanel implements MouseListener,
MouseMotionListener
Point p;
Point r;
public MouseMotionEvents()
addMouseListener(this);
addMouseMotionListener(this);
public void mouseClicked(MouseEvent me)
// p = me.getPoint();
// repaint();
public void mouseEntered(MouseEvent me)
public void mouseExited(MouseEvent me)
public void mousePressed(MouseEvent me)
p = me.getPoint();
// repaint();
public void mouseReleased(MouseEvent me)
r = me.getPoint();
repaint();
public void mouseDragged(MouseEvent me)
r = me.getPoint();
repaint();
public void mouseMoved(MouseEvent me)
public void paint(Graphics g)
if (p != null && r != null)
Dimension d = getSize();
int xc = d.width / 2;
int yc = d.height / 2;
if(p.getX()-r.getX()>0 && p.getY()-r.getY()>0)
g.drawRect((int)p.getX(), (int)p.getY(), (int)(p.getX()-r.getX()), (int)(p.getY()-r.getY()));
if(p.getX()-r.getX()>0 && p.getY()-r.getY()<0)
g.drawRect((int)p.getX(), (int)p.getY(), (int)(p.getX()-r.getX()), (int)(-p.getY()+r.getY()));
if(p.getX()-r.getX()<0 && p.getY()-r.getY()>0)
g.drawRect((int)p.getX(), (int)p.getY(), (int)(-p.getX()+r.getX()), (int)(p.getY()-r.getY()));
if(p.getX()-r.getX()<0 && p.getY()-r.getY()<0)
g.drawRect((int)p.getX(), (int)p.getY(), (int)(-p.getX()+r.getX()), (int)(-p.getY()+r.getY()));
【问题讨论】:
覆盖paintComponent而不是paint。 如果还是不行,在repaint()之前调用invalidate()。 还是不行, “它仍然不起作用”不要告诉我们什么不起作用。什么不工作? 我只是浏览了其他人的帖子,他们使用类似“jpanel.addMouseMotionListener(new MouseMotionAdapter() ... )”的东西,但我写的类只是实现了 MouseListener 和 MouseMotionListener,做你认为这是个问题吗? 【参考方案1】:在您问题的代码中,您将JPanel
添加到JPanel
,因为MouseMotionEvents
是JPanel
(因为它扩展了类JPanel
)。 JPanel
的默认 layout manager 是 FlowLayout
,它尝试以首选大小显示其包含的组件。因此,当您运行 GUI 时,您无法真正看到 MouseMotionEvents
出现的位置。您可以通过添加以下内容为其添加边框(在类MouseMotionEvents
的构造函数中)
setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.red));
现在当你运行 GUI 时,它看起来像这样
这是因为 JPanel
的大小为零(首选),因为它的大小由它包含的组件决定,但在您的代码中 MouseMotionEvents
不包含任何组件。您可以通过显式设置首选大小来解决此问题。这是设置合适的首选尺寸后的样子。
现在您可以在红色边框内拖动鼠标并绘制矩形。
另外,您应该重写方法 paintComponent
而不是方法 paint
。参考Performing Custom Painting。
这是代码。
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class MouseMotionEvents extends JPanel implements MouseListener, MouseMotionListener
Point p;
Point r;
public MouseMotionEvents()
addMouseListener(this);
addMouseMotionListener(this);
setBorder(BorderFactory.createLineBorder(Color.red));
setPreferredSize(new Dimension(300, 300));
public void mouseClicked(MouseEvent me)
// p = me.getPoint();
// repaint();
public void mouseEntered(MouseEvent me)
public void mouseExited(MouseEvent me)
public void mousePressed(MouseEvent me)
System.out.println("mousePressed");
p = me.getPoint();
// repaint();
public void mouseReleased(MouseEvent me)
System.out.println("mouseReleased");
r = me.getPoint();
repaint();
public void mouseDragged(MouseEvent me)
r = me.getPoint();
repaint();
public void mouseMoved(MouseEvent me)
protected void paintComponent(Graphics g)
super.paintComponent(g);
if (p != null && r != null)
Dimension d = getSize();
int xc = d.width / 2;
int yc = d.height / 2;
if (p.x - r.x > 0 && p.y - r.y > 0)
g.drawRect(p.x, p.y, (p.x - r.x), (p.y - r.y));
if (p.x - r.x > 0 && p.y - r.y < 0)
g.drawRect(p.x, p.y, (p.x - r.x), (-p.y + r.y));
if (p.x - r.x < 0 && p.y - r.y > 0)
g.drawRect(p.x, p.y, (-p.x + r.x), (p.y - r.y));
if (p.x - r.x < 0 && p.y - r.y < 0)
g.drawRect(p.x, p.y, (-p.x + r.x), (-p.y + r.y));
public static void main(String[] args)
JFrame aWindow = new JFrame();
aWindow.setBounds(600, 600, 600, 600);
aWindow.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel content = new JPanel();
content.add(new MouseMotionEvents());
aWindow.add(content);
aWindow.setVisible(true);
请注意,x
和 y
是类 Point
的公共成员,因此不需要使用方法 getX
和 getY
,因此不需要强制转换。
当您将MouseMotionEvents
直接添加到JFrame
时,您将MouseMotionEvents
添加到带有JPanel
的BorderLayout
并且您将其添加到中心。由于您提供了JFrame
和明确的大小,BorderLayout
确保MouseMotionEvents
的大小在JFrame
中占用尽可能多的空间。因此MouseMotionEvents
足够大,您可以在其中拖动鼠标。
【讨论】:
【参考方案2】:要将 MouseMotionListener 添加到 JPanel,您必须使用
myPanel.setMouseMotionListener ( myMouseListener );
并直接在您的面板上调用它,就像您在 mouseMotionEvents 类中所做的那样。这就是它起作用的原因,当您将它直接添加到您的 JFrame 时。
修复您的代码后,我得到了这个,它应该可以正常工作。我把它分成了两个类,一个是 JFrame 的主类,一个是 JPanel(内容)的主类。
主类:
public class MouseMotionListenerTest
public static void main ( String[] args )
JFrame aWindow = new JFrame();
aWindow.setBounds( 600, 600, 600, 600 );
aWindow.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
ContentPanel content = new ContentPanel();
aWindow.add( content );
aWindow.setVisible( true );
面板类:
public class ContentPanel extends JPanel
private Point p;
private Point r;
public ContentPanel ()
MouseMotionEvents mme = new MouseMotionEvents();
addMouseListener( mme );
addMouseMotionListener( mme );
public void paint ( Graphics g )
if ( p != null && r != null )
Dimension d = getSize();
int xc = d.width / 2;
int yc = d.height / 2;
if ( p.getX() - r.getX() > 0 && p.getY() - r.getY() > 0 )
g.drawRect( ( int ) p.getX(), ( int ) p.getY(), ( int ) ( p.getX() - r.getX() ), ( int ) ( p.getY() - r.getY() ) );
if ( p.getX() - r.getX() > 0 && p.getY() - r.getY() < 0 )
g.drawRect( ( int ) p.getX(), ( int ) p.getY(), ( int ) ( p.getX() - r.getX() ), ( int ) ( -p.getY() + r.getY() ) );
if ( p.getX() - r.getX() < 0 && p.getY() - r.getY() > 0 )
g.drawRect( ( int ) p.getX(), ( int ) p.getY(), ( int ) ( -p.getX() + r.getX() ), ( int ) ( p.getY() - r.getY() ) );
if ( p.getX() - r.getX() < 0 && p.getY() - r.getY() < 0 )
g.drawRect( ( int ) p.getX(), ( int ) p.getY(), ( int ) ( -p.getX() + r.getX() ), ( int ) ( -p.getY() + r.getY() ) );
private class MouseMotionEvents extends MouseAdapter
public void mouseClicked ( MouseEvent me )
// p = me.getPoint();
// repaint();
public void mousePressed ( MouseEvent me )
p = me.getPoint();
// repaint();
public void mouseReleased ( MouseEvent me )
r = me.getPoint();
repaint();
public void mouseDragged ( MouseEvent me )
r = me.getPoint();
repaint();
【讨论】:
以上是关于如何将自定义的 MouseMotionListener 添加到 JPanel?的主要内容,如果未能解决你的问题,请参考以下文章
如何以编程方式将自定义图像设置为 UIBarButtonItem