3

I am trying to accomplish my code for my high school beginning programming class, and I am confused that Java tells me it cannot find Listener (when I've already imported it?). After trying again with import java.awt.event.*;, it still doesn't work. Could someone help me with this aggravating issue?

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
import javax.swing.Timer;
public class PrizePanelA extends JPanel {
    private static final int FRAME = 400;
    private static final Color BACKGROUND = new Color(204, 204, 204);
    private BufferedImage myImage;
    private Graphics myBuffer;
    private Ball ball;
    private Polkadot prize;
    private int hits;
    private Timer c;
    private Bumper bumper1;
    private Bumper bumper2;

    public PrizePanelA() {
        myImage = new BufferedImage(400, 400, 1);
        myBuffer = this.myImage.getGraphics();

        ball = new Ball(200, 200, 50, Color.black);
        ball.jump(400, 400);
        bumper1 = new Bumper(50, 170, 50, 50, Color.yellow);
        prize = new Polkadot(200, 200, 25, Color.red);
        prize.jump(400, 400);
        hits = 0;
        addKeyListener(new Key());
        setFocusable(true);
        c = new Timer(10, new Listener());
        c.start();
    }
    private class Key extends KeyAdapter {

        public void keyPressed(KeyEvent e) {
            if ((e.getKeyCode() == 38)) {
                prize.setY(prize.getY() + 10);
            }
        }

        public void paintComponent(Graphics g) {
            g.drawImage(myImage, 0, 0, getWidth(), getHeight(), null);
        }

        private class Listener implements ActionListener {
            private Listener() {}

            public void actionPerformed(ActionEvent e) {
                myBuffer.setColor(BACKGROUND);
                myBuffer.fillRect(0, 0, 400, 400);

                ball.move(400.0, 400.0);
                collide(ball, prize);

                ball.draw(myBuffer);
                prize.draw(myBuffer);

                myBuffer.setColor(Color.BLACK);
                myBuffer.setFont(new Font("Monospaced", 1, 24));
                myBuffer.drawString("Count: " + hits, 250, 25);
                repaint();
            }
        }

        public void collide(Ball b, Polkadot pd) {
            double d = distance(b.getX(), b.getY(), pd.getX(), pd.getY());
            if (d <= b.getDiameter() / 2 + pd.getDiameter() / 2) {
                pd.jump(400, 400);
                hits += 1;
            }
        }

        private double distance(double x1, double y1, double x2, double y2) {
            return Math.sqrt(Math.pow(x1 - x2, 2.0) + Math.pow(y1 - y2, 2.0));
        }
    }
  }

Error:

PrizePanelA.java:37: error: cannot find symbol
        c = new Timer(10, new Listener());
                              ^
  symbol:   class Listener
  location: class PrizePanelA
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
Harris Lew
  • 39
  • 5
  • 1
    FYI: `Key` can never paint anything and since you never call it's `paintComponent`, nothing will get painted. Maybe take a look at [Performing Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) and [Painting in Swing](http://www.oracle.com/technetwork/java/painting-140037.html) – MadProgrammer Dec 02 '17 at 05:21
  • 2
    A little advice: _"Why does Java incorrectly complain about not finding Listener?"_ comes across as highly arrogant. The Java compiler is not incorrect, it is your understanding of scopes that is incorrect. Pay attention to the error message. If it's telling you something you "know" is wrong, it's time to question what you think is right, and learning this sooner rather than later will make you a much better developer in the long run. – Jim Garrison Dec 02 '17 at 05:22
  • 1
    Also, `KeyListener` is notorious for causing issues, a better solution would be to use the [Key Bindings API](https://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html) which was designed to solve these issues – MadProgrammer Dec 02 '17 at 05:22
  • 1
    I'd also recommend spending some time reading through [Nested Classes](https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html) to better understand your issue and any of the solutions which might be presented – MadProgrammer Dec 02 '17 at 05:23
  • 1
    I'd also be worried about structuring your code this way, what does a `KeyListener` care about the `Timer` or the core logic of your application, it's just provides a supporting role – MadProgrammer Dec 02 '17 at 05:25
  • 1
    @JimGarrison I am sorry that I came off as arrogant to you, I'll try to put more thought into my titles. Thanks. – Harris Lew Dec 02 '17 at 05:49
  • *"I'll try to put more thought into my titles."* Good call. Although the question itself remains less than optimal (best to post code in the form of a [mcve]) making a commitment to thinking more carefully about titles earns a plus one from me. – Andrew Thompson Dec 02 '17 at 06:05
  • @HarrisLew Thank you. Sorry if I was a bit harsh, but I was young once and made the same mistake, so I speak from experience. I once filed an official bug report against a compiler for what I was _positive_ was a bug, only to figure out the next day it was my mental model that was broken. Rather embarrassing :-) – Jim Garrison Dec 02 '17 at 06:06

1 Answers1

2

Your Listener class is inside Key class so move it outside the scope of Key class because you cannot use non-static inner-class without the instantiation of outer class.

    // move it outside of class Key
    private class Listener implements ActionListener {
        private Listener() {}

        public void actionPerformed(ActionEvent e) {
            myBuffer.setColor(BACKGROUND);
            myBuffer.fillRect(0, 0, 400, 400);

            ball.move(400.0, 400.0);
            collide(ball, prize);

            ball.draw(myBuffer);
            prize.draw(myBuffer);

            myBuffer.setColor(Color.BLACK);
            myBuffer.setFont(new Font("Monospaced", 1, 24));
            myBuffer.drawString("Count: " + hits, 250, 25);
            repaint();
        }
    }

    private class Key extends KeyAdapter {

Reference : What is the difference between static and non static inner class?

JIC : if you want to go with current implementation then as i said , use outer class instance c = new Timer(10, new Key().new Listener());

Pavneet_Singh
  • 36,884
  • 5
  • 53
  • 68