javafx GridPane извлекает определенное содержимое ячейки

Я хочу получить содержимое одной конкретной ячейки в Gridpane. Я разместил кнопки в ячейках с

setConstraints(btt , 0 ,1 ) 

setConstraints(btt , 0 ,2 )

getChildren().add....

В моем случае GridPane.getChildren.get(10) не годится. Я хочу перейти непосредственно к ячейке (4,2) и получить ее содержимое.


person Elias Elias    schedule 18.12.2013    source источник
comment
Спасибо большое за ответ   -  person Elias Elias    schedule 18.12.2013


Ответы (5)


Ну, я думаю, если нет решения для получения определенного узла из панели сетки по индексу столбца и строки, у меня есть функция для этого,

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;
}
person Shreyas Dave    schedule 18.12.2013
comment
Крайне странно, что после стольких лет java не предоставляет базовой функциональности, и вам приходится использовать такие неэффективные обходные пути, чтобы базовые вещи работали. Но я думаю, что в основе лежит базовая структура данных. - person th3penguinwhisperer; 07.04.2018
comment
Убедитесь, что ваши ограничения установлены. Scenebuilder любит рассматривать 0 как не установленный и обнуляет поле. Поэтому вручную установите ограничения в файле fxml. например, ‹Canvas GridPane.columnIndex="0" GidPan.rowIndex="0"›. Кроме того, поскольку не гарантируется возврат ненулевого значения из getRowIndex/getColumnIndex, вы должны использовать объект Integer и проверять наличие null в операторе if. например if(null != nodeRow && null != nodeCol ... - person Olmstov; 10.12.2018
comment
Не могли бы вы рассказать мне, как реализовать это для label ? - person Mayur Patel; 26.08.2019

Предполагая, что у вас есть girdPane 8x8, где i — это строки, а j — столбец, вы можете написать:

myGridPane.getChildren().get(i*8+j)

Тип возвращаемого значения — это объект, поэтому вам придется его привести, в моем случае это:

(StackPane) (myGridPane.getChildren().get(i*8+j))

person Ahmad Tn    schedule 27.12.2016
comment
В некоторых случаях это может быть правдой, но дочерний список не обязательно сохраняется в порядке строки/столбца и может быть изменен позже с помощью GridPane.setRowIndex() и т.д. - person Adam; 19.07.2017
comment
Я никогда не использовал setRowIndex(), поэтому ничего не могу сказать. Это решение сработало для меня, и я считаю, что оно должно выполнять работу в большинстве случаев, когда вы не изменяете индексы строк/столбцов по умолчанию. - person Ahmad Tn; 23.07.2017
comment
Что произойдет, если в конкретной ячейке изначально нет узла? - person ihavenoidea; 22.05.2018
comment
@leandrocoutom Я не уверен, что происходит. Я не работаю с javafx в настоящее время, поэтому я не могу точно сказать. Но он отвечает на вопрос о извлечении контента из ячейки. Если вы попробуете это сами, я хотел бы знать, что произойдет. Спасибо - person Ahmad Tn; 23.05.2018

У меня были некоторые проблемы с представленным решением в этом вопросе, потому что метод 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;
}
person F.M.    schedule 01.09.2020

Вы можете добавить список, который содержит каждого дочернего элемента сетки, и каждый родитель дочернего элемента должен иметь две целые строки и столбец, поэтому вам просто нужно просмотреть этот список и посмотреть, имеет ли он правильные координаты! (Возможно, вам следует добавить новый класс, чтобы вы могли хранить эти координаты), вот минимальный пример моего решения

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;
    }
}
person BHA Bilel    schedule 26.03.2019

Как сказано в дубликат, у вас могут быть проблемы с производительностью с выбранным ответом (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
person Dorian N.    schedule 21.12.2020