Java: simple but unusual NullPointerException - java

I'm stuck on something that is usually really simple. I'm getting a NullPointerException when calling this simple class's constructor:
import java.awt.geom.*;
public class Brick extends ColorShape {
private int xPos = 0;
private int yPos = 0;
private int width = 0;
private int height = 0;
private Rectangle2D.Double shape;
// constructor
public Brick(int x, int y, int w, int h) {
super(new Rectangle2D.Double(x, y, w, h));
//set brick x, y, width, and height
xPos = x;
yPos = y;
width = w;
height = h;
// update shape
shape.setRect((double)xPos, (double)yPos, (double)width, (double)height);
}
public int getX() {
return xPos;
}
public Rectangle2D.Double getShape() {
return shape;
}
}
It gets called this way:
for (int i = 0; i < numCols; i++) {
for (int j = 0; j < numRows; j++) {
// initialize bricks[i][j]
bricks[i][j].setLocation((double)(i*brickWidth), (double)(j*brickHeight));
bricks[i][j].setSize((double)brickWidth, (double)brickHeight);
//bricks[i][j] = new Brick(i*brickWidth, j*brickHeight, brickWidth, brickHeight);
//bricks[i][j] = new Brick(0, 0, 0, 0);
}
}
No matter what I try, I always get a NullPointerException trying to initialize that class.
EDIT:
Tristan's suggestions along with changing the nested for loops to the code below fixed it
// create new bricks and store them in bricks array
for (int i = 0; i < numCols; i++) {
for (int j = 0; j < numRows; j++) {
// initialize bricks[i][j]
//bricks[i][j].setLocation((double)(i*brickWidth), (double)(j*brickHeight));
//bricks[i][j].setSize((double)brickWidth, (double)brickHeight);
bricks[i][j] = new Brick(i*brickWidth, j*brickHeight, brickWidth, brickHeight);
//bricks[i][j] = new Brick(0, 0, 0, 0);
}
}

I think you are accidentally redeclaring shape as an uninitialized field. The shape you are calling setRect on has not been initialized the way you think it has.
If you have a shape in the parent class that you are trying to access, simply set its modifier to protected and remove the private shape declaration in the class you posted.
/* REMOVE THIS */
private Rectangle2D.Double shape; // uninitialized!
// constructor
public Brick(int x, int y, int w, int h) {
super(new Rectangle2D.Double(x, y, w, h));
//set brick x, y, width, and height
xPos = x;
yPos = y;
width = w;
height = h;
// update shape
// This now references a protected instance variable inherited from the parent.
shape.setRect((double)xPos, (double)yPos, (double)width, (double)height);
}
However looking through this constructor, it seems rather off. If it is the case that the parent class has a shape itself, why do you need to set the rectangle any differently than the way you set it in the parent class?
For example, this code appears to be logically equivalent.
// Call the parents constructor to set the shape of this brick..
public Brick(int x, int y, int w, int h) {
super(new Rectangle2D.Double(x, y, w, h));
}

As mentioned by Tristan, the problem with the initial brick constructor is that shape has been declared but not instantiated.
That said, it is simple to instantiate shape:
public Brick(int x, int y, int w, int h) {
super(new Rectangle2D.Double(x, y, w, h));
//set brick x, y, width, and height
xPos = x;
yPos = y;
width = w;
height = h;
// update shape
// This now references a protected instance variable inherited from the parent.
shape = (Rectangle2D.Double)super.shape;
shape.setRect(xPos, yPos, width, height);
}

Related

Using Abstract Class and super()

