java gui 移动,Java GUI中:如何使用移动WASD键一球?

I want to write a program in which the user can move the ball on the window by pressing WASD keys. Yet, when the user presses the keys, nothing happens. Bellow are the codes of my program, can anyone tell me what's wrong or how can I improve my program? ( The ball can move if I delete the KeyListener and put super.x ++; in ball.move() )

import java.awt.BorderLayout;

import java.awt.Color;

import java.awt.Graphics;

import java.awt.Graphics2D;

import java.awt.RenderingHints;

import java.awt.event.KeyAdapter;

import java.awt.event.KeyEvent;

import java.awt.event.KeyListener;

import java.util.concurrent.ScheduledThreadPoolExecutor;

import java.util.concurrent.TimeUnit;

import javax.swing.JApplet;

import javax.swing.JComponent;

import java.awt.geom.*;

public class MoveBall extends JApplet

{

public final int Width = 567;

public final int Height = 567;

public static PaintSurface canvas;

public void init()

{

canvas = new PaintSurface();

this.setSize(Width, Height);

this.add(canvas, BorderLayout.CENTER);

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(3);

executor.scheduleAtFixedRate(new Action(), 0L, 10L, TimeUnit.MILLISECONDS);

}

}

class Action implements Runnable

{

public void run()

{

MoveBall.canvas.repaint();

}

}

class PaintSurface extends JComponent

{

Ball ball = new Ball(20);

public PaintSurface()

{

addKeyListener(new Listener());

}

public void paint(Graphics g)

{

Graphics2D g2 = (Graphics2D)g;

g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

ball.move();

g2.setColor(Color.GREEN);

g2.fill(ball);

g2.setColor(Color.BLACK);

g2.drawString("W,A,S,D or arrow keys to move", 7, 17);

}

}

class Ball extends Ellipse2D.Float

{

public int xspeed, yspeed;

public Ball(int d)

{

super(370,370, d,d);

}

public void move()

{

if(super.x >567)

super.x -=567;

if(super.x <0)

super.x +=567;

if(super.y >567)

super.y -=567;

if(super.y < 0)

super.y +=567;

super.x += xspeed ;

super.y += yspeed ;

}

}

class Listener implements KeyListener

{

public void keyPressed(KeyEvent ev)

{

if(ev.getKeyCode() == KeyEvent.VK_W)

{

MoveBall.canvas.ball.xspeed = 0 ;

MoveBall.canvas.ball.yspeed = -1 ;

}

if(ev.getKeyCode() == KeyEvent.VK_A)

{

MoveBall.canvas.ball.xspeed = -1 ;

MoveBall.canvas.ball.yspeed = 0 ;

}

if(ev.getKeyCode() == KeyEvent.VK_S)

{

MoveBall.canvas.ball.xspeed = 0 ;

MoveBall.canvas.ball.yspeed = 1 ;

}

if(ev.getKeyCode() == KeyEvent.VK_D)

{

MoveBall.canvas.ball.xspeed = 1 ;

MoveBall.canvas.ball.yspeed = 0 ;

}

}

public void keyReleased(KeyEvent arg0){}

public void keyTyped(KeyEvent arg0){}

}

解决方案

Yet, when the user press the keys, nothing happens.

Don't use a KeyListener. A KeyListener only works if the component has focus, so I would guess your component doesn't have focus.

Instead use Key Bindings, then the keyboard will work even if the component doesn't have focus.

See Motion Using the Keyboard for more information about both approaches. As well as working code for both approaches.

Also:

Custom painting should be done by overriding paintComponent(...), not paint(...). You should invoke super.paintComponent(...) at the start. Although in this case because you are extending JComponent the background will not be cleared automatically, so instead you need to add a fillRect(...) statement to paint the background of your component before painting the ball.

Don't use a ScheduledThreadPoolExecutor for animation. Updates to the state of GUI components should be done on the Event Dispatch Thread. You should be using a Swing Timer.

Take a look at the Swing Tutorial. There are sections on Custom Painting and How to Use Swing Timers to get you started.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值