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);
}
}
Here's the frame class. ^^
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.
MoveShip
class. Perhaps you meant to create an instance of this class in the main method rather instead of just aJFrame
.Ship
in the KeyListener method), and want to repaint so that change in coordinates takes affect, you should explicitly callrepaint
on the object you wish to paint (in this casePaintObjects
).MoveShip
andPaintObjects
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.KeyListener
to fire, the component must have focus. You might consider using KeyBindings.I used key bindings instead of a key listener. The advantage to using key bindings is that you can bind the WASD keys (for left handed players) and the arrow keys (for right handed players) to the same AbstractAction.
Here's the GUI I created.
I didn't put in any error checking to make sure the circle stays in the JPanel drawing area.
I started the Swing GUI on the Event Dispatch thread by making a call to the SwingUtilities invokeLater method in the main method.
I used a JFrame. The only time you override a Swing component (or any Java class) is when you want to override one or more of the class methods.
The setKeyBindings method sets the WASD keys and the arrow keys to the AbstractAction method.
Here's the code.