We used existing Java classes to create objects until now: Point and Rectangle. But it is also possible to create your own, custom class.
For example, we want to register a product with its price, we could create a class for this with String productName and int priceInCents, and use that in our code.
Product
. A new file is created and opened in the editor.public class Product { String name; int priceInCents; }
Now switch back to the Application file and copy this into your run()
method:
Product product = new Product(); product.name = "Expensive designer lamp"; product.priceInCents = 12000;
Extend this code:
ArrayList<Product> cart = new ArrayList<>();
Product product = new Product();
product.name = "Expensive designer lamp";
product.priceInCents = 12000;
cart.add(product);
Product anotherProduct = new Product();
anotherProduct.name = "Fake turd";
anotherProduct.priceInCents = 520;
cart.add(anotherProduct);
Extend the code so it calculates and shows the total price of the items in the cart. Hint:
ArrayList<Product> cart = new ArrayList<>();
Product product = new Product();
product.name = "Expensive designer lamp";
product.priceInCents = 12000;
cart.add(product);
Product anotherProduct = new Product();
anotherProduct.name = "Fake turd";
anotherProduct.priceInCents = 520;
cart.add(anotherProduct);
int sum = 0;
for (Product item : cart) {
sum = sum + item.priceInCents;
}
SaxionApp.printLine("The total is: €" + ((double)sum / 100));
Go back to the file with the Product class. You can see the fields name
and priceInCents
here. Add a new field shippingCostsInCents
with type int.
public class Product {
String name;
int priceInCents;
int shippingCostsInCents;
}
Change your program: set the shipping costs to a value for both of the products that you add to the cart. And also calculate the shipping costs total.
ArrayList<Product> cart = new ArrayList<>();
Product product = new Product();
product.name = "Expensive designer lamp";
product.priceInCents = 12000;
product.shippingCostsInCents = 625;
cart.add(product);
Product anotherProduct = new Product();
anotherProduct.name = "Fake turd";
anotherProduct.priceInCents = 520;
anotherProduct.shippingCostsInCents = 325;
cart.add(anotherProduct);
int sum = 0;
int shipping = 0;
for (Product item : cart) {
sum = sum + item.priceInCents;
shipping = shipping + item.shippingCostsInCents;
}
SaxionApp.printLine("The total is: €" + ((double)sum / 100));
SaxionApp.printLine(" plus shipping: €" + ((double)shipping / 100));
Create a new class Circle
with these fields, all ints: x, y, radius, red, green, blue.
In your program, add 150 objects of type Circle to a list. They all should have random values for x, y, radius, red, green and blue. Restrictions:
Finally draw all the circles in the list to the canvas with the correct position, size and color. Use SaxionApp.createColor()
to convert r-g-b values to a color. Use SaxionApp.setFill
to set the background color of the circles. Use SaxionApp.turnBorderOff()
to remove the ugly green border.
// the Circle class (in a separate file)
public class Circle {
int x;
int y;
int radius;
int red;
int green;
int blue;
}
// in your application run() method:
ArrayList<Circle> circles = new ArrayList<>();
while (circles.size() < 150) {
Circle c = new Circle();
c.x = SaxionApp.getRandomValueBetween(0, SaxionApp.getWidth());
c.y = SaxionApp.getRandomValueBetween(0, SaxionApp.getHeight());
c.radius = SaxionApp.getRandomValueBetween(30, 100);
c.red = SaxionApp.getRandomValueBetween(0, 255);
c.green = SaxionApp.getRandomValueBetween(0, 255);
c.blue = SaxionApp.getRandomValueBetween(0, 255);
circles.add(c);
}
SaxionApp.turnBorderOff();
for (Circle c : circles) {
Color color = SaxionApp.createColor(c.red, c.green, c.blue);
SaxionApp.setFill(color);
SaxionApp.drawCircle(c.x, c.y, c.radius);
}
Change the program and add three counters. Count the circles that are
Show all three results afterwards and decide which color won.
ArrayList<Circle> circles = new ArrayList<>();
while (circles.size() < 150) {
Circle c = new Circle();
c.x = SaxionApp.getRandomValueBetween(0, SaxionApp.getWidth());
c.y = SaxionApp.getRandomValueBetween(0, SaxionApp.getHeight());
c.radius = SaxionApp.getRandomValueBetween(30, 100);
c.red = SaxionApp.getRandomValueBetween(0, 255);
c.green = SaxionApp.getRandomValueBetween(0, 255);
c.blue = SaxionApp.getRandomValueBetween(0, 255);
circles.add(c);
}
int red = 0;
int green = 0;
int blue = 0;
SaxionApp.turnBorderOff();
for (Circle c : circles) {
Color color = SaxionApp.createColor(c.red, c.green, c.blue);
SaxionApp.setFill(color);
SaxionApp.drawCircle(c.x, c.y, c.radius);
if (c.red > c.green && c.red > c.blue) {
red++;
}
if (c.green > c.red && c.green > c.blue) {
green++;
}
if (c.blue > c.red && c.blue > c.green) {
blue++;
}
}
SaxionApp.print("Counted circles mainly red: " + red);
SaxionApp.print(", mainly green: " + green);
SaxionApp.prinLine(", mainly blue: " + blue);
if (red > green && red > blue) {
SaxionApp.printLine("RED WON", Color.RED);
}
if (green > red && green > blue) {
SaxionApp.printLine("GREEN WON", Color.GREEN);
}
if (blue > red && blue > green) {
SaxionApp.printLine("BLUE WON", Color.BLUE);
}
Classes and data go well together. Data are values stored in a file on disk. One of the formats to store data is the CSV-format. It can store one object per line, the fields are separated with a comma (,
) or semicolon (;
), depending on the program used to create it.
An example of CSV data for our Circle class:
x;y;radius;red;green;blue 350;350;200;200;200;200 200;200;105;0;0;0 200;200;100;200;200;200 200;200;85;0;0;0 200;200;80;230;200;200 500;200;105;0;0;0 500;200;100;200;200;200 500;200;85;0;0;0 500;200;80;230;200;200 350;350;180;200;200;200 350;340;150;200;0;0 350;320;150;200;200;200 270;300;35;0;0;0 430;300;35;0;0;0 270;300;30;255;255;255 430;300;30;255;255;255 260;290;20;0;0;0 440;300;20;0;0;0 260;290;18;60;0;255 440;300;18;60;0;255 260;290;8;0;0;0 440;300;8;0;0;0 350;350;30;100;100;100
The first line is the field names, the other lines contain values for the fields. Each row defines one circle.
Create a new CSV file in your Exercise:
The SaxionApp has a builtin CSV reader.
Change your program, so the while loop that creates the circles doesn't use random values, but values from the CSV. Use this example to modify your code:
ArrayList<Circle> circles = new ArrayList<>(); // NOTE: instead of "Exercise1", use the correct Exercise directory name here // or "Sandbox" if you use the Sandbox project. CsvReader reader = new CsvReader("Exercise1/circles.csv"); reader.setSeparator(';'); // fields separated by semicolon reader.skipRow(); // skip the header row with field names while (reader.loadRow()) { // keep looping until there are no more rows Circle c = new Circle(); c.x = reader.getInt(0); c.y = reader.getInt(1); // do the rest of the fields yourself ... // add the circle to the arraylist }
If you do it correctly, you should see a painting that is rumoured to have been made by Van Gogh himself. At least it has the same qualities.
ArrayList<Circle> circles = new ArrayList<>();
CsvReader reader = new CsvReader("Exercise15/circles.csv");
reader.setSeparator(';'); // fields separated by semicolon
reader.skipRow(); // skip the header row with field names
while (reader.loadRow()) {
Circle c = new Circle();
c.x = reader.getInt(0);
c.y = reader.getInt(1);
c.radius = reader.getInt(2);
c.red = reader.getInt(3);
c.green = reader.getInt(4);
c.blue = reader.getInt(5);
circles.add(c);
}
// (removed the color counting stuff)
SaxionApp.turnBorderOff();
for (Circle c : circles) {
Color color = SaxionApp.createColor(c.red, c.green, c.blue);
SaxionApp.setFill(color);
SaxionApp.drawCircle(c.x, c.y, c.radius);
}
Store this data as CSV-file in your exercise, call it temp.csv.
The data is the average temperature (*10, so 97 means 9.7 degrees) per year in the eastern part of the Netherlands since 1951.
weatherstation;year;temperature Twente;1951;97 Twente;1952;86 Twente;1953;98 Twente;1954;88 Twente;1955;86 Twente;1956;79 Twente;1957;97 Twente;1958;93 Twente;1959;102 Twente;1960;94 Twente;1961;97 Twente;1962;78 Twente;1963;76 Twente;1964;89 Twente;1965;83 Twente;1966;92 Twente;1967;97 Twente;1968;88 Twente;1969;85 Twente;1970;85 Twente;1971;91 Twente;1972;85 Twente;1973;90 Twente;1974;93 Twente;1975;93 Twente;1976;92 Twente;1977;93 Twente;1978;87 Twente;1979;78 Twente;1980;85 Twente;1981;91 Twente;1982;97 Twente;1983;96 Twente;1984;86 Twente;1985;78 Twente;1986;85 Twente;1987;83 Twente;1988;99 Twente;1989;104 Twente;1990;104 Twente;1991;91 Twente;1992;102 Twente;1993;90 Twente;1994;101 Twente;1995;98 Twente;1996;78 Twente;1997;97 Twente;1998;98 Twente;1999;105 Twente;2000;105 Twente;2001;99 Twente;2002;103 Twente;2003;99 Twente;2004;99 Twente;2005;101 Twente;2006;108 Twente;2007;107 Twente;2008;101 Twente;2009;100 Twente;2010;85 Twente;2011;103 Twente;2012;98 Twente;2013;94 Twente;2014;113 Twente;2015;105 Twente;2016;102 Twente;2017;105 Twente;2018;111 Twente;2019;110 Twente;2020;113 Twente;2021;101 Twente;2022;113
Create a new program.
Use the list afterwards to create a diagram:
// class YearTemperature. You probably chose a better name.
public class YearTemperature {
// there are three columns in the csv, so three fields here
// the first is a string, the last contain only numbers, so int.
String weatherStation;
int year;
int temp;
}
// in the run() method of the Application:
// (change YearTemperature to your own classname)
ArrayList<YearTemperature> yearTemperatures = new ArrayList<>();
// (change to your own path and file name)
CsvReader reader = new CsvReader("Exercise15/temp.csv");
reader.setSeparator(';'); // fields separated by semicolon
reader.skipRow(); // skip the header row with field names
while (reader.loadRow()) {
YearTemperature t = new YearTemperature();
t.weatherStation = reader.getString(0);
t.year = reader.getInt(1);
t.temp = reader.getInt(2);
yearTemperatures.add(t);
}
int x = 10; // little margin on the left
int scale = 3; // to enlarge the graph a bit, otherwise it is such a tiny graph
for (YearTemperature t : yearTemperatures) {
// draw vertical line
SaxionApp.drawLine(x, SaxionApp.getHeight(), x, SaxionApp.getHeight() - t.temp * scale);
x = x + scale; // move right for the next line
}
Now change the program:
// (change YearTemperature to your own classname)
ArrayList<YearTemperature> yearTemperatures = new ArrayList<>();
// (change to your own path and file name)
CsvReader reader = new CsvReader("Exercise15/temp.csv");
reader.setSeparator(';'); // fields separated by semicolon
reader.skipRow(); // skip the header row with field names
while (reader.loadRow()) {
YearTemperature t = new YearTemperature();
t.weatherStation = reader.getString(0);
t.year = reader.getInt(1);
t.temp = reader.getInt(2);
yearTemperatures.add(t);
}
int selectedYear = 0;
// keep asking until it is ok
while (selectedYear < 1951 || selectedYear > 2022) {
SaxionApp.printLine("From which year do you want to see the graph? (1951-2022)");
selectedYear = SaxionApp.readInt();
}
int x = 10;
int scale = 3;
for (YearTemperature t : yearTemperatures) {
// only draw if it matches our criterium: year should be >= than the selected year
if (t.year >= selectedYear) {
SaxionApp.drawLine(x, SaxionApp.getHeight(), x, SaxionApp.getHeight() - t.temp * scale);
x = x + scale;
}
}