get the number row of gridpane Javafx - javafx

I Have a gridpane and the number of row may be inderterminate.
How add a number row of gridpane ?
Or How add at the last of gridpane ?
Thanks.

Simply find the maximum row index from the children of the GridPane:
GridPane gridPane = ...
int maxIndex = gridPane.getChildren().stream().mapToInt(n -> {
Integer row = GridPane.getRowIndex(n);
Integer rowSpan = GridPane.getRowSpan(n);
// default values are 0 / 1 respecively
return (row == null ? 0 : row) + (rowSpan == null ? 0 : rowSpan - 1);
}).max().orElse(-1);
// add nodes after last row
gridPane.addRow(maxIndex+1, node1, node2, ...);

Related

How can I swap the order of the children in an HBox with a button in JavaFX?

If you had an HBox like this:
HBox hbox = new HBox(image1, image2);
How would you swap image1 and image2 with a button click so that image2 comes before image1?
If those are the only 2 children, you can use toFront on the first one
hbox.getChildren().get(0).toFront();
If they are not the only children you need to modify the list in a way that guarantees that none of the nodes is present in the list at the same time more than once:
List<Node> children = hbox.getChildren();
int index1 = children.indexOf(image1);
int index2 = children.indexOf(image2);
//get indices in order
if (index1 > index2) {
int temp = index1;
index1 = index2;
index2 = temp;
}
Node n = children.remove(index2);
n = children.set(index1, n);
children.add(index2, n);

(JavaFX) - Snake Iteration 2D Matrix at Snakes and Ladders game

I am creating the game "Snakes And Ladders". I am using a GridPane to represent the game board and obviously I want to move through the board in a "snake" way. Just like that: http://prntscr.com/k5lcaq .
When the dice is rolled I want to move 'dice_num' moves forward + your current position, so I am calculating the new index using an 1D array and I convert this index to 2D coordinates (Reverse Row-Major Order).
gameGrid.add(pieceImage, newIndex % ROWS, newIndex / ROWS);
Where gameGrid is the ID of my grid pane, newIndex % ROWS represents the column coordinate and newIndex / ROWS the row coordinate.
PROBLEM 1: The grid pane is iterating in its own way. Just like that: https://prnt.sc/k5lhjx.
Obviously when the 2D array meets coordinates [0,9] , next position is [1,0] but what I actually want as next position is [1,9] (going from 91 to 90).
PROBLEM 2: I want to start counting from the bottom of the grid pane (from number 1, see screenshots) and go all the way up till 100. But how am I supposed to reverse iterate through a 2D array?
You can easily turn the coordinate system upside down with the following conversion:
y' = maxY - y
To get the "snake order", you simply need to check, if the row the index difference is odd or even. For even cases increasing the index should increase the x coordinate
x' = x
for odd cases you need to apply a transformation similar to the y transformation above
x' = xMax - x
The following methods allow you to convert between (x, y) and 1D-index. Note that the index is 0-based:
private static final int ROWS = 10;
private static final int COLUMNS = 10;
public static int getIndex(int column, int row) {
int offsetY = ROWS - 1 - row;
int offsetX = ((offsetY & 1) == 0) ? column : COLUMNS - 1 - column;
return offsetY * COLUMNS + offsetX;
}
public static int[] getPosition(int index) {
int offsetY = index / COLUMNS;
int dx = index % COLUMNS;
int offsetX = ((offsetY & 1) == 0) ? dx : COLUMNS - 1 - dx;
return new int[] { offsetX, ROWS - 1 - offsetY };
}
for (int y = 0; y < ROWS; y++) {
for (int x = 0; x < COLUMNS; x++, i++) {
System.out.print('\t' + Integer.toString(getIndex(x, y)));
}
System.out.println();
}
System.out.println();
for (int j = 0; j < COLUMNS * ROWS; j++) {
int[] pos = getPosition(j);
System.out.format("%d: (%d, %d)\n", j, pos[0], pos[1]);
}
This should allow you to easily modify the position:
int[] nextPos = getPosition(steps + getIndex(currentX, currentY));
int nextX = nextPos[0];
int nextY = nextPos[1];

Suming a specific TableView column/row in JavaFX

