How does one properly handle keypresses and repainting of a JComponent in the context of moving a ball around a screen?
===

I thought I would try and write a program that would paint a ball, and when the arrow keys are pressed, would move the ball around the screen in the direction pressed. First I started off to try and make a program that would just do "UP" arrow key motion.

I've looked around for a solution, and just can't figure out what's wrong with this code. I don't know if it's a problem with my input and action maps (i.e., a problem with the program recognizing key presses) or if it's a problem with how the JComponent and JFrame classes work in swing. I thought maybe the problem might also be focus; I don't really know how to tell when a component has focus. I think the key has been set to CNTRL+Y instead of up for now, just because at some point I thought it might be a problem with my string designating the up arrow in the input map maker.

At this point, I'm so frustrated I'm just trying to get the damn thing to do <em>something</em>, so I'm using more input maps than should be necessary.

the code is as follows, it's pretty short, formatted horribly (sorry):



    import java.util.*;
    import java.awt.*;
    import java.awt.geom.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    class BallMover
    {
        public static void main(String[] args)
        {
    	    EventQueue.invokeLater(new Runnable()
	        {
		    public void run()
		    {
		        BallFrame frame = new BallFrame();
		    }
	        });

    }
    }

    class BallFrame extends JFrame
    {
    private static final int DEFAULT_WIDTH = 500;
    private static final int DEFAULT_HEIGHT = 500;
    private BallComponent comp;

    public BallFrame()
    {
	super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	super.setSize(this.DEFAULT_WIDTH, this.DEFAULT_HEIGHT);
	super.setResizable(false);
	super.add(new BallComponent());
	super.setVisible(true);
	super.setFocusable(true);
    }
    }

    class BallComponent extends JComponent
    {
    private Ellipse2D.Double ellipse;
    private double x = 225;
    private double y = 225;
    private ActionPress actionPress;

    public BallComponent()
    {
	super();
	super.setFocusable(true);

	InputMap imap1 = this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
	imap1.put(KeyStroke.getKeyStroke("ctrl Y"), "keyUp1");
	InputMap imap2 = this.getInputMap(JComponent.WHEN_FOCUSED);
	imap1.put(KeyStroke.getKeyStroke("ctrl Y"), "keyUp2");
	InputMap imap3 = this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);	
	imap1.put(KeyStroke.getKeyStroke("ctrl Y"), "keyUp3");

	ActionMap amap = this.getActionMap();
	amap.put("keyUp1", actionPress);
	amap.put("keyUp2", actionPress);	
	amap.put("keyUp3", actionPress);
    }

    public void paintComponent(Graphics g)
    {
	super.repaint(); // clear component //
	Graphics2D g2d = (Graphics2D)g;
	this.ellipse = new Ellipse2D.Double(x, y, 50, 50);
	g2d.fill(this.ellipse);
    }

    private class ActionPress extends AbstractAction
    {
	public void actionPerformed(ActionEvent event)
	{
	    y = y + 10;
	    ellipse = new Ellipse2D.Double(x, y, 50, 50);
	    repaint();
	}
    }
    }

