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];
}
}
Related
I'm trying to use JTable to show data from excel files.
I'm using RowSorter.SortKey, so I can order many columns:
for(int i = 0; i < x; i++){
sortKeys.add(new RowSorter.SortKey(i, order));
}
sorter.setSortKeys(sortKeys);
sorter.sort();
The problem is that the empty rows are put at the top during ascending order.
Is there way to keep using the JTable sorting function but moving empty rows at the end of the JTable?
Thank you
P.S.: I'm new to java swing.
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.
I am trying to make a very simple grid in which a user can move through. Through my research i have concluded that the best way to achieve this would be using a two-dimensional array to represent the grid. However i am unsure of how to draw this array to a Jframe or Jpanel if i were to make an array of rectangles.
Many Stackoverflow questions seem to ask simmilar queries but unforunately i have found non that entirely explains how to draw a simple grid of rectangles.
You can make arrays out of everything. Notice how the way to implement an array is
*datatype* [] *arrayname* = new *datatype* [*lengthOfArray*];
Lets say the name of the class that contains the rectangles is RECTANGLE. So if you want an Array, that contains, lets say, 5 rectangles, it would look somewhat like that:
RECTANGLE [] rectangelArray = new RECTANGLE [5];
If you want to take that to a 2 dimensional Level, just add another bracket:
RECTANGLE [][] rectangelMatrix = new RECTANGLE [4][5];
Assuming that by "drawing to the JPanel" you mean that you want to put the rectangles onto the screen, you would then have a for-loop in a for-loop, that would for example call each rectangle to draw itself:
for(int i = 0; i<rectangleMatrix.length; i++){
for(int j = 0; j<rectangleMatrix[i].length; j++){
rectangleMatrix[i][j].draw();
}
}
rectangleMatrix.draw() calls a method that will draw the rectangle based on its coordinates and size. you could also in a similar fashion call a method that will read the information of each rectangle and then draw it based on that information. This will help you seperate between information and drawing purposes in your classes, which is always a good thing to do:
for(int i = 0; i<rectangleMatrix.length; i++){
for(int j = 0; j<rectangleMatrix[i].length; j++){
drawRectangle(rectangleMatrix[i][j]);
}
}
drawRectangle(RECTANGLE toDraw) is in the same class that you have the method with the for-loop in.
In your parent component of grid set layout like
gamePanel.setLayout(new GridLayout(ix, iy));
where ix and iy is dimension size
you also need array of cells private Cell[][] cells; in this case cell is simply
public class Cell extends JPanel{
//some game specific code, fields, constructors
}
now use it
for (int i = 0; i < ix; i++) {
for (int j = 0; j < iy; j++) {
progres.setValue(progres.getValue() + 1);
cells[i][j] = new Cell(i, j, passer);
gamePanel.add(cells[i][j]);
}
}
now if in constructor of cell you will set a border this.setBorder(new LineBorder(Color.GRAY)); grid will appear. in cell constructor or setter method you can also pass whole cells so each cell will be aware of another, and be able to interact with them. but be aware- if you pass it in loop that also create cells, you might encounter a null values.
this way you can use swing components so each cell can be clickable etc.
You can extend a JComponent and overriding its paint(Graphics) method to draw the grid using Graphics.drawLine.
If you need the grid cells to be interactive in some way, then you should probably just create components with rectangular borders and position them using a grid layout.
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.
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.