I have done this in java where I sum the values of the price column/row. But I am wondering how to do this in JavaFX.
I want to sum everything in column 1 and display it in a inputField, I used this to do it in java but how do you do this in JavaFX?
tableview.getValueAt(i, 1).toString();
Here is what I'm trying to do:
int sum = 0;
for (int i = 0; i < tableview.getItems().size(); i++) {
sum = sum + Integer.parseInt(tableview.getValueAt(i, 1).toString());
}
sumTextField.setText(String.valueOf(sum));
If you really have a TableView<Integer>, which seems to be what you are saying in the comments, you can just do
TableView<Integer> table = ... ;
int total = 0 ;
for (Integer value : table.getItems()) {
total = total + value;
}
or, using a Java 8 approach:
int total = table.getItems().stream().summingInt(Integer::intValue);
If you have a more standard set up with an actual model class for your table, then you would need to iterate through the items list and call the appropriate get method on each item, then add the result to the total. E.g. something like
TableView<Item> table = ...;
int total = 0 ;
for (Item item : table.getItems()) {
total = total + item.getPrice();
}
or, again in Java 8 style
int total = table.getItems().stream().summingInt(Item::getPrice);
Both of these assume you have an Item class with a getPrice() method, and the column in question is displaying the price property of each item.
public void totalCalculation (){
double TotalPrice = 0.0;
TotalPrice = Yourtable.getItems().stream().map(
(item) -> item.getMontant()).reduce(TotalPrice, (accumulator, _item) -> accumulator + _item);
TexfieldTotal.setText(String.valueOf(TotalPrice));
}
//getMontant is the getter of your column

how to access the girdpane columns and rows in javafx?

I build a gridpane in scenebuilder.I have a image view in every cell.I want to build a dynamic gallery pictures.I want to remove the last image in every row and add it to the first column in next row?How can I do it?I am beginer in javafx, please help me :(
Thank you
Not tested, but this should work:
// if you know how many columns you have (and their indexes) this step is unnecessary:
int minColIndex = Integer.MAX_VALUE ;
int maxColIndex = Integer.MIN_VALUE ;
for (Node node : gridPane.getChildren()) {
int colIndex = GridPane.getColumnIndex(node);
if (colIndex < minColIndex) minColIndex = colIndex ;
if (colIndex > maxColIndex) maxColIndex = colIndex ;
}
// Update row and column indexes:
for (Node node : gridPane.getChildren()) {
int colIndex = GridPane.getColumnIndex(node);
if (colIndex == maxColIndex) {
int rowIndex = GridPane.getRowIndex(node);
GridPane.setRowIndex(node, rowIndex+1);
GridPane.setColIndex(node, minColIndex);
} else {
GridPane.setColIndex(node, colIndex + 1) ;
}
}
Are you sure a TilePane wouldn't suit your needs better, though?

Inserting empty rows into table due to 'duplicate items'

I have a table view that requires the same information on multiple rows however these rows keep appearing empty and the same log message appears
'Ignoring duplicate insertion of item'
Basically I iterate over a model setup to contain all information and take the value at each index to populate another model attached to the table.
I tried to assign each index into a variable each time the loop iterates (which seems like overkill)
QString var1, var2, var3;
for ( int row = 0; row < m_infoModel->rowCount(); ++row )
{
item = new QStandardItem;
var1 = m_infoModel->data( m_infoModel->index( row, 0 ) ).toString();
item->setText( var1 );
m_displayModel->setItem( row, 1, item );
item = new QStandardItem;
var2 = m_infoModel->data( m_infoModel->index( row, 1 ) ).toString();
item->setText( var2 );
m_displayModel->setItem( row, 2, item );
item = new QStandardItem;
var3 = m_infoModel->data( m_infoModel->index( row, 2 ) ).toString();
item->setText( var3 );
m_displayModel->setItem( row, 3, item );
}
Is there a correct/more efficient way of getting around this 'duplicate insertion' or am I looking at it the wrong way?
Thanks
In case anyone stumbles across this as I did. The clue is in Marek R's answer about parents. When you insert an item into a model and that item is already in another model it will cause this issue.
To fix it you need to make a new QStandardItem encapsulating the data from the existing QStandardItem.
Hopefully how I fixed it makes sense.
This was my code experiencing the same issue (copying new rows of text from m_logModel to m_model):
for (int i = first; i <= last; i++)
{
QList<QStandardItem*> nextRow;
for (int j = 0; j < m_logModel->columnCount(); j++)
{
nextRow << m_logModel->item(i, j);
}
m_model->appendRow(nextRow);
}
This changed code makes it work as expected:
for (int i = first; i <= last; i++)
{
QList<QStandardItem*> nextRow;
for (int j = 0; j < m_logModel->columnCount(); j++)
{
nextRow << new QStandardItem(m_logModel->item(i, j)->text());
}
m_model->appendRow(nextRow);
}
Hopefully this will help the next person who finds this issue.

Resources