graphic.addAnimation calling addAnimation - java

I run this code:
graphic.addAnimation("standart",new int[] {0,1},1.0,true);
which calls the graphic.addAnimation(String,int[],float,boolean) Method:
public void addAnimation(String nme,int[] frmes,float time,boolean loop) {
animations.push(new Aim(nme, frmes, time, loop));
}
but I get this error:
the function addAnimation(String,int[],float,boolean) does not exist.
SpriteSheet:
package progame;
import java.util.Stack;
import processing.core.PImage;
public class SpriteSheet extends Graphic {
public int height,width,index;
public int timer;
public String playing;
public Stack<PImage> sheet = new Stack<PImage>();
public Stack<Aim> animations = new Stack<Aim>();
public SpriteSheet(String path,int h,int w) {
super(path);
height = h;
width = w;
for(int i = 0; i < Math.floor(source.height/height); i++) {
for(int j = 0; j < Math.floor(source.width/width); j++) {
sheet.push(source.get(j*width, i*height, width, height));
}
}
}
public SpriteSheet(String path,Entity e,int h,int w) {
super(path,e);
height = h;
width = w;
for(int i = 0; i < Math.floor(source.height/height); i++) {
for(int j = 0; j < Math.floor(source.width/width); j++) {
sheet.push(source.get(j*width, i*height, width, height));
}
}
}
public Aim getAnimation(String name) {
for(int i = 0; i< animations.size(); i++)
{
if(animations.get(i).name == name) {
return(animations.get(i));
}
}
return null;
}
public void play(String name) {
for(int i = 0; i< animations.size(); i++)
{
if(animations.get(i).name == name) {
playing = name;
index = 0;
timer = 0;
}else
{
playing = null;
return;
}
}
}
public void update() {
timer ++;
Aim aim = getAnimation(playing);
if( timer > aim.frameRate)
{
timer = 0;
if(index == aim.frames.length)
{
if(aim.looping) {
index = 0;
}else
{
playing = null;
}
}else
{
index++;
}
}
source = sheet.get(index);
}
public void render() {
update();
super.render();
}
public void addAnimation(String nme,int[] frmes,float time,boolean loop) {
animations.push(new Aim(nme, frmes, time, loop));
}
private class Aim
{
String name;
int[] frames;
float frameRate;
boolean looping;
public Aim(String nme,int[] frmes,float time,boolean loop)
{
name = nme;
frames = frmes;
frameRate = time;
looping = loop;
}
}
}

Where did you obtain the instance 'graphic' from in the following line?
graphic.addAnimation("standart",new int[] {0,1},1.0,true);
Or more importantly, what is its declaration? You can't call addAnimation on a variable of type Graphic. As it's SpriteSheet that defined this method.

Based on OP's comment: its declared in the Entity class, like this: public Graphic graphic;
((SpriteSheet)graphic).addAnimation("standart",new int[] {0,1},1.0,true);
would fix the problem.

You said
its declared in the Entity class, like this: public Graphic graphic;
Declare it as:
public SpriteSheet graphic;

Related

JavaFX scene is not changing when root gets updated

