Setters not seeming to work in main method - java

I am having trouble using setter methods from the main class with a JFrame "position". The active parts of the JFrame(triangles called "turtles" moving about) are leaving the JFrame and my current method of changing the coordinates when this happens is not working. Any help would be greatly appreciated, as I have been stuck for days.
The method wrapPosition is designed to change the coordinate if they're off the "screen" which is (800x600)pixels. This check is in the loop so a turtle never goes off the screen.
here is the Main Class:
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
class Lab7b
{
public static void main(String [ ] args)
{
int deltaTime = 50;
JFrame frame = new JFrame();
Canvas canvas = new Canvas();
frame.setTitle("Welcome to turtle land!");
frame.setSize(800, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(canvas);
ArrayList<DynamicTurtle> turtles = new ArrayList<DynamicTurtle>(); //An ArrayList containing Turtle elemenets
turtles.add(new RandomTurtleA(turtleCanvas, 400, 300));
turtles.add(new RandomTurtleA(turtleCanvas, 400, 300));
turtles.add(new RandomTurtleA(turtleCanvas, 400, 300));
while(true)
{
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).unDrawTurtle();
hello.setText("X: " + (turtles.get(i)).getPositionX() + " Y: " + (turtles.get(i)).getPositionY()); //print to JFRAME
System.out.println("X: " + (turtles.get(i)).getPositionX() + " Y: " + (turtles.get(i)).getPositionY()); //print to CMD
(turtles.get(i)).wrapPosition((turtles.get(i)).getPositionX(), (turtles.get(i)).getPositionY()); //this is the wrapPosition method that does not work
}
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).update(1000);
}
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).drawTurtle();
}
Utils.pause(deltaTime/2);
}
}
}
the Turtle class with the troublesome wrapPosition method:
class Turtle
{
protected Canvas canvas; // private field reference to a canvas private
private CartesianCoordinate myLocation, oldLocation;
private boolean penDown = true;
private double Angle, maxX, maxY, x, y;
public double d, e, first, second;
public Turtle(Canvas canvas, CartesianCoordinate initLocation)
{
this.canvas = canvas;
this.myLocation = new CartesianCoordinate(0,0);
Angle = 0;
penDown = true;
myLocation = initLocation.copy();
}
public void wrapPosition(double x, double y)
{
this.x = maxX;
this.y = maxY;
if(maxX < 0)
{
this.setPositionX(800);
}
if(maxX > 800)
{
this.setPositionX(0);
}
if(maxY < 0)
{
this.setPositionY(600);
}
if(maxY > 600)
{
this.setPositionY(0);
}
}
public double getPositionX()
{
double getPosX;
getPosX = myLocation.getX();
return getPosX;
}
public double getPositionY()
{
double getPosY;
getPosY = myLocation.getY();
return getPosY;
}
public void setPositionX(double x)
{
myLocation.setX(x);
}
public void setPositionY( double y)
{
myLocation.setY(y);
}
}
Also, if it is any help the coordinate class:
class CartesianCoordinate
{
private double xPosition, yPosition, setterX, setterY;
public CartesianCoordinate(double x, double y)
{
this.xPosition = x;
this.yPosition = y;
}
public double getX()
{
return this.xPosition;
}
public double getY()
{
return this.yPosition;
}
public void setX(double setterX)
{
this.setterX = xPosition;
}
public void setY(double setterY)
{
this.setterY = yPosition;
}
}
Any Help would be greatly appreciated. Thank you in advance.

The "setters" in class CartesianCoordinate do virtually nothing because they just assign to member variables which are not read.
public void setX(double setterX)
{
this.setterX = xPosition;
}
public void setY(double setterY)
{
this.setterY = yPosition;
}
Try these instead to have coordinates to be read be updated:
public void setX(double setterX)
{
this.xPosition= setterX;
}
public void setY(double setterY)
{
this.yPosition= setterY;
}

Related

Character can not move any more

