鼠标运动监听器只在一个方向

时间:2013-11-21 18:37:59

标签: java applet awt keylistener mouselistener

我一直在研究Java中的鼠标运动监听器无法将其完全排序,因为我希望对象朝着鼠标所指向的屏幕方向移动但不幸的是当鼠标位于applet窗口内部时,物体仅向单一方向移动。这是我的代码。

import java.awt.*;
import java.awt.geom.*;
import java.util.*;
import java.applet.*;
import java.awt.event.*;
import javax.swing.*;

public class MouseOver extends Applet implements KeyListener, MouseListener,
      MouseMotionListener {
   private int[] Xpoints = { 0, -5, 5 };
   private int[] Ypoints = { -10, -2, -2 };
   private double xpos, ypos;
   private Polygon poly;
   int polyrot = 0;
   private int width; // !! added
   private int height; // !! added

   public void init() {
      poly = new Polygon(Xpoints, Ypoints, Xpoints.length);
      addKeyListener(this);
      addMouseListener(this);
      addMouseMotionListener(this);
   }

   public void paint(Graphics g) {
      Graphics2D g2d = (Graphics2D) g;
      AffineTransform id = new AffineTransform();
      width = getSize().width;
      height = getSize().height;
      g2d.setColor(Color.BLACK);
      g2d.fillRect(0, 0, width, height);
      g2d.setColor(Color.RED);
      g2d.draw(poly);
      g2d.translate(width / 2, height / 2);
      g2d.rotate(Math.toRadians(polyrot));
      g2d.scale(5, 5);
   }

   public void keyReleased(KeyEvent k) {
   }

   public void keyTyped(KeyEvent k) {
   }

   public void keyPressed(KeyEvent k) {
      switch (k.getKeyCode()) {
      case KeyEvent.VK_LEFT:
         if (polyrot < 0) {
            polyrot = 359;
            polyrot++;
         }
         repaint();
         break;
      case KeyEvent.VK_RIGHT:
         if (polyrot > 360) {
            polyrot = 0;
            polyrot--;
         }
         repaint();
         break;
      }
   }

   public void mouseEntered(MouseEvent m) {
   }

   public void mouseExited(MouseEvent m) {
   }

   public void mouseReleased(MouseEvent m) {
   }

   public void mouseClicked(MouseEvent m) {
   }

   public void mousePressed(MouseEvent m) {
      switch (m.getButton()) {
      case MouseEvent.BUTTON1:
         if (polyrot < 0) {
            polyrot = 359;
            polyrot--;
         }
         repaint();
         break;
      case MouseEvent.BUTTON2:
         if (polyrot > 360) {
            polyrot = 0;
            polyrot++;
         }
         repaint();
         break;
      }
   }

   public void mouseMoved(MouseEvent e) {
      xpos = getX();
      if (xpos < 0) {
         polyrot--;
      } else if (xpos > 0) {
         polyrot++;
      }
      repaint();
      // !! break; // Doesn't belong here
   }

   @Override
   public void mouseDragged(MouseEvent e) {
      // You forgot this method
   }
}

4 个答案:

答案 0 :(得分:2)

你的问题在于这一行:

public void mouseMoved(MouseEvent e){
 xpos=getX(); // ******
 if(xpos<0){polyrot--;}
 else if(xpos>0){polyrot++;}
 repaint();
 break;
}

返回小程序的x位置鼠标光标。你需要使用你的MouseEvent对象,而不是鼠标的位置。将其更改为:

xpos = e.getX();

请不要忽略我对您的问题所做的评论。请记住,我们是帮助我们空闲时间的志愿者。请不要让它比帮助你更困难。


我尝试编辑你的代码以便编译,现在缩进了。考虑创建一个Swing应用程序,而不是AWT应用程序,因为Swing应用程序更灵活,更强大,更强大。

答案 1 :(得分:1)

有一些事情......

keyPressedmousePressed事件中,只会处理越界条件,例如......

if (polyrot < 0) {
    polyrot = 359;
    polyrot++;
}
//...
if (polyrot > 360) {
    polyrot = 0;
    polyrot--;
}

但是当你在可接受的范围内(0-359)时,你永远不会处理它应该做的事情......

