【问题标题】:Java:: Use a mouse listener object in a different classJava:: 在不同的类中使用鼠标侦听器对象
【发布时间】:2012-08-17 12:43:29
【问题描述】:

大家好,

我正在尝试为多点触控屏幕编写动画角色。我希望我的对象有 5 只眼睛,并且每只眼睛的瞳孔都可以以不同的方式拖放,当然是在眼睛内。

我试图在一个班级中完成所有这些,问题似乎是为五个学生中的每一个分配鼠标处理程序!换句话说,如果我移动一个瞳孔,所有的瞳孔都在移动。

然后,我只为学生使用了定制课程。当我单独使用它时,瞳孔是可拖动的。但是,当我在眼睛类中使用它作为对象时,瞳孔是静态的!未记录任何点击,未跟踪鼠标活动。

我查看了教程、鼠标处理程序的其他相关问题,但没有取得任何进展。在最终发布到这里之前,我从各种教程和建议中更改了十几次代码。我错过了提示的任何想法?任何指针将不胜感激。

提前致谢。

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

【问题讨论】:

    标签: java arrays swing graphics paintcomponent


    【解决方案1】:

    您有 Pupil 扩展 JPanel,但实际上不应该这样做。相反,使用您在当前 Pupil 课程中学到的概念——如何绘制一个可移动的圆圈,并在更大的 FiveEyes 课程中扩展它,只是这次创建一个List&lt;Pupil&gt; 并绘制它们。我的建议:

    • 使瞳孔不扩展 JPanel。而是给它机器在某些位置绘制圆圈并更改该位置。
    • 您还需要通过给它一个 contains(Point p) 方法来给它一个方法来识别它的圆圈是否已被点击。一种方法是使用 Shape 对象,或者您可以滚动自己的方法。
    • 给 FiveEyes 一个 List&lt;Pupil&gt;,它实际上是一个 ArrayList&lt;Pupil&gt;,并用瞳孔对象填充它。
    • 在 FiveEyes paintComponent(...) 方法中,遍历此列表,告诉每个学生自己绘制。
    • 在您的 FiveEyes MouseAdapter 的 mousePressed(...) 方法中,遍历您的瞳孔列表以查看是否单击了瞳孔。如果是,请移动它。
    • 或者,您可以创建一个 Pupil BufferedImage,将其放入 ImageIcon,然后将其放入 JLabel,然后允许 FiveEyes 类的 MouseAdapter 拖动标签。

    【讨论】:

    • 谢谢。这种方法是否意味着我们不能在本身没有任何鼠标/事件处理功能的父类中使用具有自己的鼠标处理事件的对象?
    • @BalaKrishnaKolluru:让眼睛使用自己的鼠标侦听器的问题在于,鼠标运动将与眼睛对象本身相关,而不是与容纳它的容器相关,后者才是最重要的你。您想将眼睛移动到其容器内部
    【解决方案2】:

    首先是这段代码

        mh = new MouseHandler();
        this.addMouseListener(mh);
        this.addMouseMotionListener(mh);
    

    只能调用一次。您正在向组件中添加数百万个鼠标处理程序!

    您需要五个Pupil 实例,每只眼睛一个。现在,你只有一个,所以渲染当然只会产生一个结果。

    最后,您必须确保一次只有一只眼睛处于“活动状态”(即不是所有的眼睛都应该接收鼠标事件或不是所有的眼睛都应该处理它们)。

    【讨论】:

    • 谢谢亚伦。必须对解决方案进行建议的更正。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-05
    • 2022-12-11
    • 1970-01-01
    相关资源
    最近更新 更多