So here is the code after taking the tips into account.
The map is kept being repainted, the keylistener has changed but there still seems to be a problem.
The problem again is, the little square in the upper left corner will not move, which is the desired outcome.
package schoolgamev2;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Spel {
public static void main(String[] args) {
Speelveld map = new Speelveld();
map.Speelveld();
map.GenerateMap();
}
}
class Speelveld extends JPanel {
final int rijen = 16;
final int kolommen = 16;
Speler speler = new Speler();
Loopgebied loopgebied = new Loopgebied();
Blokken blok = new Blokken();
int[][] coordinaten = new int[rijen][kolommen];
public void Speelveld() {
JFrame frame = new JFrame();
frame.setSize(500, 500);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(this);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
setFocusable(true);
addKeyListener(new KeyListener(this));
}
//genereer map
public void GenerateMap() {
Random random = new Random();
int x;
int y;
for (y = 0; y < rijen; y++) { //scan langs y
for (x = 0; x < kolommen; x++) { //scan langs x
//selecteert type blok voor coordinaten x y
coordinaten[x][y] = random.nextInt(4);
//debugprint
}
//debugprint
}
coordinaten[0][0] = 4; //speler begint altijd links boven
coordinaten[15][15] = 5; //finish is altijd rechts onder
}
public int[][] getCoordinaten() {
return coordinaten;
}
public Speler getSpeler2() {
return speler;
}
public int getSpelerX() {
return speler.getX();
}
public int getSpelerY() {
return speler.getY();
}
public void setSpelerX(int x) {
speler.setX(x);
}
public void setSpelerY(int y) {
speler.setY(y);
}
//#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x;
int y;
for (y = 0; y < rijen; y++) { //scan langs y
System.out.println("");
for (x = 0; x < kolommen; x++) { //scan langs x
blok.setX(x);
blok.setY(y);
blok.setType(coordinaten[x][y]);
System.out.print(coordinaten[x][y] + " ");
switch (blok.getType()) {
case 0:
loopgebied.teken(g);
break;
case 4:
speler.teken(g);
/*case 5:
eindveld.teken(g);
break;*/
default:
break;
}
}
}
}
}
class Speler extends Blokken {
Blokken blok = new Blokken();
public void teken(Graphics g) {
g.drawRect(blok.getX(), blok.getY(), 10, 10);
}
}
class Loopgebied extends Blokken {
Blokken blok = new Blokken();
public void teken(Graphics g) {
g.drawRect(blok.getX() * size, blok.getY() * size, size, size);
}
}
class Blokken {
private static int x;
private static int y;
private static int type;
public int size = 16;
//setters voor x y en type
public void setX(int xIn) {
x = xIn;
}
public void setY(int yIn) {
y = yIn;
}
public void setType(int typeIn) {
type = typeIn;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getType() {
return type;
}
}
class KeyListener extends KeyAdapter {
private static final int SCALE = 3;
private Speelveld speelveld;
public KeyListener(Speelveld speelveld) {
this.speelveld = speelveld;
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
int deltaX = 0;
int deltaY = 0;
if (key == KeyEvent.VK_LEFT) {
deltaX = -1 * SCALE;
deltaY = 0;
} else if (key == KeyEvent.VK_UP) {
deltaX = 0;
deltaY = -1 * SCALE;
} else if (key == KeyEvent.VK_RIGHT) {
deltaX = 1 * SCALE;
deltaY = 0;
} else if (key == KeyEvent.VK_DOWN) {
deltaX = 0;
deltaY = 1 * SCALE;
} else {
return;
}
int x = speelveld.getSpelerX() + deltaX;
int y = speelveld.getSpelerY() + deltaY;
speelveld.setSpelerX(x);
speelveld.setSpelerY(y);
speelveld.repaint();
}
}
As mentioned in comments, you got your player, the Speler class, that extends JPanel and is wired to use a KeyListener, but note that it is not being used as a JPanel, and so the KeyListener is non-functioning, because they only work when they have been added to a visible component that has focus.
Suggestions:
Again as per comments, make Speler a non-GUI logical class. Meaning don't have it extend JPanel or any other Swing component, and certainly don't add a KeyListener to it.
Instead give it code for the player's behavior and for having the player draw itself, and that's it. What I'm suggesting is that you try to separate part of your "Model" here the player from the "View" here the Swing GUI.
Have one JPanel and only one that does drawing. Have it override paintComponent (don't forget to call the super's paintComponent within it), and have it draw each logical component by calling the logical component's draw method (public void verf(Graphics2D g2)? or public void teken(Graphics2D g2)?) within its paintComponent method.
As a general rule, you also don't want your GUI component classes, the JPanel here, directly implementing listener interfaces, such as the KeyListener, but will want to keep them separate.
Either make this drawing JPanel focusable, give it focus and add the KeyListener, a separate class, to it.
Or better, use Key Bindings as per the tutorial: Key Bindings
For example the simple [MCVE] below doesn't use a Swing Timer or change velocities, but rather it uses a KeyListener to change position of the Speler2 object using only one drawing JPanel and a KeyListener. If I were making this more robust and larger, I would use the Swing Timer, would use Key Bindings, and would change the velocities using the key bindings.
import java.awt.Dimension;
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.image.BufferedImage;
import javax.swing.*;
public class Spel2 {
private static final int VELD_WIDTH = 500;
private static void createAndShowGui() {
Speelveld2 speelveld2 = new Speelveld2(VELD_WIDTH, VELD_WIDTH);
JFrame frame = new JFrame("Spel2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(speelveld2);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
speelveld2.requestFocusInWindow();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
class MyKeyListener extends KeyAdapter {
private static final int SCALE = 3;
private Speelveld2 speelveld2;
public MyKeyListener(Speelveld2 speelveld2) {
this.speelveld2 = speelveld2;
}
#Override
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
int deltaX = 0;
int deltaY = 0;
if (key == KeyEvent.VK_LEFT) {
deltaX = -1 * SCALE;
deltaY = 0;
} else if (key == KeyEvent.VK_UP) {
deltaX = 0;
deltaY = -1 * SCALE;
} else if (key == KeyEvent.VK_RIGHT) {
deltaX = 1 * SCALE;
deltaY = 0;
} else if (key == KeyEvent.VK_DOWN) {
deltaX = 0;
deltaY = 1 * SCALE;
} else {
return;
}
int x = speelveld2.getSpelerX() + deltaX;
int y = speelveld2.getSpelerY() + deltaY;
speelveld2.setSpelerX(x);
speelveld2.setSpelerY(y);
speelveld2.repaint();
}
}
#SuppressWarnings("serial")
class Speelveld2 extends JPanel {
private int prefW;
private int prefH;
private Speler2 speler2 = new Speler2();
public Speelveld2(int prefW, int prefH) {
this.prefW = prefW;
this.prefH = prefH;
setFocusable(true);
addKeyListener(new MyKeyListener(this));
}
public Speler2 getSpeler2() {
return speler2;
}
public int getSpelerX() {
return speler2.getX();
}
public int getSpelerY() {
return speler2.getY();
}
public void setSpelerX(int x) {
speler2.setX(x);
}
public void setSpelerY(int y) {
speler2.setY(y);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
speler2.teken(g2);
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(prefW, prefH);
}
}
class Speler2 extends Blokken2 {
private static final int RECT_W = 10;
public Speler2() {
super(BlokkenType.SPELER);
}
#Override
public void teken(Graphics2D g2) {
int x = getX();
int y = getY();
g2.drawRect(x, y, RECT_W, RECT_W);
}
}
class Blokken2 {
private int x;
private int y;
private int velx = 0;
private int vely = 0;
private BlokkenType type;
private BufferedImage img;
public Blokken2(BlokkenType type) {
this.type = type;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getVelx() {
return velx;
}
public void setVelx(int velx) {
this.velx = velx;
}
public int getVely() {
return vely;
}
public void setVely(int vely) {
this.vely = vely;
}
public BlokkenType getType() {
return type;
}
public void setType(BlokkenType type) {
this.type = type;
}
public void setImg(BufferedImage img) {
this.img = img;
}
public BufferedImage getImg() {
return img;
}
public void teken(Graphics2D g2) {
if (img != null) {
g2.drawImage(img, x, y, null);
}
}
}
enum BlokkenType {
LOOPGEBIED, BARRICADE, MUUR, SLEUTEN, SPELER, EINDVELD
}
Edit: your latest code has an error here:
class Speler extends Blokken {
Blokken blok = new Blokken();
public void teken(Graphics g) {
g.drawRect(blok.getX(), blok.getY(), 10, 10);
}
}
Regarding your edit:
Now when you create a Speler instance, you create TWO Blokken instances, one which is the Speler instance since it extends Blokken and the other which is contained by the Speler instance since it also has a Blokken field.
You update the x/y state of the first one, but you draw with the second one, and that's why no motion is being displayed. The solution is obvious: use one or the other but not both. Either have Speler extend Blokken or have it contain a Blokken instance but don't do both.

Java Eclipse game - restart game

I have made a game in Eclipse neon with the language Java, but I was wondering how I can make the game so that if the user presses r he or she could go back to the first screen where it says press spacebar to start. here are my 3 files of code if you need it to figure out the solution.
//This is the game file (main)
import processing.core.PApplet;
public class Game extends PApplet{
public static void main(String[] args) {
// TODO Auto-generated method stub
PApplet.main("Game");
}
James james1;
Wall wall1;
Wall wall2;
Wall wall3;
public void settings() {
size(500, 700);
}
public void setup() {
frameRate(40);
james1 = new James(this, 250, 650, 50);
wall1 = new Wall(this, 0);
wall2 = new Wall(this, 250);
wall3 = new Wall(this, -250);
}
public void draw() {
if(key == ' ') {
clear();
background(0, 255, 255);
boolean loser = wall1.col(james1.getX(), james1.getY()) || wall2.col(james1.getX(), james1.getY()) ||wall3.col(james1.getX(), james1.getY());
james1.show();
move();
if (!loser){
wall1.update();
wall2.update();
wall3.update();
}
else {
reset();
}
wall1.display();
wall2.display();
wall3.display();
}
else {
background(255, 0, 255);
textSize(45);
text("Press Space to Start!", 50, 350);
}
}
public void reset() {
clear();
frameRate(0);
textSize(40);
text("You Lose, R to restart", 25, 550);
}
public void restart() {
}
public void move() {
james1.setX(mouseX);
if (mouseX <= 25) {
james1.setX(25);
}
else if (mouseX >= 475) {
james1.setX(475);
}
}
}
//This is the character file (James)
import processing.core.PApplet;
public class James {
PApplet p;
private float x;
private float y;
private float size;
public James(PApplet np, float nx, float ny, float nsize) {
p = np;
x = nx;
y = ny;
size = nsize;
}
public void show() {
p.fill(255,20,147);
p.ellipse(x, y, size, size);
p.fill(128,128,0);
p.ellipse(x - 10, y - 10, size - 30, size - 30);
p.ellipse(x + 10, y - 10, size -30, size - 30);
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getSize() {
return size;
}
public void setX(float gx) {
x = gx;
}
public void setY(float gy) {
y = gy;
}
public void setSize(float gSize) {
size = gSize;
}
}
//This is obstacle class file (walls)
import processing.core.PApplet;
public class Wall {
PApplet p;
private float x;
private float y;
private float w;
private float xw;
private float yw;
private float h;
private float wh;
private float xspeed;
private float yspeed;
public Wall (PApplet np, float ny) {
p = np;
x = 0;
y = ny;
wh = 0;
xw = p.random(0, 450);
yw = p.random(0, 450);
w = p.random(0, 450);
h = 30;
yspeed = 10;
}
public void display() {
p.rect(0, y, w, h);
p.rect(w + 100, y, 500-(w+100), h);
}
public void update() {
if(y > p.height) {
y = 0;
w = p.random(0,450);
xw = p.random(0, 450);
yw = p.random(0, 450);
}
y = yspeed + y;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getW() {
return w;
}
public float getXW() {
return xw;
}
public float getYW() {
return yw;
}
public float getWH() {
return wh;
}
public float getH() {
return h;
}
public float getxSpeed() {
return xspeed;
}
public float getySpeed() {
return yspeed;
}
public void setX(float gx) {
x = gx;
}
public void setYW(float gyw) {
yw = gyw;
}
public void setW(float gw) {
w = gw;
}
public void setY(float gy) {
y = gy;
}
public void setH(float gh) {
h = gh;
}
public void setxSpeed(float gxSpeed) {
xspeed = gxSpeed;
}
public void setySpeed(float gySpeed) {
yspeed = gySpeed;
}
public boolean col(float ballX, float ballY) {
if (y + h >= ballY - 25 && y <= ballY + 25 ) {
if(ballX - 25 <= w || ballX+25 >= w+100) {
return true;
}
}
return false;
}
}
Hope that wasn't too long for just one goal ;)
Copy everything from method setup to method restart and then call restart from method setup.
You get something like this:
public void setup()
{
restart();
}
public void restart()
{
frameRate(40);
james1 = new James(this, 250, 650, 50);
wall1 = new Wall(this, 0);
wall2 = new Wall(this, 250);
wall3 = new Wall(this, -250);
}
Now just call restart whenever you want the game to restart. In your example: when the user presses the 'r' button.
In games, it really is a good idea to have a Map class that handles these kind of things.
You can just basically copy setup and paste it with a new method name, or even use that same method to make it so when pressed "r", it just calls that method back again. But just for it to be cleaner and much more readable. you can do this.
public void setup() {
if(key.r) { //of course this key.r will have to be created as a KeyListener.
restart();
}
}
public void restart() {
frameRate(40);
james1 = new James(this, 250, 650, 50);
wall1 = new Wall(this, 0);
wall2 = new Wall(this, 250);
wall3 = new Wall(this, -250);
}
You can either create a new class for the KeyInput or do it in the same class, but it should be a little like this:
public boolean[] keys = new boolean[120];
public boolean r;
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
f3 = (key == KeyEvent.VK_F3);
}
public void keyReleased(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
public void keyTyped(KeyEvent e) {
keys[e.getKeyCode()] = false;
}
}
Have a nice day!
:D

Accessing ArrayList objects outside of main class to change CartesianCoordiantes

I'm a bit stuck trying to manipulate information stored in an ArrayList in the main class.
My ArrayList contains a "RandomTurtleA" object called "turtles"(more turtles will be added to the ArrayList later) which extends "DynamicTurtle" which extends "Turtle". If I can change the CartesianCoordinates for the "turtles" stored in the ArrayList in Class Turtle, I can then make sure they do not leave the visible JFrame.
I have setter methods to change the CartesianCoordinates, however cannot find out how to use them outside of the Main class in the wrapPosition method where the various if statements are to check if the turtles off screen.
Here is the Main Class: (The ArrayList)
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
class Lab7b
{
public static void main(String [ ] args)
{
int deltaTime = 50;
double currentX, currentY;
JFrame frame = new JFrame();
Canvas canvas = new Canvas();
frame.setTitle("Welcome to turtle land!");
frame.setSize(1000, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.add(canvas);
JLabel hello = new JLabel("Hello all Word!");
hello.setHorizontalAlignment(SwingConstants.CENTER);
frame.add(hello, BorderLayout.PAGE_END);
Canvas turtleCanvas = new Canvas();
frame.add(turtleCanvas, BorderLayout.CENTER);
ImageIcon supermanImage = new ImageIcon("superman.png");
JLabel supermanJLable = new JLabel(supermanImage);
frame.add(supermanJLable, BorderLayout.LINE_START);
ImageIcon hulkImage = new ImageIcon("hulk.png");
JLabel hulkJLable = new JLabel(hulkImage);
frame.add(hulkJLable, BorderLayout.LINE_END);
CartesianCoordinate randomInit = new CartesianCoordinate(400,300);
ArrayList<DynamicTurtle> turtles = new ArrayList<DynamicTurtle>();
turtles.add(new RandomTurtleA(turtleCanvas, 400, 300));
while(true)
{
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).unDrawTurtle();
hello.setText("X: " + (turtles.get(i)).getPositionX() + " Y: " + (turtles.get(i)).getPositionY());
(turtles.get(i)).getPositionX() = currentX; // Problems here trying to access the current position of the turtle
(turtles.get(i)).getPositionX() = currentY; // " "
(turtles.get(i)).wrapPosition(1000, 600);
}
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).update(1000);
}
for (int i = 0; i < turtles.size(); i++)
{
(turtles.get(i)).drawTurtle();
}
Utils.pause(deltaTime/2);
}
}
}
The Turtle Class: (containing the wrapPosition Method)
import java.util.ArrayList;
class Turtle
{
protected Canvas canvas; // private field reference to a canvas private
private CartesianCoordinate myLocation, oldLocation;
private boolean penDown = true;
private double Angle;
public Turtle kieranMullen;
public Turtle(Canvas canvas, CartesianCoordinate initLocation)
{
this.canvas = canvas;
this.myLocation = new CartesianCoordinate(0,0);
Angle = 0;
penDown = true;
myLocation = initLocation.copy();
}
public void wrapPositon(double maximumXPosition, double mamimumYPosition)
{
if(turtles.getPositionX() < 0) //if current x of turtle is less than 0
{
this.setX(1000); //set to 1000
}
if(currentX > 1000)
{
this.setX(0);
}
if(currentY < 0)
{
this.setY(600);
}
if(currentY > 600)
{
this.setX(0);
}
}
public double getPositionX()
{
double getPosX;
getPosX = myLocation.getX();
return getPosX;
}
public double getPositionY()
{
double getPosY;
getPosY = myLocation.getY();
return getPosY;
}
}
The CartesianCoordinate Class: (Containing the setter Methods)
class CartesianCoordinate
{
private double xPosition, yPosition, setterX, setterY;
public CartesianCoordinate(double x, double y)
{
this.xPosition = x;
this.yPosition = y;
}
public double getX()
{
return this.xPosition;
}
public double getY()
{
return this.yPosition;
}
public void setX(double setterX)
{
this.setterX = xPosition;
}
public void setY(double setterY)
{
this.setterY = yPosition;
}
}
I Would greatly appreciate any help given to me, thanks in advance. Regards, Hornsbeh.
Your Problem is, that you only have a getter for position x and y in your turtle class.
You have to add a setter for your location that is public in the Turtle class that in turn calls the functions of your Coordinates Object. Just like you already did with the get methods.
Setter:
class Turtle {
//...
public void setPositionX(final double x)
{
myLocation.setX(x);
}
The same for Y.
Then in your main class you can set X by using that method:
(turtles.get(i)).setPositionX(currentX);

Getting Java Application to Run as an Applet or Standalone

I have written code to drive a Differential Drive Robot through a fixed path, chosen by me. I am trying to get the code to run either from the command line:
java StartRobot
or being able to run the application an an Applet within a browser. My code is below:
import java.awt.*;
import javax.swing.*;
import java.util.ArrayList;
import java.util.List;
class DifferentialDriveRobot {
public static void main(String[] args) {
new DifferentialDriveRobot();
}
public DifferentialDriveRobot() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
public void createAndShowGUI() {
JFrame frame = new JFrame("Differential Drive Robot");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
Robots robots = new Robots();
frame.add(robots);
frame.setSize(400,400);
frame.setVisible(true);
new Thread(new Drive(robots)).start();
}
public static int random(int maxRange) {
return (int) Math.round((Math.random() * maxRange));
}
public class Robots extends JPanel {
private List<Bot> robots;
public Robots() {
robots = new ArrayList<Bot>(1);
robots.add(new Bot(Color.red));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for(Bot robot : robots) {
robot.paint(g2d);
}
g2d.dispose();
}
public List<Bot> getRobots() {
return robots;
}
}
public class Drive implements Runnable {
private Robots parent;
public Drive(Robots parent) {
this.parent = parent;
}
#Override
public void run() {
int width = getParent().getWidth();
int height = getParent().getHeight();
for(Bot robot : getParent().getRobots()) {
int x = 5;
int y = 5;
int diameter = robot.getDiameter();
if(x + diameter > width) {
x = width - diameter;
}
if(y + diameter > height) {
y = height - diameter;
}
robot.setX(x);
robot.setY(y);
}
while(getParent().isVisible()) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
getParent().repaint();
}
});
for(Bot robot : getParent().getRobots()) {
move(robot);
}
try {
Thread.sleep(100);
} catch(InterruptedException ex) {}
}
}
public Robots getParent() {
return parent;
}
public void move(Bot robot) {
int diameter = robot.getDiameter();
double v1 = robot.getV1();
double v2 = robot.getV2();
double x = robot.getX();
double y = robot.getY();
double theta = robot.getTheta();
double dx, dy, dtheta;
int time = robot.getTime();
dx = 0.5*(Math.cos(Math.toRadians(theta)))*(v1+v2);
dy = 0.5*(Math.sin(Math.toRadians(theta)))*(v1+v2);
dtheta = (-1)*(0.5*(v2-v1));
if((x + dx < 0 || x + diameter + dx > getParent().getWidth()) || (y + dy < 0 || y + diameter + dy > getParent().getHeight())) {
v1 = 0;
v2 = 0;
} else {
if(time == 50) {
v2 = 0;
} else if(time > 50 && time < 300 && theta == 89.5) {
v1 = v2 = 1;
} else if(time > 300 && time < 450) {
v1 = 1;
v2 = 3;
}
if(time > 400 && theta == -89.0 && time < 500) {
v1 = 5;
v2 = 5;
}
if(time > 500 && time < 550) {
v1 = v2 = 0;
} else if(time > 550 && time < 600) {
v1 = v2 = -2;
} else if(time > 600) {
v1 = v2 = 0;
}
}
x = x + dx;
y = y + dy;
theta = theta + dtheta;
time = time + 1;
robot.setTheta(theta);
robot.setV1(v1);
robot.setV2(v2);
robot.setX(x);
robot.setY(y);
robot.setTime(time);
}
}
public class Bot {
private Color color;
private double x, y;
private int diameter;
private double v1, v2;
private double theta;
private int time;
public Bot(Color color) {
setColor(color);
v1 = 1;
v2 = 1;
diameter = 30;
theta = 0;
time = 0;
}
public int getTime() {
return time;
}
public void setTime(int time) {
this.time = time;
}
public int getDiameter() {
return diameter;
}
public void setColor(Color color) {
this.color = color;
}
public void setX(double x) {
this.x = x;
}
public void setY(double y) {
this.y = y;
}
public void setTheta(double theta) {
this.theta = theta;
}
public Color getColor() {
return color;
}
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getV1() {
return v1;
}
public double getV2() {
return v2;
}
public double getTheta() {
return theta;
}
public void setV1(double v1) {
this.v1 = v1;
}
public void setV2(double v2) {
this.v2 = v2;
}
protected void paint(Graphics2D g2d) {
double x = getX();
double y = getY();
double v1 = getV1();
double v2 = getV2();
g2d.rotate(Math.toRadians(theta),x,y);
g2d.setColor(getColor());
g2d.fillRect((int)x, (int)y, getDiameter(), getDiameter());
g2d.setColor(Color.black);
g2d.fillOval((int)x+9,(int)y-5,15,15);
g2d.fillOval((int)x+9,(int)y+20,15,15);
}
}
}
In the past I have been able to accomplish this by adding the following into my .java file:
public class StartRobot extends JApplet {
public void init() {
EventQueue.invokeLater(new Runnable() {
public void run() {
DifferentialDriveRobot panel = new DifferentialDriveRobot();
getContentPane.add(panel);
}
});
}
public static void main(String[] args) {
//Schedule a job for the event-dispatching thread:
//creating and showing this application's GUI.
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
DifferentialDriveRobot panel = new DifferentialDriveRobot();
panel.createAndShowGUI();
}
});
}
}
However, this throws an error while compiling. I think this is due to the fact that my main class DifferentialDriveRobot does not extend JPanel, instead it is a subclass where I accomplish this. Is there a quick fix to this?
The class DifferentialDriveRobot is a non-component class that cannot be added to an applet. It is a class that causes a JFrame to be created and adds your Robot panel class. This will cause a JFrame to appear if you run the applet in a browser, which is usually not desirable.
You could define the class Robot as your applet:
public class Robot extends JApplet {
public void init() {
...
}
then add the applet to your main method:
public static void main(String[] args) {
JFrame frame = new JFrame("Applet Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 400);
JApplet applet = new Robot();
applet.init();
applet.start();
frame.add(applet);
frame.setVisible(true);
}
If you want the applet to run as an application, a good alternative is to convert it completely an JFrame-based application and deploy it using Java Web Start.

My Bouncing Ball Does Not Draw

I am having a problem getting my application to draw a Ball when i click on the frame.
I thought my code was correct, and I don't get any errors, but it still doesn't work.
I feel the problem is with the MouseListener implementation and that the application is not handling the MouseEvent properly.
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class BouncingBallApp extends JFrame
{
public static void main(String[] args)
{
Container container;
BouncingBallApp bouncingBalls = new BouncingBallApp();
bouncingBalls.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container = new Container();
BouncingBallPanel BBP = new BouncingBallPanel();
container.add(BBP);
bouncingBalls.addMouseListener(BBP);
//addMouseListener;
bouncingBalls.setBackground( Color.WHITE );
bouncingBalls.setSize(400,300);
bouncingBalls.setVisible( true );
}//end of main method
}//end of BouncingBallApp
class BouncingBallPanel extends JPanel implements MouseListener, Runnable
{
private Ball[] ballArray = new Ball[20];
private int ballCount = 0;
public void run()
{
for(int i = 0; i<ballArray.length; i++){
if(ballArray[i] != null){
ballArray[i].move();}}
repaint();
//delay(1);
}
public void mouseClicked(MouseEvent e)
{
ballArray[ballCount] = new Ball();
ballCount++;
if(ballCount == 1)
(new Thread(new BouncingBallPanel())).start();
}
//empty interface methods
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void paintComponent(Graphics g)
{
super.paintComponent( g );
Graphics2D g2d = (Graphics2D) g;
for(int i = 0; i<ballArray.length; i++)
{
if(ballArray[i] != null){
g2d.setColor(ballArray[i].getColor());
g2d.fill(new Ellipse2D.Double(ballArray[i].getX(),ballArray[i].getY(),ballArray
[i].getDiameter(),ballArray[i].getDiameter()));}
}//end of for loop
}
}//end of BouncingBallPanel
class Ball
{
private double x;
private double y;
private double deltaX;
private double deltaY;
private double diameter;
private Color color;
Random random = new Random();
public Ball()
{
x = random.nextInt(400);
y = random.nextInt(300);
deltaX = 2;
deltaY = 2;
diameter = 10;
color = new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256));
}//end of constructor
public double getX(){
return x;}
public double getY(){
return y;}
public double getDiameter(){
return diameter;}
public Color getColor(){
return color;}
public void move()
{
x += deltaX;
y += deltaY;
if (x < 0) {
x = 0;
deltaX = -deltaX;}
else if (x > 400) {
x = 400;
deltaX = -deltaX;}
if (y < 0) {
y = 0;
deltaY = -deltaY;}
else if (y > 300) {
y = 300;
deltaY = -deltaY;}
}//end of method move
}//end of ball
3 Things
No size for container
You are not adding container
No loop to update graphics
The code below is working
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class BouncingBallApp extends JFrame {
public static void main(String[] args) {
// Container container;
BouncingBallApp bouncingBalls = new BouncingBallApp();
bouncingBalls.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// container = new Container();
BouncingBallPanel BBP = new BouncingBallPanel();
// container.add(BBP);
bouncingBalls.addMouseListener(BBP);
// addMouseListener;
bouncingBalls.setBackground(Color.WHITE);
bouncingBalls.setSize(400, 300);
BBP.setSize(400, 300);
BBP.setLayout(null);
bouncingBalls.setContentPane(BBP);
/*
* JTextField jtf = new JTextField(); BBP.add(jtf); jtf.setSize(100,
* 20);
*/
bouncingBalls.setVisible(true);
}// end of main method
}// end of BouncingBallApp
class BouncingBallPanel extends JPanel implements MouseListener {
private Ball[] ballArray = new Ball[20];
private int ballCount = 0;
public void mouseClicked(MouseEvent e) {
ballArray[ballCount] = new Ball();
ballCount++;
if (ballCount == 1) {
final Runnable updateGraphics = new Runnable() {
public void run() {
for (int i = 0; i < ballArray.length; i++) {
if (ballArray[i] != null) {
ballArray[i].move();
}
}
repaint();
}
};
Runnable animation = new Runnable() {
public void run() {
while (true) {
try {
EventQueue.invokeLater(updateGraphics);
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
}
}
};
new Thread(animation).start();
}
}
// empty interface methods
public void mouseExited(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void paintComponent(Graphics g) {
// super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (int i = 0; i < ballArray.length; i++) { if (ballArray[i] !=
null) { System.out.println(" ball " + i + " , " +
ballArray[i].getColor() + " , " + ballArray[i].getX() + " , " +
ballArray[i].getY() + " , " + ballArray[i].getDiameter());
g2d.setColor(ballArray[i].getColor());
g2d.fillRect((int)ballArray[i].getX(), (int)ballArray[i].getY(),
(int)ballArray[i].getDiameter(), (int)ballArray[i].getDiameter()); }
}// end of for loop
}
}// end of BouncingBallPanel
class Ball {
private double x;
private double y;
private double deltaX;
private double deltaY;
private double diameter;
private Color color;
Random random = new Random();
public Ball() {
x = random.nextInt(400);
y = random.nextInt(300);
deltaX = 2;
deltaY = 2;
diameter = 10;
color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
}// end of constructor
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getDiameter() {
return diameter;
}
public Color getColor() {
return color;
}
public void move() {
x += deltaX;
y += deltaY;
if (x < 0) {
x = 0;
deltaX = -deltaX;
}
else if (x > 400) {
x = 400;
deltaX = -deltaX;
}
if (y < 0) {
y = 0;
deltaY = -deltaY;
}
else if (y > 300) {
y = 300;
deltaY = -deltaY;
}
}// end of method move
}// end of ball

Categories