相反,您可以简单地从polyrot添加或减去金额,并允许API处理它(令人惊讶的是,它能够处理角度&lt; 0和&gt; 359),例如......

public void mousePressed(MouseEvent m) {
    switch (m.getButton()) {
        case MouseEvent.BUTTON1:
            polyrot--;
            repaint();
            break;
        case MouseEvent.BUTTON2:
            polyrot++;
            repaint();
            break;
    }
}

现在,我不确定你是什么意思“对象移向屏幕上鼠标指向的方向”。这是否意味着对象实际上应该改变它的x / y坐标,或者只是“看”鼠标光标......

基于你实际上没有移动代码的事实,你基本上把对象画在一个固定的位置,我假设“看看”......

基本上,您需要知道鼠标的位置和对象的位置,然后确定它们之间的角度......

public void mouseMoved(MouseEvent e) {
    int x = width / 2;
    int y = height / 2;

    Point mousePoint = e.getPoint();

    int deltaX = mousePoint.x - x;
    int deltaY = mousePoint.y - y;

    polyrot = -Math.atan2(deltaX, deltaY);
    polyrot = Math.toDegrees(polyrot) + 180;

    repaint();
}

你应该注意我将'polyrot'改为'double'

您的paint方法也是错误的。基本上,你在改造它之前就是在画你的物体,相反,你应该使用更像......的物体......

g2d.translate(width / 2, height / 2);
g2d.rotate(Math.toRadians(polyrot));
g2d.draw(poly);

在应用自己的自定义绘画之前,您还应该调用super.paint(g) ...

作为旁注,您应该避免覆盖paint顶级容器,例如JApplet,而是创建一个自定义组件,从JPanel扩展并覆盖它{ {1}}方法,在那里执行自定义绘画(不要忘记调用paintComponent)。请查看Performing Custom Painting了解更多详情

您还应该避免使用super.paintComponent,而是使用Key Bindings API,因为它不会遇到与KeyListener相同的焦点问题......

已更新为可运行示例

所以我玩了代码并制作了这个简单的例子......

enter image description here

基本上,我抛弃了KeyListener以支持Polygon,主要是因为它提供了更多功能,并且在扩展时很容易处理;)

Path2D

答案 2 :(得分:1)

此:

  if (xpos < 0) {

表示“如果光标位于面板之外”。

此:

  xpos = getX();

没有获得鼠标坐标。

将您的活动更改为以下内容:

public void mouseMoved(MouseEvent e) {
    xpos = e.getX();
    if (xpos < getWidth() / 2) {
        polyrot--;
    } else {
        polyrot++;
    }
    repaint();
}

现在,如果光标位于面板左侧,则逆时针旋转;如果光标位于右侧,则顺时针旋转。

此:

  g2d.draw(poly);
  g2d.translate(width / 2, height / 2);
  g2d.rotate(Math.toRadians(polyrot));
  g2d.scale(5, 5);

不会做任何改变图像的事情,因为你在绘制它之后正在进行转换。

此:

  Graphics2D g2d = (Graphics2D) g;

是一个坏主意,因为您正在将变换应用于全局图形上下文,这将继续进行其他组件的后续重新绘制。

将你的油漆变成这样的东西:

public void paint(Graphics g) {
    super.paint(g);
    Graphics2D g2d = (Graphics2D) g.create();
    width = getSize().width;
    height = getSize().height;
    g2d.setColor(Color.BLACK);
    g2d.fillRect(0, 0, width, height);
    g2d.translate(width / 2, height / 2);
    g2d.rotate(Math.toRadians(polyrot));
    g2d.scale(5, 5);
    g2d.setColor(Color.RED);
    g2d.draw(poly);
    g2d.dispose();
}

进一步阅读:

答案 3 :(得分:-1)

从这里开始:

public void mouseMoved(MouseEvent e){
 xpos=getX();
 if(xpos<0){polyrot--;}
 else if(xpos>0){polyrot++;}
 repaint();
 break;
}

似乎你只更新了xpos。您还应该更新变量ypos。 您可能想要这样做:

ypos=e.getY();
if (this.ypos<0){
 this.polyrot--;
}else if (this.ypos>0) {
 this.polyrot++;
}
this.repaint();