1

I'm unable to click one button, then click another button to swap with the previously clicked button. Then make the first clicked button a blank button.

I can't think of how to do this. I just try with if statements like

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
}

this doesn't work because it goes straight passed the second if statement, and makes the first button blank without swapping anything.

not much code to go off of, this is just test code to figure out this single action

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();
    }
}
c0der
  • 18,467
  • 6
  • 33
  • 65
Travelsbyfire
  • 35
  • 1
  • 10
  • Should this `GridPane` hold buttons only ? what is the purpose of the `Canvas` ? – c0der Jul 28 '19 at 04:33
  • I'm not sure what else the GridPane would hold, unless you mean having another class wrap itself over the button array? I have no idea what the canvas is for, I'm so new to javafx, this is just how my book explained building a graphical display – Travelsbyfire Jul 28 '19 at 22:50

3 Answers3

0

You could create a property to save the selected button state.... But I think "changing the text" isn't really going to help you create a chess game. I would have a "ChessPiece" object with its underlying rules/properties...

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

         }
     });

  }
trilogy
  • 1,738
  • 15
  • 31
  • Yeah this was just code to figure out the swapping action, my other code has all the classes for chess pieces and what not that are connected to the button arrays. Ok so your suggestion is similar to the other message, except you're using code that looks like you know what you're doing haha – Travelsbyfire Jul 28 '19 at 20:00
  • It’s similar as in I’m keeping the buttons in their place and only changing their appearance. The other suggestion takes the actual buttons and moves them. You would have to decide which methodology is best. He/she used a for-each loop, which is fine, but in this case, when you’re literally working with a grid, your loop style is actually more clear imo. – trilogy Jul 28 '19 at 22:50
0

i don't really know how this can be useful in a chess game but here is what i did to swap two buttons in a gridPane

i created a variable for the first-clicked button that would remain "null" until you click a button, so the first click will save the clicked button in 'first', and the second click will swap and erase the content of 'first'

to swap them i have to retrieve their position in the gridPane (i only saved the column index and you might need to save the row index as well)

//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;
        }
    });
}
SDIDSA
  • 894
  • 10
  • 19
  • what does the statement "for(Button button : buttons)" do? For the else if part, in what case would clicking a button not prompt the variable first to be found as null and be assigned button that it wouldn't be found as != button? if that made any sense? Is it just for reassurance? – Travelsbyfire Jul 28 '19 at 19:49
  • for(Button button:buttons) is a for-each loop (you can look it up), note that you can still use your method to loop through the array, the variable first would be not null if you have previously clicked a button, if you click a button and first is null, the button gets saved in first so the next time you click a button, first won't be null so the program knows that's the second button you click and knows that it's time to swap, and about the second if statement, it only checks if you're trying to swap the same button so it doesn't do the swap, if you click the same button twice nothing happens – SDIDSA Jul 28 '19 at 21:26
0

The following is mre of swapping two buttons in a 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);
    }
}

enter image description here

c0der
  • 18,467
  • 6
  • 33
  • 65
  • damn, all that just to swap a couple buttons? I've got some work ahead of me to try and understand this code. I really appreciate the post – Travelsbyfire Jul 30 '19 at 19:06
  • So do you not need to use an Event Handler to use a button? That's the only method I was taught about. – Travelsbyfire Jul 30 '19 at 19:20
  • What is the purpose of the node array? I see the `nodes[colIndex]= node;` assigns the button object to it, but why? I've never used the node class, and the oracle documentation explains that it's the Base class for scene graph nodes. Are all things in graphical forms a node in that case? Is there a similar type of class that does the same thing, or is this the one class that should always be used for buttons and other things graphical? – Travelsbyfire Jul 30 '19 at 20:18
  • See the comments I added. Each button is assigned an even handler. The `Node` class is the super class of `Control` class. See [here](https://docs.oracle.com/javase/8/javafx/api/overview-tree.html) the full hierarchy. If you find it confusing you can use `Button[]`. – c0der Jul 31 '19 at 04:19