EDIT: to clarify, one of my requirements is to use a single array.
I am having trouble storing multiple variables to a single element in an array. We are creating a really simple program to mimic Microsoft Paint. One of the requirements is to store each element I draw in to an array so that the 'paint' method repaints the drawings each time the windows is minimized and then redisplayed. Here are the requirements
We are to assume a max size for the array is 20.
Each element should include 5 variables:
char shape (l for line, r for rectangle, c for circle)
Start x value
Start y value
width (rectangle), or ending x (line), or radius (circle)
height (rectangle), or ending y (line), or radius (circle)
Here is my code for the array class:
class storeDraws {
final int MAXSIZE = 20;
static int S[];
static int n; //number of draws user makes
static char shape;
static double px, py, w, h;
storeDraws () {
S = new int [MAXSIZE];
n = 0;
shape = 'l';
px = 0;
py = 0;
w = 0;
h = 0;
}
}
I have read a few places that I can input the array as (using the mouseReleased(MouseEvent e) method:
storeDraws[] input = new storeDraws{value, value, value, value, value};
But I don't think that would work for what I am trying to do with the 'paint' method to redraw the shapes. I thought I could somehow pass it using the standard format of S[n] = (char, double, double, double, double), but I get warning that this is illegal.
Edit 8:30 am
I got this part working. In my class here is my code now.
class storeDraws {
static char shape;
static int px, py, w, h;
storeDraws () {
shape = 'l';
px = 0;
py = 0;
w = 0;
h = 0;
}
}
I then declared this in the DrawPanel class:
private storeDraws[] store = new storeDraws[20];
private int n = 0;
And mouseReleased method of DrawPanel:
public void mouseReleased(MouseEvent e) {
if (drawShape == "line") {
store[n].shape = 'l';
store[n].px = p1.x;
store[n].py = p1.y;
store[n].w = p3.x;
store[n].h = p3.y;
n++;
}
And paint:
public void paint(Graphics g) {
for (int i = 0; i < n; i++) {
if (store[i].shape == 'l')
g.drawLine(store[n].px, store[n].py, store[n].w, store[n].h);
But if I draw 6 lines it only repaints the last line.
I think you need to separate some of the functionality you want. You can have a class for each of the elements and then store instances of the class in an array of DrawingElement objects.
So you'd do something like this:
DrawingElement[] drawing = new DrawingElement[20];
DrawingElement circle = new DrawingElement('c', 10, 10, 10, 10);
DrawingElement rect = new DrawingElement('r', 20, 10, 10, 10);
drawing[0] = circle;
drawing[1] = rect;
Note: If you need to be able to get the number of objects in the array (variable n in your code) you may want to use some implementation of
a Linked List (which has a size() method) and do some check when adding elements to make sure you don't add past the max of 20.
Example with LinkedList:
LinkedList<DrawingElement> drawing = new LinkedList<DrawingElement>();
DrawingElement circle = new DrawingElement('c', 10, 10, 10, 10);
DrawingElement rect = new DrawingElement('r', 20, 10, 10, 10);
drawing.add(circle);
drawing.add(rect);
int n = drawing.size(); //will be 2
The Drawing Element Class:
public class DrawingElement
{
char shape;
double px, py, w, h;
public DrawingElement(char shape, double px, double py, double w, double h)
{
this.shape = shape;
this.px = px;
this.py = py;
this.w = w;
this.h = h;
}
//Add getters and setters (accessors and mutators) for class variables
}
I think you should use collection for this purpose.Create array, store values
then add each array object in collection(list).
you can use arraylist instead of array. this will help you to store different variable.
If there is need of using only array you can use object array
Sample Code
object a[]= {'a',10,10.2,10.3,10.4,10.5}
Please refer ArrayList
In your case it would be better to use Java Collection(ArrayList) rather than Array.
First point, We cannot store different types of variables values into an Array.
An array is a container object that holds a fixed number of values of a single type.
Here you are trying to store multiple type of variables into integer array.
see this link:
https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
To overcome this drawback, We have Collection API introduced with JDK1.5
Refer this link:
http://docs.oracle.com/javase/tutorial/collections/index.html
Related
I have declared my variables to get random values with SecureRandom class.
Inside my paintComponent method I have a for loop in case to creating many random shapes.
If the Random value equals to zero, draw a rectangle shape else draw an oval.
When I run my project I get only one shape because all my variables are outside of my loop.
Any hints please how to achieve that scenario ( to create many random shapes ) ?
Thanks.
My declarations :
SecureRandom RC = new SecureRandom();
int r = RC.nextInt();
int g2 = RC.nextInt();
int b = RC.nextInt();
int cl = (r + g2 + b) / 3;
int choice = RC.nextInt(2);
int x = RC.nextInt(230);
int y = RC.nextInt(250);
int w = RC.nextInt(115);
int h = RC.nextInt(125);
My paintComponent method :
for(int i = 1; i <= 10; i++)
{
super.paintComponent(g);
Color mc = new Color(cl);
if(choice == 0)
{
g.setColor(mc);
g.fillRect(x, y, w, h);
}
else
{
g.setColor(mc);
g.fillOval(x, y, w, h);
}
}
When I run my project I get only one shape because all my variables are outside of my loop.
That's correct. You need to call choice = RC.nextInt(2); inside the loop, and based on the value you get back, create either a new oval or rectangle.
It would probably be a good idea (although not strictly necessary) to write separate functions for creating random ovals and rectangles. That way your loop doesn't have to be cluttered with this code.
You need to place all the variables you are using to create your random shape into your for loop so that after each iteration of the for-loop you create a new random value for each variable. Simply take all your variables that you need and place them inside the for-loop that will only be used inside the for-loop. Any variable you want to be the same throughout, you initialize outside before the for-loop.
The following code creates a completely random rectangle or oval each iteration
for(int i = 1; i <= 10; i++)
{
int r = RC.nextInt();
int g2 = RC.nextInt();
int b = RC.nextInt();
int cl = (r + g2 + b) / 3;
int x = RC.nextInt(230);
int y = RC.nextInt(250);
int w = RC.nextInt(115);
int h = RC.nextInt(125);
super.paintComponent(g);
Color mc = new Color(cl);
int choice = RC.nextInt(2);
if(choice == 0)
{
g.setColor(mc);
g.fillRect(x, y, w, h);
}
else
{
g.setColor(mc);
g.fillOval(x, y, w, h);
}
}
I have experimented and I can't find a way to parse an array of Integers and a Matrix of doubles to a la4j matrice/vector object.
public void fillData(int[][] data2D, int height, int width) throws IOException{
int[] data = initializeData(height, width);
double [][] coordinates = initializeDataCoordinates(height, width);
Matrix a = new Basic2DMatrix();
int index1d = 0;
for(int row = 0; row < height; row++){
for(int col = 0; col < width; col++){
int y = col+1;
int x = row+1;
//System.out.println("Current X: " + x);
//System.out.println("Current Y: " + y);
double xPow = Math.pow(x, 2);
double yPow = Math.pow(y, 2);
coordinates[row][0] = xPow*yPow;
coordinates[row][1] = x*yPow;
coordinates[row][2] = yPow;
coordinates[row][3] = xPow*y;
coordinates[row][4] = x*y;
coordinates[row][5] = y;
coordinates[row][6] = xPow;
coordinates[row][7] = x;
coordinates[row][8] = 1;
a.add((double)data2D[row][col]);
data[index1d] = data2D[row][col];
index1d++;
}
}
}
As you can see, I try to use the add method of the la4j lib but the matrice stays empty. My goal is to parse the whole content of double[][] coordinates and int[] data to la4j matrice and vector, respectivelly.
I have also tried parsing these to a CSV file but the scientific notation (due to extremely big numbers in my coordinates matrix) I can't parse it properly.
Any tips and ideas?
Here is the thing. First, you create 0x0 matrix with just call to the constructor new Basic2DMatrix(). Second, matrix.add is addition operation not insertion into the matrix (like matrix plus other matrix, or matrix plus value in your case). Calling matrix.add(value) adds given value to all the cells. In your case there is no cells in your matrix = nothing happened. All you need to do is call the constructor and pass the coordinates array there.
Matrix a = new Basic2DMatrix(coordinates); // easy-peasy
You can also use public access methods like get/set to manually set every element.
One of the exercises in my Java textbook says "Consult the API documentation to find methods for:
Computing the smallest rectangle that contains two given rectangles. • Returning a random floating-point number."
I've looked at the Java API for class Rectangle, but I can't find one that computes the smaller rectangle. The closest methods I've found are union and bounds, but I don't think that's correct.
I found min from the Java Math class and wrote a test program to see if it would work, but min cannot have arguments of rectangles.
Here's the code I wrote:
import java.awt.Rectangle;
public class RectangleSize {
public static void main(String[] args)
{
Rectangle a = new Rectangle(5, 5, 10, 10);
Rectangle b = new Rectangle(5, 5, 20, 20);
int min = Math.min(a, b); //In Eclipse, I get an error.
System.out.println(min);
}
}
I am studying java recently using the textbook of Big Java Early Object. I found the same question in chapter 2. Eventually I found the answer by looking at Java SE8 API list.
First use method .add() to combine 2 rectangles.
Note: actually, this combined one is already the one you need. But you can get a new rectangle (same size and location) at step 2.
Them use .getBounds() to get the smallest rectangle containing the combined one.
.
import java.awt.*;
public class RectangleTester01 {
public static void main(String[] args) {
Rectangle box1 = new Rectangle(10, 20, 40, 40);
Rectangle box2 = new Rectangle(20, 30, 60, 60);
box1.add(box2);
System.out.println(box1);
Rectangle box3 = box1.getBounds();
System.out.println(box3);
}
}
output is:
java.awt.Rectangle[x=10,y=20,width=70,height=70]
java.awt.Rectangle[x=10,y=20,width=70,height=70]
You want to use Rectangle.contains . You would be given many rectangles. You'd need to loop through all the rectangles and see if it contains the two rectangles given. If it does you should calculate the size of that rectangle. In the end you take the rectangle with the smallest size.
public Rectangle getSmallest(Rectangle one, Rectangle two, Rectangle[] rectangles) {
Rectangle smallest = null;
double area = Double.MAX_VALUE;
for (Rectangle r: rectangles) {
if (r.contains(one) && r.contains(two)) {
calculatedArea = r.getWidth() * r.getHeight();
if (calculatedArea < area) {
area = calculatedArea;
smallest = r;
}
}
}
return r;
}
I think the method you're looking for is Rectangle2D.createUnion. It combines two rectangles to make a bigger one that contains both with a minimum of extra space.
Here is another question to find a rectangle which contains a list of rectangles.find-smallest-area-that-contains-all-the-rectangles.
Here is my brute answer which is not accuracy and did not try the union function of Rectengle and also the createUnion(Rectengle2D r) as well.
Math.min can help find the minimum number in a number array. You may write a similar one for Rectangle. This is something from 1D to 2D in my mind. BTW, it would be much interesting if you extends it to 3D or nD objects calculation.
package com.stackoverflow.q26311076;
import java.awt.Rectangle;
public class Test {
public static void main(String[] args) {
Rectangle a = new Rectangle(5, 5, 10 , 10);
Rectangle b = new Rectangle(5, 5, 20 , 20);
Rectangle min = getMin(a, b) ;
// ...
}
public static Rectangle getMin(Rectangle a, Rectangle b) {
//find the min range in X.
{
double x1 = a.getX();
double x2 = a.getX() + a.getWidth();
double x3 = b.getX();
double x4 = b.getX() + b.getWidth();
double minX1 =Math.min( Math.min(x1, x2), Math.min(x3, x4)) ;
double maxX1 =Math.max( Math.max(x1, x2), Math.max(x3, x4)) ;
}
//find the min range in Y.
{
double y1 = a.getY();
double y2 = a.getY() + a.getHeight();
double y3 = b.getY();
double y4 = b.getY() + b.getHeight();
double minY1 =Math.min( Math.min(y1, y2), Math.min(y3, y4)) ;
double maxY1 =Math.max( Math.max(y1, y2), Math.max(y3, y4)) ;
}
//build new rectangle with X & Y
Rectangle r = new Rectangle();
r.setRect(minX1, minY1, maxX1 - minX1, maxY1 - minY1);
return r;
}
}
Can someone please tell me what's wrong with this simple program? I'm getting output as "0".
package myConst;
public class Doconstructor
{
int length,width;
Doconstructor(int x, int y)
{
int area;
area = length * width;
System.out.println("area ="+area);
}
}
class work
{
public static void main(String args[])
{
Doconstructor d1 = new Doconstructor(10, 15);
}
}
Doconstructor d1 = new Doconstructor(10, 15);
// you are assigning values for x and y
But
Doconstructor (int x,int y)
{
int area; // you are never use x and y values for calculation
area = length *width; // so area remain 0 since current length and width is 0
System.out.println("area ="+area);
}
You need to change your code as follows.
Doconstructor (int x,int y)
{
int area;
this.length=x;
this.width=y;
area = length *width;
System.out.println("area ="+area);
}
Edit like this:-
package myConst;
public class Doconstructor
{
int length,width;
Doconstructor(int x, int y)
{
int area;
this.length=x;//Using this for current object
this.width=y;//Using this for current object
area = length * width;
System.out.println("area ="+area);
}
}
class work
{
public static void main(String args[])
{
Doconstructor d1 = new Doconstructor(10, 15);
}
}
Your output will be:
area =150
Must read this :
http://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
You are not setting the values of length and width and by default they are both 0. You might have to do this:
Doconstructor(int x, int y){
int area;
area = x * y;
length = x;
width = y;
System.out.println("Area = "+area);
}
You're not using the variable values you pass to the constructor in it but rather the length and width values that have been initialized to 0. You want area = x * y; instead.
The length and width fields are implicitly initialized to 0. Multiply them and you get 0.
I think what you want is
length = y ;
width = x ;
int area = length * width ;
System.out.println("area ="+area);
You have this:
public class Doconstructor {
int length,width;
Doconstructor (int x,int y)
{
int area;
area = length *width;
System.out.println("area ="+area);
}
}
At no point do you set length or width equal to anything. Their initial values are 0 and your program is doing precisely what you told it to do. area = length * width = 0 * 0 = 0.
You also are not doing anything with the x or y that you passed to the constructor, but this probably was not your intention. When writing programs, you basically need to clearly instruct the computer to do what you want to do. It's not going to guess what you want. If you ignore x and y, and don't assign any values to length or width, then that is precisely what will happen and you cannot be surprised when you see the results you see.
you are writing int length,width at class level so length and width are set to 0 as default.
After that in the constructor you are not setting any values to length and width so you are the values for length and width are 0.Hence area is also 0
Please check this link for list of default values
Constructors are used to create objects and to set the attributes. You are not setting the attributes in your constructor. Here is how your constructor should look like.
Doconstructor(int x, int y){
length = x;
width = y;
}
Secondly you are mixing the logic of a constructor and a method. You are doing the calculation of area, which seems to be a perfect fit for another method in your class. so better move that logic in a separate method:
public int calculateArea() {
int area;
area = x * y;
return area;
}
Finally create an object using constructor to set the attributes length and width. And then call calculateArea method to do the business logic of calculating area.
public static void main(String args[]){
Doconstructor d1 = new Doconstructor(10, 15); // create object and set length & width
d1.calculateArea();
}
you are not assigning the value of x and y to the variables width and length. The default value of width and length are (int) 0. Thats why you are getting the output (0*0=0). First assign the values to the variables or use "area=x*y;" .
So a section of my assignment is to make a triangle class to be linked to various buttons...but I'm not sure how to make one in eclipse. The specific instructions say this:
Create a triangle class
Data fields: Point[] coords;
constructors
Implement all abstract methods defined in superclass
Getters and setters for each data field
Override public void paint(Graphics arg0) method
I have everything set up in the other classes..except for the triangle class. I'm confused on how to create a triangle using an array of points...Do I need to use Point x,y or somehow store 3 (x,y) coordinate pairs in that one array variable coords? I imagine to create it you would use drawPolygon...but I'm not certain. Any tips?
Here is an example class for Triangle
public class Triangle {
private Point[] coords;
// Null object constructor
public Triangle() {
this.coords = null;
}
// Constructor with point array
public Triangle(Point[] coords) {
this.coords = coords;
}
// Constructor with multiple points
public Triangle(Point a, Point b, Point c) {
this.coords = new Point[3];
coords[0] = a;
coords[1] = b;
coords[2] = c;
}
// The actual paint method
public void paint(Graphics arg0) {
// Setup local variables to hold the coordinates
int[] x = new int[3];
int[] y = new int[3];
// Loop through our points
for (int i = 0; i < coords.length; i++) {
Point point = coords[i];
// Parse out the coordinates as integers and store to our local variables
x[i] = Double.valueOf(point.getX()).intValue();
y[i] = Double.valueOf(point.getY()).intValue();
}
// Actually commit to our polygon
arg0.drawPolygon(x, y, 3);
}
}
Not sure what exactly this class is supposed to be extending, so nothing is marked as an override or anything, and it is missing setters and accessors, but you should be able to make it work.
Use the g.drawPolygon that takes an array of Points as it's args.
Did something similar, where I drew a polygon of three sides. Might help..
for (int i = 0; i < 3; i++){
polygon1.addPoint(
(int) (40 + 50 * Math.cos(i * 2 * Math.PI / 3)),
(int) (150 + 50 * Math.sin(i * 2 * Math.PI / 3))
);
}
g.drawPolygon(polygon1);