GUI object doesn't draw - java

I've been looking for answers in similar threads here but I can't find out what's wrong with my code.
I'm trying to make an agar.io simulator and the agar object doesn't draw. Food draws but agar doesn't draw regardless of what I do.
Agar class code:
import java.awt.*;
import java.awt.event.*;
public class Agar {
//instance field
public static final int DEFAULT_SIZE = 1000, DEFAULT_X =
ArenaPanel.PANEL_WIDTH/2, DEFAULT_Y = ArenaPanel.PANEL_HEIGHT/2;
private int x, y, size;
private Color clr;
public Agar(Color c) {
x = DEFAULT_X;
y = DEFAULT_Y;
clr = c;
}
public void move() {
//blank for now, not used yet
}
//grows by 10% width
public void grow() {
size += 10;
}
public void draw(Graphics fred) {
fred.setColor(clr);
fred.fillOval(0,0,size,size);
fred.setColor(Color.black);
fred.drawOval(0,0,size,size);
}
}
Panel class code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.ArrayList;
public class ArenaPanel extends JPanel {
//instance field
public static final int PANEL_WIDTH = 1000, PANEL_HEIGHT = 500;
private ArrayList<Food> food;
private Timer foodAdder;
private Agar agar;
public ArenaPanel() {
//agar stuff
agar = new Agar(getRandomColor());
//food stuff
food = new ArrayList<Food>();
//add some initial food
for (int i = 0; i < 50; i++)
addRandomFood();
//"this will last a while"
foodAdder = new Timer(3000, new FoodAdder());
foodAdder.start();
//listeners
addComponentListener(new ResizeListener());
//more basic stuff
setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
setBackground(Color.white);
}
public void paintComponent(Graphics fred) {
super.paintComponent(fred);
agar.draw(fred);
for (int i = 0; i < food.size(); i++)
food.get(i).draw(fred);
}
//put it here so I can use it for both agar and food
private Color getRandomColor() {
int rand = (int)(Math.random()*7);
Color c;
switch (rand) {
case 0:
c = Color.red;
break;
case 1:
c = Color.orange;
break;
case 2:
c = Color.yellow;
break;
case 3:
c = Color.green;
break;
case 4:
c = Color.cyan;
break;
case 5:
c = Color.blue;
break;
default:
c = Color.pink;
}
return c;
}
private void addRandomFood() {
int x = (int)(Math.random()*PANEL_WIDTH);
int y = (int)(Math.random()*PANEL_HEIGHT);
food.add(new Food(x,y,getRandomColor()));
}
private class FoodAdder implements ActionListener {
public void actionPerformed(ActionEvent e) {
addRandomFood();
repaint();
}
}
private class ResizeListener extends ComponentAdapter {
public void componentResized(ComponentEvent e) {
setPreferredSize(getSize());
}
}
}
I tried debugging (placing System.out.println command into draw(), paintComponent(), agar's constructor) and all methods are in fact running properly. So I thought maybe it was just not showing up, but even when I tried changing agar's colour to black square (which should contrast a lot to colourful circular food) located at 0,0 but it still doesn't show.
What could be the problem here?

It has zero size. Call method grow at leas once.

Related

Why is my java animation taking up my entire CPU

I made a program to display interference patterns for light waves. I did this by using the paint method on a JPanel to draw 2 sources and then drawing concentric circles around them. This would be double slit interference, so I allowed one of the sources to move around to experiment with the slit width.
The problem is that when I run this, my computer says it is using 80% of my CPU! There's really not much to it. Circle in the middle, circles around it, and it moves. My code follows.
main class:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class main {
static final int UP = -1;
static final int DOWN = 1;
static final int RIGHT = 1;
static final int LEFT = -1;
static final int NOMOVEMENT = 0;
static int verticalMovement = NOMOVEMENT;
static int horizontalMovement = NOMOVEMENT;
public static void main(String[] args) {
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Point s1 = new Point((int)(screenSize.getWidth()/3), 50);
Point s2 = new Point((int)(2*screenSize.getWidth()/3), 50);
JFrame frame = new JFrame("Physics Frame");
frame.setPreferredSize(screenSize);
PhysicsPane pane = new PhysicsPane(screenSize, 15, s1, s2);
pane.setPreferredSize(screenSize);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(pane);
frame.pack();
Timer time = new Timer(1000 / 20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
switch (verticalMovement){
case UP:
s2.changeY(UP);
break;
case DOWN:
s2.changeY(DOWN);
break;
default:
break;
}
switch (horizontalMovement){
case RIGHT:
s2.changeX(RIGHT);
break;
case LEFT:
s2.changeX(LEFT);
break;
default:
break;
}
pane.repaint();
}
});
frame.addKeyListener(new KeyListener() {
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==37){
horizontalMovement = LEFT;
} else if (e.getKeyCode()==38){
verticalMovement = UP;
} else if (e.getKeyCode()==39){
horizontalMovement = RIGHT;
} else if (e.getKeyCode()==40){
verticalMovement = DOWN;
}
if(e.getKeyChar()=='a'){
pane.setWaveLength(2);
}
if(e.getKeyChar()=='s'){
pane.setWaveLength(-2);
}
}
#Override
public void keyReleased(KeyEvent e) {
switch (e.getKeyCode()){
case 37:
horizontalMovement = NOMOVEMENT;
break;
case 38:
verticalMovement = NOMOVEMENT;
break;
case 39:
horizontalMovement = NOMOVEMENT;
break;
case 40:
verticalMovement = NOMOVEMENT;
break;
}
}
});
frame.setVisible(true);
time.start();
}
}
Panel class. If there's an inefficiency with the drawing method, it would be here.
import javax.swing.*;
import java.awt.*;
public class PhysicsPane extends JPanel {
private Dimension size;
private Point[] pointArray = new Point[2];
private double waveLength;
public PhysicsPane(Dimension size, double wavelength, Point source1, Point source2) {
this.size = size;
pointArray[0] = source1;
pointArray[1] = source2;
setPreferredSize(size);
this.waveLength = wavelength;
}
#Override
public void paintComponent(Graphics g){
for (int i = 0; i < 2; i++) {
g.setColor(Color.black);
double x = this.pointArray[i].getX();
double y = this.pointArray[i].getY();
g.fillOval((int)x, (int)y, 2, 2);
for (int j = (int)waveLength; j < 1500; j+=waveLength) {
g.setColor(Color.red);
g.drawOval((int)x-(j/2+1), (int)y-(j/2+1), 2 + j, 2 + j);
}
}
}
public void setWaveLength(double increment){
this.waveLength+=increment;
}
}
Point Class: Really just puts x and y coordinates into one construct. Not important particularly
public class Point {
private double x;
private double y;
public Point(double x, double y) {
this.x = x;
this.y = y;
}
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
public void changeX(double dX){
this.x+=dX;
}
public void changeY(double dY){
this.y+=dY;
}
}
So what is wrong with my program? Why is such a simple animation consuming so much of my processor?
UPDATED CODE SECTION:
#Override
public void paintComponent(Graphics g){
BufferedImage bi = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
Graphics graphics = bi.getGraphics();
for (int i = 0; i < 2; i++) {
graphics.setColor(Color.black);
double x = this.pointArray[i].getX();
double y = this.pointArray[i].getY();
graphics.fillOval((int)x, (int)y, 2, 2);
for (int j = (int)waveLength; j < 1500; j+=waveLength) {
graphics.setColor(Color.red);
graphics.drawOval((int)x-(j/2+1), (int)y-(j/2+1), 2 + j, 2 + j);
}
}
g.drawImage(bi, 0, 0, new ImageObserver() {
#Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height) {
return false;
}
});
}
The improvement that I recommend is removal of unnecessary tasks being performed, notably how your code updates the pane being drawn on, even when there aren't changes.
The following update reduced CPU usage from 12% to 0% (static frame):
Timer time = new Timer(1000 / 20, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
boolean refresh = false;
switch (verticalMovement) {
case UP:
s2.changeY(UP);
refresh = true;
break;
case DOWN:
s2.changeY(DOWN);
refresh = true;
break;
default:
break;
}
switch (horizontalMovement) {
case RIGHT:
s2.changeX(RIGHT);
refresh = true;
break;
case LEFT:
s2.changeX(LEFT);
refresh = true;
break;
default:
break;
}
if (refresh == true) {
pane.repaint();
}
}
});

