Related
After I upgraded the Firestore android sdk from v20.1.0 to v21.6.0, my Firestore queries are not working as expected.
If I make a simple get() query or a snapshotListener query (realtime) on a single document, the query works once (or twice) then stops working or getting updates (if realtime query), the onEvent() method wouldn't be triggered.
After deep investigation and multiple tests, we (my work team) found that what causes this is that our documents, each, contain a large Map field with at least 5 levels of multi key-value pairs.
Our map field is called "items", when we tried to remove it from the document, the realtime query works perfectly as expected.
P.S: we tried to check the size of the documents, the average was between 6k bytes and 5k bytes, and Firestore allows 1Mb (1M bytes) as a maximum document size.
To reproduce the bug, follow below steps :
Add this line into your project gradle file :
dependencies {
classpath 'com.google.gms:google-services:4.3.3'
}
Add those two lines into the module:app gradle file :
dependencies {
implementation 'com.google.firebase:firebase-firestore:21.6.0'
implementation 'com.google.code.gson:gson:2.8.6'
}
Add this code to create and write a copy of my document into
firestore :
private void createAndWriteDocument() {
GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.setDateFormat("MMM d, yyyy HH:mm:ss");
gson = gsonBuilder.create();
FirebaseFirestore.getInstance()
.collection(COLLECTION_ORDERS)
.document("ZYaJKmQF9n1RknziD1tj")
.set(gson.fromJson(jsonOrder2, FireStoreOrder.class));
}
private final String jsonOrder2 = "{\n" +
" \"app_name\":\"Firestore-Sample\",\n" +
" \"app_version\":\"1.0.0\",\n" +
" \"canceled_at\":\"Sep 4, 2020 15:12:34\",\n" +
" \"comments_count\":4,\n" +
" \"countryID\":\"fr\",\n" +
" \"created_at\":\"Sep 4, 2020 12:21:55\",\n" +
" \"currency\":\"EUR\",\n" +
" \"delivered_at\":\"Sep 4, 2020 15:11:30\",\n" +
" \"delivery_agent_id\":\"1rvlTtfJKNVPVxZ2mp4T2CcI1Fj2\",\n" +
" \"delivery_assignment_status\":\"accepted\",\n" +
" \"delivery_fee\":5.0,\n" +
" \"distance\":3.2547,\n" +
" \"hearts_count\":0,\n" +
" \"in_progress_at\":\"Sep 4, 2020 15:06:51\",\n" +
" \"is_friends\":false,\n" +
" \"is_private\":false,\n" +
" \"is_public\":true,\n" +
" \"is_visible\":true,\n" +
" \"items\":{\n" +
" \"-MGNqMoKy8YovI11-QUK\":{\n" +
" \"category_id\":\"-LlbKEnwkC4KZtJyN691\",\n" +
" \"discount_price\":0.0,\n" +
" \"extras\":{\n" +
" \"-M1-qhcXr8tp5KpnLp9p\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Chèvre\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":5,\n" +
" \"row\":6\n" +
" },\n" +
" \"-M1-rHnm7Xzjo7rE73Pk\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Vache kiri\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":7,\n" +
" \"row\":4\n" +
" },\n" +
" \"-M1-me-3qKOqWzul67Sr\":{\n" +
" \"is_sub_extra\":true,\n" +
" \"max\":3,\n" +
" \"name\":\"Crispy Tenders\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":0\n" +
" },\n" +
" \"-M1-mKvK76SYLJBf3zh-\":{\n" +
" \"is_sub_extra\":true,\n" +
" \"max\":3,\n" +
" \"name\":\"Escalope de Poulet\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" },\n" +
" \"-M1-rNaEFCyHlf9WIOaH\":{\n" +
" \"max\":10,\n" +
" \"name\":\"Raclette\",\n" +
" \"price\":0.6,\n" +
" \"quantity\":4,\n" +
" \"row\":5\n" +
" }\n" +
" },\n" +
" \"extras_title\":\"Suppléments\",\n" +
" \"ingredients\":{\n" +
" \"-MEYbO7SlOBFWUVzcvg6\":{\n" +
" \"description\":\"Ingredients description\",\n" +
" \"name\":\"Cheddar\",\n" +
" \"row\":0\n" +
" },\n" +
" \"-MEYbLvKvqPu3YZPPAjo\":{\n" +
" \"description\":\"Ingredients description\",\n" +
" \"name\":\"Laitus\",\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"ingredients_title\":\"Ingrédients : Décocher pour enlever\",\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582717663739.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582717663739.jpg?alt\\u003dmedia\\u0026token\\u003d1bbfd8a0-be5a-44c2-8dd9-d5a7dacf2243\"\n" +
" },\n" +
" \"max_extras\":30,\n" +
" \"name\":\"Tacos\",\n" +
" \"options\":{\n" +
" \"-LlfWYJR_zKtO1l0DjnF\":{\n" +
" \"elements\":{\n" +
" \"-LlfWj5L6weXYZUPUoGW\":{\n" +
" \"extras_title\":\"3 Viandes\",\n" +
" \"max\":1,\n" +
" \"max_extras\":3,\n" +
" \"min_extras\":3,\n" +
" \"name\":\"L : Choisir 3 Viandes\",\n" +
" \"price\":9.5,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Taille\",\n" +
" \"row\":-1\n" +
" },\n" +
" \"-LlfX5HY1rzcQpz1p6mG\":{\n" +
" \"elements\":{\n" +
" \"-LlfXbVB-QA-utApD3HO\":{\n" +
" \"max\":3,\n" +
" \"name\":\"Barbecue\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" },\n" +
" \"-LlfXxF-7RRTZhFwXhyX\":{\n" +
" \"max\":3,\n" +
" \"name\":\"Marocaine\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":2,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"max_quantity\":4,\n" +
" \"min_quantity\":1,\n" +
" \"name\":\"Sauces\",\n" +
" \"row\":3\n" +
" },\n" +
" \"-LlfWPIAjjgTiqtqEzep\":{\n" +
" \"elements\":{\n" +
" \"-LlfWPI9_w1gH1A3HTsB\":{\n" +
" \"name\":\"Tacos\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Type\",\n" +
" \"row\":2\n" +
" }\n" +
" },\n" +
" \"price\":0.0,\n" +
" \"product_id\":\"-LlfTFlgrNBdLZRn5xgn\",\n" +
" \"quantity\":2,\n" +
" \"sub_category_id\":\"-LlbKEnvPMIV3DnSiYlJ\"\n" +
" },\n" +
" \"-MGNqOGcRfYb-myLgc1d\":{\n" +
" \"category_id\":\"-LlkUx5iBSXhKdMYGxTA\",\n" +
" \"discount_price\":3.5,\n" +
" \"extras\":{\n" +
" \"-M2JOJaB_Gsc28GT8wEg\":{\n" +
" \"max\":2,\n" +
" \"name\":\"Harissa\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":2\n" +
" }\n" +
" },\n" +
" \"extras_title\":\"Sauces\",\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582809519364.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582809519364.jpg?alt\\u003dmedia\\u0026token\\u003dabc457cb-2462-44be-886a-af83db3cb501\"\n" +
" },\n" +
" \"max_extras\":2,\n" +
" \"name\":\"Oignons frites\",\n" +
" \"options\":{\n" +
" \"-M15mpsXwAzsDRlLDHJI\":{\n" +
" \"elements\":{\n" +
" \"-M15mpsXwAzsDRlLDHJG\":{\n" +
" \"name\":\"Cheddar\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Au choix :\",\n" +
" \"row\":-1\n" +
" }\n" +
" },\n" +
" \"price\":3.5,\n" +
" \"product_id\":\"-M15mV_4Ui2B90GlzsaR\",\n" +
" \"quantity\":1,\n" +
" \"sub_category_id\":\"-LlkUx5h8rXECP8L_hjQ\"\n" +
" },\n" +
" \"-MGNqOxoHFGoigUXao96\":{\n" +
" \"category_id\":\"-LlkUx5iBSXhKdMYGxTA\",\n" +
" \"discount_price\":3.5,\n" +
" \"extras\":{\n" +
" \"-M2JOmBf1oN1BmUUHeiY\":{\n" +
" \"name\":\"Biggy burger\",\n" +
" \"price\":0.0,\n" +
" \"quantity\":1,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"itemPrice\":0.0,\n" +
" \"main_image\":{\n" +
" \"ref\":\"/ZKRBeLgCauXKZ15rfRcuQTY2S1k1/-LlXe_ZbTQytlKujrhLF/products/1582809369789.jpg\",\n" +
" \"url\":\"https://firebasestorage.googleapis.com/v0/b/urban-food-a9a70.appspot.com/o/ZKRBeLgCauXKZ15rfRcuQTY2S1k1%2F-LlXe_ZbTQytlKujrhLF%2Fproducts%2F1582809369789.jpg?alt\\u003dmedia\\u0026token\\u003d705593e0-e403-4931-b040-5b2261cb96e5\"\n" +
" },\n" +
" \"name\":\"Bacon frites\",\n" +
" \"options\":{\n" +
" \"-M15lyQyHs1GujtZxMtS\":{\n" +
" \"elements\":{\n" +
" \"-M15lyQxrRFaLAWGaa3i\":{\n" +
" \"name\":\"Sauce fromagère\",\n" +
" \"price\":0.0,\n" +
" \"row\":0\n" +
" }\n" +
" },\n" +
" \"name\":\"Au choix :\",\n" +
" \"row\":-1\n" +
" }\n" +
" },\n" +
" \"price\":3.5,\n" +
" \"product_id\":\"-M15lqmhF16ZOLqebPzs\",\n" +
" \"quantity\":1,\n" +
" \"sub_category_id\":\"-LlkUx5h8rXECP8L_hjQ\"\n" +
" }\n" +
" },\n" +
" \"itemsCount\":0,\n" +
" \"level_one_zone_id\":\"Île-de-France\",\n" +
" \"level_two_zone_id\":\"Paris\",\n" +
" \"order_id\":\"ZYaJKmQF9n1RknziD1tj\",\n" +
" \"order_number\":31,\n" +
" \"order_type\":\"delivery\",\n" +
" \"paid\":false,\n" +
" \"paid_with_loyalty\":0.0,\n" +
" \"picked_at\":\"Sep 4, 2020 15:12:46\",\n" +
" \"platform\":\"android\",\n" +
" \"processedAt\":{\n" +
" \"nanoseconds\":994000000,\n" +
" \"seconds\":1599228406\n" +
" },\n" +
" \"restaurant_photo\":\"https://firebasestorage.googleapis.com/v0/b/menutium-319d0.appspot.com/o/LHx3fTdtoaRlrAHSjznJSaPz9rP2%2F-MEYUb7iepk3pLwUyWX3%2Fprofile%2F1597250393877.jpg?alt\\u003dmedia\\u0026token\\u003dcbccd3fe-91fd-4397-ab34-79f5f241def2\",\n" +
" \"status\":\"picked\",\n" +
" \"store_id\":\"-MEYUb7iepk3pLwUyWX3\",\n" +
" \"store_name\":\"La Fourchette\",\n" +
" \"total_price\":50.2,\n" +
" \"updated_at\":\"Sep 7, 2020 18:54:02\",\n" +
" \"user_address\":\"166 Quai de Stalingrad, 92130 Issy-les-Moulineaux, France\\nIssy-les-Moulineaux\",\n" +
" \"user_coordinates\":\"48.8256954,2.2579879\",\n" +
" \"user_name\":\"Mo Salah\",\n" +
" \"user_phone\":\"+21650001002\",\n" +
" \"user_photo\":\"https://firebasestorage.googleapis.com/v0/b/menutium-319d0.appspot.com/o/2Bz8euUmPgMqc4Z7QZWJjLfsgV72%2Fphoto_profile?alt\\u003dmedia\\u0026token\\u003df5dcee5b-fdda-45bd-9ec3-982cfe7832bd\",\n" +
" \"user_uid\":\"2Bz8euUmPgMqc4Z7QZWJjLfsgV72\",\n" +
" \"validated_at\":\"Sep 4, 2020 15:12:42\",\n" +
" \"validatedBy\":{\n" +
" \"name\":\"Urban-Admin\",\n" +
" \"id\":\"admin\"\n" +
" }\n" +
"}";
Start a realtime query on this document :
FirebaseFirestore.getInstance()
.collection("orders")
.document("ZYaJKmQF9n1RknziD1tj")
.addSnapshotListener(new EventListener<DocumentSnapshot>() {
#Override
public void onEvent(#Nullable DocumentSnapshot value,
#Nullable FirebaseFirestoreException error) {
Log.d("testing", "onEvent triggered");
if (error != null) {
Log.i("testing", "test error : "+ error.getMessage());
}
}
});
We created two Android projects (Java code), put them into public Github repos so that anyone could reproduce the issue we are facing.
Everything is detailed into the Readme repos.
First Project repository
Second Project repository with minimal code
Before i create this question, i created an issue within the official firebase-android-sdk repository.
After five days, someone from the Firebase team answered me, they did found a bug in the Firestore sdk, fixed it, but still didn't released it, so he recommended to downgrade to older version than 21.5.0 to avoid the bug as a temporary workaround.
Github issue link here
I want to change the firstPattern with the secondPattern. When I am using Pattern Matcher / String.replaceAll()
I am using the following logic to replace
System.out.println(fileContent.replaceAll(firstPattern, secondPattern));
I am getting following error =
at java.util.regex.Pattern.error(Pattern.java:1955)
at java.util.regex.Pattern.closure(Pattern.java:3157)
at java.util.regex.Pattern.sequence(Pattern.java:2134)
at java.util.regex.Pattern.expr(Pattern.java:1996)
at java.util.regex.Pattern.compile(Pattern.java:1696)
at java.util.regex.Pattern.<init>(Pattern.java:1351)
at java.util.regex.Pattern.compile(Pattern.java:1028)
at java.lang.String.replaceAll(String.java:2223)
It is happening because in the first pattern I have used "{" and "}" brace. So it is throwing an error. Don't know how to replace these.
String firstPattern = "text.append(\" where \");\r\n" +
" text.append(\"ObjId\" + \" = \");\r\n" +
" text.append(getObjId().toString());\r\n" +
"\r\n" +
" text.append(\" and \");\r\n" +
" text.append(\" LastCngDTime = \");\r\n" +
"\r\n" +
" try {\r\n" +
" tempString = dbaExecObj.Get_DataConverter()\r\n" +
" .SmsTimeStampToDBMSTimestampString(LastCngDTime,\r\n" +
" \"-WQ\");\r\n" +
" } catch (Exception e) {\r\n" +
" throw new SmsTntResult(new SmsSystemResult(logger,\r\n" +
" SmsCsvWhoAmI.getMyFullyQualifiedMethodName(),\r\n" +
" SmsTntCodes.DATA_TYPE_CONVERSION_ERROR,\r\n" +
" SmsSystemResult.ERROR));\r\n" +
" }\r\n" +
"\r\n" +
" text.append(tempString);";
String secondPattern = "text.append(\" where \");\r\n" +
" text.append(\"ObjId\" + \" = \");\r\n" +
" text.append(getObjId().toString());\r\n" +
"\r\n" +
" text.append(\" and \");\r\n" +
" text.append(\" LastCngDTime = \");\r\n" +
"\r\n" +
" try {\r\n" +
" tempString = dbaExecObj.Get_DataConverter()\r\n" +
" .SmsTimeStampToDBMSTimestampString(LastCngDTime,\r\n" +
" \"-WQ\");\r\n" +
" } catch (Exception e) {\r\n" +
" throw new SmsTntResult(new SmsSystemResult(logger,\r\n" +
" SmsCsvWhoAmI.getMyFullyQualifiedMethodName(),\r\n" +
" SmsTntCodes.DATA_TYPE_CONVERSION_ERROR,\r\n" +
" SmsSystemResult.ERROR));\r\n" +
" }\r\n" +
"\r\n" +
" text.append(\"CAST(\");" +
" text.append(tempString);" +
" text.append(\" AS datetime)\");";
String fileContent = new Scanner(new File(filePath)).useDelimiter("\\A").next();
System.out.println(fileContent.replaceAll(firstPattern, secondPattern));
I'm trying to create another array but I want it to be the array double gainT[], which is the temperature in Fahrenheit, converted to Celcius to make another array called double gainTC[]. I am also trying to do the same thing but with the precipitation. I just can't seem to find a way to do it though.
import java.io.IOException;
import java.util.Scanner;
public class AnnualClimate1 {
public static void main(String [] args) throws IOException
{
Scanner in = new Scanner(System.in);
System.out.print("Choose the temperature Scale (F = Fahrenheit, C = Celsius): ");
String tFC = in.nextLine();
System.out.print("Choose the precipitation Scale (I = Inches, C = Centimeters): ");
String pIC = in.nextLine();
System.out.println("");
System.out.println("");
System.out.println(" Climate Data");
System.out.println(" Location: Gainesville, Florida");
System.out.println(" Temperature " + tFC + " Precipitation " + pIC);
System.out.println("=================================================");
double gainT[]={54.3, 57.0, 62.5, 67.6, 74.3, 79.2, 80.9, 80.4, 77.8, 70.1, 62.8, 56.3};
double gainTC[] = {(gainT[] - 32) / 1.8};
double gainP[]={3.5, 3.4, 4.3, 2.9, 3.2, 6.8, 6.1, 6.6, 4.4, 2.5, 2.2, 2.6};
double gainPC[] = {gainP[] / .3937};
if(tFC.equalsIgnoreCase("F") && pIC.equalsIgnoreCase("I")){
System.out.println("Jan. " + gainT[1] + " " + gainP[1]);
System.out.println("Feb. " + gainT[2] + " " + gainP[2]);
System.out.println("Mar. " + gainT[3] + " " + gainP[3]);
System.out.println("Apr. " + gainT[4] + " " + gainP[4]);
System.out.println("May " + gainT[5] + " " + gainP[5]);
System.out.println("Jun. " + gainT[6] + " " + gainP[6]);
System.out.println("Jul. " + gainT[7] + " " + gainP[7]);
System.out.println("Aug. " + gainT[8] + " " + gainP[8]);
System.out.println("Sep. " + gainT[9] + " " + gainP[9]);
System.out.println("Oct. " + gainT[10] + " " + gainP[10]);
System.out.println("Nov. " + gainT[11] + " " + gainP[11]);
System.out.println("Dec. " + gainT[12] + " " + gainP[12]);
}
else if(tFC.equalsIgnoreCase("C") && pIC.equalsIgnoreCase("C")){
System.out.println("Jan. " + gainTC[1] + " " + gainPC[1]);
System.out.println("Feb. " + gainTC[2] + " " + gainPC[2]);
System.out.println("Mar. " + gainTC[3] + " " + gainPC[3]);
System.out.println("Apr. " + gainTC[4] + " " + gainPC[4]);
System.out.println("May " + gainTC[5] + " " + gainPC[5]);
System.out.println("Jun. " + gainTC[6] + " " + gainPC[6]);
System.out.println("Jul. " + gainTC[7] + " " + gainPC[7]);
System.out.println("Aug. " + gainTC[8] + " " + gainPC[8]);
System.out.println("Sep. " + gainTC[9] + " " + gainPC[9]);
System.out.println("Oct. " + gainTC[10] + " " + gainPC[10]);
System.out.println("Nov. " + gainTC[11] + " " + gainPC[11]);
System.out.println("Dec. " + gainTC[12] + " " + gainPC[12]);
}
}
}
Here is an incomplete example so you can fill in the blanks yourself:
double gainT[]={54.3, 57.0, 62.5, 67.6, 74.3, 79.2, 80.9, 80.4, 77.8, 70.1, 62.8, 56.3};
double gainTC[] = new double[gainT.length]; //create array which matches the size of gainT
//array.length is a property value returning the 'size' or length or the array
//Now just iterate through all the gainT[] values you populated above and read each one
for(int i = 0; i < gainT.length; i++){
double math = //use your conversion math here, and store the value
gainTC[i] = math; //assign the results of your math to the same spot in the new array
}
If you'd like more information on Loops and Arrays, check here:
For Loops: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/for.html
Arrays: https://docs.oracle.com/javase/tutorial/java/nutsandbolts/arrays.html
I have a small part of code where I get an error when I try to compile. Any pointers?
The code:
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.size(); j++) {
if(fra.linjeList[i].equals(til.linjeList[j])){
Linje aktuellLinje=new Linje(linjerMap.get(linjeList[i]));
retning=aktuellLinje.stasjonsNummer(startStasjon) - aktuellLinje.stasjonsNummer(sluttStasjon);
endeStasjonsNavn=aktuellLinje.endestasjon(retning).stasjonsNavn;
System.out.println("Ta T-bane linje " + aktuellLinje.linjeNummer + " fra " + startStasjon + " til " sluttStasjon + " i retning " + endeStasjonsNavn + ". Estimert reisetid: " + tid);
}
}
}
}
And the error:
oblig5.java:132: error: ')' expected
System.out.println("Ta T-bane linje " + aktuellLinje.linjeNummer + " fra " + startStasjon + " til "
sluttStasjon + " i r etning " + endeStasjonsNavn + ". Estimert
reisetid: " + tid);
^
This is the culprit :
" til " sluttStasjon
Make it
" til " + sluttStasjon
You are missing a plus in
" til " sluttStasjon
^ HERE
You are missing a + before sluttStasjon in your print statement
I am learning java, and from what I can tell, what I am looking to do is a rare situation.
I am trying to use an API (kindof) to randomly generate musical notes. I want it to generate 20 times so i have it in a for loop. I realize that i could have used a list for this I just dont know how I could have implemented it. The question I have is, when I try to compile this code, the first part runs. It lets me make the seed. However after that it gives me
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 2
at co.kbcomp.music.Main.main(Main.java:64)
What could I do to prevent this? I know that what I am doing is wrong. That much I dont need to be told. What I want to know is where am I going wrong.
package co.kbcomp.music;
import java.util.*;
import org.jfugue.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args){
Scanner in = new Scanner(System.in);
System.out.println("Please enter a number for the seed of the song");
long seed = in.nextLong();
Calendar cal = Calendar.getInstance();
Random rand;
//rand = new Random(cal.getTime());
rand = new Random(seed);
int NoteNumber = 0;
int NoteLength = 0;
int OctiveNumber = 0;
int ChordNumber = 0;
int InversionNumber = 0;
//int Duration = rand.nextInt(100 - 5) + 5;
//This keeps track of the iteration of the for loop.
String[] NN = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
String[] NL = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
String[] IN = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
String[] CN = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
String[] ON = { " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " ", " "};
//This is what is being played
String[] note = { "A", "B", "C", "D", "E", "F", "G" };
String[] noteLength = {"", "w", "", "h", "", "q","", "i"};
String[] octive = { "","1","", "2", "", "3", "", "4", "", "5", "", "6", "", "7", "", "8", "", "9"};
String[] chord = { "", "maj", "", "min"};
String[] inversion = {"", "^", "", "^^", "", "^^^", "", "^^^^", "", "^^^^^"};
String[] key = {"",""};
String keys= " ";
String randstr = " ";
//this is the loop that defines the music legnth
for (int i = 0; i < 21; i++) {
NoteNumber = rand.nextInt(7);
NoteLength = rand.nextInt(8);
OctiveNumber = rand.nextInt(18);
ChordNumber = rand.nextInt(4);
InversionNumber = rand.nextInt(10);
NN[i] = note[NoteNumber]; // This randomly generates the note to be played.
NL[i] = noteLength[NoteLength]; // This randomly generates the length of the note.
ON[i] = octive[OctiveNumber]; // This defines the octive to be played in.
CN[i] = chord[ChordNumber]; // This is defines the major or the minor
IN[i] = inversion[InversionNumber]; // IN[i] = inversion[InversionNumber];
key[i] = NN[i] + NL[i] + ON[i] + CN[i] + IN[i];
//randstr = c[0] + " " + c[1] + " " + c[2] + " " + c[3] + " " + c[4] + " " + c[5] + " " + c[6] + " " + c[7] + " " + c[8] + " " + c[9] + " " + c[10] + " " + c[11] + " " + c[12] + " " + c[13] + " " + c[14] + " " + c[15] + " " + c[16];
keys = (key[0] + " " + key[1] + " " + key[2] + " " + key[3] + " " + key[4] + " " + key[5] + " " + key[6] + " " + key[7] + " " + key[8] + " " + key[9] + " " + key[10] + " " + key[11] + " " + key[12] + " " + key[13] + " " + key[14] + " " + key[15] + " " + key[16] + " " + key[17] + " " + key[18] + " " + key[19] + " " + key[20]);
}
System.out.println(key);
Player player = new Player();
Pattern pattern = new Pattern(key[0]);
player.play(pattern);
}
}
You declare your key array with a length of two:
String[] key = {"",""};
But then later in your for loop, you try to access elements beyond the length of your array:
keys = (key[0] + " " + key[1] + " " + key[2] + " " + key[3] + " " + key[4] +
" " + key[5] + " " + key[6] + " " + key[7] + " " + key[8] + " " + key[9] +
" " + key[10] + " " + key[11] + " " + key[12] + " " + key[13] + " " +
key[14] + " " + key[15] + " " + key[16] + " " + key[17] + " " + key[18] +
" " + key[19] + " " + key[20]);
Since your array has only a length of two, when you try to access the third element (at array index 2), you get an ArrayIndexOutOfBoundsException.
String[] key = {"",""};
...
for (int i = 0; i < 21; i++) {
...
key[i] = ....
Do you see the problem?
As you array in only 20 in length
then this
for (int i = 0; i < 21; i++) {
is going to cause an overflow
It should be < 20
Plus this code is meaningless as your key is only an array of 2
keys = (key[0] + " " + key[1] + " " + key[2] + " " + key[3] + " " + key[4] + " " + key[5] + " " + key[6] + " " + key[7] + " " + key[8] + " " + key[9] + " " + key[10] + " " + key[11] + " " + key[12] + " " + key[13] + " " + key[14] + " " + key[15] + " " + key[16] + " " + key[17] + " " + key[18] + " " + key[19] + " " + key[20]);