1

我写了一个MouseMotionListenerfor JPanel,但我对如何使用它感到困惑。

使用 将侦听器类添加到框架时效果很好aWindow.add(new MouseMotionEvents()),但是当我尝试使用 将它添加到面板content.add(new MouseMotionEvents())时,它不起作用。我是 Swing 和JComponents 的新手,有人可以给我一些提示吗?

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()));
      }
      
    }
  }
}
4

2 回答 2

3

在您问题的代码中,您将 a 添加JPanel到 aJPanel因为MouseMotionEvents是 a JPanel(因为它扩展了 class JPanel)。默认布局管理器JPanel尝试FlowLayout以首选大小显示其包含的组件。因此,当您运行 GUI 时,您无法真正看到MouseMotionEvents出现在哪里。您可以通过添加以下内容来为其添加边框(在 class 的构造函数中MouseMotionEvents

setBorder(javax.swing.BorderFactory.createLineBorder(java.awt.Color.red));

现在,当您运行 GUI 时,它看起来像这样

原版gui

这是因为 a 的JPanel大小为零(首选),因为它的大小由它包含的组件决定,但在您的代码MouseMotionEvents中不包含任何组件。您可以通过显式设置首选大小来解决此问题。这是设置适当的首选尺寸后的样子。

首选尺寸

现在您可以在红色边框内拖动鼠标,将绘制矩形。

此外,您应该覆盖 methodpaintComponent而不是 method paint。请参阅执行自定义绘画

这是代码。

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);
    }
}

请注意,xandy是类的公共成员,Point因此不需要使用方法getXgetY因此不需要强制转换。

当您MouseMotionEvents直接添加到时,JFrame您正在添加MouseMotionEventsJPanelwithBorderLayout并且您正在将其添加到 CENTER。由于您给出了JFrame明确的大小,因此BorderLayout确保 的大小MouseMotionEventsJFrame. 因此MouseMotionEvents足够大,您可以在其中拖动鼠标。

于 2021-11-24T11:32:14.153 回答
0

要将 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();
        }
    }
}
于 2021-11-24T16:35:05.980 回答