What should I use to add a String[1000][1000] to JavaFX - java

As per the title.
I have a 2D array with size of 1000 x 1000.
I tried adding in to a gridpane and it went out of memory(haha...)
I am just wondering what would be the best way to go about this?
Requirements:
1) All container for the items in the array has to be of same size
2) I would like to show colour being applied to selected position of the 2D array.
Any guide to the right direction is greatly appreciated.
Really new to JavaFX.
*Contemplating canvas but...
Code:
private String[][] dataFromTxtFile;
GridPane gridpane = new GridPane();
private void initialize() {
TextFileData txtFileData = new TextFileData();
//txtFileData.getTxtFileData() gets a [1000][1000] array
dataFromTxtFile = txtFileData.getTxtFileData();
//Gridpane.add(dataon the box, column, row)
for (int i =0; i<dataFromTxtFile.length;i++){
for (int j=0; j<dataFromTxtFile[i].length;j++){
Text data = new Text(dataFromTxtFile[i][j]);
System.out.println("HERE: "+dataFromTxtFile[i][j]);
gridpane.add(data,i,j);
}
}
}
I am trying to display the data on a 1000 x 1000 grid.
The items in it are just numbers.

If you are only storing numbers, use an Array of ints. It might still be not enough memory, but ints take up less memory than strings. Use Integer.parseInt("string") to convert from string to int.

Related

Is there any other way to implement setOnMouseClicked on JavaFX

I had to create a matrix in javaFX. I created it without any problem with GridPane. The next thing is to create like "buttons" on the right side of the matrix, these buttons will move +1 element of the matrix to the right. Like this:
110 <-
101 <- //ie: I clicked this button
100 <-
The result:
110 <-
110 <-
100 <-
The way I handle this bit-shifting-moving was with circular linked list. I don't have any problem with that I think you can ommit that part. I use this method:
private void moveRowRight(int index){
//recives a index row and moves +1 the elements of that row in the matrix.
}
cells is the matrix
The problem is that, first the matrix can be modified by the user input i.e. 5x5 6x6 7x7, so the number of buttons will also change. I tried using a BorderPane(center: gridpane(matrix), right: VBox()) and this is the part of the code how I added some HBox inside the Vbox (right part of the border pane) and using the setOnMouseClicked.
private void loadButtonsRight(){
for(int i = 0; i < cells[0].length ; i++){
HBox newBox = new HBox();
newBox.getChildren().add(new Text("MOVE"));
newBox.prefHeight(50);
newBox.prefWidth(50);
newBox.setOnMouseClicked(e -> {
moveRowRight(i);
});
VBRightButtons.getChildren().add(newBox); //where I add the HBox to the VBox (right part of the Border Pane)
}
}
}
But then there's this problem.
Local variables referenced from lambda expression must be final or effectively final
It seems that I cannot implement lambda with a value that will change. Is there any way to help me to put "buttons" that depends of the matrix size and that uses the method I've created?
The message tells you all you need to know to fix the problem:
Local variables referenced from lambda expression must be final or effectively final
Assign your changing variable to a final constant and use the constant value in the lambda instead of the variable:
final int idx = i;
newBox.setOnMouseClicked(e ->
moveRowRight(idx);
);
If you wish to understand this more, see the baeldung tutorial
https://www.baeldung.com/java-lambda-effectively-final-local-variables

Fill ArrayList with colors for Android

