javafx GridPane получить определенное содержимое ячейки
Я хочу получить содержимое одной конкретной ячейки в Gridpane. Я положил кнопки в ячейках с
setConstraints(btt , 0 ,1 )
setConstraints(btt , 0 ,2 )
getChildren().add....
В моем случае GridPane.getChildren.get(10)
не хорошо. Я хочу пойти прямо в ячейку (4,2) и получить ее содержимое.
5 ответов
Ну, я думаю, что если нет решения, чтобы получить конкретный узел из gridpane по столбцу и индексу строки, у меня есть функция для этого,
private Node getNodeFromGridPane(GridPane gridPane, int col, int row) {
for (Node node : gridPane.getChildren()) {
if (GridPane.getColumnIndex(node) == col && GridPane.getRowIndex(node) == row) {
return node;
}
}
return null;
}
Предполагая, что у вас есть 8x8 GirdPane где i
это строки и j
это столбец, вы можете написать:
myGridPane.getChildren().get(i*8+j)
Тип возвращаемого значения - это объект, поэтому вам придется его привести, в моем случае это:
(StackPane) (myGridPane.getChildren().get(i*8+j))
У меня возникли проблемы с представленным решением в этом вопросе, потому что метод GridPane.getColumnIndex(Node node)
может вернуться null
в первой строке или столбце (когда фактически индекс равен 0). Поэтому я работал с классом-оболочкойInteger
и пришел к следующему решению. Может быть, это поможет другим с той же проблемой.
private Node getNodeFromGridPane(GridPane gridPane, int col, int row) {
ObservableList<Node> children = gridPane.getChildren();
for (Node node : children) {
Integer columnIndex = GridPane.getColumnIndex(node);
Integer rowIndex = GridPane.getRowIndex(node);
if (columnIndex == null)
columnIndex = 0;
if (rowIndex == null)
rowIndex = 0;
if (columnIndex == col && rowIndex == row) {
return node;
}
}
return null;
}
Вы можете добавить список, который содержит каждого дочернего элемента в сетке, и родительский элемент каждого дочернего элемента должен иметь две целые строки и столбца, поэтому вам просто нужно просмотреть этот список и посмотреть, имеет ли он правильные координаты! (Вы, вероятно, должны добавить новый класс, чтобы вы могли хранить эти координаты), вот минимальный пример моего решения
import java.util.ArrayList;
import java.util.List;
import javafx.scene.Node;
import javafx.scene.layout.GridPane;
public class SpecialGridPane extends GridPane {
List<NodeParent> list = new ArrayList<>();
public void addChild(int row, int column, Node node) {
list.add(new NodeParent(row, column, node));
setConstraints(node, column, row);
getChildren().add(node);
}
public Node getChild(int row, int column) {
for (NodeParent node : list) {
if (node.getRow() == row && node.getColumn() == column)
return node.getNode();
}
return null;
}
}
class NodeParent {
private int row;
private int column;
private Node node;
public NodeParent(int row, int column, Node node) {
this.row = row;
this.column = column;
this.node = node;
}
public int getRow() {
return row;
}
public int getColumn() {
return column;
}
public Node getNode() {
return node;
}
}
Как сказано в дубликат, у вас могут быть проблемы с производительностью с выбранным ответом (getNodeFromGridPane)
Вот способ преодолеть это: https://stackoverflow.com/a/65386693/11284920 Но, подводя итог:
1. иметь двумерный массив:
private Node[][] gridPaneArray = null;
2. Вызовите подобный метод во время инициализации вашего представления:
private void initializeGridPaneArray()
{
this.gridPaneArray = new Node[this.gridModel.getLines() [this.gridModel.getColumns()];
for(Node node : this.mainPane.getChildren())
{
this.gridPaneArray[GridPane.getRowIndex(node)][GridPane.getColumnIndex(node)] = node;
}
}
3. Получите свой узел
Node n = this.gridPaneArray[x][y]; // and cast it to any type you want/need