I am trying to make a snake JavaFX game. The scene is a board that consists of 25x25 images. For now, I just want to make the snake go to the right before I add userInput. The first scene is loading from Controller.java and then in Main.java, I am calling run_game() method (inside controller.java) which changes the scene every second. The issue is that the first scene shows up but the scene does not get updated. There is no error, the program just keeps running till I stop it.
Here are the classes:-
Main.java
import javafx.application.Application;
import javafx.stage.Stage;
import java.util.Timer;
import java.util.TimerTask;
public class Main extends Application {
public Controller game;
#Override
public void start(Stage primaryStage) throws Exception{
primaryStage.setTitle("Snake Game");
game = new Controller();
primaryStage.setScene(game.scene);
primaryStage.show();
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask(){
#Override
public void run() {
try {
game.run_game();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},0,1000);
}
public static void main(String[] args) { launch(args); }
}
Controller.java
import javafx.animation.AnimationTimer;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.GridPane;
import java.util.TimerTask;
public class Controller {
public Snake snake;
public Board board;
public Food food;
public Movement move;
public static GridPane grid_pane;
public Scene scene;
// Creating all the necessary instances of snake game
public Controller() throws InterruptedException {
food = new Food();
grid_pane = new GridPane();
//assigning a random food position to the food apple
assign_random_position_to_food();
snake = new Snake(food);
board = new Board();
move = new Movement(snake);
board.generateBoard(food.row, food.col, snake);
Parent root = grid_pane;
scene = new Scene(root, Board.BOARDHEIGHT,Board.BOARDWIDTH);
}
public void run_game() throws InterruptedException {
snake = move.move_RIGHT();
scene.setRoot( grid_pane);
}
public void assign_board_to_grid(){
for ( int row = 0; row < board.board.length; ++row)
for( int col = 0; col < board.board[row].length; ++col )
grid_pane.add(board.board[row][col], row, col, 1, 1);
}
public void assign_random_position_to_food(){
food.RandomPosition();
}
}
Board.java
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
public class Board {
public static int BOARDHEIGHT = 500;
public static int BOARDWIDTH = 500;
public static int BLOCKHEIGHT = 20;
public static int BLOCKWIDTH = 20;
public static int TOTAL_BLOCKS_ROW = BOARDHEIGHT/ BLOCKHEIGHT;
public static int TOTAL_BLOCKS_COL = BOARDWIDTH/ BLOCKWIDTH;
public ImageView[][] board;
public Image black_square;
public Image apple;
public Image snake_dot;
public GridPane gridPane = new GridPane();
public void assign_images(){
try{
apple = new Image("images/apple.png");
snake_dot = new Image("images/dot.png");
black_square = new Image("images/black_square.png");
}catch(Exception e){
System.out.println("Error: related to the address of images");
}
}
public Board(){
assign_images();
//initializing the board
board = new ImageView[TOTAL_BLOCKS_ROW][TOTAL_BLOCKS_COL];
}
public void generateBoard(int food_x, int food_y, Snake snake_body) {
for(int row=0; row< TOTAL_BLOCKS_ROW; row++){
for(int col=0; col< TOTAL_BLOCKS_COL; col++){
if(row == food_x && col == food_y)// && check if it is not on snake body)
board[row][col] = new ImageView(apple);
else if( snake_body.is_snake_present(row,col) && col != 0)
board[row][col] = new ImageView(snake_dot);
else
board[row][col] = new ImageView(black_square);
// Setting the size of each block on the scene
board[row][col].setFitHeight(BLOCKHEIGHT);
board[row][col].setFitWidth(BLOCKWIDTH);
Controller.grid_pane.add(board[row][col], row, col, 1 ,1);
}
}
}
}
Movement.java
public class Movement {
public Snake snake;
public static int new_y_position;
public static int new_x_position;
public Movement(Snake snake){
this.snake = snake;
}
public Snake move_RIGHT(){
new_x_position = snake.getHead_x() + 1;
new_y_position = snake.getHead_y();
if(!check_if_snake_is_in_bounds(new_x_position, new_y_position))
return null;
//System.out.println(new_x_position);
snake.setHead_x(new_x_position);
Block b;
for (int i = snake.snake.size() - 1; i >= 0; --i){
b = snake.snake.get(i);
b.setX(b.getX() + 1);
snake.snake.set(i,b);
}
// System.out.println(snake);
return snake;
}
public Snake move_LEFT(){
new_x_position = snake.getHead_x() - 1;
new_y_position = snake.getHead_y();
if(!check_if_snake_is_in_bounds(new_x_position, new_y_position))
return null;
//snake is inbounds update position
snake.setHead_x(new_x_position);
Block b;
for (int i = snake.snake.size() - 1; i >= 0; --i){
b = snake.snake.get(i);
b.setX(b.getX() - 1);
snake.snake.set(i,b);
}
System.out.println(snake);
return snake;
}
public Snake move_UP(){
new_x_position = snake.getHead_x();
new_y_position = snake.getHead_y() + 1;
if(!check_if_snake_is_in_bounds(new_x_position, new_y_position))
return null;
//snake is inbounds update position
snake.setHead_y(new_y_position);
Block b;
for (int i = snake.snake.size() - 1; i >= 0; --i){
b = snake.snake.get(i);
b.setY(b.getY() + 1);
snake.snake.set(i,b);
}
System.out.println(snake);
return snake;
}
public Snake move_DOWN(){
new_x_position = snake.getHead_x();
new_y_position = snake.getHead_y() - 1;
if(!check_if_snake_is_in_bounds(new_x_position, new_y_position))
return null;
//snake is inbounds update position
snake.setHead_y(new_y_position);
Block b;
for (int i = snake.snake.size() - 1; i >= 0; --i){
b = snake.snake.get(i);
b.setY(b.getY() - 1);
snake.snake.set(i,b);
}
System.out.println(snake);
return snake;
}
public boolean check_if_snake_is_in_bounds(int x, int y){
return x >= 0 && x <= Board.TOTAL_BLOCKS_COL && y >= 0 && y <= Board.TOTAL_BLOCKS_ROW;
}
}
Snake.java
import java.util.ArrayList;
public class Snake {
public ArrayList<Block> snake = new ArrayList<>();
public int snake_size = snake.size();
int head_x, head_y;
public Snake(Food food){
// initializes a snake head location on board and stores it in a list.
do{
head_x = (int) (Math.random()*Board.TOTAL_BLOCKS_COL);
head_y = (int) (Math.random()*Board.TOTAL_BLOCKS_ROW);
}while(food.getRow() == head_x || food.getCol() == head_y);
//inserting head and a block in snake arraylist
snake.add(new Block(head_x, head_y));
snake.add(new Block(head_x - 1, head_y));
}
// Adds new body part when snake eats an apple.
public void add_snake_body() {
snake.add( retrieve_new_block_position() );
}
// gets new snake body part position.
public Block retrieve_new_block_position(){
int last_block_x = snake.get(snake_size - 1).getX();
int last_block_y = snake.get(snake_size - 1).getY();
int second_last_block_x = snake.get(snake_size - 2).getX();
int second_last_block_y = snake.get(snake_size - 2).getY();
int new_block_x;
int new_block_y;
if(second_last_block_x == last_block_x){
new_block_x = last_block_x;
new_block_y = last_block_y - 1;
}
else{
new_block_x = last_block_x - 1;
new_block_y = last_block_y;
}
return new Block(new_block_x, new_block_y);
}
//checks if a position is occupied by a snake body part.
public boolean is_snake_present(int row, int col){
int index = 0;
int snake_curr_block_x;
int snake_curr_block_y;
while(index < snake.size()){
snake_curr_block_x = snake.get(index).getX();
snake_curr_block_y = snake.get(index).getY();
if( snake_curr_block_x == row && snake_curr_block_y == col)
return true;
index++;
}
return false;
}
//GETTER & SETTER METHODS
public ArrayList<Block> getSnake() {
return snake;
}
public int getHead_x() {
return head_x;
}
public void setHead_x(int head_x) {
this.head_x = head_x;
}
public int getHead_y() {
return head_y;
}
public void setHead_y(int head_y) {
this.head_y = head_y;
}
}
Food.java
import java.util.Random;
public class Food {
int row;
int col;
public Food(){
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public void RandomPosition(){
this.row = (int) (Math.random() * Board.TOTAL_BLOCKS_ROW);
this.col = (int) (Math.random() * Board.TOTAL_BLOCKS_COL);
System.out.println(this.row+" -food- "+ this.col);
//need to check if it clashes with the snake body................
}
}
Block.java
public class Block {
private int x;
private int y;
public Block(int x, int y){
this.x = x;
this.y = y;
}
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;
}
}

Grid DFS visualization

Hello guys I am working on a project where I am trying to create a maze generator.
So far I have a gird that is a 2D array of a Cell class and a JPanel that paints the grid to a JFrame and a function which uses Depth first Search to visit each Cell in the grid.
When the Cell has been visited the Cell color changes to black on the grid. My problem is the repaint on the grid is too fast is there anyway I can slow the time or set a timer to repaint after a number of seconds. Here is the code below
import java.util.Arrays;
import java.util.Stack;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.security.SecureRandom;
public class Maze extends JPanel implements ActionListener {
private Cell [][] maze;
private int dims;
private Stack<Cell> S = new Stack<Cell>();
private SecureRandom num = new SecureRandom();
Timer t;
public Maze(int din)
{
dims = din;
maze = new Cell[dims][dims];
}
public void generator()
{
for(int i = 0; i < maze.length; i++)
{
for (int j = 0;j < maze[0].length; j++)
{
maze[i][j] = new Cell(i,j);
}
}
}
public boolean checkAll()
{
for(int i = 0; i < maze.length; i++)
{
for (int j = 0;j < maze[0].length; j++)
{
if(!maze[i][j].visited)
return false;
}
}
return true;
}
public void adjlist()
{
for(int i = 0; i < maze.length; i++)
{
for (int j = 0;j < maze[0].length; j++)
{
if(i+1 >= 0 && i+1 < dims)
{
maze[i][j].neighbor.add(maze[i+1][j]);
}
if(i-1 >= 0 && i-1 < dims)
{
maze[i][j].neighbor.add(maze[i-1][j]);
}
if(j-1 >= 0 && j-1 < dims)
{
maze[i][j].neighbor.add(maze[i][j-1]);
}
if(j+1 >= 0 && j+1 < dims)
{
maze[i][j].neighbor.add(maze[i][j+1]);
}
}
}
}
public void DFS(Cell x)
{
if (!checkAll() && !maze[x.row][x.column].visited)
{
S.push(x);
System.out.println(Arrays.toString(S.toArray()));
maze[x.row][x.column].visited = true;
int randnum = num.nextInt(maze[x.row][x.column].neighbor.size());
Cell temp1 = maze[x.row][x.column].neighbor.get(randnum);
if (!maze[temp1.row][temp1.column].visited)
{
DFS(maze[temp1.row][temp1.column]);
}
else if (maze[x.row][x.column].neighbor.isEmpty())
{
S.pop();
maze[S.peek().row][S.peek().column].visited = false;
DFS(S.pop());
}
else
{
if(S.size()-1 == 0)
return;
Cell temp = null;
for (Cell c : maze[x.row][x.column].neighbor)
{
if (!maze[c.row][c.column].visited)
{
temp = c;
DFS(temp);
}
}
if (temp == null) {
S.pop();
maze[S.peek().row][S.peek().column].visited = false;
DFS(S.pop());
}
}
}
}
public void paint(Graphics g)
{
super.paint(g);
for (int row = 0; row < maze.length; row++)
{
for (int col = 0; col < maze[0].length; col++)
{
g.drawRect(35*row, 35 * col , 35, 35);
if(maze[row][col].visited)
{
//t.start();
g.fillRect(35*row, 35 * col , 35, 35);
//t.setDelay(5000);
}
}
}
repaint();
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args)
{
Maze p = new Maze(10);
p.generator();
p.adjlist();
System.out.println("------------------------");
JFrame f = new JFrame();
f.setTitle("Maze");
f.add(p);
f.setVisible(true);
f.setSize(700, 700);
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
p.DFS(new Cell(1,5));
}
#Override
public void actionPerformed(ActionEvent e) {}
}
The cell class
import java.util.ArrayList;
public class Cell{
public int row, column;
boolean visited;
ArrayList<Cell> neighbor;
public Cell(int i, int j)
{
row = i;
column = j;
visited = false;
neighbor = new ArrayList<Cell>();
}
public int getRow()
{
return this.row;
}
public int getCol()
{
return this.column;
}
public String toString()
{
return this.row + " " + this.column;
}
}
The following code demonstrates the use of SwingWorker to demonstrate performing long tasks (in your case dfs search) which update the gui.
Specific dfs information was removed because they are not relevant:
import java.awt.Dimension;
import java.awt.Graphics;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingWorker;
public class Maze extends JPanel {
private final Cell [][] maze;
private final int dims;
private static final int SIZE = 35;
public Maze(int dim) {
setPreferredSize(new Dimension( dim*SIZE,dim*SIZE));
dims = dim;
maze = new Cell[dims][dims];
}
public void generator()
{
for(int i = 0; i < maze.length; i++)
{
for (int j = 0;j < maze[0].length; j++)
{
maze[i][j] = new Cell(i,j);
//set some arbitrary initial date
if(i%2 ==0 && j%2 ==0) {
maze[i][j].setVisited(true);
}
}
}
}
public void DFS()
{
new DFSTask().execute();
}
#Override
public void paintComponent(Graphics g) //override paintComponent not paint
{
super.paintComponent(g);
for (int row = 0; row < maze.length; row++)
{
for (int col = 0; col < maze[0].length; col++)
{
g.drawRect(SIZE*row, SIZE * col , SIZE, SIZE);
if(maze[row][col].visited)
{
g.fillRect(SIZE*row, SIZE * col , SIZE, SIZE);
}
}
}
}
public static void main(String[] args)
{
Maze p = new Maze(10);
p.generator();
JFrame f = new JFrame();
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(p);
f.pack();
f.setVisible(true);
p.DFS();
}
//use swing worker perform long task
class DFSTask extends SwingWorker<Void,Void> {
private static final long DELAY = 1000;
private final Random rand = new Random();
#Override
public Void doInBackground() {
dfs();
return null;
}
#Override
public void done() { }
void dfs() { //simulates long process that repeatedly updates gui
while (true){ //endless loop, just for demonstration
//update info
int row = rand.nextInt(dims);
int col = rand.nextInt(dims);
maze[row][col].setVisited(! maze[row][col].isVisited());
repaint(); //update jpanel
try {
Thread.sleep(DELAY); //simulate long process
} catch (InterruptedException ex) { ex.printStackTrace();}
}
}
}
}
class Cell{
private final int row, column;
boolean visited;
public Cell(int i, int j)
{
row = i;
column = j;
visited = false;
}
int getRow() { return row; }
int getColumn() {return column; }
boolean isVisited() { return visited; }
void setVisited(boolean visited) { this.visited = visited;}
#Override
public String toString()
{
return row + " " + column;
}
}
For more information about using SwingWorker see doc

Java program not running while it should

For a project in school we got a simple simulator for a parking lot, and it is our job to add features to this simulator. I'm trying to add a GUI to the simulator and so that you can fill in your values and that the simulation bases its simulation based upon those values. But i first made a simple button to go from 1 frame to the other but when i run the Frame1 file with the following code:
JButton btnSubmit = new JButton("Submit");
btnSubmit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
frame.dispose();
Simulator mysimulator = new Simulator();
mysimulator.run();
}
it doesn't load, it just gives me a blank window.
the view of the simulator is made in the following code:
//package Parkeersimulator;
import javax.swing.*;
import java.awt.*;
public class SimulatorView extends JFrame {
public JFrame frame;
private CarParkView carParkView;
private int numberOfFloors;
private int numberOfRows;
private int numberOfPlaces;
private int numberOfOpenSpots;
private Car[][][] cars;
public SimulatorView(int numberOfFloors, int numberOfRows, int numberOfPlaces) {
this.numberOfFloors = numberOfFloors;
this.numberOfRows = numberOfRows;
this.numberOfPlaces = numberOfPlaces;
this.numberOfOpenSpots =numberOfFloors*numberOfRows*numberOfPlaces;
cars = new Car[numberOfFloors][numberOfRows][numberOfPlaces];
carParkView = new CarParkView();
Container contentPane = getContentPane();
contentPane.add(carParkView, BorderLayout.CENTER);
pack();
setVisible(true);
updateView();
}
public void updateView() {
carParkView.updateView();
}
public int getNumberOfFloors() {
return numberOfFloors;
}
public int getNumberOfRows() {
return numberOfRows;
}
public int getNumberOfPlaces() {
return numberOfPlaces;
}
public int getNumberOfOpenSpots(){
return numberOfOpenSpots;
}
public Car getCarAt(Location location) {
if (!locationIsValid(location)) {
return null;
}
return cars[location.getFloor()][location.getRow()][location.getPlace()];
}
public boolean setCarAt(Location location, Car car) {
if (!locationIsValid(location)) {
return false;
}
Car oldCar = getCarAt(location);
if (oldCar == null) {
cars[location.getFloor()][location.getRow()][location.getPlace()] = car;
car.setLocation(location);
numberOfOpenSpots--;
return true;
}
return false;
}
public Car removeCarAt(Location location) {
if (!locationIsValid(location)) {
return null;
}
Car car = getCarAt(location);
if (car == null) {
return null;
}
cars[location.getFloor()][location.getRow()][location.getPlace()] = null;
car.setLocation(null);
numberOfOpenSpots++;
return car;
}
public Location getFirstFreeLocation() {
for (int floor = 0; floor < getNumberOfFloors(); floor++) {
for (int row = 0; row < getNumberOfRows(); row++) {
for (int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
if (getCarAt(location) == null) {
return location;
}
}
}
}
return null;
}
public Car getFirstLeavingCar() {
for (int floor = 0; floor < getNumberOfFloors(); floor++) {
for (int row = 0; row < getNumberOfRows(); row++) {
for (int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
Car car = getCarAt(location);
if (car != null && car.getMinutesLeft() <= 0 && !car.getIsPaying()) {
return car;
}
}
}
}
return null;
}
public void tick() {
for (int floor = 0; floor < getNumberOfFloors(); floor++) {
for (int row = 0; row < getNumberOfRows(); row++) {
for (int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
Car car = getCarAt(location);
if (car != null) {
car.tick();
}
}
}
}
}
private boolean locationIsValid(Location location) {
int floor = location.getFloor();
int row = location.getRow();
int place = location.getPlace();
if (floor < 0 || floor >= numberOfFloors || row < 0 || row > numberOfRows || place < 0 || place > numberOfPlaces) {
return false;
}
return true;
}
private class CarParkView extends JPanel {
private Dimension size;
private Image carParkImage;
/**
* Constructor for objects of class CarPark
*/
public CarParkView() {
size = new Dimension(0, 0);
}
/**
* Overridden. Tell the GUI manager how big we would like to be.
*/
public Dimension getPreferredSize() {
return new Dimension(800, 500);
}
/**
* Overriden. The car park view component needs to be redisplayed. Copy the
* internal image to screen.
*/
public void paintComponent(Graphics g) {
if (carParkImage == null) {
return;
}
Dimension currentSize = getSize();
if (size.equals(currentSize)) {
g.drawImage(carParkImage, 0, 0, null);
}
else {
// Rescale the previous image.
g.drawImage(carParkImage, 0, 0, currentSize.width, currentSize.height, null);
}
}
public void updateView() {
// Create a new car park image if the size has changed.
if (!size.equals(getSize())) {
size = getSize();
carParkImage = createImage(size.width, size.height);
}
Graphics graphics = carParkImage.getGraphics();
for(int floor = 0; floor < getNumberOfFloors(); floor++) {
for(int row = 0; row < getNumberOfRows(); row++) {
for(int place = 0; place < getNumberOfPlaces(); place++) {
Location location = new Location(floor, row, place);
Car car = getCarAt(location);
Color color = car == null ? Color.white : car.getColor();
drawPlace(graphics, location, color);
}
}
}
repaint();
}
/**
* Paint a place on this car park view in a given color.
*/
private void drawPlace(Graphics graphics, Location location, Color color) {
graphics.setColor(color);
graphics.fillRect(
location.getFloor() * 260 + (1 + (int)Math.floor(location.getRow() * 0.5)) * 75 + (location.getRow() % 2) * 20,
60 + location.getPlace() * 10,
20 - 1,
10 - 1); // TODO use dynamic size or constants
}
}
}
and the simultion self is made in the following code:
//package Parkeersimulator;
import java.util.Random;
import javax.swing.*;
public class Simulator {
private static final String AD_HOC = "1";
private static final String PASS = "2";
private CarQueue entranceCarQueue;
private CarQueue entrancePassQueue;
private CarQueue paymentCarQueue;
private CarQueue exitCarQueue;
private SimulatorView simulatorView;
private int day = 0;
private int hour = 0;
private int minute = 0;
private int tickPause = 100;
int weekDayArrivals= 100; // average number of arriving cars per hour
int weekendArrivals = 200; // average number of arriving cars per hour
int weekDayPassArrivals= 50; // average number of arriving cars per hour
int weekendPassArrivals = 5; // average number of arriving cars per hour
int enterSpeed = 3; // number of cars that can enter per minute
int paymentSpeed = 7; // number of cars that can pay per minute
int exitSpeed = 5; // number of cars that can leave per minute
public static void main(String[] args){
Simulator mySimulator = new Simulator();
mySimulator.run();
}
public Simulator() {
entranceCarQueue = new CarQueue();
entrancePassQueue = new CarQueue();
paymentCarQueue = new CarQueue();
exitCarQueue = new CarQueue();
simulatorView = new SimulatorView(3, 6, 30);
}
public void run() {
for (int i = 0; i < 10000; i++) {
tick();
}
}
private void tick() {
advanceTime();
handleExit();
updateViews();
// Pause.
try {
Thread.sleep(tickPause);
} catch (InterruptedException e) {
e.printStackTrace();
}
handleEntrance();
}
private void advanceTime(){
// Advance the time by one minute.
minute++;
while (minute > 59) {
minute -= 60;
hour++;
}
while (hour > 23) {
hour -= 24;
day++;
}
while (day > 6) {
day -= 7;
}
}
private void handleEntrance(){
carsArriving();
carsEntering(entrancePassQueue);
carsEntering(entranceCarQueue);
}
private void handleExit(){
carsReadyToLeave();
carsPaying();
carsLeaving();
}
private void updateViews(){
simulatorView.tick();
// Update the car park view.
simulatorView.updateView();
}
private void carsArriving(){
int numberOfCars=getNumberOfCars(weekDayArrivals, weekendArrivals);
addArrivingCars(numberOfCars, AD_HOC);
numberOfCars=getNumberOfCars(weekDayPassArrivals, weekendPassArrivals);
addArrivingCars(numberOfCars, PASS);
}
private void carsEntering(CarQueue queue){
int i=0;
// Remove car from the front of the queue and assign to a parking space.
while (queue.carsInQueue()>0 &&
simulatorView.getNumberOfOpenSpots()>0 &&
i<enterSpeed) {
Car car = queue.removeCar();
Location freeLocation = simulatorView.getFirstFreeLocation();
simulatorView.setCarAt(freeLocation, car);
i++;
}
}
private void carsReadyToLeave(){
// Add leaving cars to the payment queue.
Car car = simulatorView.getFirstLeavingCar();
while (car!=null) {
if (car.getHasToPay()){
car.setIsPaying(true);
paymentCarQueue.addCar(car);
}
else {
carLeavesSpot(car);
}
car = simulatorView.getFirstLeavingCar();
}
}
private void carsPaying(){
// Let cars pay.
int i=0;
while (paymentCarQueue.carsInQueue()>0 && i < paymentSpeed){
Car car = paymentCarQueue.removeCar();
// TODO Handle payment.
carLeavesSpot(car);
i++;
}
}
private void carsLeaving(){
// Let cars leave.
int i=0;
while (exitCarQueue.carsInQueue()>0 && i < exitSpeed){
exitCarQueue.removeCar();
i++;
}
}
private int getNumberOfCars(int weekDay, int weekend){
Random random = new Random();
// Get the average number of cars that arrive per hour.
int averageNumberOfCarsPerHour = day < 5
? weekDay
: weekend;
// Calculate the number of cars that arrive this minute.
double standardDeviation = averageNumberOfCarsPerHour * 0.3;
double numberOfCarsPerHour = averageNumberOfCarsPerHour + random.nextGaussian() * standardDeviation;
return (int)Math.round(numberOfCarsPerHour / 60);
}
private void addArrivingCars(int numberOfCars, String type){
// Add the cars to the back of the queue.
switch(type) {
case AD_HOC:
for (int i = 0; i < numberOfCars; i++) {
entranceCarQueue.addCar(new AdHocCar());
}
break;
case PASS:
for (int i = 0; i < numberOfCars; i++) {
entrancePassQueue.addCar(new ParkingPassCar());
}
break;
}
}
private void carLeavesSpot(Car car){
simulatorView.removeCarAt(car.getLocation());
exitCarQueue.addCar(car);
}
}
please do note that i only just began programming and i have little to no knowledge at all.
You need a add the button to a panel.
JPanel panel = new JPanel();
JButton btnSubmit = new JButton("Submit");
Container content = this.getContentPane(); // Get the content pane
content.add(panel, BorderLayout.CENTER);
content.add(btnSubmit, BorderLayout.SOUTH);
setVisible(true); // Display the window