How would I make a random object move in this code?

Here is the deal, basically I have to have a code that has a bucket that can catch the falling fruit and every time it catches it you get a point a new fruit falls.
So I know how to make the bucket move and how to make the fruit go again once it reaches the bottom. However, I don't know how to make it actually fall. So far i got a switch but no idea what to do with it. I got the fruit popping up in random places which is a start. Anyways, here is my code. All help appreciated. Again, i need to have a random fruit drop once one of them reaches the bottom.
import java.awt.Color;
import java.awt.event.KeyEvent;
import acm.graphics.GOval;
import acm.graphics.GPolygon;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
import acm.util.RandomGenerator;
import java.awt.event.*;
public class FruitCatcher extends GraphicsProgram {
private static final int APPLET_WIDTH = 500;
private static final int APPLET_HEIGHT = 500;
private static final int BUCKET_X = 250;
private static final int BUCKET_Y = 500;
private static final int BUCKET_SPEED = 10;
private static final int BUCKET_SPEED2 = -10;
private GPolygon Bucket;
public void init() {
setSize(APPLET_WIDTH, APPLET_HEIGHT);
addKeyListeners();
}
public void run() {
RandomGenerator random = new RandomGenerator();
makeBucket();
for (int i = 1; i <= 3; i++) {
int randomX = random.nextInt(0, 300 - 20);
addFruit(i, randomX, 0);
}
while (true)
;
}
public void makeBucket() {
Bucket = new GPolygon(BUCKET_X, BUCKET_Y);
Bucket.addVertex(-60, 0);
Bucket.addVertex(-70, -85);
Bucket.addVertex(10, -85);
Bucket.addVertex(0, 0);
add(Bucket);
Bucket.setFilled(true);
Bucket.setFillColor(Color.GRAY);
}
public void addFruit(int a, int x, int y) {
switch (a) {
case 1:
GRect Banana = new GRect(x, y, 10, 60);
Banana.setColor(Color.YELLOW);
Banana.setFilled(true);
add(Banana);
break;
case 2:
GOval lime = new GOval(x, y, 20, 20);
lime.setColor(Color.GREEN);
lime.setFilled(true);
add(lime);
break;
case 3:
GOval Orange = new GOval(x, y, 30, 30);
Orange.setColor(Color.ORANGE);
Orange.setFilled(true);
add(Orange);
}
}
public void keyPressed(KeyEvent event) {
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_LEFT:
if (Bucket.getX() > 0) {
Bucket.move(-BUCKET_SPEED, 0);
}
break;
case KeyEvent.VK_RIGHT:
if (Bucket.getX() < APPLET_WIDTH) {
Bucket.move(BUCKET_SPEED, 0);
}
break;
}
}
}
In my code you can see a while (true) I am just assuming that is where I would write it. However, I am at a little loss what would actually go there.
You need to keep a list of references to all the fruits, so you can manipulate them later
Each iteration of the game loop, move each fruit down
You may want to implement some timing mechanism, so that the fruit
speed is not dependent on the CPU speed.
package jsyn;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;
import acm.graphics.GOval;
import acm.graphics.GPolygon;
import acm.graphics.GRect;
import acm.program.GraphicsProgram;
import acm.util.RandomGenerator;
import java.awt.event.*;
public class FruitCatcher extends GraphicsProgram {
private static final int APPLET_WIDTH = 500;
private static final int APPLET_HEIGHT = 500;
private static final int BUCKET_X = 250;
private static final int BUCKET_Y = 500;
private static final int BUCKET_SPEED = 10;
private static final int BUCKET_SPEED2 = -10;
//Speed of fruit falling
private static final int FRUIT_PX_PER_MS = 10;
private GPolygon Bucket;
public void init() {
setSize(APPLET_WIDTH, APPLET_HEIGHT);
addKeyListeners();
fruits = new ArrayList<Component>();
}
// Keep list of fruits
List<GObject> fruits;
public void run() {
RandomGenerator random = new RandomGenerator();
makeBucket();
for (int i = 1; i <= 3; i++) {
int randomX = random.nextInt(0, 300 - 20);
addFruit(i, randomX, 0);
}
long last = System.currentTimeMillis();
while (true) {
long current = System.currentTimeMillis();
update(current - last);
last = current;
}
}
void update(long delta) {
for (GObject fruit : fruits) {
//this code may not work, replace with code that moves fruit down
fruit.setLocation(fruit.getX(), fruit.getY() + delta * FRUIT_PX_PER_MS);
}
}
public void makeBucket() {
Bucket = new GPolygon(BUCKET_X, BUCKET_Y);
Bucket.addVertex(-60, 0);
Bucket.addVertex(-70, -85);
Bucket.addVertex(10, -85);
Bucket.addVertex(0, 0);
add(Bucket);
Bucket.setFilled(true);
Bucket.setFillColor(Color.GRAY);
}
public void addFruit(int a, int x, int y) {
switch (a) {
case 1:
GRect Banana = new GRect(x, y, 10, 60);
Banana.setColor(Color.YELLOW);
Banana.setFilled(true);
add(Banana);
fruits.add(Banana);
break;
case 2:
GOval lime = new GOval(x, y, 20, 20);
lime.setColor(Color.GREEN);
lime.setFilled(true);
add(lime);
fruits.add(lime);
break;
case 3:
GOval Orange = new GOval(x, y, 30, 30);
Orange.setColor(Color.ORANGE);
Orange.setFilled(true);
add(Orange);
fruits.add(Orange);
}
}
public void keyPressed(KeyEvent event) {
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_LEFT:
if (Bucket.getX() > 0) {
Bucket.move(-BUCKET_SPEED, 0);
}
break;
case KeyEvent.VK_RIGHT:
if (Bucket.getX() < APPLET_WIDTH) {
Bucket.move(BUCKET_SPEED, 0);
}
break;
}
}
}