I have created an abstract shape class for 2d game but i am getting an error in both the shape classes. The error is something to do with super(). There maybe other errors as well. i have also shown where i get the error in the code. IS super() suitable to use.
Shape class
public abstract class Shape {
int Y;
int WIDTH;
int HEIGHT;
int DIAMETER;
public Shape(int Y, int WIDTH, int HEIGHT, int DIAMETER) {
this.Y = Y;
this.WIDTH = WIDTH;
this.HEIGHT = HEIGHT;
this.DIAMETER = DIAMETER;
}
public abstract void paint(Graphics g);
}
Racquet class
public class Racquet extends Shape {
int x = 0;
int xa = 0;
private Game game;
public Racquet(int Y, int WIDTH, int HEIGHT) {
super(Y, WIDTH, HEIGHT); // <- **Error Here**
}
public void move() {
if (x + xa > 0 && x + xa < game.getWidth() - this.WIDTH)
x = x + xa;
}
public void paint(Graphics r) {
r.setColor(new java.awt.Color(229, 144, 75));
r.fillRect(x, Y, this.WIDTH, this.HEIGHT);
}
public Rectangle getBounds() {
return new Rectangle(x, this.Y, this.WIDTH, this.HEIGHT);
}
public int getTopY() {
return this.Y - this.HEIGHT;
}
}
Ball Class
import java.awt.*;
public class Ball extends Shape {
int x = 0;
int y = 0;
int xa = 1;
int ya = 1;
private Game game;
public Ball(Integer DIAMETER) {
super(DIAMETER); // <- **Error Here**
}
void move() {
if (x + xa < 0)
xa = game.speed;
if (x + xa > game.getWidth() - this.DIAMETER)
xa = -game.speed;
if (y + ya < 0)
ya = game.speed;
if (y + ya > game.getHeight() - this.DIAMETER)
game.CheckScore();
if (collision()) {
ya = -game.speed;
y = game.racquet.getTopY() - this.DIAMETER;
game.speed++;
}
x = x + xa;
y = y + ya;
}
private boolean collision() {
return game.racquet.getBounds().intersects(getBounds());
}
public void paint(Graphics b) {
b.setColor(new java.awt.Color(237, 238, 233));
b.fillOval(x, y, this.DIAMETER, this.DIAMETER);
}
public Rectangle getBounds() {
return new Rectangle(x, y, this.DIAMETER, this.DIAMETER);
}
}
Thanks a lot.
By calling super(...), you are actually calling constructor of super class. In the super class you have only one constructor which expects 4 parameters: Shape(int Y, int WIDTH, int HEIGHT, int DIAMETER), so you either have to provide 4 parameters when calling super(...), or provide needed constructors in the super class, with 3 parameters and with 1 parameter
Your Shape class doesn't have constructor with three parameters or one parameters.
You may want to use;
in recquet class
super(Y, WIDTH, HEIGHT, 0);
in Ball class
super(0, 0, 0, DIAMETER);
Shape doesn't have constructors that fit the parameters you are using in Racquet and Ball.
From a "best-practice" perspective, since Ball and Racquet should logically be constructed differently, it may be better to use composition, rather than inheritance.

Java - Change the color of some squares created with Graphics2D

I just want to create a simple game with 100 x 100 square, each square is 5 pixels.
I created a class:
public class Draw extends JComponent{
private List<Graphics2D> recList = new ArrayList<Graphics2D>();
public void paint(Graphics g) {
//THIS TO SET (0,0) PANEL START AT BOTTOM LEFT
Graphics2D g2 = (Graphics2D)g;
AffineTransform at = g2.getTransform();
at.translate(0, getHeight());
at.scale(1, -1);
g2.setTransform(at);
//THIS TO DRAW ALL THE SQUARES
for (int i = 0;i<100;i++){
for (int j=0;j<100;j++){
g2.setColor(Color.red);
g2.drawRect(5*i, 5*j, 5, 5);
recList.add(g2); //Store each square to the list to change the color
}
}
}
}
Then I just drag it to the design windows of netbeans and the squares are painted, looks good...
But it seems like I made a wrong move. At the first time I wanted to get a specific square from the list using their location, but the Graphic2d doesn't have any method to get the location (x and y) or to change the color.
I don't know if there is any other way I can make it come true?
PS: One more thing, can I set the location of each square to its center?
You could create your own Tile class, which stores info such as x, y, width, height, and color. Each Tile object could also be in charge of painting itself:
class Tile {
private int x, y, width, height;
private Color color;
public Tile(int x, int y, int width, int height, Color color) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.color = color;
}
public void paint(Graphics g) {
g.setColor(color);
g.fillRect(x, y, width, height);
}
}
Create the tiles before-hand:
List<Tile> tiles = ...;
void createTiles() {
for(int x = 0; x < 100; x++) {
for(int y = 0; y < 100; y++) {
Color color = ...; //choose color
int size = 5;
int tileX = x * size;
int tileY = y * size;
tiles.add(new Tile(tileX, tileY, size, size, color));
}
}
}
Then render by passing the graphics object to them in the paint method:
void paint(Graphics g) {
tiles.forEach(tile -> tile.paint(g));
}