Repaint() doesn't work when called from new thread

I want to do a sorting animation. I've got a JFrame with GridLayout(1,3) because I have 3 sorting alghorithms. In each cell I have a JPanel with BorderLayout(). In the center of the JPanel I have the numbers and for each number a stick with different widths(I placed them horizontally). For each type of sorting I need a thread to call them. So I created class SortThread which does my sorting (it extends JThread). Each pair of numbers and sticks are painted on the center panel with class StickNumber which extends JLabel. The problem is when I start the thread. The repaint() method doesn't seem to work.
Here is class SortThread:
public class SortThread extends Thread{
private JPanel sortPanel;
private StickNumber[] listOfNumbers;
public SortThread(JPanel sortPanel)
{
this.sortPanel = sortPanel;
Component[] components = sortPanel.getComponents();
listOfNumbers = new StickNumber[components.length];
for(int i = 0; i<components.length; i++)
listOfNumbers[i] = (StickNumber) components[i];
}
public SortThread(){}
public void bubbleSort()
{
boolean swapped = true;
int j = 0;
StickNumber tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < listOfNumbers.length - j; i++) {
if (listOfNumbers[i].getValue() > listOfNumbers[i+1].getValue()) {
tmp = listOfNumbers[i];
listOfNumbers[i]=listOfNumbers[i+1];
listOfNumbers[i+1]=tmp;
swapped = true;
sortPanel.validate();
sortPanel.repaint();
}
}
}
}
public void run(){
bubbleSort();
}
Here is the listener for my button which starts the thread:
ActionListener sortListener = new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if(sortFlag == false)
{
sortFlag = true;
SortThread thread1= new SortThread(centerPanel1);
thread1.start();
appFrame.validate();
appFrame.repaint();
}
}
};
sortButton.addActionListener(sortListener);
StickNumber class:
private void doDrawing(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
String number = Integer.toString(value);
if(dimension!=0)
setText(number);
g2.setStroke(new BasicStroke(5));
g2.draw(new Line2D.Float(dimension*10, 5, height+dimension*10, 5));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
doDrawing(g);
}
Using SwingWorker, assuming your code does what it should and your problems is the EDT is blocked:
import java.awt.Component;
import java.util.List;
import javax.swing.*;
public class SortSwingWorker extends SwingWorker<Object, Object> {
private JPanel sortPanel;
private StickNumber[] listOfNumbers;
public SortSwingWorker(JPanel sortPanel) {
this.sortPanel = sortPanel;
Component[] components = sortPanel.getComponents();
listOfNumbers = new StickNumber[components.length];
for (int i = 0; i < components.length; i++) {
listOfNumbers[i] = (StickNumber) components[i];
}
}
#Override
protected Object doInBackground() throws Exception {
boolean swapped = true;
int j = 0;
StickNumber tmp;
while (swapped) {
swapped = false;
j++;
for (int i = 0; i < listOfNumbers.length - j; i++) {
if (listOfNumbers[i].getValue() > listOfNumbers[i + 1].getValue()) {
tmp = listOfNumbers[i];
listOfNumbers[i] = listOfNumbers[i + 1];
listOfNumbers[i + 1] = tmp;
swapped = true;
publish(null);
}
}
}
return null;
}
#Override
protected void process(List<Object> list) {
sortPanel.validate();
sortPanel.repaint();
}
//dummy class
private class StickNumber extends Component {
public Integer getValue() {
return null;
}
}
}

