0

My KeyListener and the methods work, but they don't do anything. When I run the code and I try to use the arrow keys, nothing happens. I also have another problem. I'm making a game and I already did the map, but when I put the map in, the map has priority and covers my character. How would I go about fixing these? This is the JFrame Package.

package MyGamePKG;

import java.awt.BorderLayout;

public class GameJFrame extends JFrame {

private JPanel contentPane;
private int x,y,x_vel,y_vel;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                GameJFrame frame = new GameJFrame();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public GameJFrame() {


    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 720, 520);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    GameJPanel Jpanel = new GameJPanel();
    Jpanel.setBounds(0, 0, 720, 480);
    contentPane.add(Jpanel);
    Jpanel.setLayout(null);




}


}

This is the JPanel.

package MyGamePKG;

import java.awt.BasicStroke;

public class GameJPanel extends JPanel implements ActionListener, KeyListener {

private int frameRate = 30;
private int x=0;
private int y=0;
private int x_vel, y_vel;
private Image map;

/**
 * Create the panel.
 */
public GameJPanel() {
    new ImageIcon(getClass().getResource("/Resources/gamemap.png"));
    gamemap = map.getImage(); //error here
    this.addKeyListener(this);
    this.setFocusable(true);
    Timer timer = new Timer(30, this);      
    timer.start();


}


}

public void background()
{
    ImageIcon icon = new ImageIcon(this.getClass().getResource("/Resources/gamemap.png"));
    map = icon.getImage();
}
@Override
public void paintComponent(Graphics g)
{
    super.paintComponent(g);
    setBackground(Color.WHITE);

    Graphics2D g2d = (Graphics2D) g;

    RenderingHints rh = new RenderingHints( RenderingHints.KEY_ANTIALIASING,
            RenderingHints.VALUE_ANTIALIAS_ON);

    g2d.setRenderingHints(rh);

    g2d.setColor(Color.green);
    g2d.setStroke(new BasicStroke(5));


    myDrawBoxOvalsandRect(x,y,100,g2d);
    myDrawArc(x+25,y+40,50,50,550,170,g2d);
} // paintComponent
public void myDrawBoxOvalsandRect( int x, int y, int scale, Graphics my_g)
{
    my_g.setColor(Color.cyan);
    my_g.fillOval(x, y, 100, 100); //face

    my_g.setColor(Color.red);
    my_g.fillOval(x+20, y+25, 15, 15); //left eye

    my_g.setColor(Color.red);
    my_g.fillOval(x+60, y+25, 15, 15); //right eye

    my_g.setColor(Color.cyan);
    my_g.fillRect(x+25,y+100,50,80);//body

    my_g.setColor(Color.cyan);
    my_g.fillRect(x-30,y+105,55,20); //left arm

    my_g.setColor(Color.cyan);
    my_g.fillRect(x+70, y+105, 60, 20); //right arm

    my_g.setColor(Color.red); 
    my_g.fillOval(x-47, y+105, 20, 20); //left hand

    my_g.setColor(Color.red);
    my_g.fillOval(x+126,y+105,20,20); //right hand

    my_g.setColor(Color.cyan); 
    my_g.fillRect(x+25, y+175, 20, 50); //left leg

    my_g.setColor(Color.cyan);
    my_g.fillRect(x+55,y+175,20,50); // right leg

}
public void myDrawArc(int x, int y, int height, int width, int angle1, int angle2, Graphics my_g)
{
    my_g.setColor(Color.red);
    my_g.drawArc(x, y, 50, 50, 550, 170); //happy face      
}
@Override
public void keyPressed(KeyEvent e) {
    // TODO Auto-generated method stub
    int c = e.getKeyCode();

    if(c == KeyEvent.VK_LEFT)
    {
        x_vel = -1;
        y_vel = 0;
    }
    if(c == KeyEvent.VK_UP)
    {
        x_vel = 0;
        y_vel = -1;
    }
    if( c == KeyEvent.VK_RIGHT)
    {
        x_vel = 1;
        y_vel = 0;
    }
    if( c == KeyEvent.VK_DOWN)
    {
        x_vel = 0;
        y_vel = 1;
    }
    repaint();

}
@Override
public void keyReleased(KeyEvent e) {
    // TODO Auto-generated method stub
    x_vel = 0;
    y_vel = 0;
    repaint();
}
@Override
public void keyTyped(KeyEvent e) {
    // TODO Auto-generated method stub

}
@Override
public void actionPerformed(ActionEvent e) {
    // TODO Auto-generated method stub
    if(x < 0)
    {
        x_vel = 0;
        x = 0;
    }
    if(x > 720)
    {
        x_vel = 0;
        x = 720;
    }
    if(y < 0)
    {
        y_vel = 0;
        y = 0;
    }
    if(y > 480)
    {
        y_vel = 0;
        y = 480;
    }
    x = x + x_vel;
    y = y + y_vel;
    repaint();

}


}

