I tried this code in BlueJ which should create a rectangle and move it around but it does not function. Then I put the same exact code into Eclipse and it functions as I thought it would. Any ideas to why this works in Eclipse but not in BlueJ?
import javax.swing.*;
import java.awt.*;
public class Shapes
{
public static void main(String[] args)
{
JFrame frame = new JFrame("Test");
Draw object = new Draw();
frame.add(object);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400,400);
frame.setVisible(true);
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class Draw extends JPanel implements ActionListener, KeyListener
{
Timer tm = new Timer(5,this);
int x = 0, y = 0, velX = 0, velY = 0;
public Draw()
{
tm.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(x,y,100,20);
}
public void actionPerformed(ActionEvent e)
{
x += velX;
y += velY;
repaint();
}
public void keyPressed(KeyEvent e)
{
int c = e.getKeyCode();
if(c == KeyEvent.VK_LEFT)
{
velX = -1;
velY = 0;
}
if(c == KeyEvent.VK_UP)
{
velX = 0;
velY = 1;
}
if(c == KeyEvent.VK_RIGHT)
{
velX = 1;
velY = 0;
}
if(c == KeyEvent.VK_DOWN)
{
velX = 0;
velY = -1;
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e)
{
velX = 0;
velY = 0;
}
}
I can see what you mean I believe it attaches it to that corner of the screen because when I resize the screen it moves with that corner. I think its not that BlueJ can't Run it properly i believe it can but it does it differently than what eclipse does.
I believe this question asks the same thing and it gets pretty good answers you should look at it first.
Related
Hey so I'm fairly new to java, but based on doing a lot of research and analyzing various code, I came up with some code to move a basic circle on a screen by using arrow keys.
However, for some reason, the code does not run the whole key event. If I press any key on the keyboard, even different arrow keys, it will cause the circle to only move one direction.
Based on my code, I feel like everything should work, but it just won't run the KeyEvent function properly. Any ways to fix it?
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class second extends JPanel implements ActionListener, KeyListener
{
Timer t = new Timer(5, this);
int x = 0, y = 0, velx = 0, vely = 0;
public second()
{
t.start();
addKeyListener(this);
setFocusable(true);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Ellipse2D.Double(x, y, 40, 40));
}
public void actionPerformed(ActionEvent e)
{
x += velx;
y += vely;
repaint();
}
public void up()
{
velx = 0;
vely = 2;
}
public void down()
{
velx = 0;
vely = -2;
}
public void left()
{
velx = -2;
vely = 0;
}
public void right()
{
velx = 2;
vely = 0;
}
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP);
{
up();
}
if (keyCode == KeyEvent.VK_DOWN);
{
down();
}
if (keyCode == KeyEvent.VK_LEFT);
{
left();
}
if (keyCode == KeyEvent.VK_RIGHT);
{
right();
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
velx = 0;
vely = 0;
}
public static void main(String args[])
{
second s = new second();
f.add(s);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800, 600);
}
}
First of all, ActionListener is not required in this case. KeyListener is sufficient. Also there is a semicolon beside if statements, this is causing all the functions up, down, left and right to be invoked negating the effect.
Also for up, y should be reduced and for down, y should be increased.
Please find the below code which works fine. You can limit the right and down movement with MAX_LIMIT based on the window size. I limited it for 0,0 for left and up movement.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class Second extends JPanel implements KeyListener
{
int x = 0, y = 0;
public Second()
{
addKeyListener(this);
setFocusable(true);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Ellipse2D.Double(x, y, 40, 40));
}
public void up()
{
if(y >= 5) {
y -= 5;
repaint();
}
}
public void down()
{
y += 5;
repaint();
}
public void left()
{
if(x >= 5) {
x -= 5;
repaint();
}
}
public void right()
{
x += 5;
repaint();
}
public void keyPressed(KeyEvent e)
{
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP)
{
up();
}
if (keyCode == KeyEvent.VK_DOWN)
{
down();
}
if (keyCode == KeyEvent.VK_LEFT)
{
left();
}
if (keyCode == KeyEvent.VK_RIGHT)
{
right();
}
}
public void keyTyped(KeyEvent e)
{
}
public void keyReleased(KeyEvent e)
{
}
public static void main(String args[])
{
Second s = new Second();
JFrame f = new JFrame();
f.add(s);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800, 600);
}
}
First, you have a semi-colon following your first if statement in keyPressed(), which impeaches considering following instructions. cf :
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode == KeyEvent.VK_UP)
up();
if (keyCode == KeyEvent.VK_DOWN)
down();
if (keyCode == KeyEvent.VK_LEFT)
left();
if (keyCode == KeyEvent.VK_RIGHT)
right();
}
You also have a negative value for vely in down() where it should be positive (and vice-versa). And since you already reset velx and vely to 0 on keyReleased(), it is unnecessary to do it in your directions functions.
public void up() {
vely = -2;
}
public void down() {
vely = 2;
}
Class names should be CamelCase (not lowercase as presented).
Have fun.
I wrote a Java program that has 3 classes:
main.class (main method class)
Infout.class (class that draws circle + methods for circle that allow it to be controlled with keyboard input (arrow keys)
obj2.class (class that draws a rectangle)
All the code is compiled fine, but for some reason when I run the program, the program executes all the code from obj2.class but does not execute the one from Infout.class.
In other words, it draws the rectangle (obj2.class) but it does not draw the controllable circle (Infout.class). Is Obj2.class over riding Infout.class? If it is, what should I do?
The code is much too big to post here, the website says the post is "mostly code" :c.
Thanks!
EDIT: Ok here's the relevant code:
main.class
import javax.swing.JFrame;
public class main {
public static void main(String args[]) {
JFrame frame = new JFrame();
Infout m = new Infout();
obj2 o = new obj2();
frame.add(m);
frame.add(o);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 400);
frame.setTitle("Circle");
}
}
Infout.class
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class Infout extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(5, this);
double x = 0, y = 0, velx = 0, vely = 0;
public Infout(){
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Ellipse2D.Double(x, y, 40, 40));
}
public void actionPerformed(ActionEvent e) {
repaint();
x += velx;
y += vely;
if (x < 0 || x > 260)
{
velx = 0;
vely = 0;
}
if (y < 0 || y > 340)
{
velx = 0;
vely = 0;
}
}
public void up() {
vely = -1.5;
velx = 0;
}
public void down() {
vely = 1.5;
velx = 0;
}
public void left() {
velx = -1.5;
vely = 0;
}
public void right() {
velx = 1.5;
vely = 0;
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
up();
}
if (code == KeyEvent.VK_DOWN) {
down();
}
if (code == KeyEvent.VK_RIGHT) {
right();
}
if (code == KeyEvent.VK_LEFT) {
left();
}
}
public void keyTyped(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
}
obj2.class
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Ellipse2D;
import javax.swing.JPanel;
public class obj2 extends JPanel{
int x;
int y;
public obj2(){
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Ellipse2D.Double(10, 20, 40, 40));
}
}
Infout and obj2 are not related.
Because obj2 extends JPanel, the call super.paintComponent(g) calls JPanel's version. If you obj2 to be a subclass of Infout, then you need to use extends:
public class obj2 extends Infout {
// Code here
}
Once this is done, super will refer to Infout.
So I was making a game for my Computer Science class, pretty much making a modified version of the game Frogger, and I first started off by just moving a circle across the JPanel to mimic the frogs movement and I realized a very annoying lag between the interactions with the buttons. Does anyone know how to completely get rid of the lag or perhaps reduce it? Any tips or help would be much appreciated! Here is the code so far for just the circle movement and if you see any improvements that could be done, please feel free to leave your comments.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
public class second extends JPanel implements ActionListener, KeyListener
{
Timer t = new Timer (5, this);
double x = 0, y = 0, velx = 0, vely = 0;
public second()
{
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
public void paintComponent (Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.fill(new Ellipse2D.Double(x, y, 10, 10));
}
public void actionPerformed (ActionEvent e)
{
repaint();
x += velx;
y += vely;
}
public void up()
{
vely = -5;
velx = 0;
}
public void down()
{
vely = 5;
velx = 0;
}
public void left()
{
velx = -5;
vely = 0;
}
public void right()
{
velx = 5;
vely = 0;
}
public void upEnd()
{
velx = 0;
vely = 0;
}
public void downEnd()
{
velx = 0;
vely = 0;
}
public void leftEnd()
{
velx = 0;
vely = 0;
}
public void rightEnd()
{
velx = 0;
vely = 0;
}
public void keyPressed (KeyEvent e)
{
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP)
{
up();
}
if (code == KeyEvent.VK_DOWN)
{
down();
}
if (code == KeyEvent.VK_RIGHT)
{
right();
}
if (code == KeyEvent.VK_LEFT)
{
left();
}
}
public void keyTyped (KeyEvent e) {}
public void keyReleased (KeyEvent e)
{
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP)
{
upEnd();
}
if (code == KeyEvent.VK_DOWN)
{
downEnd();
}
if (code == KeyEvent.VK_RIGHT)
{
rightEnd();
}
if (code == KeyEvent.VK_LEFT)
{
leftEnd();
}
}
}
And here is the Main file:
import javax.swing.JFrame;
public class Macheads
{
public static void main (String[] args)
{
JFrame f = new JFrame();
second s = new second();
f.add(s);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800,600);
}
}
Don't use a KeyListener. Instead you should be using Key Bindings.
The keyboard has a delay for repeating events. Use a Swing Timer to schedule the animation instead of relying on key events to be generated. See Motion Using the Keyboard for more information and examples.
Try using only the keyListener without the timer and actionlistener.
public void keyPressed (KeyEvent e)
{
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP)
{
up();
}
if (code == KeyEvent.VK_DOWN)
{
down();
}
if (code == KeyEvent.VK_RIGHT)
{
right();
}
if (code == KeyEvent.VK_LEFT)
{
left();
}
x += velx;
y += vely;
repaint(); //added and will repaint everytime key is pressed
}
//no need to place arguments in keyTyped and keyReleased because JPanel is repainted on keypressed...
I'm trying to create the beginning of a simple game. The first thing I am trying to do is import a graphic into my code and move it across the screen. I was able to draw a ball on the screen and move it around but when I import a graphic from a file I am unable to move it around. What am I missing or doing wrong?
import javax.swing.*;
import java.awt.Graphics;
import java.awt.*;
import java.awt.event.*;
import javax.swing.ImageIcon;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Game extends JPanel implements ActionListener, KeyListener {
Timer t = new Timer(5, this);
double x = 0, y = 0, velX = 0, velY = 0;
private ImageIcon image;
public Game(){
setBackground(Color.WHITE);
t.start();
addKeyListener(this);
this.setFocusable(true);
setFocusTraversalKeysEnabled(false);
image = new ImageIcon ("ship.gif");
}
public void paintComponent(Graphics g){
super.paintComponent(g);
ImageIcon i = new ImageIcon("C:\\Users\\Bryan\\Pictures\\ship.gif");
i.paintIcon(this, g, 0, 0);
}
public void actionPerformed(ActionEvent e){
repaint();
x += velX;
y += velY;
if(x<0){
velX = 0;
x = 0;
}
if(x>750){
velX = 0;
x = 750;
}
if(y<0);{
velY = 0;
y = 0;
}
if(y>550){
velY = 0;
y = 550;
}
}
public void up(){
velY = -1.5;
velX = 0;
}
public void down(){
velY = 1.5;
velX = 0;
}
public void left(){
velX = -1.5;
velY = 0;
}
public void right(){
velX = 1.5;
velY = 0;
}
public void keyPressed(KeyEvent e){
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP){
up();
}
if (code == KeyEvent.VK_DOWN){
down();
}
if (code == KeyEvent.VK_LEFT){
left();
}
if (code == KeyEvent.VK_RIGHT){
right();
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){
// velX = 0;
// velY = 0;
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP){
velY = 0;
}
if (code == KeyEvent.VK_DOWN){
velY = 0;
}
if (code == KeyEvent.VK_LEFT){
velX = 0;
}
if (code == KeyEvent.VK_RIGHT){
velX = 0;
}
}
}
My driver is in another class as follows:
import java.awt.Color;
import javax.swing.JFrame;
public class GameDriver {
public static void main(String[] args) {
JFrame f = new JFrame();
Game g = new Game();
f.add(g);
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(800,600);
}
}
Two big problems here:
public void paintComponent(Graphics g){
super.paintComponent(g);
ImageIcon i = new ImageIcon("C:\\Users\\Bryan\\Pictures\\ship.gif");
i.paintIcon(this, g, 0, 0);
}
You're reading from a file from within paintComponent(...). Never do this as this will slow your drawing unnecessarily. Read the image once, perhaps in a constructor, and then use the stored image variable in drawing. The paintComponent method should be for painting only, and it should be lean, mean and fast.
You're drawing at 0, 0 always. If you want to move something, draw at a variable position, and then change the values held by the variable and repaint.
Also: You should use Key Bindings to accept key strokes in a Swing application as this will help solve focus issues.
For example, please have a look at my code in this answer.
When I run the program and move the circle, it appears as if I'm drawing with a paintbrush in paint. I'm not quite sure what I did to make it to this, or what I can do to make it stop. All help is highly appreciated.
Here is my code:
import java.awt.Graphics;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.JFrame;
import javax.swing.Timer;
import javax.swing.JPanel;
import java.awt.event.KeyListener;
public class MovingCar extends JPanel implements ActionListener, KeyListener {
Timer tm = new Timer(5, this);
int x = 0, y = 0, velX = 0, velY = 0;
public MovingCar()
{
tm.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
}
protected void paintComponent (Graphics g) {
super.paintComponents(g);
g.drawOval(x, y, 50, 50);
}
public void actionPerformed(ActionEvent e){
x = x + velX;
y = y + velY;
repaint();
}
public void keyPressed(KeyEvent e){
int c = e.getKeyCode();
if (c == KeyEvent.VK_DOWN) {
velX = -1;
velY = 0;
}
if (c == KeyEvent.VK_UP)
{
velX = 1;
velY = 0;
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){
if (x < 0)
{
velX = 0;
x = 0;
}
if (x > 600)
{
velX = 0;
x = 0;
}
repaint();
velY = 0;
velX = 0;
}
public static void main(String[] args) {
MovingCar o = new MovingCar();
JFrame jf = new JFrame();
jf.setTitle("Circle Move");
jf.setSize(600,400);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(o);
jf.setVisible(true);
}
}
You're calling super.paintComponents(g); instead of super.paintComponent(g);