Search code examples
javajavafxvbox

How to properly stack shapes in a vbox? JavaFX


I'm currently trying to create a tower of hanoi in javafx. I'm a bit lost on how to make the rectangles properly stack in each VBox. If you run the code below, moving more than one block to the same vbox will result in the newest block added being at the bottom, but it should be at the top. How can I implement this properly?

Thanks in advance.

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class TowersOfHanoi extends Application {
Rectangle selectedpiece;
VBox selectedbox;
Paint temp;

public static void main(String[] args){
    launch();
}
@Override
public void start(Stage mainStage) throws Exception {
    GridPane gp = new GridPane();

    //Adding 3 panels
    VBox panel1 = new VBox();
    panel1.setBackground(new Background(new BackgroundFill(Color.LIGHTGREEN, CornerRadii.EMPTY, Insets.EMPTY)));
    panel1.setAlignment(Pos.BOTTOM_CENTER);
    panel1.setPrefHeight(980);
    panel1.setPrefWidth(500);
    panel1.setSpacing(1);
    panel1.setPadding(new Insets(0, 20, 10, 20));
    panel1.setOnMouseClicked(new panelEventHandler());

    VBox panel2 = new VBox();
    panel2.setBackground(new Background(new BackgroundFill(Color.LIGHTBLUE, CornerRadii.EMPTY, Insets.EMPTY)));
    panel2.setAlignment(Pos.BOTTOM_CENTER);
    panel2.setPrefHeight(500);
    panel2.setPrefWidth(500);
    panel2.setSpacing(1);
    panel2.setPadding(new Insets(0, 20, 10, 20));
    panel2.setOnMouseClicked(new panelEventHandler());

    VBox panel3 = new VBox();
    panel3.setBackground(new Background(new BackgroundFill(Color.LIGHTSALMON, CornerRadii.EMPTY, Insets.EMPTY)));
    panel3.setAlignment(Pos.BOTTOM_CENTER);
    panel3.setPrefHeight(500);
    panel3.setPrefWidth(500);
    panel3.setSpacing(1);
    panel3.setPadding(new Insets(0, 20, 10, 20));
    panel3.setOnMouseClicked(new panelEventHandler());

    //Adding all 4 pieces
    Rectangle piece1 = new Rectangle(250, 50);
    piece1.setFill(Color.RED);
    piece1.setStroke(Color.BLACK);
    panel1.getChildren().add(piece1);
    piece1.setOnMouseClicked(new pieceEventHandler());

    Rectangle piece2 = new Rectangle(300, 50);
    piece2.setFill(Color.BLUE);
    piece2.setStroke(Color.BLACK);
    panel1.getChildren().add(piece2);
    piece2.setOnMouseClicked(new pieceEventHandler());

    Rectangle piece3 = new Rectangle(350, 50);
    piece3.setFill(Color.CORAL);
    piece3.setStroke(Color.BLACK);
    panel1.getChildren().add(piece3);
    piece3.setOnMouseClicked(new pieceEventHandler());

    Rectangle piece4 = new Rectangle(400, 50);
    piece4.setFill(Color.MAGENTA);
    piece4.setStroke(Color.BLACK);
    panel1.getChildren().add(piece4);
    piece4.setOnMouseClicked(new pieceEventHandler());

    gp.getChildren().add(panel1);
    gp.getColumnConstraints().add(new ColumnConstraints(500));
    GridPane.setColumnIndex(panel1, 0); 
    gp.getChildren().add(panel2);
    GridPane.setColumnIndex(panel2, 5);
    gp.getChildren().add(panel3);
    GridPane.setColumnIndex(panel3, 10);


    Scene scene = new Scene(gp, 1500, 980);
    mainStage.setScene(scene);
    mainStage.show();
}



class panelEventHandler implements EventHandler<MouseEvent>{

    @Override
    public void handle(MouseEvent event) {

        if(selectedpiece == null){
            ;
        }
        else{
            selectedbox = (VBox)event.getSource();
            if(selectedbox.getChildren().contains(selectedpiece)){
                ;
            }
            else{
                VBox parentbox = (VBox) selectedpiece.getParent();
                parentbox.getChildren().remove(selectedpiece);
                selectedbox.getChildren().add(selectedpiece);
                selectedpiece.setFill(temp);
                selectedpiece = null;
                selectedbox = null;

            }
        }
    }

}

class pieceEventHandler implements EventHandler<MouseEvent>{

    @Override
    public void handle(MouseEvent event) {
        if(selectedpiece == null){
        selectedpiece = (Rectangle) event.getSource();
        temp = selectedpiece.getFill();
        selectedpiece.setFill(Color.YELLOW);
        }
        else if(selectedpiece == (Rectangle) event.getSource()){
            selectedpiece.setFill(temp);
            selectedpiece = null;
        }
        else{
            selectedpiece.setFill(temp);
            selectedpiece = (Rectangle) event.getSource();
            temp = selectedpiece.getFill();
            selectedpiece.setFill(Color.YELLOW);
        }
    }

}

}


Solution

  • Just replace

    selectedbox.getChildren().add(selectedpiece);
    

    with

    selectedbox.getChildren().add(0, selectedpiece);