0

I have asked several questions already but I have yet to make any sort of breakthrough. So I followed the example here:http://www.camick.com/java/source/KeyboardAnimation.java that was referred to me. I switched out the JLabel for my Animation test which extends JComponent. However I am still getting no results. I think it might be the code from the Animation class that prevents the coordinates from being updated. Does this class interfere with the keybindings animation?(This class below loops through some buffered images for the walking animation not moving it across the screen but just switching between one image of a still and another with the legs of the character moving.)

import java.awt.Graphics;
import java.awt.image.BufferedImage;

import javax.swing.JComponent;



public class Animation extends JComponent{
    private static final long serialVersionUID = 1L;
    public BufferedImage currentFrame;
    public boolean walking=false;
    public int x=50;
    public int y=50;
    public int dx,dy;
    public void update()
    {
        if (walking){
            for(int frame=0;frame<(Art.player.length+1);frame++)
            {
                try{
                    currentFrame=Art.player[frame][0];
                    try {
                        Thread.sleep(200);
                        repaint();
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }           
                }catch(IndexOutOfBoundsException e)
                {
                    frame=0;
                    currentFrame=Art.player[frame][0];
                    try {
                        Thread.sleep(200);
                        repaint();
                    } catch (InterruptedException e1) {
                        // TODO Auto-generated catch block
                        e1.printStackTrace();
                    }

                }
            }
        }else
        {
            currentFrame=Art.player[0][0];
        }
    }
    public void startAnimation()
    {
        walking=true;
    }
    public void stopAnimation()
    {
        walking=false;
    }
    public void paintComponent(Graphics g)
    {
        g.drawImage(currentFrame,x,y,null);
    }

}

Here is the keybindings class:

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.util.Map;
import java.util.HashMap;
import javax.swing.*;

public class KeyboardAnimation implements ActionListener
{
    private final static String PRESSED = "pressed ";
    private final static String RELEASED = "released ";

    private JComponent component;
    private Timer timer;
    private Map<String, Point> pressedKeys = new HashMap<String, Point>();

    public KeyboardAnimation(JComponent component, int delay)
    {
        this.component = component;

        timer = new Timer(delay, this);
        timer.setInitialDelay( 0 );
    }

    /*
    *  &param keyStroke - see KeyStroke.getKeyStroke(String) for the format of
    *                     of the String. Except the "pressed|released" keywords
    *                     are not to be included in the string.
    */
    public void addAction(String keyStroke, int deltaX, int deltaY)
    {
        //  Separate the key identifier from the modifiers of the KeyStroke

        int offset = keyStroke.lastIndexOf(" ");
        String key = offset == -1 ? keyStroke :  keyStroke.substring( offset + 1 );
        String modifiers = keyStroke.replace(key, "");

        //  Get the InputMap and ActionMap of the component

        InputMap inputMap = component.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
        ActionMap actionMap = component.getActionMap();

        //  Create Action and add binding for the pressed key

        Action pressedAction = new AnimationAction(key, new Point(deltaX, deltaY));
        String pressedKey = modifiers + PRESSED + key;
        KeyStroke pressedKeyStroke = KeyStroke.getKeyStroke(pressedKey);
        inputMap.put(pressedKeyStroke, pressedKey);
        actionMap.put(pressedKey, pressedAction);

        //  Create Action and add binding for the released key

        Action releasedAction = new AnimationAction(key, null);
        String releasedKey = modifiers + RELEASED + key;
        KeyStroke releasedKeyStroke = KeyStroke.getKeyStroke(releasedKey);
        inputMap.put(releasedKeyStroke, releasedKey);
        actionMap.put(releasedKey, releasedAction);
    }

    //  Invoked whenever a key is pressed or released

    private void handleKeyEvent(String key, Point moveDelta)
    {
        //  Keep track of which keys are pressed

        if (moveDelta == null)
            pressedKeys.remove( key );
        else
            pressedKeys.put(key, moveDelta);

        //  Start the Timer when the first key is pressed

        if (pressedKeys.size() == 1)
        {
            timer.start();
        }

        //  Stop the Timer when all keys have been released

        if (pressedKeys.size() == 0)
        {
            timer.stop();
        }
    }

    //  Invoked when the Timer fires

    public void actionPerformed(ActionEvent e)
    {
        moveComponent();
    }

    //  Move the component to its new location

    private void moveComponent()
    {
        int componentWidth = component.getSize().width;
        int componentHeight = component.getSize().height;

        Dimension parentSize = component.getParent().getSize();
        int parentWidth  = parentSize.width;
        int parentHeight = parentSize.height;

        //  Calculate new move

        int deltaX = 0;
        int deltaY = 0;

        for (Point delta : pressedKeys.values())
        {
            deltaX += delta.x;
            deltaY += delta.y;
        }


        //  Determine next X position

        int nextX = Math.max(component.getLocation().x + deltaX, 0);

        if ( nextX + componentWidth > parentWidth)
        {
            nextX = parentWidth - componentWidth;
        }

        //  Determine next Y position

        int nextY = Math.max(component.getLocation().y + deltaY, 0);

        if ( nextY + componentHeight > parentHeight)
        {
            nextY = parentHeight - componentHeight;
        }

        //  Move the component

        component.setLocation(nextX, nextY);
    }

