Je ne parviens pas à cliquer sur un bouton, puis sur un autre bouton pour échanger avec le bouton précédemment cliqué. Ensuite, faites du premier bouton cliqué un bouton vide.
Je ne vois pas comment faire cela. J'essaie juste avec des instructions if comme
public class SimpleButtonSwapper extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { GridPane pane = new GridPane(); pane.setPadding(new Insets(50, 50, 50, 50)); //creates 50 pixel padding pane.setVgap(2); pane.setHgap(2); Scene scene = new Scene(pane); Canvas canvas = new Canvas(50, 400); GraphicsContext graphics = canvas.getGraphicsContext2D(); pane.getChildren().add(canvas); stage.setTitle("Chess"); Button[] buttons = new Button[6]; for (int i = 0; i < 6; i++) { buttons[i] = new Button(); buttons[i].setText("banana " + i); } for (int i = 0; i < 6; i++) { pane.add(buttons[i], i, 0); } for (int i = 0; i < 6; i++) { buttons[i].setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { } }); } stage.setScene(scene); stage.show(); } }
cela ne fonctionne pas car il passe directement la deuxième instruction if et rend le premier bouton vide sans rien échanger. P >
il n'y a pas beaucoup de code à utiliser, c'est juste du code de test pour comprendre cette action unique
If button = this{ //this should find the first button if button = that{ //this should find the second button that = this //this swaps the buttons } this = blank //and ends with making the first button blank }
3 Réponses :
Vous pouvez créer une propriété pour enregistrer l'état du bouton sélectionné ... Mais je pense que "changer le texte" ne va pas vraiment vous aider à créer une partie d'échecs. J'aurais un objet "ChessPiece" avec ses règles / propriétés sous-jacentes ...
SimpleObjectProperty<Button> selectedButtonProperty = new SimpleObjectProperty<>(); for (int i = 0; i < 6; i++) { buttons[i].setOnAction(new EventHandler<ActionEvent>() { @Override public void handle(ActionEvent event) { Button thisButton = (Button) event.getSource(); if (selectedButtonProperty.get() == null) { selectedButtonProperty.set(thisButton); } else { thisButton.setText(selectedButtonProperty.get().getText()); selectedButtonProperty.get().setText(null); selectedButtonProperty.set(null); } } }); }
Ouais, c'était juste du code pour comprendre l'action d'échange, mon autre code a toutes les classes pour les pièces d'échecs et tout ce qui n'est pas connecté aux tableaux de boutons. Ok, donc votre suggestion est similaire à l'autre message, sauf que vous utilisez un code qui semble savoir ce que vous faites haha
C’est comme dans Je garde les boutons à leur place et ne change que leur apparence. L'autre suggestion prend les boutons réels et les déplace. Vous devrez décider quelle méthodologie est la meilleure. Il / elle a utilisé une boucle for-each, ce qui est bien, mais dans ce cas, lorsque vous travaillez littéralement avec une grille, votre style de boucle est en fait plus clair imo.
Je ne sais pas vraiment comment cela peut être utile dans une partie d'échecs mais voici ce que j'ai fait pour échanger deux boutons dans un gridPane
J'ai créé une variable pour le premier bouton cliqué qui resterait "null" jusqu'à ce que vous cliquiez sur un bouton, le premier clic enregistrera le bouton cliqué dans 'premier', et le deuxième clic échangera et effacera le contenu de 'premier'
pour les échanger je dois récupérer leur position dans le gridPane (je n'ai enregistré que l'index de colonne et vous devrez peut-être également enregistrer l'index de ligne)
//looping through the buttons for (Button button : buttons) { //adding a listener button.setOnAction(e -> { if (first == null) first = button; else { if (first != button) { Button second = button; int index1 = GridPane.getColumnIndex(first); int index2 = GridPane.getColumnIndex(second); pane.getChildren().removeAll(first, second); pane.add(first, index2, 0); pane.add(second, index1, 0); } first = null; } }); }
que fait l'instruction "pour (bouton bouton: boutons)"? Pour la partie else if, dans quel cas le fait de cliquer sur un bouton ne demanderait-il pas à la variable d'être d'abord trouvée comme nulle et se verrait attribuer un bouton qui ne serait pas trouvé comme! = Bouton? Si cela avait du sens? Est-ce juste pour se rassurer?
for (Button button: buttons) est une boucle for-each (vous pouvez la rechercher), notez que vous pouvez toujours utiliser votre méthode pour parcourir le tableau, la variable d'abord ne serait pas nulle si vous avez déjà cliqué sur un bouton, si vous cliquez sur un bouton et que le premier est nul, le bouton est enregistré en premier donc la prochaine fois que vous cliquez sur un bouton, le premier ne sera pas nul afin que le programme sache que c'est le deuxième bouton sur lequel vous cliquez et sait qu'il est temps d'échanger, et à propos de la deuxième instruction if, il ne vérifie que si vous essayez d'échanger le même bouton afin qu'il ne fasse pas l'échange, si vous cliquez deux fois sur le même bouton, rien ne se passe
Ce qui suit est mre d'échanger deux boutons dans un GridPane
:
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; 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 swap 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(e.getSource())); //add action listener node.prefHeight(100); node.prefWidth(100); nodes[colIndex]= node; } grid.addRow(rowIndex, nodes); } return grid; } private void buttonCliked(Object source) { if(!(source instanceof Button)) return; Button button = (Button)source; if(clickCounter == 0){ first = button; }else{ second = button; swap(); } System.out.println(clickCounter + " " + ((Button)source).getText() ); clickCounter= ++clickCounter %2 ; // changes values between 0 1 } private void swap() { int firstRow = GridPane.getRowIndex(first); int firstCol = GridPane.getColumnIndex(first); int secondRow = GridPane.getRowIndex(second); int secondCol = GridPane.getColumnIndex(second); grid.getChildren().removeAll(first, second); grid.add(first, secondCol, secondRow); grid.add(second, firstCol, firstRow); } public static void main(final String[] args) { launch(args); } }
putain, tout ça juste pour échanger quelques boutons? J'ai du travail devant moi pour essayer de comprendre ce code. J'apprécie vraiment le post
Vous n'avez donc pas besoin d'utiliser un gestionnaire d'événements pour utiliser un bouton? C'est la seule méthode qui m'a été enseignée.
Quel est le but du tableau de nœuds? Je vois le nodes [colIndex] = node;
lui attribue l'objet bouton, mais pourquoi? Je n'ai jamais utilisé la classe node, et la documentation oracle explique que c'est la classe Base pour les nœuds de graphe de scène. Toutes les choses sous forme graphique sont-elles un nœud dans ce cas? Existe-t-il un type de classe similaire qui fait la même chose, ou est-ce la seule classe qui devrait toujours être utilisée pour les boutons et autres éléments graphiques?
Voir les commentaires que j'ai ajoutés. Chaque bouton se voit attribuer un gestionnaire pair. La classe Node
est la super classe de la classe Control
. Consultez ici la hiérarchie complète. Si vous trouvez cela déroutant, vous pouvez utiliser Button []
.
Ce
GridPane
doit-il contenir uniquement des boutons? quel est le but duCanvas
?Je ne suis pas sûr de ce que le GridPane contiendrait d'autre, sauf si vous voulez dire qu'une autre classe s'enroule sur le tableau de boutons? Je n'ai aucune idée à quoi sert le canevas, je suis tellement nouveau sur javafx, c'est comme ça que mon livre expliquait la construction d'un affichage graphique