Problem Adding incremented class member variable to arraylist inside loop

Trying to add an incremented class member variable 'nNodeIndex' to arraylist, but at the end of the loop all the values stored are identical to the last iteration increment??
Class with member variable:
import java.util.ArrayList;
public class Graph {
private static ArrayList<GraphNode> Nodes = new ArrayList<GraphNode>();
private static ArrayList<GraphEdge> Edges = new ArrayList<GraphEdge>();
private static boolean diGraph;
private static int nNodeIndex;
private boolean uniqueEdge(int from, int to)
{
for(int i=0; i< Edges.size(); i++){
if(Edges.get(i).from() == from && Edges.get(i).to() == to)
return false;
}
return true;
}
private void removeInvalidEdges(int nodeIndex)
{
for(int i=0; i<Edges.size(); i++)
{
if(Edges.get(i).from() == nodeIndex)
Edges.remove(i);
if(Edges.get(i).to() == nodeIndex)
Edges.remove(i);
}
}
Graph(boolean directionalGraph)
{
diGraph = directionalGraph;
nNodeIndex = 1;
}
public GraphNode getNode(int nodeIndex)
{
return Nodes.get(nodeIndex);
}
public int getIndexByVector(int x, int y)
{
for(int i=0; i<Nodes.size(); i++)
{
if(Nodes.get(i).x() == x && Nodes.get(i).y() == y)
return i;
}
return -1;
}
public int nextFreeNodeIndex(){ return nNodeIndex; }
public void addNode(GraphNode node)
{
if(Nodes.size() > 0)
Nodes.add(node.index()-1, node);
else
Nodes.add(node);
nNodeIndex++;
}
public void removeNode(int index)
{
Nodes.get(index).setIndex(-1);
removeInvalidEdges(index);
}
public void addEdge(GraphEdge edge)
{
if(uniqueEdge(edge.from(), edge.to()))
Edges.add(edge);
if(!diGraph)
{
if(uniqueEdge(edge.to(), edge.from()))
Edges.add(new GraphEdge(edge.to(), edge.from()));
}
}
public void removeEdge(GraphEdge edge)
{
for(int i=0; i<Edges.size(); i++)
if(Edges.get(i).from() == edge.from() &&
Edges.get(i).to() == edge.to())
{
Edges.remove(i);
}
}
public int totalNodes(){ return Nodes.size(); }
public int totalEdges(){ return Edges.size(); }
public int nActiveNodes()
{
int count = 0;
for(int i=0; i<Nodes.size(); i++)
{
if(Nodes.get(i).index() != -1 )
count++;
}
return count;
}
public void reset()
{
nNodeIndex = 1;
Nodes.clear();
Edges.clear();
}
}
Use within main class:
for(int row = 1; row <= boardWidth; row++){
for(int col = 1; col <= boardHeight; col++){
graph.addNode(new GraphNode(graph.nextFreeNodeIndex(), row, col));
}
}
Graph Node class:
public class GraphNode extends Square {
private static int indexNum;
GraphNode(int n, int x, int y)
{
super(x,y);
indexNum = n;
}
public int index(){ return indexNum; }
public void setIndex(int index){ indexNum = index; }
}
Do you need to show us the GraphNode class? I wonder if the node index held by it (set by the first parameter passed in its constructor) is a static variable.

Categories