drawing and JLabel on a Frame

I wanted to create a caterpillar game using Java Frame. It basically has two players trying to occupy a square to increase their scores. I've been using two classes:
the caterpillar class
package caterpillar;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.Queue;
class Caterpillar {
private Color color;
private Point position;
private char direction;
private Queue<Point> body;
private Queue<Character> commands;
private int score;
public Caterpillar (Color c, Point p){
color = c;
direction = 'E';
body = new LinkedList<Point>();
score = 0;
commands = new LinkedList<Character>();
for (int i = 0; i < 10; i++){
position= new Point(p.x + i, p.y);
body.offer(position);
}
}
public void setDirection(char direction){
commands.offer(new Character(direction));
}
public void move(CaterpillarGame game){
if(commands.size()>0){
Character c = (Character)commands.peek();
commands.poll();
direction = c.charValue();
if(direction == 'Z')
return;
}
Point np = newPosition();
if(game.canMove(np)){
body.poll();
body.offer(np);
position = np;
}
score+=game.squareScore(np);
}
private Point newPosition(){
int x = position.x;
int y = position.y;
if(direction == 'E')
x++;
else if(direction == 'W')
x--;
else if(direction == 'N')
y--;
else if(direction == 'S')
y++;
return new Point(x, y);
}
public boolean inPosition(Point np){ //check if position has alredy been occupied
Iterator <Point>it = body.iterator();
while(it.hasNext()){
Point location = it.next();
if(np.equals(location))
return true;
}
return false;
}
public int getScore(){
return score;
}
public void paint(Graphics g){
g.setColor(color);
Iterator <Point>it = body.iterator();
while(it.hasNext()){
Point p = it.next();
g.fillOval(5 + CaterpillarGame.SegmentSize * p.x,
15 + CaterpillarGame.SegmentSize * p.y,
CaterpillarGame.SegmentSize,
CaterpillarGame.SegmentSize);
}
}
}
the game class:
package caterpillar;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Random;
import javax.swing.JLabel;
public class CaterpillarGame extends Frame{
final static int BoardWidth = 60;
final static int BoardHeight = 40;
final static int SegmentSize = 10;
private Caterpillar playerOne;
private Caterpillar playerTwo;
private Point square;
private int number; //points the players will get if occupy the square
private Random generator;
private JLabel score1, score2;// scores of two players
public static void main(String[] args){
CaterpillarGame game= new CaterpillarGame();
game.run();
}
public CaterpillarGame(){
setBackground(Color.GREEN);
setVisible(true);
setSize((BoardWidth+1)*SegmentSize, BoardHeight*SegmentSize + 30);
addKeyListener(new KeyReader());
playerOne = new Caterpillar(Color.blue, new Point(20, 10));
playerTwo = new Caterpillar(Color.red, new Point(20, 30));
addWindowListener(new CloseQuit());
generator = new Random();
number = 1;
score1 = new JLabel("Player One: "+playerOne.getScore());
score2 = new JLabel("Player Two: "+playerTwo.getScore());
this.add(score1);
this.add(score2);
square = new Point(newSquare());
}
public void run(){
while(true){
movePieces();
repaint();
try{
Thread.sleep(100);
}catch(Exception e){}
}
}
public void paint(Graphics g){
playerOne.paint(g);
playerTwo.paint(g);
g.setColor(Color.white);
g.fillRect(square.x, square.y, 10,10); //line 62, exception thrown
g.setColor(Color.BLACK);
g.drawString(Integer.toString(number), 10, 10);
}
public void movePieces(){
playerOne.move(this);
playerTwo.move(this);
}
public boolean canMove(Point np){
int x = np.x;
int y = np.y;
if((x<=0)||(y<=0))
return false;
if((x>=BoardWidth)||(y>=BoardHeight))
return false;
if(playerOne.inPosition(np))
return false;
if(playerTwo.inPosition(np))
return false;
return true;
}
private class KeyReader extends KeyAdapter{
public void keyPressed(KeyEvent e){
char c = e.getKeyChar();
switch(c){
case 'q': playerOne.setDirection('Z');
break;
case 'a': playerOne.setDirection('W');
break;
case 'd': playerOne.setDirection('E');
break;
case 'w': playerOne.setDirection('N');
break;
case 's': playerOne.setDirection('S');
break;
case 'p': playerTwo.setDirection('Z');
break;
case 'j': playerTwo.setDirection('W');
break;
case 'l': playerTwo.setDirection('E');
break;
case 'i': playerTwo.setDirection('N');
break;
case 'k': playerTwo.setDirection('S');
break;
}
}
}
public Point newSquare(){
Point p = new Point(generator.nextInt(51), generator.nextInt(31));
while(playerOne.inPosition(p)||playerTwo.inPosition(p)){
p = new Point(generator.nextInt(51), generator.nextInt(31));
}
number++;
return square = p;
}
public int squareScore(Point p){
if(p.equals(square)){
newSquare();
return number;
}
return 0;
}
private class CloseQuit extends WindowAdapter{
public void windowClosing(WindowEvent e){
System.exit(0);
}
}
}
this is what i have so far, but i got several problems when i ran the program:
the JLabels, square, and string didn't show up
it kept throwing java.lang.NullPointerException
how do i have the program stopped when the score of one player reaches a certain number?
how to check if a caterpillar touches the square?
Thanks in advance.
the JLabels, square, and string didn't show up
They are, you're just screwing with the paint process so badly that you're preventing them from been painted. Also, I "believe" that java.awt.Frame uses a BorderLayout.
This is one of the reasons we generally discourage people from overriding paint, it's far to easy to break the paint chain
Add a call to super.paint before you perform any custom painting.
#Override
public void paint(Graphics g) {
super.paint(g);
I'd prefer that you used paintComponent from a JComponent based class and add that object to your frame, but you seem to have restrictions from doing so...
Also, change the layout manager to something like FlowLayout to get both labels on the screen.
See Painting in AWT and Swing and Laying Out Components Within a Container for more details
it kept throwing java.lang.NullPointerException
This seems to be a race condition. Essentially, you are calling setVisible on the frame BEFORE you've finished initialising the requirements of the UI, which is causing paint to be called BEFORE the frame is fully initialized.
Call setVisible last. Better yet, don't call setVisible from within the constructor...
how do i have the program stopped when the score of one player reaches a certain number?
... In your "game loop" you need to be checking that state of the score and breaking out of the "game loop" when the required state is meet...
how to check if a caterpillar touches the square?
That's a much more complicated question. Essentially you could use the interests or contains method of a Rectangle (or other Shape object). You know where the Point of the square and "segments" of the Caterpillar are. You know the size of the square and the "segments".
You need to compare each of the segments to see if they intersect the are of the square. Take a closer look at java.awt.Rectangle for more details

Java error for beginner

I just start learning Java. I write a program like this:
Bacteria.class
import java.awt.*;
public class Bacteria extends Creature{
public static final int COLOR_STEP = 256/MAX_AGE;
Bacteria(Board board, int _x, int _y){
super.board = board;
//initialize age, x, y
super.age = 1;
super.x = _x;
super.y = _y;
}
//Draw a circle representing the creature at its position
//This function is done.
public void draw(Graphics g) {
g.setColor(new Color(0, COLOR_STEP * age, 0));
g.fillOval(x * board.CELL_SIZE, y * board.CELL_SIZE, board.CELL_SIZE, board.CELL_SIZE);
}
public void tick() {
//your code
// this is how the creature lives in one tick
// make the creature get older if it is not dead.
// if it's got older than MAX_AGE then it should die
// ...call board.addDead() to register the dead creature
// if it can have baby then try reproduce()
age++;
if (this.canHaveBaby()) {
this.reproduce();
}
//this.reproduce();
if (age > MAX_AGE) {
board.addDead(this);
}
}
}
Creature.class
import java.awt.*;
public class Creature {
public static final int MAX_AGE = 5;
public Board board;
public int age; // age of the creature measures in ticks
public int x; // (x,y) is the position of the creature
public int y;
Creature(Board board, int _x, int _y) {
this.board = board;
//initialize age, x, y
age = 1;
x = _x;
y = _y;
}
public Creature() {
}
//Draw a circle representing the creature at its position
//This function is done.
public void draw(Graphics g){}
public void tick(){}
public void reproduce() {
//your code
// if it can have a baby then produce a baby
// ...in an empty cell next to its cell.
// board.emptyCell() should be used
// ....to check whether a cell in the board is empty
// and call board.addBaby() to place the baby to the board
//int x_current = x, y_current = y;
if(board.emptyCell(x, y+1)){
Creature baby = new Creature(board,x, y+1);
//System.out.println("1");
board.addBaby( baby);
}
else if(board.emptyCell(x+1,y)){
Creature baby = new Creature(board,x+1, y);
board.addBaby(baby);
}
else if(board.emptyCell(x+1,y+1)){
Creature baby = new Creature(board,x+1, y+1);
board.addBaby(baby);
}
else if(board.emptyCell(x-1,y)){
Creature baby = new Creature(board,x-1, y);
board.addBaby(baby);
}
else if(board.emptyCell(x,y-1)){
Creature baby = new Creature(board,x, y-1);
board.addBaby(baby);
}
else if(board.emptyCell(x-1,y-1)){
Creature baby = new Creature(board,x-1, y-1);
board.addBaby(baby);
}
else if(board.emptyCell(x-1,y+1)){
Creature baby = new Creature(board,x-1, y+1);
board.addBaby(baby);
}
else if(board.emptyCell(x+1,y-1)){
Creature baby = new Creature(board,x+1, y-1);
board.addBaby(baby);
}
}
public boolean canHaveBaby() {
//your code
// if the creature is dead or it is too young
// then it cannot have a baby
if(age == 0 || age > MAX_AGE){
return false;
}
return true;
}
public boolean atPosition(int _x, int _y) {
//your code
// return true if the creature is at the position (_x,_y)
// you need this function for board.empty to function correctly
if(_x == x && _y == y){
return true;
}
return false;
}
}
Board.class
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class Board extends JPanel {
public static final int CELL_SIZE = 10;
private final int rows = 10;
private final int cols = 20;
ArrayList<Creature> creatureList;
ArrayList<Creature> babies, dead;
// ArrayList<Bacteria> bacteriaList;
// ArrayList<Bacteria> babies_bac, dead_bac;
Board() {
super();
setBackground(Color.white);
creatureList = new ArrayList<Creature>();
//creatureList.size();
babies = new ArrayList<Creature>();
dead = new ArrayList<Creature>();
setPreferredSize(new Dimension(cols * CELL_SIZE, rows * CELL_SIZE));
creatureList.add(new Bacteria(this, 1, 1));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Creature creature: creatureList) {
creature.draw(g);
}
}
public void tick() {
dead = new ArrayList<Creature>();
babies = new ArrayList<Creature>();
for (Creature creature: creatureList) {
creature.tick();
}
creatureList.addAll(babies);
creatureList.removeAll(dead);
}
public void addBaby(Creature baby) {
if (baby != null) babies.add(baby);
}
public void addDead(Creature deadCreature) {
if (deadCreature != null) dead.add(deadCreature);
}
public boolean emptyCell(int x, int y) {
if (x < 0 || y < 0 || x >= cols || y >= rows) return false;
for (Creature creature : creatureList) {
if (creature.atPosition(x, y)) {
return false;
}
}
for (Creature creature : creatureList) {
if (creature.atPosition(x, y)) {
return false;
}
}
return true;
}
public String getPopulation() {
return String.format("%d", creatureList.size());
}
}
and BacteriaSimulator.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class BacteriaSimulator extends JFrame {
private Board board;
private JLabel label;
public BacteriaSimulator() {
initUI();
setTitle("Bacteria Simulator");
setSize(350, 200);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
}
private void initUI() {
JPanel panel = new JPanel();
board = new Board();
panel.add(board);
label = new JLabel(board.getPopulation());
panel.add(label);
JButton button = new JButton("Tick");
button.addActionListener(new ButtonNextListener());
panel.add(button);
add(panel);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
BacteriaSimulator ex = new BacteriaSimulator();
ex.setVisible(true);
}
});
}
private class ButtonNextListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
board.tick();
label.setText(board.getPopulation());
repaint();
}
}
}
I want Board.class work with creatureList. However, Board is still initialized with a bacteria (creatureList.add(new Bacteria(this, 1, 1));). I got a problem that is Board.class can not run draw() and tick() method which I want. How to draw objects bacteria and make the right method of tick ()? Can you help me! Thank you!
Your draw() and tick() functions are part of Bacteria.java. They cannot be used from Board.java unless you create an instance of Bacteria and then invoke the methods using that.

