Javafx如何在GridPane中定位特定按钮

Javafx如何在GridPane中定位特定按钮,java,button,javafx,gridpane,Java,Button,Javafx,Gridpane,我正在做一个带按钮的跳棋游戏。要杀死另一个棋子,你必须将你的棋子斜移到另一个棋子上,但我不知道如何确保你的棋子移到另一个棋子上 我解决这个问题的想法是得到第二个按钮的行和列,这是你的作品移动到的按钮,然后从每行和每列中减去1,然后从该按钮中得到文本,以测试它是“黑色”还是“红色” 第一个和第二个=按钮 System.out.println((GridPane.getColumnIndex(second) + " vs " + (GridPane.getColumnIndex(second) -

我正在做一个带按钮的跳棋游戏。要杀死另一个棋子,你必须将你的棋子斜移到另一个棋子上,但我不知道如何确保你的棋子移到另一个棋子上

我解决这个问题的想法是得到第二个按钮的行和列,这是你的作品移动到的按钮,然后从每行和每列中减去1,然后从该按钮中得到文本,以测试它是“黑色”还是“红色”

第一个和第二个=按钮

System.out.println((GridPane.getColumnIndex(second) + " vs " + (GridPane.getColumnIndex(second) - 1)));


    if (GridPane.getColumnIndex(second) > 0) {
        System.out.println("checking if a button has been jumped");
        GridPane.setRowIndex(second, (GridPane.getRowIndex(second) - 1));
        GridPane.setColumnIndex(second, (GridPane.getColumnIndex(second) - 1));
        System.out.println("this is a printing of the second button name for location " + (GridPane.getColumnIndex(second)) + " " + (GridPane.getRowIndex(second)) + " " + second.getText());

        if (second.getText().contains("black")) {
            System.out.println("it's a kill");
        } 
        else {
            System.out.println("no kill");
            GridPane.setRowIndex(second, (GridPane.getRowIndex(second) + 1));
            GridPane.setColumnIndex(second, (GridPane.getColumnIndex(second) + 1));
        }
    }

我可以将行和列更改为与另一块的位置匹配的内容,但是当我从那个按钮(第二个)得到文本时,它不会返回为“黑色”或“红色”的名称,而只是空白按钮的名称。


我的猜测是GridPane可能不会像这样工作,我只需要想出另一个解决方案,希望我不必将整个代码作为2d数组或其他东西来重做。

所以这是可能的,我从这篇文章中找到了答案。他只需要用自己的方法找到具体的位置。

}

尽管出于我自己的目的,我仍然需要弄清楚如何能够测试节点是否包含“红色”或“黑色”,所以我刚刚添加了这个,现在一切都正常了

private Boolean getNodeFromGridPane(GridPane gridPane, int col, int row) {

    for (Node node : gridPane.getChildren()) {
        if (GridPane.getColumnIndex(node) == col && GridPane.getRowIndex(node) == row) {

            if (node.toString().contains("black")) {

                System.out.println("The second button is black = " + node.toString().contains("black"));

                return true;
            }

            if (node.toString().contains("red")) {

                System.out.println("The second button is red = " + node.toString().contains("red"));

                return true;
            }

        }
    }
    return false;

}

通过迭代
GridPane
子节点,可以获得对
GridPane
中节点的引用
添加一些简单计算,以查找单击的两个按钮之间的对角线(如果有):

import java.awt.Toolkit;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class FxMain extends Application {

    private static final int COLS = 5, ROWS = 5;
    private int clickCounter = 0;
    private GridPane grid;
    private Button first, second;

    @Override
    public void start(Stage primaryStage){

        VBox root = new VBox(10);
        root.setPadding(new Insets(10));
        root.getChildren().addAll(makeGrid(), 
                new Text("Click 2 buttons to find the \n diagonally between them"));
        primaryStage.setScene(new Scene(root));
        primaryStage.sizeToScene();
        primaryStage.show();
    }

    private Pane makeGrid() {

        grid = new GridPane();
        for(int rowIndex = 0; rowIndex < ROWS ; rowIndex++) {
            //an array to hold buttons of one row
            Node[] nodes = new Node[COLS];
            for(int colIndex = 0; colIndex < COLS ; colIndex++) {
                Button node= new Button(rowIndex+""+colIndex);
                node.setOnAction(e->buttonCliked(node)); //add action listener
                nodes[colIndex]= node;
            }
            grid.addRow(rowIndex, nodes);
        }
        return grid;
    }

    private void buttonCliked(Button button) {

        if(clickCounter == 0){
            first = button;
        }else{
            second = button;
            markNode(findMidDiagonalButton());
        }

        System.out.println(clickCounter + " " + button.getText()    );
        clickCounter=  ++clickCounter %2 ;  // changes values between 0 1
    }

    //change node background for a short while, and then reset it
    private void markNode(Node node) {

        if(node == null) return;
        String style = node.getStyle();
        node.setStyle("-fx-background-color: cornflowerblue;");
        PauseTransition pause = new PauseTransition(Duration.seconds(1));
        pause.play();
        pause.setOnFinished(e-> node.setStyle(style));
    }

    private Node findMidDiagonalButton() {

        int rowDelta = GridPane.getRowIndex(first) - GridPane.getRowIndex(second);
        int colDelta = GridPane.getColumnIndex(first) - GridPane.getColumnIndex(second);

        if( Math.abs(rowDelta) != 2 ||  Math.abs(colDelta) != 2 ){
            Toolkit.getDefaultToolkit().beep();
            return null;
        }

        int rowsSum = GridPane.getRowIndex(first) + GridPane.getRowIndex(second);
        int colsSum = GridPane.getColumnIndex(first) + GridPane.getColumnIndex(second);

        return  getNodeByRowCol(Math.abs(rowsSum / 2), Math.abs(colsSum / 2) );
    }

    public Node getNodeByRowCol (int row, int col) {

        for (Node node : grid.getChildren()) {
            if(GridPane.getRowIndex(node) == row && GridPane.getColumnIndex(node) == col)
                return node;
        }

        return null;
    }

    public static void main(final String[] args) {
        launch(args);
    }
}
导入java.awt.Toolkit;
导入javafx.animation.PauseTransition;
导入javafx.application.application;
导入javafx.geometry.Insets;
导入javafx.scene.Node;
导入javafx.scene.scene;
导入javafx.scene.control.Button;
导入javafx.scene.layout.GridPane;
导入javafx.scene.layout.Pane;
导入javafx.scene.layout.VBox;
导入javafx.scene.text.text;
导入javafx.stage.stage;
导入javafx.util.Duration;
公共类FxMain扩展了应用程序{
私有静态final int COLS=5,行=5;
私有int clickCounter=0;
私有网格;
私人按钮第一,第二;
@凌驾
公共无效开始(阶段primaryStage){
VBox根=新的VBox(10);
根。设置填充(新插图(10));
root.getChildren().addAll(makeGrid(),
新文本(“单击两个按钮以找到它们之间的对角线”);
primaryStage.setScene(新场景(根));
primaryStage.sizeToScene();
primaryStage.show();
}
私有窗格makeGrid(){
grid=新的GridPane();
对于(int-rowIndex=0;rowIndexbuttonliked(node));//添加操作侦听器
节点[colIndex]=节点;
}
addRow(行索引,节点);
}
返回网格;
}
私有无效按钮(按钮按钮){
如果(单击计数器==0){
第一个=按钮;
}否则{
第二个=按钮;
markNode(findMidDiagonalButton());
}
System.out.println(单击计数器+“”+按钮.getText());
clickCounter=++clickCounter%2;//在0和1之间更改值
}
//暂时更改节点背景,然后将其重置
私有void标记节点(节点节点){
if(node==null)返回;
String style=node.getStyle();
node.setStyle(“-fx背景色:矢车菊蓝;”);
暂停转换暂停=新的暂停转换(持续时间。秒(1));
暂停。玩();
pause.setOnFinished(e->node.setStyle(样式));
}
专用节点FindDidDiagonalButton(){
int rowdta=GridPane.getRowIndex(第一个)-GridPane.getRowIndex(第二个);
int colDelta=GridPane.getColumnIndex(第一个)-GridPane.getColumnIndex(第二个);
if(Math.abs(rowDelta)!=2 | | Math.abs(colDelta)!=2){
getDefaultToolkit().beep();
返回null;
}
int-rowsSum=GridPane.getRowIndex(第一)+GridPane.getRowIndex(第二);
int colsSum=GridPane.getColumnIndex(第一)+GridPane.getColumnIndex(第二);
返回getNodeByRowCol(Math.abs(rowsSum/2)、Math.abs(colsSum/2));
}
公共节点getNodeByRowCol(int行,int列){
对于(节点:grid.getChildren()){
if(GridPane.getRowIndex(节点)=行和&GridPane.getColumnIndex(节点)==列)
返回节点;
}
返回null;
}
公共静态void main(最终字符串[]args){
发射(args);
}
}


C++中没有什么东西是C++引用的。code>setColumn/RowIndex不会更改作为第一个参数传递给另一个节点的值…因此,实际上,唯一的其他方法是使用2d按钮数组来访问特定节点?您可以在子列表中找到相应的子节点,但这是一个更复杂的问题:如果您担心每次移动子对象时都必须同时更新
GridPane
和数组,只需创建一个负责更新布局参数和数组的方法。我实际上刚刚了解了如何操作,并将其发布在下面。哦,这和我发现的代码也很相似。谢谢你的帮助!
import java.awt.Toolkit;
import javafx.animation.PauseTransition;
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Duration;

public class FxMain extends Application {

    private static final int COLS = 5, ROWS = 5;
    private int clickCounter = 0;
    private GridPane grid;
    private Button first, second;

    @Override
    public void start(Stage primaryStage){

        VBox root = new VBox(10);
        root.setPadding(new Insets(10));
        root.getChildren().addAll(makeGrid(), 
                new Text("Click 2 buttons to find the \n diagonally between them"));
        primaryStage.setScene(new Scene(root));
        primaryStage.sizeToScene();
        primaryStage.show();
    }

    private Pane makeGrid() {

        grid = new GridPane();
        for(int rowIndex = 0; rowIndex < ROWS ; rowIndex++) {
            //an array to hold buttons of one row
            Node[] nodes = new Node[COLS];
            for(int colIndex = 0; colIndex < COLS ; colIndex++) {
                Button node= new Button(rowIndex+""+colIndex);
                node.setOnAction(e->buttonCliked(node)); //add action listener
                nodes[colIndex]= node;
            }
            grid.addRow(rowIndex, nodes);
        }
        return grid;
    }

    private void buttonCliked(Button button) {

        if(clickCounter == 0){
            first = button;
        }else{
            second = button;
            markNode(findMidDiagonalButton());
        }

        System.out.println(clickCounter + " " + button.getText()    );
        clickCounter=  ++clickCounter %2 ;  // changes values between 0 1
    }

    //change node background for a short while, and then reset it
    private void markNode(Node node) {

        if(node == null) return;
        String style = node.getStyle();
        node.setStyle("-fx-background-color: cornflowerblue;");
        PauseTransition pause = new PauseTransition(Duration.seconds(1));
        pause.play();
        pause.setOnFinished(e-> node.setStyle(style));
    }

    private Node findMidDiagonalButton() {

        int rowDelta = GridPane.getRowIndex(first) - GridPane.getRowIndex(second);
        int colDelta = GridPane.getColumnIndex(first) - GridPane.getColumnIndex(second);

        if( Math.abs(rowDelta) != 2 ||  Math.abs(colDelta) != 2 ){
            Toolkit.getDefaultToolkit().beep();
            return null;
        }

        int rowsSum = GridPane.getRowIndex(first) + GridPane.getRowIndex(second);
        int colsSum = GridPane.getColumnIndex(first) + GridPane.getColumnIndex(second);

        return  getNodeByRowCol(Math.abs(rowsSum / 2), Math.abs(colsSum / 2) );
    }

    public Node getNodeByRowCol (int row, int col) {

        for (Node node : grid.getChildren()) {
            if(GridPane.getRowIndex(node) == row && GridPane.getColumnIndex(node) == col)
                return node;
        }

        return null;
    }

    public static void main(final String[] args) {
        launch(args);
    }
}