使用keylistener在jpanel上移动圈 [英] Move circle around jpanel using keylistener

查看:152
本文介绍了使用keylistener在jpanel上移动圈的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好,所以我尝试创建一个Jpanel,该Jpanel创建一个圆,然后可以在屏幕上移动它.我来回走了一段时间,似乎无法弄清楚如何让实际的东西为我运动.

Ok so i'm attempting to create a Jpanel that creates a circle which can then be moved around the screen. I've been going back and forth for awhile and can't seem to figure out how to get the actual thing to move for me.

package astroidlab;

import java.awt.BorderLayout;
import javax.swing.JFrame;

public class MainFrame {
    public static void main(String[] args) {
      //components
    JFrame jf = new JFrame();
    PaintObjects po = new PaintObjects();


    jf.setLayout(new BorderLayout());
    jf.add(po, BorderLayout.CENTER);

    jf.setVisible(true);
    jf.setSize(300, 300);
    jf.setLocationRelativeTo(null);
    jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

  }
}

这是框架类. ^^

package astroidlab;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JPanel;
import javax.swing.Timer;

public class PaintObjects extends JPanel implements ActionListener{
//global variable
Ship s = new Ship();

//constructor
public PaintObjects() {
    super();

    Timer t = new Timer(50, this);
    t.start();
}

@Override
public void paintComponent(Graphics g) {
        super.paintComponents(g);
        g.setColor(Color.BLACK);

        g.fillOval(s.getXpos(),  s.getYpos(),  s.getHeight(),  s.getWidth());

}

@Override
public void actionPerformed(ActionEvent ae) {
    int xpos = s.getXpos();
    int ypos = s.getYpos();


    repaint();
}
}

上面的类应该绘制对象并更新它们.它确实绘制了椭圆形,但是好像我在上下一堂课时遇到了麻烦.

The above class is supposed to paint the objects and update them. It does paint the oval but it seems like i'm having trouble incorporating my next class.

package astroidlab;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JFrame;

public class MoveShip extends JFrame{
Ship s = new Ship();

public MoveShip() {

    ballMover bm = new ballMover();
    this.addKeyListener(bm);

}

private class ballMover implements KeyListener {

    @Override
    public void keyPressed(KeyEvent ke) {
        if(ke.getKeyCode() == 37) {
            s.goLeft();
        }
        if(ke.getKeyCode() == 39) {
            s.goRight();
        }
        if(ke.getKeyCode() == 38) {
            s.goUp();
        }
        if(ke.getKeyCode() == 40) {
            s.goDown();
        }
    }

    @Override
    public void keyReleased(KeyEvent ke) {
    }

    @Override
    public void keyTyped(KeyEvent ke) {
    }

}

}

上面的课程似乎是我出问题的地方.我没有图形方面的经验,所以我觉得我只是缺少一些简单的东西.

The class above appears to be where i'm going wrong. I'm not experienced with graphics so I have a feeling i'm just missing something simple.

package astroidlab;

public class Ship {
//fields
int xpos = 0;
int ypos = 0;
int height = 20;
int width = 20;

public Ship() {
    super();
}

//move methods
public  void goLeft() {
    xpos -= 2;
    System.out.println("xpos: " + xpos + " ypos: " + ypos);
}
public  void goRight() {
    xpos += 2;
    System.out.println("xpos: " + xpos + " ypos: " + ypos);
}

public  void goUp() {
    ypos -= 2;
    System.out.println("xpos: " + xpos + " ypos: " + ypos);
}
public  void goDown() {
    ypos += 2;
    System.out.println("xpos: " + xpos + " ypos: " + ypos);
}

//get methods
public int getXpos() {
    return xpos;
}
public int getYpos() {
    return ypos;
}
public int getHeight() {
    return height;
}
public int getWidth() {
    return width;
}

//set methods
public void setXpos() {
    this.xpos = xpos;
}
public void setYpos() {
    this.ypos = ypos;
}
public void setHeight() {
    this.height = height;
}
public void setWidth() {
    this.width = width;
}

}

然后此类会跟踪椭圆的位置,并在按下键时对其进行更新. (或者应该)

And then this class keeps track of the ovals position and will update it when a key is pressed. (Or should)

无论如何,任何反馈都将不胜感激.我确定我只是在犯一些菜鸟错误.预先感谢.

Anyways any feedback would be appreciated. I'm sure I'm just doing some noob mistakes. Thanks in advance.

推荐答案

  1. 上面的代码从不使用MoveShip类.也许您打算在main方法中创建此类的实例,而不仅仅是JFrame.
  2. 如果您更改某物的坐标(在本例中为KeyListener方法中的Ship),并且想要重新绘制以使坐标的更改生效,则应在要绘制的对象上显式调用repaint(在这种情况下PaintObjects).
  3. MoveShipPaintObjects都包含自己的Ship实例-如果一个实例移动,则不会影响另一个实例.而是创建一个可以在两个类之间共享的实例.
  4. 要触发KeyListener,组件必须具有焦点.您可以考虑使用 KeyBindings .
  1. The above code never makes use of the MoveShip class. Perhaps you meant to create an instance of this class in the main method rather instead of just a JFrame.
  2. If you change a coordinate of something (in this case Ship in the KeyListener method), and want to repaint so that change in coordinates takes affect, you should explicitly call repaint on the object you wish to paint (in this case PaintObjects).
  3. Both MoveShip and PaintObjects contain their own instance of Ship - if one instance moves it will not affect the other. Instead, create a single instance which you can share between the two class.
  4. For a KeyListener to fire, the component must have focus. You might consider using KeyBindings.

这篇关于使用keylistener在jpanel上移动圈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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