-1

I am trying to make a PacMan alternative with a tiger chasing bagels (don't ask why). I'm on the first stage still, trying to make the tiger move around the JFrame. However, now that I implemented the KeyEvent, the image is no longer showing up. I have been stuck on this for an hour, and I don't understand where I went wrong.

Edit: I have got the image to show up, but the image does not update or change location when pressing on the arrow keys, probably something to do with the connection between the KeyEvent and the PacMan class.

Main:

public Main() {

}

public static void main(String[] args) {
    javax.swing.SwingUtilities.invokeLater(new Runnable() {
        public void run() {


            UI frame = null;
            try {
                frame = new UI();
            } catch (IOException e) {
                e.printStackTrace();
                System.exit(-1);
            }

        }
    });
}

UI:

public PacMan PacMan;

@Override
public void keyTyped(KeyEvent e) {

}

@Override
public void keyPressed(KeyEvent e) {

}

@Override
public void keyReleased(KeyEvent e) {
    int key = e.getKeyCode();
    if (key == KeyEvent.VK_RIGHT){
        PacMan.moveRight();
    }
    if (key == KeyEvent.VK_LEFT){
        PacMan.moveLeft();
    }
    if (key == KeyEvent.VK_UP){
        PacMan.moveUp();
    }
    if (key == KeyEvent.VK_DOWN){
        PacMan.moveDown();
    }
}
public UI() throws IOException {
    this.PacMan = new PacMan();
    addKeyListener(this);
    setFocusable(true);
    setFocusTraversalKeysEnabled(false);
    JFrame frame = new JFrame();
    JPanel panel = new JPanel();

    frame.setTitle("PacMan");
    frame.setResizable(false);
    frame.setSize(1200, 700);
    frame.setMinimumSize(new Dimension(1200, 700));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    panel.setBackground(Color.BLACK);
    panel.add(PacMan.getImage());
    frame.add(panel);
    frame.setVisible(true);
}

PacMan:

public int xCoords = 570;
public int yCoords = 320;
JLabel pacManImage = new JLabel();
Icon tigerLeft;
Icon tigerRight;
public PacMan() throws IOException {

    ImageIcon tigerLeft = new ImageIcon(new ImageIcon("textures/tigerLeft.png").getImage().getScaledInstance(60, 40, Image.SCALE_DEFAULT));
    ImageIcon tigerRight = new ImageIcon(new ImageIcon("textures/tigerRight.png").getImage().getScaledInstance(60, 40, Image.SCALE_DEFAULT));

    pacManImage.setIcon(tigerRight);

    pacManImage.setVisible(true);
}

public void initialDraw() {
    pacManImage.setBounds(xCoords, yCoords, 60, 40);
    pacManImage.setIcon(tigerRight);
    pacManImage.repaint();

}

public void moveRight() {
    System.out.println("here: " + tigerRight);
    //xCoords = xCoords + 2;
    pacManImage.setIcon(tigerRight);
    pacManImage.setLocation(pacManImage.getLocationOnScreen().x + 2, pacManImage.getLocationOnScreen().y);
    pacManImage.repaint();
}


public void moveLeft() {
    //xCoords = xCoords + 2;
    pacManImage.setIcon(tigerLeft);
    pacManImage.setLocation(pacManImage.getLocationOnScreen().x - 2, pacManImage.getLocationOnScreen().y);
    pacManImage.repaint();
}

public void moveUp() {
    //yCoords = yCoords + 2;
    pacManImage.setLocation(pacManImage.getLocationOnScreen().x, pacManImage.getLocationOnScreen().y - 2);
    pacManImage.repaint();
}

public void moveDown() {
    //yCoords = yCoords + 2;
    pacManImage.setLocation(pacManImage.getLocationOnScreen().x, pacManImage.getLocationOnScreen().y + 2);
    pacManImage.repaint();
}
public JLabel getImage(){
    return pacManImage;
}
Alty
  • 15
  • 4
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/223902/discussion-on-question-by-alty-the-image-not-showing-up-in-jframe-after-adding-t). – Samuel Liew Oct 31 '20 at 09:56

2 Answers2

2

Your UI class is not complete so I can't tell exactly what you are doing. I can only guess.

Ignoring the actual KeyListener code, my guess is you have code like:

public class UI extends JPanel
{
    public UI() throws IOException 
    {
        this.PacMan = new PacMan();
        addKeyListener(this);
    
        JFrame frame = new JFrame();
        JPanel panel = new JPanel();
    
        panel.setBackground(Color.BLACK);
        panel.add(PacMan.getImage());
        frame.add(panel);
        frame.setVisible(true);
    }
}

So once again you have two JPanel components:

  1. the UI class "is a" JPanel and you add the KeyListener to it.
  2. then you create a second JPanel and add the "PacMan" to that panel and add that panel to the frame.

So the problem is the first panel has the KeyListener but it is never added to the frame.

Your class should look like:

public class UI extends JPanel
{
    public UI() throws IOException 
    {
        this.PacMan = new PacMan();
        addKeyListener(this);
    
        setBackground(Color.BLACK);
        add(PacMan.getImage());
    }
}

That's it. The creation of the frame does not belong in this class.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • Glad it helped. Don't forget to "accept" the answer by clicking on the checkmark (beside the answer) so people know the problem has been solved. See: https://stackoverflow.com/help/accepted-answer – camickr Oct 31 '20 at 14:27
0

I found out that my keyReleased function was never being called, and I fixed that issue by issuing the simplest fix, moving the KeyListener within the UI method.

UI class code:

public class UI extends JPanel {
public PacMan PacMan;


public UI() throws IOException {
    this.PacMan = new PacMan();
    addKeyListener(new KeyListener() {
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_DOWN){
                PacMan.moveDown();
            }
            if (e.getKeyCode() == KeyEvent.VK_UP){
                PacMan.moveUp();
            }
            if (e.getKeyCode() == KeyEvent.VK_LEFT){
                PacMan.moveLeft();
            }
            if (e.getKeyCode() == KeyEvent.VK_RIGHT){
                PacMan.moveRight();
            }
        }

        @Override
        public void keyReleased(KeyEvent e) {}

        @Override
        public void keyTyped(KeyEvent e) {}
    });
    setFocusable(true);
    setBackground(Color.BLACK);
    add(PacMan.getImage());

}
Alty
  • 15
  • 4
  • 1
    *I found out that my keyReleased function was never being called* - and I gave you the reason for that. The reason was you had TWO panels and added the KeyListener to the wrong panel. *moving the KeyListener within the UI method* - was completely unnecessary. Whether you define the KeyListener as an anonymous inners class or whether you implement KeyListener in your class is irrelevant. What is relevant is the component you add the KeyListener to. – camickr Nov 06 '20 at 18:49