Ecco un esempio funzionante!

codice:
package caralu;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.Timer;

public class Caralu extends JFrame {
    
    static int JUMP = 1;
    static int APPLET_HEIGHT=480;
    static int APPLET_WIDTH=640;
    static int IMAGE_SIZE=50; // Sarebbe meglio avere dimensioni separate
    static int MILLISECONDI=100; // Ogni quanti ms vuoi che si muova l'immagine?
    
    int x; // posizione orizzontale corrente
    int inc_x; // aggiungi alla posizione orizzontale corrente
    int y; // posizione verticale corrente
    int inc_y; // aggiungi alla posizione verticale corrente
    
    JLabel ics, ipsilon; // Mi spiace, non so come si visualizza un'immagine...
    JPanel u;
    Timer timer;
    
    public Caralu(int x0, int y0) {
        x=x0;
        y=y0;
        inc_x=inc_y=0;
        
        ics = new JLabel("");
        ipsilon = new JLabel("");
        
        u = new JPanel();
        u.add(ics);
        u.add(ipsilon);
        
        addKeyListener(new DirectionKeyListener());
        u.addKeyListener(new DirectionKeyListener());
        ics.addKeyListener(new DirectionKeyListener());
        ipsilon.addKeyListener(new DirectionKeyListener());
        
        timer = new Timer(MILLISECONDI, new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                int x1 = x + inc_x;
                int y1 = y + inc_y;
                if ((x1>0) && (x1<APPLET_WIDTH))
                    x=x1;
                if ((y1>0) && (y1<APPLET_HEIGHT))
                    y=y1;
                aggiorna();
            }
        });
    }
    
    public void aggiorna() {
        ics.setText(String.valueOf(x));
        ipsilon.setText(String.valueOf(y));
    }
    
    public Dimension getPreferredSize() {
        return new Dimension(APPLET_WIDTH, APPLET_HEIGHT);
    }
    
    public static void main(String[] args) {
        Caralu c= new Caralu(100,100);
        c.setContentPane(c.u);
        c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        c.pack();
        c.show();
        c.timer.start();
    }
    
    
    private class DirectionKeyListener extends KeyAdapter {
        
        //Spostiamo l'immagine a seconda dell'evento della tastiera
        public void keyPressed(KeyEvent event) {
            
            switch (event.getKeyCode()) {
                case KeyEvent.VK_UP:
                    inc_y=-JUMP;
                    break;
                case KeyEvent.VK_DOWN:
                    inc_y=JUMP;
                    break;
                case KeyEvent.VK_LEFT:
                    inc_x=-JUMP;
                    break;
                case KeyEvent.VK_RIGHT:
                    inc_x=JUMP;
                    break;
            }
        }
        
        public void keyReleased(KeyEvent event) {
            
            switch (event.getKeyCode()) {
                case KeyEvent.VK_UP:
                case KeyEvent.VK_DOWN:
                    inc_y=0;
                    break;
                case KeyEvent.VK_LEFT:
                case KeyEvent.VK_RIGHT:
                    inc_x=0;
                    break;
            }
        }
    }
    
}