1 Answers1

4

You have a few problems you need to deal with

  1. You've created two sets of variable. One set in your frame, and one set in your panel. With your Keyalistener, you are only changing the values of the ones in the frame, which will have no affect on the ones in the panel.

  2. Updates to the UI should be done on the Event Dispatch Thread. Don't use a new thread with while(true) and Thread.sleep(). Instead use a javax.swing.Timer for animation. See more at How to Use Swing Timers. You also see a bunch of examples here and here and here and here and here and here.

  3. You should be using key binding for key specific actions, instead of KeyListener. See more at How to Use Key Bindings. You can also see a simple example here


Others:

  • Why are you using a ActionListener when it is not being added to anything?
  • Don't use null layouts. Learn to use LayoutManagers, and let them do the sizing and positioning for you.
  • For painted panels, you should override getPreferredSize() to set a preferred size to the panel, and it will be respected when you pack() your frame (as you should, instead of setting the size)
  • Don't set the background in the paint method. Do it in the constructor.

UPDATE

Here is the complete code. It works fine for me

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.border.EmptyBorder;

public class GameFrame extends JFrame {

    private JPanel contentPane;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GameFrame frame = new GameFrame();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public GameFrame() {

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 720, 520);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        GameJPanel Jpanel = new GameJPanel();
        Jpanel.setBounds(0, 0, 720, 480);
        contentPane.add(Jpanel);
        Jpanel.setLayout(null);

    }
}

class GameJPanel extends JPanel implements ActionListener, KeyListener {

    private int frameRate = 30;
    private int x = 0;
    private int y = 0;
    private int x_vel, y_vel;
    private Image map;

    /**
     * Create the panel.
     */
    public GameJPanel() {
        map = new ImageIcon(getClass().getResource("/resources/gamemap.png")).getImage();
        this.addKeyListener(this);
        this.setFocusable(true);
        Timer timer = new Timer(30, this);
        timer.start();
        /*
        Thread myAnimationThread = new Thread() {
            @Override
            public void run() {
                while (true) {
                    repaint(); // Refresh the display which calls paintComponent
                    try {
                        Thread.sleep(1000 / frameRate);
                    } // try
                    catch (InterruptedException ex) {
                    }
                } // while
            } // run
        }; // Thread
        */
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        setBackground(Color.WHITE);

        Graphics2D g2d = (Graphics2D) g;

        RenderingHints rh = new RenderingHints(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        g2d.setRenderingHints(rh);

        g2d.setColor(Color.green);
        g2d.setStroke(new BasicStroke(5));


        g2d.drawImage(map, 0, 0, 720, 480, getParent());
        myDrawBoxOvalsandRect(x, y, 100, g2d);
        myDrawArc(x + 25, y + 40, 50, 50, 550, 170, g2d);
    } // paintComponent

    public void myDrawBoxOvalsandRect(int x, int y, int scale, Graphics my_g) {
        my_g.setColor(Color.cyan);
        my_g.fillOval(x, y, 100, 100); // face

        my_g.setColor(Color.red);
        my_g.fillOval(x + 20, y + 25, 15, 15); // left eye

        my_g.setColor(Color.red);
        my_g.fillOval(x + 60, y + 25, 15, 15); // right eye

        my_g.setColor(Color.cyan);
        my_g.fillRect(x + 25, y + 100, 50, 80);// body

        my_g.setColor(Color.cyan);
        my_g.fillRect(x - 30, y + 105, 55, 20); // left arm

        my_g.setColor(Color.cyan);
        my_g.fillRect(x + 70, y + 105, 60, 20); // right arm

        my_g.setColor(Color.red);
        my_g.fillOval(x - 47, y + 105, 20, 20); // left hand

        my_g.setColor(Color.red);
        my_g.fillOval(x + 126, y + 105, 20, 20); // right hand

        my_g.setColor(Color.cyan);
        my_g.fillRect(x + 25, y + 175, 20, 50); // left leg

        my_g.setColor(Color.cyan);
        my_g.fillRect(x + 55, y + 175, 20, 50); // right leg

    }

    public void myDrawArc(int x, int y, int height, int width, int angle1,
            int angle2, Graphics my_g) {
        my_g.setColor(Color.red);
        my_g.drawArc(x, y, 50, 50, 550, 170); // happy face
    }

    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        int c = e.getKeyCode();

        if (c == KeyEvent.VK_LEFT) {
            x_vel = -1;
            y_vel = 0;
        }
        if (c == KeyEvent.VK_UP) {
            x_vel = 0;
            y_vel = -1;
        }
        if (c == KeyEvent.VK_RIGHT) {
            x_vel = 1;
            y_vel = 0;
        }
        if (c == KeyEvent.VK_DOWN) {
            x_vel = 0;
            y_vel = 1;
        }
        repaint();

    }

