1

我对 Java 完全陌生,我正在学习如何编写一个程序,该程序可以根据教授的讲座视频检测碰撞并做出反应。这是视频的链接

我所有的代码都应该与他的演讲中的相似。我的错误似乎在 NewJFrame.java 文件中。为什么 ActionListener 不起作用?在此先感谢您的帮助。

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package collisiondetection;

import java.awt.event.ActionListener;
import javafx.event.ActionEvent;
import javax.swing.Timer;

/**
 *
 * @author PC
 */
public class NewJFrame extends javax.swing.JFrame {

    /**
     * Creates new form NewJFrame
     */

    public NewJFrame() {
        initComponents();
        bf = new BallField(getWidth(), getHeight());
        add(bf);
        pack();
        njTimer = new Timer(1, 
                new ActionListener() {
                    public void actionPerformed(ActionEvent e) {
                        bf.detectCollision();
                    }
                });
        njTimer.start();
    }
    BallField bf;
    Timer njTimer;
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 400, Short.MAX_VALUE)
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 300, Short.MAX_VALUE)
        );

        pack();
    }// </editor-fold>                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(NewJFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new NewJFrame().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    // End of variables declaration                   
}

说“new ActionListener() {”的行带有下划线,我收到一条错误消息:

线程“主”java.lang.RuntimeException 中的异常:无法编译的源代码 - 不是抽象的,并且不会在碰撞检测的 java.awt.event.ActionListener 中覆盖抽象方法 actionPerformed(java.awt.event.ActionEvent)。NewJFrame.(NewJFrame .java:28) 在碰撞检测.Main.main(Main.java:20)

NewJFrame.java:28 指的是上面代码中“njTimer = new Timer(1”) 的行。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

这是我的其他 .java 文件的代码以供参考。

主文件:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package collisiondetection;

/**
 *
 * @author PC
 */
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        // TODO code application logic here
        NewJFrame njf = new NewJFrame();
        njf.setVisible(true);   
    }    
}

BallField.java:

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package collisiondetection;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.LinkedList;
import java.util.ListIterator;
import javax.swing.JPanel;

/**
 *
 * @author PC
 */
public class BallField extends JPanel {

    public BallField(int width, int height)
    {
        setSize(new Dimension(width, height));
        setMinimumSize(new Dimension(width, height));
        setMaximumSize(new Dimension(width, height));
        bfList = new LinkedList<Shape>();
        fillList();
    }

    public void detectCollision()
    {
        if(bfList.size() == 0)
        {
            fillList();
        }
        bfBall.move();
        ListIterator iter = bfList.listIterator();
        boolean collision = false;
        while ((collision == false && iter.hasNext()))
        {
            Shape sh = (Shape) iter.next();
            if(sh.collide(bfBall))
            {
                iter.remove();
                collision = true;
            }
        }
    }


    public void PaintComponent(Graphics gfx)
    {
        int bWidth = getWidth();
        int bHeight = getHeight();
        gfx.setColor(bfBackground);
        gfx.fillRect(0, 0, bWidth, bHeight);
        ListIterator iter = bfList.listIterator();
        while(iter.hasNext())
        {
            Shape sh = (Shape) iter.next();
            sh.drawShape(gfx);
        }
        bfBall.drawBall(gfx);
    }

    private void fillList() {
        int bWidth = getWidth();
        int bHeight = getHeight();
        int size = Math.min(bWidth, bHeight);
        size -= Math.max(bfNumRow, bfNumCol) * brickGap;
        size = size / (Math.max(bfNumRow, bfNumCol) + bfEmptyRow);

        // add more margin
        Shape.setSize(size);
        if (bfBall == null) {
            bfBall = new MovingBall(size, bWidth, bHeight);
        } else {
            bfBall.reset();
        }

        for (int rowCnt = 0; rowCnt < bfNumRow; rowCnt++) {
            int xloc = bWidth / 2 - (bfNumRow / 2 - rowCnt) * (size + brickGap);
            for (int colCnt = 0; colCnt < bfNumCol; colCnt++) {
                double rand = Math.random();
                Float cR = new Float(Math.random());
                Float cG = new Float(Math.random());
                Float cB = new Float(Math.random());
                Color bc = new Color(cR.floatValue(), cG = cG.floatValue(), cB.floatValue());
                int yloc = bHeight / 2 - (bfNumCol / 2 - colCnt) * (size + brickGap);
                if (rand > .5) {
                    Circle cb = new Circle(xloc, yloc, bc);
                    bfList.add(cb);
                } else {
                    Square sb = new Square(xloc, yloc, bc);
                    bfList.add(sb);
                }
            }
        }
    }


    LinkedList<Shape> bfList;
    MovingBall bfBall;

    static private final Color bfBackground = Color.white;
    static private final int bfNumRow = 6;
    static private final int bfNumCol = 6;
    static private final int bfEmptyRow = 4;
    static private final int brickGap = 4;
}

Vector2D.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package collisiondetection;

/**
 *
 * @author PC
 */
public class Vector2D {
    public Vector2D(double x, double y, boolean u)
    {
        xVal = x;
        yVal = y;
        unit = u;
        if(unit)
        {
            makeUnit();
        }
    }

    public void add(Vector2D vec)
    {
        xVal += vec.xVal;
        yVal += vec.yVal;
        if(unit)
        {
            makeUnit();
        }
    }

    public double getX()
    {
        return xVal;
    }

    public double getY()
    {
        return yVal;
    }

    public void reflect(Vector2D nor)
    {
        if((unit == false) || (nor.unit == false))
        {
            System.out.println("ERROR, not unit vector");
        }

        double ip = innerProduct(nor);
        xVal += -2 * ip * nor.xVal;
        yVal += -2 * ip * nor.yVal;
        makeUnit();
    }