Repainting an instance of a class from an ArrayList

Ok so I am very new to Java Swing and a beginner in Java in general. My current problem is I have designed a "cityscape". I am working on a UFO flying around, but my randomly generated buildings continue to get regenerated. I am wondering if there is a way to save my instance of buildings to an ArrayList as I have attempted, and paint that selection from that list each time paint is called. I tried what I thought of and I believe it just crashed it when run, because it didn't even open a JFrame and instead produced errors upon errors. Here is what I have:
CityScape class (the main class):
import java.awt.*;
import javax.swing.*;
public class CityScape extends JPanel
{
Buildings a = new Buildings ();
UFO b = new UFO();
#Override
public void paint (Graphics g)
{
//RememberBuildings.buildingList.get(1).paint(g);
a.paint(g);
b.paint(g);
}
public void move()
{
b.move();
}
public static void main(String[] args) throws InterruptedException
{
JFrame frame = new JFrame("Frame");
CityScape jpe = new CityScape();
frame.add(jpe);
frame.setSize(800, 750);
frame.setBackground(Color.BLACK);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(frame.getContentPane().getSize());
while (true)
{
jpe.move(); //Updates the coordinates
jpe.repaint(); //Calls the paint method
Thread.sleep(10); //Pauses for a moment
}
}
}
Buildings class (the class that generates the buildings):
import java.awt.*;
public class Buildings
{
private int maxX = 784;
private int maxY = 712;
private int width = (int)(Math.random()*100+100);
private int height = (int)(Math.random()*350+100);
private int rows = Math.round((height)/25);
private int columns = Math.round(width/25);
public void addBuilding()
{
RememberBuildings.addBuilding();
}
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
Color transYellow = new Color (255, 255, 0, 59);
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, maxX, maxY);
g2d.setColor(Color.WHITE);
g2d.fillRect(5, 5, 25, 25);
int a = 0;
for (int i =10; i<634; i+=(a+10))//buildings
{
g2d.setColor(Color.GRAY);
g2d.drawRect(i, maxY-height, width, height);
g2d.fillRect(i, maxY-height, width, height);
rows = Math.round((height)/25);
columns = Math.round(width/25);
for (int j = 1; j<=columns; j++)//windows
{
for (int k = 1; k<=rows; k++)
{
g2d.setColor(Color.BLACK);
g2d.drawRect(i+5*j+20*(j-1), (maxY-height)+5*k+20*(k-1), 20, 20);
if (Math.random()<0.7)
{
g2d.setColor(Color.YELLOW);
g2d.fillRect(i+5*j+20*(j-1), (maxY-height)+5*k+20*(k-1), 20, 20);
}
else
{
g2d.setColor(Color.BLACK);
g2d.fillRect(i+5*j+20*(j-1), (maxY-height)+5*k+20*(k-1), 20, 20);
g2d.setColor(transYellow);
g2d.fillRect(i+5*j+20*(j-1), (maxY-height)+5*k+20*(k-1), 20, 20);
}
}
}
addBuilding();
a = width;
height = (int)(Math.random()*462+100);
width = (int)(Math.random()*100+100);
}
}
}
RememberBuildings class (the point of this is to add an instance to an ArrayList):
import java.util.*;
public class RememberBuildings
{
public static ArrayList<Buildings> buildingList = new ArrayList<Buildings>();
public static void addBuilding()
{
buildingList.add(new Buildings());
}
}
And finally my UFO class (creates the UFO flying by):
import java.awt.*;
import javax.swing.*;
public class UFO extends JPanel
{
private int x = 20; //x and y coordinates of the ball
private int y = 20;
private int xa = 1;
public void move() //Increase both the x and y coordinates
{
if (x + xa < 0) {
xa = 1;
}
if (x + xa > 784-75)
{
xa = -1;
}
x = x + xa;
}
public void paint(Graphics g)
{
super.paint(g); //Clears the panel, for a fresh start
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillOval(x,y,75,25); //Draw the ball at the desired point
}
}
Avoid overriding paint, use paintComponent instead. Always call the super paint method before you do any custom painting to ensure that the paint chain is maintained. See Painting in AWT and Swing and Performing Custom Painting for more details
Beware, Swing is not thread safe and it's unwise to update any component (or any variable that a component may rely on) from outside the context of the Event Dispatching Thread. A simple solution might be to use a Swing Timer instead of a while (true) loop and Thread.sleep. See How to use Swing Timers for more details.
You should also only create and modify UI components from within the context of the event dispatching thread, see Initial Threads for more details
If you have a problem with your code not working, you should consider providing a runnable example which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses. Providing code which is not runnable and is missing classes makes it difficult to know why it's not working and how to fix it.
A few things here:
To address the paintComponent note and view an example, check out this other thread: Concerns about the function of JPanel: paintcomponent()
There seems to be a bit of a disconnect between the logic you've got going and the object-oriented programming logic that I think will help sort things out (for general info on OOP: https://en.wikipedia.org/wiki/Object-oriented_programming):
What You've Got:
The Structure you've got going is as follows:
CityScape :: here's where you've extended JPanel and setup the main function
UFO :: an object class that represents 1 UFO
Building :: a class that has methods for drawing randomized buildings and calling methods in RememberBuildings
RememberBuildings :: I think this is intended to track buildings that have been drawn
The issue here is that your Building class's paint method continually draws multiple newly randomized buildings instead of a set building that retains its structure.
My Suggestion:
There are plenty of solutions to this issue and different ways to implement each solution, but my recommendation is to remodel your Building class in an OOP fashion, meaning that it would represent 1 single building (truer to the name of the class). This would contain a constructor that initializes all of the randomized dimensions of that single building once and draws that single building on the jpanel. Then you would need to keep an array or list of some sort in the cityscape that contains buildings that are part of the cityscape, eliminating the need for a "RememberBuildings" class. so roughly:
CityScape extends JPanel:
variables:
Building[] buildings; //might be useful to use an arraylist/stack/queue instead of an array depending on implementation
UFO craft;
constructor:
setup new Building objects and add to list buildings
initialize craft to new UFO
paintComponent:
calls the paint methods for each building & the ufo craft
Building:
variables:
int x, y; // position of building
int height, width; // of this building
constructor:
initializes x, y // probably needs to be inputed from CityScape with this setup
calc height and width randomly // stored in this.height/width
paint:
paints single building based on it's variables
//side-note, you'll probably need getters for the x/y/width to build each building from CityScape
Everything else should be much the same.
Good Luck !
So, every time Buildings#paint is called, it regenerates all the builds, which is done randomly.
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
Color transYellow = new Color(255, 255, 0, 59);
g2d.setColor(Color.BLACK);
g2d.fillRect(0, 0, maxX, maxY);
g2d.setColor(Color.WHITE);
g2d.fillRect(5, 5, 25, 25);
int a = 0;
for (int i = 10; i < 634; i += (a + 10))//buildings
{
g2d.setColor(Color.GRAY);
g2d.drawRect(i, maxY - height, width, height);
g2d.fillRect(i, maxY - height, width, height);
rows = Math.round((height) / 25);
columns = Math.round(width / 25);
for (int j = 1; j <= columns; j++)//windows
{
for (int k = 1; k <= rows; k++) {
g2d.setColor(Color.BLACK);
g2d.drawRect(i + 5 * j + 20 * (j - 1), (maxY - height) + 5 * k + 20 * (k - 1), 20, 20);
if (Math.random() < 0.7) {
g2d.setColor(Color.YELLOW);
g2d.fillRect(i + 5 * j + 20 * (j - 1), (maxY - height) + 5 * k + 20 * (k - 1), 20, 20);
} else {
g2d.setColor(Color.BLACK);
g2d.fillRect(i + 5 * j + 20 * (j - 1), (maxY - height) + 5 * k + 20 * (k - 1), 20, 20);
g2d.setColor(transYellow);
g2d.fillRect(i + 5 * j + 20 * (j - 1), (maxY - height) + 5 * k + 20 * (k - 1), 20, 20);
}
}
}
addBuilding();
a = width;
height = (int) (Math.random() * 462 + 100);
width = (int) (Math.random() * 100 + 100);
}
}
There's two ways you might be able to solve this, which you use will depend on what you want to achieve. You could render the buildings directly to a BufferedImage and simply paint that on each paint cycle or you could cache the information you need in order to re-create the buildings.
The BufferedImage approach is quicker, but can't be animated, so if you want to animate the buildings in some way (make the lights flicker), you will need to build up a series of information which allows you to simply repaint them.
I'm going for the second, as you've asked about painting assets from a ArrayList.
I started by translating your "paint" code into a single concept of a virtual building, which has also has information about it's own lights.
public class Building {
protected static final Color TRANS_YELLOW = new Color(255, 255, 0, 59);
private int x, y, width, height;
private List<Light> lights;
public Building(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
lights = new ArrayList<>(25);
int rows = Math.round((height) / 25);
int columns = Math.round(width / 25);
for (int j = 1; j <= columns; j++)//windows
{
for (int k = 1; k <= rows; k++) {
Color color = null;
if (Math.random() < 0.7) {
color = Color.YELLOW;
} else {
color = TRANS_YELLOW;
}
lights.add(new Light(x + 5 * j + 20 * (j - 1), y + 5 * k + 20 * (k - 1), color));
}
}
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.GRAY);
g2d.drawRect(x, y, width, height);
g2d.fillRect(x, y, width, height);
for (Light light : lights) {
light.paint(g2d);
}
}
public class Light {
private int x, y;
private Color color;
public Light(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.BLACK);
g2d.fillRect(x, y, 20, 20);
g2d.setColor(color);
g2d.fillRect(x, y, 20, 20);
}
}
}
This allows you to generate the primary parameters for the Building and simple cache the results and when needed, simply paint it.
For example...
public class Buildings {
private int maxX = 784;
private int maxY = 712;
private List<Building> buildings;
public Buildings() {
buildings = new ArrayList<>(25);
for (int i = 10; i < 634; i += 10)//buildings
{
int width = (int) (Math.random() * 100 + 100);
int height = (int) (Math.random() * 350 + 100);
int x = i;
int y = maxY - height;
buildings.add(new Building(x, y, width, height));
}
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for (Building building : buildings) {
building.paint(g2d);
}
}
}
I also changed your UFO class so it no longer extends from JPanel, as it just doesn't need to and is probably the primary cause of confusion with your painting.
I then updated your paint method in your CityScape to use paintComponent instead...
public class CityScape extends JPanel {
Buildings a = new Buildings();
UFO b = new UFO();
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
a.paint(g);
b.paint(g);
}
As a runnable example...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class CityScape extends JPanel {
Buildings a = new Buildings();
UFO b = new UFO();
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g); //To change body of generated methods, choose Tools | Templates.
a.paint(g);
b.paint(g);
}
public void move() {
b.move();
}
public static void main(String[] args) throws InterruptedException {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Frame");
CityScape jpe = new CityScape();
frame.add(jpe);
frame.setSize(800, 750);
frame.setBackground(Color.BLACK);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
System.out.println(frame.getContentPane().getSize());
Timer timer = new Timer(10, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jpe.move(); //Updates the coordinates
jpe.repaint(); //Calls the paint method
}
});
timer.start();
}
});
}
public class Buildings {
private int maxX = 784;
private int maxY = 712;
private List<Building> buildings;
public Buildings() {
buildings = new ArrayList<>(25);
for (int i = 10; i < 634; i += 10)//buildings
{
int width = (int) (Math.random() * 100 + 100);
int height = (int) (Math.random() * 350 + 100);
int x = i;
int y = maxY - height;
buildings.add(new Building(x, y, width, height));
}
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
for (Building building : buildings) {
building.paint(g2d);
}
}
}
public static class Building {
protected static final Color TRANS_YELLOW = new Color(255, 255, 0, 59);
private int x, y, width, height;
private List<Light> lights;
public Building(int x, int y, int width, int height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
lights = new ArrayList<>(25);
int rows = Math.round((height) / 25);
int columns = Math.round(width / 25);
for (int j = 1; j <= columns; j++)//windows
{
for (int k = 1; k <= rows; k++) {
Color color = null;
if (Math.random() < 0.7) {
color = Color.YELLOW;
} else {
color = TRANS_YELLOW;
}
lights.add(new Light(x + 5 * j + 20 * (j - 1), y + 5 * k + 20 * (k - 1), color));
}
}
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.GRAY);
g2d.drawRect(x, y, width, height);
g2d.fillRect(x, y, width, height);
for (Light light : lights) {
light.paint(g2d);
}
}
public class Light {
private int x, y;
private Color color;
public Light(int x, int y, Color color) {
this.x = x;
this.y = y;
this.color = color;
}
public void paint(Graphics2D g2d) {
g2d.setColor(Color.BLACK);
g2d.fillRect(x, y, 20, 20);
g2d.setColor(color);
g2d.fillRect(x, y, 20, 20);
}
}
}
public class UFO {
private int x = 20; //x and y coordinates of the ball
private int y = 20;
private int xa = 1;
public void move() //Increase both the x and y coordinates
{
if (x + xa < 0) {
xa = 1;
}
if (x + xa > 784 - 75) {
xa = -1;
}
x = x + xa;
}
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillOval(x, y, 75, 25); //Draw the ball at the desired point
}
}
}

