【问题标题】:javafx GridPane retrieve specific Cell contentjavafx GridPane 检索特定的单元格内容
【发布时间】:2014-01-06 10:43:50
【问题描述】:

我想检索 Gridpane 中一个特定单元格的内容。我已经在带有

的单元格中放置了按钮
setConstraints(btt , 0 ,1 ) 

setConstraints(btt , 0 ,2 )

getChildren().add....

就我而言,GridPane.getChildren.get(10) 不好。我想直接进入 cell(4,2) 并获取它的内容。

【问题讨论】:

  • 非常感谢您的回复

标签: javafx cell gridpanel


【解决方案1】:

好吧,我想如果没有解决方案可以通过列和行索引从网格窗格中获取特定节点,我有一个函数可以做到这一点,

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;
}

【讨论】:

  • 很奇怪,这么多年来,Java 不提供基本功能,而您必须使用这些低效的变通方法才能使基本的东西正常工作。但我想这是基础的底层数据结构。
  • 确保您的约束已设置。 Scenebuilder 喜欢将 0 视为未设置并将该字段设为空。所以在fxml文件中手动设置约束。例如 。此外,由于不能保证从 getRowIndex/getColumnIndex 返回非空值,因此您应该使用 Integer 对象并在 if 语句中检查空值。例如if(null != nodeRow && null != nodeCol ...
  • 你能告诉我如何为label 实现这个吗?
【解决方案2】:

假设您有一个 8x8 girdPane,其中 i 是行,j 是列,您可以这样写:

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

返回类型是一个对象,所以你必须强制转换它,在我的例子中是:

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

【讨论】:

  • 这在某些情况下可能是正确的,但子列表不一定按行/列的顺序维护,以后可能会使用 GridPane.setRowIndex() 等进行更改...
  • 我从来没有用过 setRowIndex() 所以我不能说太多。这个解决方案对我有用,我相信当您不更改默认行/列索引时,大多数时候应该可以完成工作。
  • 如果首先在特定单元格内没有节点会发生什么?
  • @leandrocoutom 我不确定会发生什么。我现在不使用 javafx,所以我真的说不出来。但它回答了从单元格中检索 content 的问题。如果您自己尝试一下,我想知道会发生什么。谢谢
【解决方案3】:

我在这个问题中提出的解决方案遇到了一些问题,因为方法 GridPane.getColumnIndex(Node node) 可能会在第一行或第一列中返回 null(当索引实际上为 0 时)。因此,我使用了 wrapperclass 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;
}

【讨论】:

    【解决方案4】:

    您可以添加一个包含网格窗格的每个子项的列表,并且每个子项的父项必须有两个整数行和列,因此您只需要遍历该列表并查看它是否具有正确的坐标! (您应该适当地添加一个新类,以便您可以存储这些坐标),这是我的解决方案的一个最小示例

    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;
        }
    }
    

    【讨论】:

      【解决方案5】:

      正如在重复中所说,您可能对所选答案 (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
      

      【讨论】:

        猜你喜欢
        • 2018-12-20
        • 2016-09-30
        • 2014-05-09
        • 2019-05-11
        • 2011-10-30
        • 1970-01-01
        • 2016-01-27
        • 2015-02-09
        • 1970-01-01
        相关资源
        最近更新 更多