Related
//With these I am getting compilation - error class not found
/*import Shape.TwoD.*;
import Shape.ThreeD.*;
import Shape.*;*/
import Shape.TwoD.Circle;
import Shape.TwoD.Line;
import Shape.ThreeD.Line3D;
import Shape.ThreeD.Sphere;
import Shape.Actions;
public class Test {
/**
* Creates a new instance of <code>Test</code>.
*/
int o;
public Test() {
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Actions obj[] = new Actions[4];
obj[0] = new Line(1,2,3,4);
obj[1] = new Circle(1,2,3);
obj[2] = new Line3D(1,2,3,4,5,6);
obj[3] = new Sphere(1,2,3,4);
for(Actions x: obj)
x.draw();
Actions.TwoD o =(Circle)obj[1];
System.out.println("Area of circle "+o.area());
o = (Sphere)obj[3];
System.out.println("Volume of sphere "+o.area());
}
}
Action is an interface which contains nested interface TwoD and ThreeD
Why import with wildcard not working in the above code? Am I using it wrong?
I couldn't find any related answer, if both wildcard and fully qualified imports are not working then there is problem in my code but in this case, compilation error occur class not found only when I use wildcard with import.
EDIT:
Sorry for the wrong naming convention, Line,Circle,Line3D and Sphere are the classes
Lineand Circle comes under Shape.TwoD
Line3D and Sphere comes under Shape.ThreeD
Actions.java:
package Shape;
public interface Actions {
interface ThreeD{
double volume();
}
interface TwoD{
double area();
}
void draw();
//void erase();
final double pi = 3.142857;
}
Line.java:
package Shape.TwoD;
public class Line implements Shape.Actions{
BaseObj.Point p1,p2;
public Line(int x1,int y1, int x2 ,int y2) {
p1 = new BaseObj.Point(x1,y1);
p2 = new BaseObj.Point(x2,y2);
}
public void draw(){
//System.out.println("Line between ("+p1.x+","+p1.y+") and ("+p2.x+","+p2.y+"));
System.out.println("Line between ("+p1.getx()+","+p1.gety()+") and ("+p2.getx()+","+p2.gety()+") has been drawn");
}
}
Circle.java:
package Shape.TwoD;
public class Circle extends BaseObj.Point implements Shape.Actions, Shape.Actions.TwoD{
protected int radius;
public Circle(int x, int y, int radius) {
super(x,y);
this.radius = radius;
}
public void draw(){
System.out.println("Circle with ("+x+","+y+") as center and radius "+radius+" units has been drawn");
}
public double area(){
return (pi*radius*radius);
}
}
Line3D.java:
package Shape.ThreeD;
public class Line3D implements Shape.Actions {
BaseObj.Point3D p1,p2;
public Line3D(int x1,int y1, int z1, int x2,int y2, int z2) {
p1 = new BaseObj.Point3D(x1,y1,z1);
p2 = new BaseObj.Point3D(x2,y2,z2);
}
public void draw(){
//System.out.println("Line between ("+p1.x+","+p1.y+") and ("+p2.x+","+p2.y+"));
System.out.println("Line between ("+p1.getx()+","+p1.gety()+","+p1.getz()+") and ("+p2.getx()+","+p2.gety()+","+p2.getz()+") has been drawn");
}
}
Sphere.java:
package Shape.ThreeD;
public class Sphere extends Shape.TwoD.Circle{
int z;
public Sphere(int x, int y, int z, int radius) {
super(x,y,radius);
this.z = z;
}
public void draw(){
System.out.println("Spere with ("+x+","+y+","+z+") as center and radius "+radius+" units has been drawn");
}
public double volume(){
return(radius*radius*pi*4/3);
}
public double area(){
System.out.println("Sphere is a 3D object so 2D quantitys doesnt apply");
return 0.0;
}
}
Edit2:
After correcting the names I got error that Actions interface is duplicate so I changed its name into ObjActions and the problem resolved. Thanks for the help. I hope the naming convention I used below is consistent with standard.
ObjActions.java
package shape;
public interface ObjActions {
interface Actions3D{
double volume();
}
interface Actions2D{
double area();
}
void draw();
//void erase();
final double pi = 3.142857;
}
Circle.java
package shape.twod;
public class Circle extends baseobj.Point implements shape.ObjActions, shape.ObjActions.Actions2D{
protected int radius;
public Circle(int x, int y, int radius) {
super(x,y);
this.radius = radius;
}
public void draw(){
System.out.println("Circle with ("+x+","+y+") as center and radius "+radius+" units has been drawn");
}
public double area(){
return (pi*radius*radius);
}
}
Line.java
package shape.twod;
public class Line implements shape.ObjActions{
baseobj.Point p1,p2;
public Line(int x1,int y1, int x2 ,int y2) {
p1 = new baseobj.Point(x1,y1);
p2 = new baseobj.Point(x2,y2);
}
public void draw(){
//System.out.println("Line between ("+p1.x+","+p1.y+") and ("+p2.x+","+p2.y+"));
System.out.println("Line between ("+p1.getx()+","+p1.gety()+") and ("+p2.getx()+","+p2.gety()+") has been drawn");
}
}
Line3D.java
package shape.threed;
public class Line3D implements shape.ObjActions {
baseobj.Point3D p1,p2;
public Line3D(int x1,int y1, int z1, int x2,int y2, int z2) {
p1 = new baseobj.Point3D(x1,y1,z1);
p2 = new baseobj.Point3D(x2,y2,z2);
}
public void draw(){
//System.out.println("Line between ("+p1.x+","+p1.y+") and ("+p2.x+","+p2.y+"));
System.out.println("Line between ("+p1.getx()+","+p1.gety()+","+p1.getz()+") and ("+p2.getx()+","+p2.gety()+","+p2.getz()+") has been drawn");
}
}
Sphere.java
package shape.threed;
public class Sphere extends shape.twod.Circle implements shape.ObjActions.Actions3D{
int z;
public Sphere(int x, int y, int z, int radius) {
super(x,y,radius);
this.z = z;
}
public void draw(){
System.out.println("Spere with ("+x+","+y+","+z+") as center and radius "+radius+" units has been drawn");
}
public double volume(){
return(radius*radius*pi*4/3);
}
}
Test.java
package test;
import shape.twod.*;
import shape.threed.*;
import shape.*;
/*import shape.twod.Circle;
import shape.twod.Line;
import shape.threed.Line3D;
import shape.threed.Sphere;
import shape.Actions;*/
public class Test {
/**
* Creates a new instance of <code>Test</code>.
*/
int o;
public Test() {
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
ObjActions obj[] = new ObjActions[4];
obj[0] = new Line(1,2,3,4);
obj[1] = new Circle(1,2,3);
obj[2] = new Line3D(1,2,3,4,5,6);
obj[3] = new Sphere(1,2,3,4);
for(ObjActions x: obj)
x.draw();
ObjActions.Actions2D o =(Circle)obj[1];
//Actions2D o =(Circle)obj[1];
System.out.println("Area of circle "+o.area());
ObjActions.Actions3D op = (Sphere)obj[3];
System.out.println("Volume of sphere "+op.volume());
}
}
The "packages" TwoD and ThreeD might get shadowed by the interfaces Action.TwoD and Action.ThreeD (or vice versa) as per JLS 7.5.2:
The declaration might be shadowed by a single-type-import declaration of a type whose simple name is Vector; by a type named Vector and declared in the package to which the compilation unit belongs; or any nested classes or interfaces.
The declaration might be obscured by a declaration of a field, parameter, or local variable named Vector.
(It would be unusual for any of these conditions to occur.)
I need to make a system where a obstacle is drawn on the screen, when it scrolls off the screen, another one will be drawn at a random value (up to a max of a certain value) on the screen after that one.
I have some code here:
public int xElapsed = 0;
this is just incremented all the time, it is how much the player has moved.
obstacleHole.paint(g);
if(obstacleHole.getX() <= 0){
obstacleHole.paint(g);
}
This is the paint function. The first obstacle is painted straight away, and the second after that condition is met. This is not working as intended, however.
x = position.nextInt(500 + player.xElapsed * 2);
and this is how the x coordinate of the obstacle is set. "position" is a random value generator.
This code is not working because only one obstacle ever shows up. How can I fix this to work as intended? I can provide extra code if necessary.
Here is the ObstacleHole class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class ObstacleHole {
Player player = new Player();
Random position = new Random();
int x;
int y;
int dx = 1;
int width = 100;
int height = 100;
public ObstacleHole(){
x = position.nextInt(500 + player.xElapsed * 2);
y = 250;
}
public void move(){
x = x - player.playerSpeed;
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, width, height);
}
public Rectangle bounds(){
return (new Rectangle(x, y, width, height));
}
public int getX() {
return x;
}
}
Screen.java
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Screen extends JPanel implements ActionListener, KeyListener{
Player player = new Player();
ObstacleHole obstacleHole = new ObstacleHole();
public Screen(){
addKeyListener(this);
setDoubleBuffered(true);
setFocusable(true);
Timer tick = new Timer(5, this);
tick.start();
}
public void actionPerformed(ActionEvent e) {
repaint();
player.move();
obstacleHole.move();
System.out.println(player.getXElapsed());
}
public void paint(Graphics g){
super.paint(g);
player.paint(g);
obstacleHole.paint(g);
if(obstacleHole.getX() <= 0){
obstacleHole.paint(g);
}
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if(player.jumpReady){
if(key == KeyEvent.VK_UP){
player.dy = -1;
player.jumpReady = false;
}
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
}
Player.java
import java.awt.Color;
import java.awt.Graphics;
public class Player {
int x;
int y;
int dx;
public int xElapsed = 0;
public int dy;
int width = 64;
int height = 64;
public int playerSpeed = 3;
public boolean isMoving = true;
public boolean hasJumped = false;
public boolean jumpReady = true;
public Player(){
x = 150;
y = 250;
}
public void move(){
x = x + dx;
y = y + dy;
xElapsed++;
if(hasJumped == true){
dy = -1;
}
if(y == 150){
dy = 1;
}
if(y == 250){
dy = 0;
jumpReady = true;
}
}
public void paint(Graphics g){
g.setColor(Color.RED);
g.fillRect(x, y, width, height);
}
public int getX(){
return x;
}
public int getY(){
return y;
}
public int getXElapsed(){
return xElapsed;
}
}
In your code you are painting obstacleHole, then when the x value of obstacleHole is less than or equal to 0, you draw it again. All you are doing is sending two calls to the paint() method of the same object.
If you want to paint a second one, you will need to create another object. Or, alternatively, move the original object back onto the screen after it leaves.
It is hard to give you sample code when you have provided so little context, but try something like this:
MyObject obstacleHoleA = new MyObject();
MyObject obstacleHoleB = new MyObject();
obstacleHoleA.paint(g);
if(obstacleHoleA.getX() <= 0){
obstacleHoleB.paint(g);
}
Or this:
obstacleHole.paint(g);
if(obstacleHole.getX() <= 0){
obstacleHole.setX(randomValueUpToAMaxOfCertainValue);
}
Edit: There are a lot of things I would do a lot differently with the above code, but they are outside the scope of the question.
Try this for your ObstacleHole class:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.util.Random;
public class ObstacleHole {
Player player = new Player();
Random position = new Random();
int x;
int y;
int dx = 1;
int width = 100;
int height = 100;
public ObstacleHole(){
x = getNewPosition();
y = 250;
}
public void move(){
x = x - player.playerSpeed;
if(x < 0 - width) {
x = getNewPosition();
}
}
public void paint(Graphics g){
g.setColor(Color.BLACK);
g.fillRect(x, y, width, height);
}
public Rectangle bounds(){
return (new Rectangle(x, y, width, height));
}
public int getX() {
return x;
}
private int getNewPosition() {
return 200 + position.nextInt(300);
}
}
Note the change to the constructor and move() method, along with the new method getNewPosition().
I believe the code will speak for itself, but in general the point of the code is the have a Map class that will take in an array of BufferedImages, x values, and y values, to compose a map of many layers (first layer being the BufferedImage array at 0, starting at the x value at 0 and the y value at 0, and so on). The main job of the map class, is to take each pixel of each image and convert them to Block Objects, which are just simply rectangles with a color (Includes a BufferedImage, because after it works, I will replace the color with the Image. Also includes an integer to specify which layer (1 being index 0) its allowed on with 0 meaning it can exist among all layers). In the end, when I call Render() on a Map object, the map object should do all the work in rendering the blocks into the correct positions. The largest problem with all of this is that I get no sytax or compiler errors, so my logic is what is messed up and I can not figure it out!
Thanks in advance, and if the question is confusing please tell me!
The Map Class:
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
public class Map {
private int width;
private int height;
public int getWidth() { return width; }
public int getHeight() { return height; }
private int xPos;
private int yPos;
public int getX(int i)
{
return xPos;
}
public int getY(int i)
{
return yPos;
}
public void setPosition(int x, int y) { xPos = x; yPos = y; }
private int[] xStarts;
private int[] yStarts;
private ArrayList<BufferedImage> layersList = new ArrayList<BufferedImage>();
public void addLayer(BufferedImage image) { layersList.add(image); }
public void setLayer(int i, BufferedImage image) { layersList.set(i, image); }
private Block[][][] blocksArray;
private boolean beenInitialized = false;
public Map(BufferedImage[] images, int[] x, int[] y){
for (BufferedImage image : images){
layersList.add(image);
xStarts = x;
yStarts = y;
}
}
public void initialize(){
int widthMax = 0;
int heightMax = 0;
for (BufferedImage image : layersList){
if (image.getHeight() > heightMax) { heightMax = image.getHeight(); }
if (image.getWidth() > widthMax) { widthMax = image.getWidth(); }
}
width = widthMax;
height = heightMax;
blocksArray = new Block[layersList.size()][width][height];
for (int i = 0; i < layersList.size(); i++){
int currentLayer = i;
for (int y = 0; y < layersList.get(i).getHeight(); y++){
for (int x = 0; x < layersList.get(i).getWidth(); x++){
int colorCode = layersList.get(i).getRGB(x, y);
boolean error = true;
Block b = null;
for (int c = 0; c < Block.BLOCKS.size(); c++){
if (Block.BLOCKS.get(i).getColorCode() == colorCode && (Block.BLOCKS.get(i).getLayerCode() == currentLayer || Block.BLOCKS.get(i).getLayerCode() == 0)){
b = Block.BLOCKS.get(c);
error = false;
}
}
if (!error){
blocksArray[currentLayer][x][y] = b;
} else {
Block bb = new Block(false, colorCode);
bb.initialize();
blocksArray[currentLayer][x][y] = bb;
}
}
}
}
beenInitialized = true;
}
public void render(Graphics2D g2d){
if (beenInitialized){
for (int i = 0; i < layersList.size(); i++){
for (int y = yStarts[i]; y < layersList.get(i).getHeight() + yStarts[i]; y += Block.SIZE){
int currentY = 0;
for (int x = xStarts[i]; x < layersList.get(i).getWidth() + xStarts[i]; x += Block.SIZE){
int currentX = 0;
blocksArray[i][currentX][currentY].setPosition(x, y);
blocksArray[i][currentX][currentY].render(g2d);
currentX ++;
}
currentY++;
}
}
}
}
public void updatePosition(int x, int y){
xPos += x;
yPos += y;
}
}
The Block Class:
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.util.ArrayList;
public class Block {
public static final int SIZE = 32;
public static final boolean DEBUG = true;
public static ArrayList<Block> BLOCKS = new ArrayList<Block>();
private Color debugColor;
public Color getColor() { return debugColor; }
public void setColor(Color color) { debugColor = color; }
private BufferedImage blockIcon;
public BufferedImage getIcon() { return blockIcon; }
public void setIcon(BufferedImage icon) { blockIcon = icon; }
private int xPos;
private int yPos;
public int getX() { return xPos; }
public int getY() { return yPos; }
public void setPosition(int x, int y) { xPos = x; yPos = y; }
private Rectangle blockShape;
public Rectangle getShape() { return blockShape; }
private int colorCode;
public int getColorCode() { return colorCode; }
private boolean colides;
public boolean doesColide() { return colides; }
private int layerCode;
public int getLayerCode() { return layerCode; }
private boolean beenInitialized = false;
public Block(boolean colides, int layerCode){
this.colides = colides;
this.layerCode = layerCode;
}
public void initialize(){
blockShape = new Rectangle(xPos, yPos, SIZE, SIZE);
int r = (colorCode >> 16) & 0x000000FF;
int g = (colorCode >> 8) & 0x000000FF;
int b = (colorCode) & 0x000000FF;
debugColor = new Color(r, g, b);
BLOCKS.add(this);
beenInitialized = true;
}
public void render(Graphics2D g2d){
if (beenInitialized){
if (DEBUG){
g2d.setColor(debugColor);
if (colides){
g2d.fill(blockShape);
} else {
g2d.draw(blockShape);
}
} else{
}
}
}
}
And finally the Game Class (I threw this together JUST to show a window for testing):
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Game extends JFrame{
public Game(){
super("Test");
try{
layer1 = ImageIO.read(getClass().getResourceAsStream("/layer1.png"));
layer2 = ImageIO.read(getClass().getResourceAsStream("/layer2.png"));
} catch (Exception ex) { ex.printStackTrace(); }
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
setLayout(new BorderLayout());
add(new panel(), BorderLayout.CENTER);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args){
new Game();
}
private int[] xStartPositions = {0, 0};
private int[] yStartPositions = {0, 0};
private BufferedImage layer1;
private BufferedImage layer2;
private BufferedImage[] imageArray = {layer1, layer2};
private Map map;
public class panel extends JPanel{
public panel(){
setMinimumSize( new Dimension(1200, 675));
setMaximumSize( new Dimension(1200, 675));
setPreferredSize( new Dimension(1200, 675));
setVisible(true);
map = new Map(imageArray, xStartPositions, yStartPositions);
}
public void paint(Graphics g){
Graphics2D g2d = (Graphics2D) g;
map.render(g2d);
}
}
}
The initialize method of Map is never called, therefore Map will never render...
Some feedback...
Don't ever override paint, use paintComponent instead (it's very rare that you would need to override paint...
Make sure you are calling super.paintXxx - there's a lot of important working going on in the background that you don't want to miss or replicate...
Instead of extending from a top level container like JFrame, start by extending from JPanel and add this to a frame you create instead
Beware of static variables, this might cause you more problems ;)
You may also want to have a read through Initial Threads
So I have an assignment for University. The concept was that we were to complete some class hierarchy stuff. Basically it was stuff to allow us to draw different shapes.
I can successfully draw each shape; where I need it to be and how big I need it to be, like required... the part I'm having trouble on is this compound hierarchy.
Basically we're supposed to have a new class called Compound.java and extending from that we are supposed to have three other classes, House, tree, and earth; each of which are supposed to take the shape objects we created (Rectangle, Square, Line, Oval and Circle) and draw the required pictures as denoted by the class name.
Where I am having the problem is in the house class; for example: I can get it to draw one rectangle but when I try to get it to draw the second rectangle after, it basically forgets about the first and only draws the second!
We haven't had any practice with the Graphics stuff so I don't know any methods or anything that I can call to draw then continue in the House constructor.
I understand why it overwrites the first rectangle, when the House constructor is called, it runs through all the stuff in the constructor, then goes back up to the Compound.java and draws it using the draw(Graphics g) method....
But I don't know how to fix it! Any help would be appreciated... it's due tomorrow.
Here's all the code:
Shape.java:
import java.awt.*;
public abstract class Shape {
int initX, initY;
Color fillColour;
public Shape() {
initX = 0;
initY = 0;
}
public Shape(int x, int y) {
initX = x;
initY = y;
}
public void setInitX (int x) {
initX = x;
}
public void setInitY (int y) {
initY = y;
}
public abstract void draw(Graphics g);
public abstract double Area();
public abstract double Perimeter();
public void Move(int deltaX, int deltaY){
//future work
}
}
ClosedShape.java :
import java.awt.Graphics;
public abstract class ClosedShape extends Shape {
boolean polygon;
int numPoints;
int[] xVertices;
int[] yVertices;
int x,y,width, height;
public ClosedShape(boolean isPolygon, int numPoints) {
super(0,0);
this.polygon = isPolygon;
this.numPoints = numPoints;
}
public ClosedShape(boolean isPolygon, int numPoints, int[] x, int[] y) {
super(x[0],y[0]);
this.polygon = isPolygon;
if (isPolygon) {
this.numPoints = numPoints;
xVertices = new int[numPoints]; // error check? if x.length == numPoints
for (int i = 0; i < x.length; i++) { // make copy of array: why?
xVertices[i] = x[i];
}
yVertices = new int[numPoints]; // error check? if y.length == numPoints
for (int i = 0; i < y.length; i++) { // make copy of array
yVertices[i] = y[i];
}
}
else { // its an oval - define bounding box
this.numPoints = 4;
this.x = x[0];
this.y = y[0];
width = x[1];
height = y[1];
}
}
public void setXYCoords(int[] x, int[] y){
this.xVertices = x;
this.yVertices = y;
}
// Gives access to the width attribute
public void setWidth(int width){
this.width = width;
}
// Gives access to the height attribute
public void setHeight(int height) {
this.height = height;
}
public void draw(Graphics g) {
if (polygon) {
g.drawPolygon(xVertices, yVertices, numPoints);
}
else {
g.drawOval(x, y, width, height);
}
}
public abstract double Area();
public abstract double Perimeter();
}
Rectangle.java :
public class Rectangle extends ClosedShape
{
public Rectangle(int x, int y, int width, int height)
{
super(true, 4);
setWidth(width);
setHeight(height);
int [] arrayX = new int[4];
arrayX[0] = x;
arrayX[1] = (x+width);
arrayX[2] = (x+width);
arrayX[3] = x;
int [] arrayY = new int[4];
arrayY[0] = y;
arrayY[1] = y;
arrayY[2] = y+height;
arrayY[3] = y+height;
setXYCoords(arrayX, arrayY);
}
public double Area()
{
return 0;
}
public double Perimeter()
{
return 0;
}
}
Compound.java :
import java.awt.*;
import java.awt.Graphics;
public class Compound
{
boolean polygon;
int[] xVertices;
int[] yVertices;
int initX, initY;
Color fillColour;
public void setXYCoords(int[] x, int[] y)
{
this.xVertices = x;
this.yVertices = y;
}
public void draw(Graphics g)
{
if (polygon) {
g.drawPolygon(xVertices, yVertices, 4);
}
else {
g.drawOval(1, 1, 1, 1);
}
}
}
House.java :
import java.awt.*;
import java.awt.Graphics;
public class House extends Compound
{
public House(int x, int y, int width, int height)
{
int [] arrayX = new int[4];
arrayX[0] = x;
arrayX[1] = (x+width);
arrayX[2] = (x+width);
arrayX[3] = x;
int [] arrayY = new int[4];
arrayY[0] = y;
arrayY[1] = y;
arrayY[2] = y+height;
arrayY[3] = y+height;
setXYCoords(arrayX, arrayY);
this.polygon = true;
Rectangle house = new Rectangle(x, y, width, height);
int [] arrayXTwo = new int[4];
arrayXTwo[0] = x+(width/4);
arrayXTwo[1] = x+(2*(width/4));
arrayXTwo[2] = x+(2*(width/4));
arrayXTwo[3] = x+(width/4);
int [] arrayYTwo = new int[4];
arrayYTwo[0] = y+(height/4);
arrayYTwo[1] = y+(height/4);
arrayYTwo[2] = y+height;
arrayYTwo[3] = y+height;
setXYCoords(arrayXTwo, arrayYTwo);
this.polygon = true;
Rectangle door = new Rectangle(x, y, width, height);
}
}
From your sample code, there is no way that to "add" any shapes to the Compound class. From your description, Compound should be a "container" of shapes. Something more along the lines of...
public class Compound
{
private List<Shape> shapes;
public Compound() {
shapes = new ArrayList<Shape>(25);
}
public void addShape(Shape shape) {
shapes.add(shape);
}
public Iterable<Shape> getShapes() {
return shape;
}
public void draw(Graphics g) {
for (Shape shape : shapes) {
shape.draw(g);
}
}
}
Now you need to decide, where is it best to associate the Color with the Shape should it be defined for the shape itself? That means you can't reuse the shape. Or with the Compound shape?
I am trying to draw a figure by constructing it out of single lines. This has worked for me for a while, but after adding a few textfields and a button to control some parameters it started beeing crazy and drawing the area around the button on the area of my figure. I tried scanning the code for the source, and it seems its BETWEEN the Repaint() method and the actual content of the method, as the bug continues to occur even when I empty the method drawComponent(), but doesnt occur whenever I remove the call of repaint(). When triggering repaint it first draws the button and a small area around it on the frame(overlapping some text fields), and then draws the actual figure on that area. The full code snippets are listed below:
base class for angles:
package customUtilitys;
public class Angle {
private double xRot,yRot,zRot;
public Angle(){}
public Angle(double x,double y,double z){
xRot = x;
yRot = y;
zRot = z;
}
public Angle(Angle ang){
setAngle(ang);}
public void setAngle(double x,double y, double z){
while(x >= 360){
x = x - 360;
}
while(y >= 360){
y = y - 360;
}
while(z >= 360){
z = z - 360;
}
xRot = x;
yRot = y;
zRot = z;
}
public void setAngle(Angle ang){
xRot = ang.getXAngle();
xRot = ang.getYAngle();
zRot = ang.getZAngle();
}
public double getXAngle(){
return xRot;
}
public double getYAngle(){
return yRot;
}
public double getZAngle(){
return zRot;
}
}
base class for 3D points:
package customUtilitys;
import java.awt.Point;
public class Point3D extends Point {
private static final long serialVersionUID = 1242102585768332716L;
public int x,y,z;
public Point3D(){};
public Point3D(double x,double y,double z){
setLocation(x,y,z);
}
public Point3D(int x, int y,int z){
setLocation(x,y,z);
}
public void setLocation(int x,int y,int z){
this.x = x;
this.y = y;
this.z = z;
}
public void setLocation(double x,double y,double z){
this.x = (int)Math.round(x);
this.y = (int)Math.round(y);
this.z = (int)Math.round(z);
}
public Point3D add(Point3D P){
return new Point3D(x+P.x,y+P.y,z+P.z);
}
public Point3D rotate(Angle A){
double xA = A.getXAngle();
double yA = A.getYAngle();
double zA = A.getZAngle();
Matrix TransformationMatrixX = new Matrix(new double[][]{{1,0,0},{0,Math.cos(xA),-Math.sin(xA)},{0,Math.sin(xA),Math.cos(xA)}});
Matrix TransformationMatrixY = new Matrix(new double[][]{{Math.cos(yA),0,-Math.sin(yA)},{0,1,0},{Math.sin(yA),0,Math.cos(yA)}});
Matrix TransformationMatrixZ = new Matrix(new double[][]{{Math.cos(zA),-Math.sin(zA),0},{Math.sin(zA),Math.cos(zA),0},{0,0,1}});
Matrix Pos = new Matrix(new double[][]{{x,y,z}});
Pos = Pos.times(TransformationMatrixX);
Pos = Pos.times(TransformationMatrixY);
Pos = Pos.times(TransformationMatrixZ);
Point3D P = new Point3D(Pos.getData()[0][0],Pos.getData()[0][1],Pos.getData()[0][2]);
return P;
}
public Point transform(){
int x2D = (int)Math.round(x/(z+4));
int y2D = (int)Math.round(y/(z+4));
Point P = new Point(x2D,y2D);
return P;
}
}
Importand Code:
code of the figure(unfinished Cube) that gets drawn:
package customUtilitys;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import javax.swing.JPanel;
#SuppressWarnings("serial")
public class Cuboid extends JPanel {
Angle angle = new Angle();
public Point3D A=new Point3D(),B=new Point3D(),C=new Point3D(),D=newPoint3D(),E=new Point3D(),F=new Point3D(),G=new Point3D(),H=new Point3D();
public Point3D center = new Point3D(8,8,8);
public Cuboid(){}
public void setCorners(Point3D A,Point3D B,Point3D C,Point3D D,Point3D E,Point3D F,Point3D G,Point3D H){
this.A=A;
this.B=B;
this.C=C;
this.D=D;
this.E=E;
this.F=F;
this.G=G;
this.H=H;
}
public void setCenter(Point3D P){
center = P;
}
public void setAngle(double X,double Y, double Z) {
angle.setAngle(X,Y,Z);
}
//The paint method of the Cube. Possible source of the problem
public void paintComponent(Graphics g){
Point a2 = center.add(A.rotate(angle)).transform();
Point b2 = center.add(B.rotate(angle)).transform();
Point c2 = center.add(C.rotate(angle)).transform();
Point d2 = center.add(D.rotate(angle)).transform();
Point e2 = center.add(E.rotate(angle)).transform();
Point f2 = center.add(F.rotate(angle)).transform();
Point g2 = center.add(G.rotate(angle)).transform();
Point h2 = center.add(H.rotate(angle)).transform();
g.setColor(Color.BLACK);
g.drawLine(a2.x*10,a2.y*10,b2.x*10,b2.y*10);
g.drawLine(b2.x*10,b2.y*10,c2.x*10,c2.y*10);
g.drawLine(c2.x*10,c2.y*10,d2.x*10,d2.y*10);
g.drawLine(d2.x*10,d2.y*10,a2.x*10,a2.y*10);
g.drawLine(e2.x*10,e2.y*10,f2.x*10,f2.y*10);
g.drawLine(f2.x*10,f2.y*10,g2.x*10,g2.y*10);
g.drawLine(g2.x*10,g2.y*10,h2.x*10,h2.y*10);
g.drawLine(h2.x*10,h2.y*10,e2.x*10,e2.y*10);
g.drawLine(a2.x*10,a2.y*10,e2.x*10,e2.y*10);
g.drawLine(b2.x*10,b2.y*10,f2.x*10,f2.y*10);
g.drawLine(c2.x*10,c2.y*10,g2.x*10,g2.y*10);
g.drawLine(d2.x*10,d2.y*10,h2.x*10,h2.y*10);
}
}
Main class:
package customUtilitys;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;
import javax.swing.JButton;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
#SuppressWarnings("serial")
public class UtilityTest extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UtilityTest frame = new UtilityTest();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public UtilityTest() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 354);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel panel = new JPanel();
panel.setBounds(5, 5, 424, 310);
contentPane.add(panel);
panel.setLayout(null);
//{...Shortened Code...}
//Definition of the Cube object and following repaint call. Hightest chance of problem here
final Cuboid Cube = new Cuboid();
panel.add(Cube);
Cube.setBounds(50,50,160,160);
Cube.invalidate();
Cube.repaint();
JButton btnDraw = new JButton("Draw");
btnDraw.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
//{...Shortened Code...}
Cube.invalidate();
Cube.repaint();
}
});
btnDraw.setBounds(240, 241, 80, 23);
panel.add(btnDraw);
}
}
You're calling cube.invalidate() which invalidates the component
public void invalidate()
Invalidates the container.
If the LayoutManager installed on this container is an instance of the LayoutManager2 interface, then the LayoutManager2.invalidateLayout(Container) method is invoked on it supplying this Container as the argument.
Afterwards this method marks this container invalid, and invalidates its ancestors.
You have to call revalidate()
Cube.revalidate();//not invalidate()