    private double innerProduct(Vector2D vec)
    {
        return (xVal * vec.xVal + yVal * vec.yVal);
    }

    private void makeUnit()
    {
        double mag = xVal * xVal + yVal * yVal;
        if(mag == 0)
        { 
            System.out.println("ERROR, zero vector");
        }
        else
        {
            mag = Math.sqrt(mag);
            xVal /= mag;
            yVal /= mag;
        }
    }
    private double xVal;
    private double yVal;
    private boolean unit;
}

移动球.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package collisiondetection;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

/**
 *
 * @author PC
 */
public class MovingBall {

    public MovingBall(int sz, int bw, int bh)
    {
        mbSize = sz;
        bWidth = bw;
        bHeight = bh;
        reset();
    }

    public Rectangle getRect()
    {
        return (new Rectangle((int) Math.round(mbLoc.getX() - mbSize/2), (int) Math.round(mbLoc.getY() - mbSize/2), mbSize, mbSize));
    }

    public void reset()
    {
        mbLoc = new Vector2D(mbSize, mbSize, false);
        mbVel = new Vector2D(Math.random() + .1, Math.random() + .1, true);
    }

    public double getX()
    {
        return mbLoc.getX();
    }

    public double getY()
    {
        return mbLoc.getY();
    }

    public int getSize()
    {
        return mbSize;
    }

    public void reflect(Vector2D nor)
    {
        mbVel.reflect(nor);
    }
    public void move()
    {
        mbLoc.add(mbVel);
        // hit a wall?
        if(mbLoc.getX() >= (bWidth - mbSize/2))
        {
            // hit right wall
            Vector2D nor = new Vector2D(-1, 0, true);
            reflect(nor);
        }
        if(mbLoc.getY() >= (bHeight - mbSize/2))
        {
            Vector2D nor = new Vector2D(0, -1, true);
            reflect(nor);
        }
    }
    public void drawBall(Graphics gfx)
    {
        int x = (int) Math.round(mbLoc.getX() - mbSize/2);
        int y = (int) Math.round(mbLoc.getY() - mbSize/2);
        gfx.setColor(bColor);
        gfx.fillOval(x, y, mbSize, mbSize);
    }
    private Vector2D mbLoc;
    private Vector2D mbVel;
    private int mbSize;
    private Color bColor = Color.black;
    int bWidth;
    int bHeight;

}

形状.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package collisiondetection;

import java.awt.Color;
import java.awt.Graphics;

/**
 *
 * @author PC
 */
abstract public class Shape {

    public Shape(int x, int y, Color c)
    {
        s_X = x;
        s_Y = y;
        s_Color = c;
    }

    public static void setSize(int sz)
    {
        s_Size = sz;
    }

    abstract public boolean collide(MovingBall ball);
    abstract public void drawShape(Graphics gfx);

    protected int s_X;
    protected int s_Y;
    protected Color s_Color;
    protected static int s_Size;
}

Square.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package collisiondetection;

import static collisiondetection.Shape.s_Size;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;

/**
 *
 * @author PC
 */
public class Square extends Shape {

    public Square(int x, int y, Color c) 
    {
        super(x, y, c);
    }

    public boolean collide(MovingBall ball) 
    {
        Rectangle r1 = new Rectangle(s_X - s_Size / 2, s_Y - s_Size, s_Size, s_Size);
        Rectangle r2 = ball.getRect();
        Rectangle r3 = r1.intersection(r2);
        if (r3.isEmpty()) 
        {
            // no collision
            // note thatr3 is not null
            return false;
        }
        if (r3.getWidth() < r3.getHeight()) 
        {
            // hit horizontally
            if (ball.getX() < s_X) {
                // hit the left side
                Vector2D nor = new Vector2D(-1, 0, true);
                ball.reflect(nor);
            } else {
                Vector2D nor = new Vector2D(1, 0, true);
                ball.reflect(nor);
            }
        } else {
            if (ball.getY() < s_Y) {
                // hit the top
                Vector2D nor = new Vector2D(0, -1, true);
                ball.reflect(nor);
            } else {
                Vector2D nor = new Vector2D(0, 1, true);
                ball.reflect(nor);
            }
        }
        return true;
    }


    public void drawShape(Graphics gfx)
    {
            gfx.setColor(s_Color);
            gfx.fillRect(s_X - s_Size/2, s_Y - s_Size/2, s_Size, s_Size);
    }
}

Circle.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package collisiondetection;

import java.awt.Color;
import java.awt.Graphics;

/**
 *
 * @author PC
 */
public class Circle extends Shape{
    public Circle(int x, int y, Color c)
    {
        super(x, y, c);
    }

    public boolean collide(MovingBall ball)
    {
        double deltaX = ball.getX() - s_X;
        double deltaY = ball.getY() - s_Y;
        double centerDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY);
        if(centerDistance * 2 > s_Size + ball.getSize())
        {
            // no collision
            // size is the diameter, not radius
            return false;
        }
        Vector2D nor = new Vector2D(deltaX, deltaY, true);
        ball.reflect(nor);
        return true;
    }

    public void drawShape(Graphics gfx)
    {
        gfx.setColor(s_Color);
        gfx.fillOval(s_X - s_Size/2, s_Y - s_Size/2, s_Size, s_Size);
    }


}
4

1 回答 1

2

您正在导入错误的 ActionEvent。

import javafx.event.ActionEvent;

应该

import java.awt.event.ActionEvent;

...欢迎来到这个网站,感谢您提供有问题的代码、错误消息和导致错误的行。我预测你的编码会走得很远。

于 2014-06-10T22:07:38.957 回答