Javafx 如何在 GridPane 中定位特定按钮
Javafx How to locate a specific button in a GridPane
我正在制作一款带按钮的西洋跳棋游戏。要杀死另一个棋子,你必须将你的棋子沿对角线移动到另一个棋子上,但我不确定如何确保你的棋子移动到另一个棋子上。
我解决这个问题的想法是获取第二个按钮的行和列,这是你的棋子移动到的按钮,然后从每个行和列中减去 1,然后从该按钮获取文本测试它是 "black" 还是 "red".
第一个和第二个 = 按钮
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));
}
}
我可以将行和列更改为与另一部分的位置相匹配的内容,但是当我从该按钮(第二个)获取文本时,它不会作为名称返回 "black" 或 "red",而只是空白按钮的名称。
我的猜测是 GridPane 可能不会像这样工作,我只需要想出另一个解决方案,希望我不必将整个代码重做为二维数组或其他东西。
所以有可能,我从这个post中找到了答案。他只要自己想办法,就能找到具体的位置。
javafx GridPane retrieve specific Cell content
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;
}
虽然,为了我自己的目的,我仍然需要弄清楚如何能够测试节点是否包含 "red" 或 "black",所以我只是添加了这个,现在它一切正常!
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);
}
}
我正在制作一款带按钮的西洋跳棋游戏。要杀死另一个棋子,你必须将你的棋子沿对角线移动到另一个棋子上,但我不确定如何确保你的棋子移动到另一个棋子上。
我解决这个问题的想法是获取第二个按钮的行和列,这是你的棋子移动到的按钮,然后从每个行和列中减去 1,然后从该按钮获取文本测试它是 "black" 还是 "red".
第一个和第二个 = 按钮
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));
}
}
我可以将行和列更改为与另一部分的位置相匹配的内容,但是当我从该按钮(第二个)获取文本时,它不会作为名称返回 "black" 或 "red",而只是空白按钮的名称。
我的猜测是 GridPane 可能不会像这样工作,我只需要想出另一个解决方案,希望我不必将整个代码重做为二维数组或其他东西。
所以有可能,我从这个post中找到了答案。他只要自己想办法,就能找到具体的位置。 javafx GridPane retrieve specific Cell content
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;
}
虽然,为了我自己的目的,我仍然需要弄清楚如何能够测试节点是否包含 "red" 或 "black",所以我只是添加了这个,现在它一切正常!
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);
}
}