    public void keyReleased(KeyEvent e) {
        // TODO Auto-generated method stub
        x_vel = 0;
        y_vel = 0;
        repaint();
    }

    public void keyTyped(KeyEvent e) {
        // TODO Auto-generated method stub

    }

    public void actionPerformed(ActionEvent e) {
        // TODO Auto-generated method stub
        if (x < 0) {
            x_vel = 0;
            x = 0;
        }
        if (x > 720) {
            x_vel = 0;
            x = 720;
        }
        if (y < 0) {
            y_vel = 0;
            y = 0;
        }
        if (y > 480) {
            y_vel = 0;
            y = 480;
        }
        x = x + x_vel;
        y = y + y_vel;
        repaint();

    }
} 
Community
  • 1
  • 1
Paul Samsotha
  • 205,037
  • 37
  • 486
  • 720
  • We haven't learned about Key Binding, timers, getPreferredSize() and packs yet. Are there any other alternatives? – user3542484 Apr 17 '14 at 02:31
  • I also tried to put the keylistener in the JPanel but it had no effect as well. – user3542484 Apr 17 '14 at 02:35
  • You can read those links and learn them on your own, and impress your teacher :) The ways I mentioned are the correct ways. Try and learn them. Work on it and if you get stuck somewhere in trying it, edit your post, and I'll be glad to help. – Paul Samsotha Apr 17 '14 at 02:38
  • I got told to put the background image before the character methods, but it still doesn't work. I also edited and added the KeyListeners to the JPanel, but my character still doesn't seem to move. – user3542484 Apr 17 '14 at 03:27
  • I don't really have time to go through your logic, but if you put `Timer timer = new Timer(30, this); timer.start();` after `setFocusable`, get rid of the Thread code, and put repaint() in the your keyXxx mwethods, it works. But I don't know if it works the way you want. You currently have an `actionPerfomed` but you never add the `ActionListener` to anything. That `actionPerformed` has some of the code logic. So what I did was add the listener to the `Timer`. The timer is supposed to do the animation, but it doesn't. You need to press the keys to move the figure. – Paul Samsotha Apr 17 '14 at 04:03
  • So fix the couple things I mentioned, review your animation logic. Keep in mind, what the timer does and call the actionListener every 30 milliseconds and changes something to animate, but currently it doesn't. So review your `actionPerformed` code. – Paul Samsotha Apr 17 '14 at 04:04
  • I added the code and removed the Threadcode, there's a red x on the public void run() method now and it says – user3542484 Apr 17 '14 at 04:33
  • Multiple markers at this line Syntax error, insert "enum identifer" to complete enum header name. - Syntax error insert "enumbody" to block statement- Syntax error on token "void" @expected. – user3542484 Apr 17 '14 at 04:34
  • I also have another question. How would I make the background show up? The image I have is in the resources package, but when I put it in the JFrame under if (map == null) map = new ImageIcon("/Resources/gamemap.png").getImage(); g2d.drawImage(map, 0, 0, 720, 480, 0, 0, 720, 480, getParent()); it just gives me a blank background. When I put it on the JFrame as a Jlabel, it shows up but it goes over the character. – user3542484 Apr 17 '14 at 04:46
  • You should use `new ImageIcon(getClass().getResource("/Reources/gamemapp.png"));` The `Resources` should be in the src – Paul Samsotha Apr 17 '14 at 04:53
  • Also don't create the image in the paintComponent method. Every time you call repaint it is going to recreate the image. Create it in the constructor – Paul Samsotha Apr 17 '14 at 04:56
  • I edited the code. I'm assuming you mean the GameJPanel constructor which still doesn't work. – user3542484 Apr 17 '14 at 05:05
  • Well now I don't see you drawing the image – Paul Samsotha Apr 17 '14 at 05:19
  • And dont set the background in the paint method. And you haven't remove the thread code. Please review all comments an the answer. – Paul Samsotha Apr 17 '14 at 05:21
  • Would I have to have a new method for the background? When I use the if statement, it doesn't recognize the g2d when I put it in the constructor. I'm still a bit confused on the Thread block since I still get the red error when I remove the parts with thread in it. Oh I think I know what you mean now. Remove the public void run method too right? I also edited the code in this thread. – user3542484 Apr 17 '14 at 05:43
  • Sorry but I have no more time to help you. I have posted the complete code that works for me. Make sure your `Resources` is in the src. Other than that, you need to check the logic of your key presses and action performed – Paul Samsotha Apr 17 '14 at 05:58
  • I managed to fix it. I added a JLabel, moved it to the contentpane, put the gamemap on the icon and added `this.setOpaque(false);` in the JPanel before my drawing methods and it worked. – user3542484 Apr 18 '14 at 03:03