1
votes

Échange de nœuds dans un Gridpane pour une partie d'échecs

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
}


2 commentaires

Ce GridPane doit-il contenir uniquement des boutons? quel est le but du Canvas ?


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


3 Réponses :


0
votes

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

         }
     });

  }


2 commentaires

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.



0
votes

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


2 commentaires

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



0
votes

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

 entrez la description de l'image ici


4 commentaires

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 [] .