如何在屏幕上移动球的情况下正确处理按键和重新绘制JComponent? [英] How does one properly handle keypresses and repainting of a JComponent in the context of moving a ball around a screen?

查看:136
本文介绍了如何在屏幕上移动球的情况下正确处理按键和重新绘制JComponent?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我以为我会尝试编写一个可以画一个球的程序,当按下箭头键时,会按照按下的方向在屏幕上移动球。首先,我开始尝试制作一个只能进行向上箭头键动作的程序。

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.

我已经四处寻找解决方案,但是不能弄清楚这段代码有什么问题。我不知道我的输入和动作映射是否有问题(即程序识别按键的问题),或者JComponent和JFrame类如何在摇摆中工作时出现问题。我想也许问题可能也是焦点;我真的不知道如何判断组件何时具有焦点。我认为键已经设置为CNTRL + Y而不是现在,只是因为在某些时候我认为我的字符串在输入地图制作者中指定向上箭头可能是个问题。

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 something, 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();
        }
    } 
}


推荐答案

似乎你从未初始化 actionPress - 尝试将此添加到你的BallComponent构造函数中:

It seems that you never initialized actionPress - try adding this to your BallComponent constructor:

actionPress = new ActionPress();

即,你的构造函数看起来像这样

ie, your constructor would look like this

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");

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

这篇关于如何在屏幕上移动球的情况下正确处理按键和重新绘制JComponent?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