How to make sure that points drawn on JFrame at random location does not overlap already drawn shapes?

I am creating 100 particles at random location all over my JPanel using random function to calculate x and y. But I have two rectangles also drawn on the panel and I do not want my points to overlap on that area.
Is there any way, by which I can create the particles all over the JPanel except those areas covered by rectangle?
int x,y=0;
super.paintComponent(g);
for(int i=0;i<list.size();i++)
{
x=randomInteger(11,670); // bounds of x between which the particles should be generated (reduced by 1 each)
y=randomInteger(11,440); // bounds of y between which the particles should be generated (reduced by 1 each)
int radius = 4;
g.fillOval(x, y, radius, radius);
}
x=randomInteger(11,670);
y=randomInteger(11,440);
drawRobot(g,x,y,50);
createObstacles(g,150,225,100,40);
createObstacles(g,500,300,40,100);
int xpoints[] = {50, 40, 60, 120};
int ypoints[] = {50, 75, 100, 130};
int npoints = 4;
createPolygonObstacle(g,xpoints,ypoints,npoints);
}
private void createPolygonObstacle(Graphics g, int xpoints[], int ypoints[], int npoints)
{
g.fillPolygon(xpoints, ypoints, npoints);
}
private void createObstacles(Graphics g, int x, int y, int width, int height)
{
g.setColor(Color.BLACK);
g.fillRect(x, y, width, height);
}
private void drawRobot(Graphics g, int x, int y, int radius)
{
g.setColor(Color.GREEN);
g.fillOval(x, y, radius, radius);
}
private static int randomInteger(int min, int max)
{
Random rand = new Random();
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
You could take advantage of the Shape API...
Rectangle rect = new Rectangle (x, y, width, height);
Then you could use it's contains method to determine if it contains a given point...
if (rect.contains(x, y)) {
// You bad little particle...
}
You should also know that the Graphics2D can also draw and paint Shape, so you could also do...
((Graphics2D)g).fill(rect);
Which should make your life some what easier. As of Java 1.4 (I think), the paint engine is guaranteed to use Graphics2D, so your paintComponent method will always receive an instance of a Graphics2D object.
Take a look at 2D Graphics for more details
Random r = new Random();
public void generateParticle(){
int x = r.nextInt();
int y = r.nextInt();
if(x > LeftEdgeOfRectangle || x < RightEdgeOfRectangle){
generateParticle();
return();
}
if(y > TopEdgeOfRectangle || y < BottomEdgeOfRectangle){
generateParticle();
return();
}
[drawParticleHere]
}

nothing happens when i execute the code. Got my methods right? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a code, and im supposed to return the rectangles area and perimeter on a JPanel. But when i execute nothing happens at all. Im suspecting an error somewhere in my methods cus i belive the rest is ok. Ill appricate all help.
Im just gonna show you my code in the JPanel.
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Rektanglar extends JPanel {
Rektanglar r1 = new Rektanglar ();
#Override
public void paintComponent (Graphics g) {
super.paintComponent (g);
g.drawString ("Rektanglar",10,20);
this.setBackground(Color.WHITE);
g.setColor(Color.BLUE);
g.fillRect(r1.getX(),r1.getY(), r1.getWidth(), r1.getHeight());
}
public int Y;
public int X;
public int width;
public int height;
public int Perimeter;
public int Area;
Rektanglar (){
width = 10;
height = 10;
X = 0;
Y = 0;
}
public void Rectangle(int x, int y, int w, int h) {
X = x;
Y = y;
width = w;
height = h;
}
public void setX(int X ){
this.X = X;
}
public int getX(int X){
return X;
}
public void setY(int Y){
this.Y = Y;
}
public int getY( int Y){
return Y;
}
public int getWidth( int width){
return width;
}
public int getHeight(int height){
return height;
}
public int getPerimeter(){
return (width + width + height + height );
}
public int getArea(){
return (height * width);}
}
}
If you ever actually try to construct an instance of Rektanglar, you'll get a stack overflow due to this:
public class Rektanglar extends JPanel {
Rektanglar r1 = new Rektanglar ();
...
}
That code says that in order to create one instance, you need to create another instance... which will create yet another instance, etc.
It's not at all clear why you've got r1 at all, but I strongly suggest you get rid of it...
I also suspect this:
public void Rectangle(int x, int y, int w, int h) {
X = x;
Y = y;
width = w;
height = h;
}
... is meant to be a constructor, in which case you'd have to write it as:
public Rektanglar(int x, int y, int w, int h) {
X = x;
Y = y;
width = w;
height = h;
}
Note that the name has to match the name of the class and you don't specify a return type.
Additionally, I'd suggest that:
You make all fields private
You compute the perimeter and area from the width and height, rather than keeping them as fields
You follow Java naming conventions for your variables (so x and y instead of X and Y).

Categories