I want to create 2 ArrayList. One holding 16 colors, the other one holding 139.
I have the list with colors (both RGB as 255,126,32 and Hex as 0xFFFF2552). I want to use the ArrayList to later pick random colors from.
I've tried int[], that doesn't work. I've tried ArrayList<Integer> and ArrayList<Color>. My problem is; I don't understand how to add the colors to the ArrayLists.
Thanks!!
For now, I'm exploring this:
Color cBlue = new Color(0,0,255);
Color cRed = new Color(255,0,0);
ArrayList colors = new ArrayList();
colors.add(cBlue);
colors.add(cRed);
and so on...
I really like int[] colors = = new int[] {4,5}; because it's only one line of code... but how do I get colors in, to later on, pick from?
or.. would it be better to store the colors in a strings.xml file and then fill the ArrayList from there? If so, how should I do that?
Thanks!!
You could try:
int[] colors = new int[] {Color.rgb(1,1,1), Color.rgb(...)};
For example, but I don't think it's a good idea to decide only using "one line" argument.
List<Integer> coloras = Arrays.asList(new Integer[]{Color.rgb(1, 1, 1), Color.rgb(...)});
Will also work.
You can create an arraylist in arrays.xml file:
<resources>
<string-array name="colors">
<item>#ff0000</item>
<item>#00ff00</item>
<item>#0000ff</item>
</string-array>
</resources>
Then use the loop to read them:
String[] colorsTxt = getApplicationContext().getResources().getStringArray(R.array.colors);
List<Integer> colors = new ArrayList<Integer>();
for (int i = 0; i < colorsTxt.length; i++) {
int newColor = Color.parseColor(colorsTxt[i]);
colors.add(newColor);
}
In my opinion keeping colors in the list is the most convinient solution.
To take a color from the list randomly, you do:
int rand = new Random().nextInt(colors.size());
Integer color = colors.get(rand);
I would make a text file or xml file populated with the color info and have a function that reads in each line of the file using a loop, creates a Color object for each line and adds it to the array list and then goes to the next line until there are no lines left.
I would recommend against using a configuration file unless you want to be able to change your colors without code changes. I suspect your colors are constant though, so the file would just add unnecessary complexity to your application.
The code sample in your question assumes java.awt.Color when you would actually use the utility class android.graphics.Color which cannot be instantiated.
Therefore I recommend the following solution as a static variable (and be careful not to modify the contents of the array later):
static final int[] colors16 = {
Color.rgb(255, 0, 0),
Color.rgb(0, 255, 0),
Color.rgb(0, 0, 255)
};
Now add a static instance of Random to use for selecting random colors from the list.
static final Random random = new Random();
And then pick your color!
int colorIndex = random.nextInt(colors16.size());
Color color = colors16.get(colorIndex);
If you feel it's important to protect the contents of your list, you can make it immutable as follows, at the small expense of boxing your color ints into Integer objects.
static final List<Integer> colors = Collections.unmodifiableList(
Arrays.asList(
Integer.valueOf(Color.rgb(255, 0, 0)),
Integer.valueOf(Color.rgb(0, 255, 0)),
Integer.valueOf(Color.rgb(0, 0, 255))
)
);
Technically you can leave out the Integer.valueOf() conversion in the above snippet and Java will autobox the ints.
You can also can use int[] colors = new int[]{color1.getRGB(),color2.getRGB()};
And decode using: Color color = new Color(colors[0]);
What you have looks like it makes sense, but you should specify the type of the ArrayList.
List<Color> colorList = new ArrayList<Color>();
colorList.add(cBlue);
... etc
(The difference between declaring it as a List or an ArrayList is that List is the interface that ArrayList implements. This is a generally pretty good practice, but for your purposes it probably won't make a difference if you declare it as a List or an ArrayList).
If you want to do it in fewer lines of code, you can use an ArrayList initializer block, like this:
List<Color> colorList = new ArrayList<Color> { new Color(...), cBlue };
Or with Arrays.asList, which takes in an array and returns a List.
But in general you should get used to verbosity with Java, don't try to optimize your lines of code so much as the performance of those lines.
(Sidenote: make sure you're using the correct Color class. There's android.graphics.Color and java.awt.Color, and they're totally different, incompatible types. The constructor you're using is from java.awt.Color, and with Android you're probably going to want to use android.graphics.Color).

Fill a GridLayout in Java with Objects from a 2DArray?

I am learning Java and am trying to implement MineSweeper as a learning experience. I've got most of the logic working, but I am running into trouble with my recursive checkMine() method. I think the problem is my understanding, or misunderstanding rather, of how the GridLayout interacts with 2D arrays.
What I need to be able to do is to construct a 2D array full of Mines--which are an object extending JButton--and assign each element of the array to its own GridLayout location. Currently, I have the game working, but the numbers are not displaying the correct number of bombs, and I believe after debugging this could only be an issue with my implementation of the 2D Array with the GridLayout.
QUESTION: Is it possible to fill a GridLayout with individual elements of a 2D array? If not, what would be the best way for me to do this?
dAssuming your class extends java.applet.Applet
// Columns, Rows
Mines[][] mineGrid;
// Add stuff to the `mineGrid` array
// Set the height to the number of rows, length to number of columns
setLayout(new GridLayout(mineGrid.length, mineGrid[0].length);
// For each row
for(int rowIndex = 0; rowIndex < mineGrid.length; rowIndex++) {
// For each column
for(int colIndex = 0; colIndex < mineGrid[0].length; colIndex++) {
// Add the button, because of GridLayout it starts # the top row, goes across left to right, down a row, across left to right, etc.
add(mineGrid[rowIndex][colIndex];
}
}

How we can increase size of 2d vector in Java?

Assume we defined a 2d vector in Java. Size of the first dimension is 10 and size of second dimension is 1. Now if we want to increase size of first dimension of this 2d vector what should we do?
Assume we want add number 1 to 30th cell (i.e. v1[29][0]=1), but our vector size is 10.
Here is my code in Java:
Vector [][] v1 = new Vector [10][];
for (int i=0 ; i<10; i++)
if (i==0) {
v1[i]=new Vector[1];
}
else
v1[i]=v1[0];
v1[0][0]=new Vector(1);
You need to assign new, bigger array, for example v1 = new Vector[30][].
Note that Vector is synchronized. If a thread-safe implementation is not needed, it is recommended to use ArrayList in place of Vector.
Also, make sure that you understand what are you doing. If you only need to "add number 1 to 30th cell (i.e. v1[30][0]=1)", then int v1 = new int[31][] should be enough, without any vectors. By the way, 30th cell is v1[29][0], not v1[30][0], watch out for this common mistake-by-one.

Create FormLayout rows and columns dynamically (at runtime)

Hello guys and ladies,
as I let the Eclipse WindowBuilder create me a JPanel with a FormLayout, I wanted to make this creation to be dynamical, because the program I'm writing needs it that way in order to avoid 1000 row long from. I used the following code:
JPanel pData = new JPanel();
pData.setBounds(10, 232, 381, 163);
FormLayout fLayout= new FormLayout(new ColumnSpec[]{}, new RowSpec[]{});
int numCols = 5;
int numRows = 10;
for(int i=1;i<=numCols;i+=2)
{
fLayout.insertColumn(i, FormFactory.RELATED_GAP_COLSPEC);
fLayout.insertColumn(i+1, FormFactory.DEFAULT_COLSPEC);
}
for(int j=1;j<=numRows;j+=2)
{
fLayout.insertRow(j, FormFactory.RELATED_GAP_ROWSPEC);
fLayout.insertRow(j+1, FormFactory.DEFAULT_ROWSPEC);
}
pData.setLayout(fLayout);
getContentPane().add(pData);
But starting the program, I get a stack of errors starting with:
"The column index 1 must be in the range [1, 0]"
Changing the index in the for-loop(s) simply changes the number in the middle of this error text, but the rest stays the same.
What am I doing wrong? Is it even possible to create a FormLayout dynamically? I'd really appreciate your help!
Additional Information:
The reason I'm using a FormLayout is the fact, the columns have different sizes. I know GridBagLayout can do so as well, but it needs many more lines and numbers to have the same result concerning insets and position. But if it's the only sensible alternative, I'll accept it ... as long as it's dynamical ;-)
It has to do with how the "insertRow()/insertColumn()" work. To insert something you must already have row/columns to insert in between. You should instead use the ".appendRow()/.appendColumn()" which just add a new row or column at the bottom of any existing rows or to the right of any existing columns.
EX:
int numCols = 2;
int numRows = 10;
for(int i=1;i<=numCols;i++)
{
fLayout.appendColumn(FormFactory.RELATED_GAP_COLSPEC);
fLayout.appendColumn(FormFactory.DEFAULT_COLSPEC );
}
for(int j=1;j<=numRows;j++)
{
fLayout.appendRow(FormFactory.RELATED_GAP_ROWSPEC);
fLayout.appendRow(FormFactory.DEFAULT_ROWSPEC);;
}
this.setLayout(fLayout);
This would add 4 columns(2 default and 2 related gaps) and 4 rows(2 default and 2 related gaps) to whatever already exists.

Categories

Resources