    //  Action to keep track of the key and a Point to represent the movement
    //  of the component. A null Point is specified when the key is released.

    private class AnimationAction extends AbstractAction implements ActionListener
    {
        private Point moveDelta;

        public AnimationAction(String key, Point moveDelta)
        {
            super(key);

            this.moveDelta = moveDelta;
        }

        public void actionPerformed(ActionEvent e)
        {
            handleKeyEvent((String)getValue(NAME), moveDelta);
        }
    }

    public static void main(String[] args)
    {
        Animation test = new Animation();

        KeyboardAnimation animation = new KeyboardAnimation(test, 24);
        animation.addAction("LEFT", -3,  0);
        animation.addAction("RIGHT", 3,  0);
        animation.addAction("UP",    0, -3);
        animation.addAction("DOWN",  0,  3);

        animation.addAction("control LEFT", -5,  0);
        animation.addAction("V",  5,  5);

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frame.getContentPane().add(test);
        frame.setSize(600, 600);
        frame.setLocationRelativeTo( null );
        frame.setVisible(true);
        test.startAnimation();
        test.update();
    }

    static class ColorIcon implements Icon
    {
        private Color color;
        private int width;
        private int height;

        public ColorIcon(Color color, int width, int height)
        {
            this.color = color;
            this.width = width;
            this.height = height;
        }

        public int getIconWidth()
        {
            return width;
        }

        public int getIconHeight()
        {
            return height;
        }

        public void paintIcon(Component c, Graphics g, int x, int y)
        {
            g.setColor(color);
            g.fillRect(x, y, width, height);
        }
    }
}
Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
user1058860
  • 513
  • 2
  • 9
  • 21
  • For better help sooner, post an [SSCCE](http://sscce.org/). – Andrew Thompson Jul 26 '13 at 15:40
  • 2
    Other notes: 1) `Thread.sleep(200); repaint();` Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling `Thread.sleep(n)` implement a Swing `Timer` for repeating tasks or a `SwingWorker` for long running tasks. See [Concurrency in Swing](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/) for more details. 2) If you cannot sort it from that, post an SSCCE and generate a simple image at runtime, something like `Image img = new BufferedImage(10,10,BufferedImage.TYPE_NT_RGB);` – Andrew Thompson Jul 26 '13 at 15:48
  • @AndrewThompson: your comment about Thread.sleep should be an answer since it address a major failing of the original poster's program. I'm more than a little surprised that he is doing this since he is using a Swing Timer, the appropriate solution for this, elsewhere in his code. – Hovercraft Full Of Eels Jul 26 '13 at 16:11
  • 1
    For reference, this complete [example](http://stackoverflow.com/a/5797965/230513) moves a line. – trashgod Jul 26 '13 at 16:15
  • Your for loop code is a bit scary. Please don't catch IOOBE like you're doing. And how will that loop detect when walking is false? Why not simply use a while loop instead? – Hovercraft Full Of Eels Jul 26 '13 at 16:16
  • 1
    Another complete example (mine) can be found [here](http://stackoverflow.com/a/6887354/522444). – Hovercraft Full Of Eels Jul 26 '13 at 16:18
  • I am completely lost in all these examples. Also I used the Timer instead of the thread, it still didn't help. All it did was make the buffered images move a lot faster between frames. And now I can't slow it down. I am very confused with this keybinding business. – user1058860 Jul 26 '13 at 16:50
  • *"I am completely lost in all these examples"* So give it your best shot, and if you still cannot manage it, prepare & post an SSCCE. We'll take a look at it. Also a tip: Add @trashgod (or whoever - the @ is important) to *notify* them of a new comment. Note that trashgod linked to an answer containing an SSCCE, it is just a small, complete example (in your case, it will be one that fails to do what you want, but we can fix it). – Andrew Thompson Jul 26 '13 at 16:53
  • so I posted an updated version that I think might be the problem in the code.http://stackoverflow.com/questions/17887315/keybindings-and-animation-loops. – user1058860 Jul 26 '13 at 17:20
  • can i just be banned for being stupid? – user1058860 Jul 26 '13 at 19:17
  • @user1058860: nope. Thanks for closing the other question. Consider editing the current question with updated information. – Hovercraft Full Of Eels Jul 26 '13 at 19:46
  • i was able to solve my problem. I didn't use keybindings, I just used key listeners – user1058860 Jul 26 '13 at 21:51
  • I'm glad that you've solved your problem. Later you will want to change it to use key bindings. – Hovercraft Full Of Eels Jul 26 '13 at 22:15

1 Answers1

3
Thread.sleep(200);
repaint();

Don't block the EDT (Event Dispatch Thread) - the GUI will 'freeze' when that happens. Instead of calling Thread.sleep(n) implement a Swing Timer for repeating tasks. See Concurrency in Swing for more details.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433