大家好,
我正在尝试为多点触控屏幕编写动画角色。我希望我的对象有 5 只眼睛,每只眼睛的瞳孔都以不同的方式拖放,当然是在眼睛内。
我曾尝试在一个类(class)中完成所有工作,但问题似乎是为五个学生中的每一个分配鼠标处理程序!换句话说,如果我移动一个瞳孔,则所有瞳孔都在移动。
然后,我求助于为学生使用定制类(class)。当我单独使用它时,瞳孔是可拖动的。但是,当我将它用作眼睛类中的对象时,瞳孔是静止的!没有记录点击,没有跟踪鼠标 Activity 。
我查看了教程和其他与鼠标处理程序相关的问题,但没有取得任何进展。在最终发布到这里之前,我根据各种教程和建议更改了代码十几次。我错过提示的任何想法?任何指针将不胜感激。
提前致谢。
PS:我知道我还没有对眼睛内的瞳孔运动施加限制。
主眼类代码:
package rollEyes;
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class FiveEyes extends JPanel
{
private static final long serialVersionUID = 1L;
private static final int SIZE = 512;
private int a = SIZE / 2;
private int b = a;
private int r = 4 * SIZE / 5;
private int n;
int circleSize=30;
Pupil dc = new Pupil(1);
public FiveEyes(int n)
{
super(true);
this.setPreferredSize(new Dimension(SIZE, SIZE));
this.n = n;
}
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.black);
a = getWidth() / 2;
b = getHeight() / 2;
int m = Math.min(a, b);
r = 4 * m / 5;
int r2 = Math.abs(m - r) / 2;
int numOfEyes = 5;
for (int i = 0; i < numOfEyes ; i++)
{
Graphics2D g2d2 = (Graphics2D) g;
double t = 2 * Math.PI * i / n;
int x = (int) Math.round(a + r * Math.cos(t));
int y = (int) Math.round(b + r * Math.sin(t));
drawEyeSockets(g2d2, x,y, 2*r2,2*r2);
}
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
create();
}
});
}
public void drawEyeSockets(final Graphics2D g2, int x, int y, int w, int h)
{
g2.drawOval(x,y,w,h);
dc.drawCircle(g2, x+12, y+12);
}
private static void create()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FiveEyes fivey = new FiveEyes(5);
f.add(fivey);
f.pack();
f.setVisible(true);
}
}
Pupil 类的代码:
package rollEyes;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Pupil extends JPanel
{
private static final long serialVersionUID = 1L;
int radius=50;
int x_after = 50;
int y_after = 50;
MouseHandler mh ;
private static int n =1;
public Pupil(int n)
{
super(true);
}
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
drawCircle(g2d,x_after,y_after);
}
public void drawCircle(final Graphics2D g2d, int x, int y)
{
g2d.setColor(Color.BLUE);
g2d.fillOval(x, y, radius/2, radius/2);
mh = new MouseHandler();
this.addMouseListener(mh);
this.addMouseMotionListener(mh);
}
private static void create()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Pupil dc = new Pupil(n);
f.add(dc);
f.pack();
f.setVisible(true);
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
@Override
public void run()
{
create();
}
});
}
private class MouseHandler extends MouseAdapter
{
boolean circleClicked=false;
public void mouseReleased(MouseEvent e)
{
circleClicked = false;
}
public void mousePressed(MouseEvent me)
{
circleClicked = true;
}
public void mouseDragged(MouseEvent me)
{
if (circleClicked)
{
x_after = me.getX();
y_after = me.getY();
repaint();
}
}
}
}
最佳答案
您让 Pupil 扩展了 JPanel,但实际上不应该这样做。相反,使用您在当前 Pupil 类中学到的概念——如何绘制可移动的圆圈,并将其扩展到更大的 FiveEyes 类中,只是这次创建一个 List<Pupil>
。并画出它们。我的建议:
- 让 Pupil 不扩展 JPanel。取而代之的是给它在某些位置画圆圈并改变该位置的机制。
- 您还需要通过给它一个 contains(Point p) 方法来给它一种识别它的圆圈是否被点击的方法。一种方法是使用 Shape 对象,或者您可以使用自己的方法。
- 给 FiveEyes 一个
List<Pupil>
实际上是一个ArrayList<Pupil>
并用 Pupil 对象填充它。 - 在五眼
paintComponent(...)
方法,遍历此列表,告诉每个 Pupil 自己绘制。 - 在您的 FiveEyes 鼠标适配器的
mousePressed(...)
中方法,遍历您的 Pupil List 以查看是否单击了 Pupil。如果是,请移动它。 - 或者,您可以创建一个 Pupil BufferedImage,将其放入 ImageIcon,然后将其放入 JLabel,然后允许 FiveEyes 类的 MouseAdapter 拖动标签。
关于Java::在不同的类中使用鼠标监听器对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12006079/