How do I add my classes to an ArrayList?

I'm very new to Java and programming in general and I'm having a bit of trouble with my homework assignment.
We're supposed to give a variation of 4 different shapes, 10 shape in each picture with variation of at least 20, also variation of at least 20 different colors and variation of position.
I've made classes for each of my 5 shapes. But I somehow don't know how to add them to my ArrayList randomShape so that they can be called in the paintComponent section.
Also I'm having trouble coming up with the code the positions :(
Its a bit frustrating that I've hit a road block of thoughts.
Thank you for any help/advice you give me
It's very much appreciated
Here is my code that I have so far
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
public class Cara extends JPanel implements ActionListener {
Random random = new Random();
public static final int MAX_AMOUNT_OF_SHAPES = 50,AMOUNT_OF_DISTINCT_SHAPES=5, AMOUNT_OF_DISTINCT_COLORS = 20, SIZE_MAX_X_COORDINATE = 400, SIZE_MAX_Y_COORDINATE = 300;;
public static ArrayList<RandomShape> randomShape = new ArrayList<RandomShape>();
int x = 0;
int xMax = 400;
int y = 0;
int yMax = 300;
int width = 0;
int height = 0;
int arcWidth = 0;
int arcHeight = 0;
int R = (int)(Math.random()*256);
int G = (int)(Math.random()*256);
int B = (int)(Math.random()*256);
Color randomColor = new Color(R,G,B);
public Cara(){
setPreferredSize( new Dimension(400,300));
}
abstract class RandomShape {
protected Color color;
protected int x,y;
abstract void draw(Graphics g);
}
public class Circle extends RandomShape{
#Override
public void draw(Graphics g) {
g.drawOval(x,y,width,width);
g.fillOval(x,y,width,width);
g.setColor(randomColor);
}
//constructor for random position
Circle (){
for ( int x; x < xMax; x++){
}
for ( int y; y < yMax; y++){
}
}
}
public class Rectangle extends RandomShape{
#Override
public void draw( Graphics g){
g.drawRect(x,y,width,height);
g.fillRect(x,y,width,height);
g.setColor(randomColor);
}
//constructor for random position
}
public class RoundRectangle extends RandomShape{
#Override
public void draw(Graphics g){
g.drawRoundRect(x,y,width,height,arcWidth,arcHeight);
g.fillRoundRect(x,y,width,height,arcWidth,arcHeight);
g.setColor(randomColor);
}
//constructor for random position
}
public class Oval extends RandomShape{
#Override
public void draw(Graphics g){
g.drawOval(x,y,width,height);
g.fillOval(x,y,width,height);
g.setColor(randomColor);
}
//constructor for position
}
public class Square extends RandomShape{
Square square = new Square();
#Override
public void draw(Graphics g){
g.drawRect(x,y,width,width); //because is a rectangle with sides of equal size
g.fillRect(x,y,width,width);
g.setColor(randomColor);
}
//constructor for position
}
protected void paintComponent(Graphics g) {
//clear the background
super.paintComponent(g);
//draw all shapes
for ( RandomShape rs: randomShape){
rs.draw(g);
}
}
public void actionPerformed (ActionEvent e){
regenerate();
repaint();
}
private void regenerate() {
//clear the shapes list
randomShape.clear();
// create random shapes
RandomShape shape = null;
for (int i = 0; i < 10 + random.nextInt(MAX_AMOUNT_OF_SHAPES); i++){
int randomInt = random.nextInt(AMOUNT_OF_DISTINCT_SHAPES);
switch (randomInt) {
case 0: shape = new Oval(400,300);
break;
case 1: shape = new Circle(400,300);
break;
case 2: shape = new Rectangle(400,300);
break;
case 3: shape = new Square(400,300);
break;
case 4: shape = new RoundRectangle(400,300);
break;
}
}
//random position
RandomShape position = null;
for (int i = 0; i < (MAX_SIZE_X_COORDINATE*MAX_SIZE_Y_COORDINATE) ; i++){
int randomIntpos = random.nextInt();
}
}
public static void main(String[] args) {
final Cara cara = new Cara();
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run(){
final JFrame frame = new JFrame("Computer Assisted Random Artist");
JButton button = new JButton("regenerate");
button.addActionListener(cara);
frame.add(button, BorderLayout.SOUTH);
frame.pack();
cara.regenerate();
frame.setVisible(true);
}
});
}
}
public class Cara extends JPanel implements ActionListener {
private static ArrayList<RandomShape> randomShape;
public Cara() {
randomShape = new ArrayList<RandomShape>();
}
}
private void regenerate() {
//clear the shapes list
randomShape.clear();
// create random shapes
RandomShape shape = null;
int randomInt;
for(int i = 0; i < 10 + random.nextInt(MAX_AMOUNT_OF_SHAPES); i++) {
randomInt = random.nextInt(AMOUNT_OF_DISTINCT_SHAPES);
switch (randomInt) {
case 0:
shape = new Oval(400,300);
break;
case 1:
shape = new Circle(400,300);
break;
case 2:
shape = new Rectangle(400,300);
break;
case 3:
shape = new Square(400,300);
break;
case 4:
shape = new RoundRectangle(400,300);
break;
}
randomShape.add(shape);
}
//random position
RandomShape position = null;
int randomIntpos;
for (int i = 0; i < (MAX_SIZE_X_COORDINATE*MAX_SIZE_Y_COORDINATE) ; i++){
randomIntpos = random.nextInt();
}
}
public class RoundRectangle extends RandomShape {
private int x;
private int y;
//constructor for random position
public RoundRectangle(int x, int y) {
this.x = x
this.y = y
}
#Override
public void draw(Graphics g){
g.drawRoundRect(x,y,width,height,arcWidth,arcHeight);
g.fillRoundRect(x,y,width,height,arcWidth,arcHeight);
g.setColor(randomColor);
}
}

Categories