I am trying to build a Rubiks Cube from scratch as my first real app using JavaFx. In the Moves class Im selecting Boxes from ObservableList based on position. The problem is that the Box.getTranslate dosent update so when I try to move the front and the left faces successively the Boxes selected by both are always moved resulting in.. chaos. How could I re-write this so that the Move methods correctly select the boxes to move? Here is the code, work in progress.
Main
package ro.adrianpush;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.scene.*;
import javafx.scene.input.KeyEvent;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Box;
import javafx.stage.Stage;
public class Main extends Application {
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
final Group root = new Group();
#Override
public void start(Stage primaryStage) throws Exception{
Camera camera = new PerspectiveCamera();
camera.translateXProperty().setValue(-200);
camera.translateYProperty().setValue(0);
camera.translateZProperty().set(-500);
AnchorPane pane = new AnchorPane();
Rubik rubik = new Rubik();
ObservableList<Box> boxArrayList = rubik.getBoxArrayList();
for (Box box: boxArrayList
) {
pane.getChildren().addAll(box);
}
primaryStage.addEventHandler(KeyEvent.KEY_PRESSED, event -> {
switch (event.getCode()){
case E:
Moves.rotateFront(boxArrayList, "clockwise");
break;
case Q:
Moves.rotateFront(boxArrayList, "counterclockwise");
break;
case A:
Moves.rotateLeft(boxArrayList, "clockwise");
break;
case D:
Moves.rotateLeft(boxArrayList, "counterclockwise");
break;
}
});
root.getChildren().add(pane);
Scene scene = new Scene(root, WIDTH, HEIGHT, true);
scene.setCamera(camera);
scene.setFill(Color.ROYALBLUE);
primaryStage.setTitle("The game nobody wants to play");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Rubik
package ro.adrianpush;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.shape.Box;
public class Rubik {
private ObservableList<Box> boxArrayList = FXCollections.observableArrayList();
public Rubik(){
for(int i = 1; i < 4; i+=1){
for( int j = 1; j < 4; j++){
for(int k = 1; k < 4; k++){
Box box = new Box(100,100,100);
box.setTranslateX(i*100);
box.setTranslateY(j*100);
box.setTranslateZ(k*100);
boxArrayList.add(box);
}
}
}
}
public ObservableList<Box> getBoxArrayList() {
return boxArrayList;
}
}
Moves
package ro.adrianpush;
import javafx.collections.ObservableList;
import javafx.scene.shape.Box;
import javafx.scene.transform.Rotate;
public class Moves {
public static void rotateFront(ObservableList<Box> boxArrayList, String direction) {
for (Box box: boxArrayList
) {
if(box.getTranslateZ() == 100){
Rotate rotate = new Rotate();
rotate.setAxis(Rotate.Z_AXIS);
if(direction == "clockwise"){
rotate.setAngle(5);
} else if (direction == "counterclockwise"){
rotate.setAngle(-5);
}
if(box.getTranslateX() == 100){
rotate.setPivotX(100);
} if (box.getTranslateX() == 300){
rotate.setPivotX(-100);
} if(box.getTranslateY() == 100){
rotate.setPivotY(100);
} if(box.getTranslateY() == 300){
rotate.setPivotY(-100);
}
box.getTransforms().add(rotate);
}
}
}
public static void rotateBack(ObservableList<Box> boxArrayList, String direction) {
for (Box box: boxArrayList
) {
if(box.getTranslateZ() == 300){
Rotate rotate = new Rotate();
if(direction == "clockwise"){
rotate.setAngle(5);
} else if (direction == "counterclockwise"){
rotate.setAngle(-5);
}
if(box.getTranslateX() == 100){
rotate.setPivotX(100);
} if (box.getTranslateX() == 300){
rotate.setPivotX(-100);
} if(box.getTranslateY() == 100){
rotate.setPivotY(100);
} if(box.getTranslateY() == 300){
rotate.setPivotY(-100);
}
box.getTransforms().add(rotate);
}
}
}
public static void rotateLeft(ObservableList<Box> boxArrayList, String direction) {
for (Box box: boxArrayList
) {
if(box.getTranslateX() == 100){
Rotate rotate = new Rotate();
rotate.setAxis(Rotate.X_AXIS);
if(direction == "clockwise"){
rotate.setAngle(5);
} else if (direction == "counterclockwise"){
rotate.setAngle(-5);
}
if(box.getTranslateY() == 100){
rotate.setPivotY(100);
} if (box.getTranslateY() == 300){
rotate.setPivotY(-100);
} if(box.getTranslateZ() == 100){
rotate.setPivotZ(100);
} if(box.getTranslateZ() == 300){
rotate.setPivotZ(-100);
}
box.getTransforms().add(rotate);
}
}
}
}
Related
So basically i am making a game in which the circle will move in the four directions. When the "S" or "RIGHT" key is pressed once, the circle will move till it reaches the maxX of the pane. And when i press the "A" key or "LEFT", the circle will move till it reaches minX of pane. The "UP" or "W" and "DOWN" or "Z" keys also follow similar logic. If it get to maxY of pane it stops till another key is pressed and vice versa.
Here is the code for the controller class
#FXML
private Pane board;
private BooleanProperty wPressed = new SimpleBooleanProperty();
private BooleanProperty aPressed = new SimpleBooleanProperty();
private BooleanProperty zPressed = new SimpleBooleanProperty();
private BooleanProperty sPressed = new SimpleBooleanProperty();
private BooleanBinding keyPressed = wPressed.or(aPressed).or(zPressed).or(sPressed);
private Circle circle = new Circle(20,40,20);
private Rectangle[][] grid;
private int size = 960;
private int spots = 16;
private int squareSize = size / spots;
#FXML
void handleB(ActionEvent event) {
}
AnimationTimer timer = new AnimationTimer() {
double deltaX = 2;
double deltaY = 2;
#Override
public void handle(long timestamp) {
double rectX = circle.getLayoutX();
Bounds bounds = board.getBoundsInLocal();
double maxX = bounds.getMaxX();
double maxY = bounds.getMaxY();
double minX = bounds.getMinX();
double minY = bounds.getMinY();
if (circle.getLayoutX() >= ( maxX- circle.getRadius())) {
deltaX = 0;
//System.out.println(rect.getLayoutX());
}
if (circle.getLayoutY() >= (maxY - circle.getRadius())) {
deltaY = 0;
}
if (circle.getLayoutX() <= ( minX + circle.getRadius())) {
deltaX = 0;
//System.out.println(rect.getLayoutX());
}
if (circle.getLayoutY() <= ( minY + circle.getRadius())) {
deltaY = 0;
}
if(wPressed.get()) {
circle.setLayoutY(circle.getLayoutY() - deltaY);
}
if(zPressed.get()){
circle.setLayoutY(circle.getLayoutY() + deltaY);
}
if(aPressed.get()){
circle.setLayoutX(circle.getLayoutX() - deltaX);
}
if(sPressed.get()){
circle.setLayoutX(circle.getLayoutX() + deltaX);
}
}
};
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
grid = new Rectangle[spots][spots];
for (int i = 0; i < size; i += squareSize) {
for (int j = 0; j < size; j += squareSize) {
Rectangle r = new Rectangle(i, j, squareSize, squareSize);
grid[i / squareSize][j / squareSize] = r;
// Filling each grid with the cell image
r.setFill(Color.GRAY);
r.setStroke(Color.BLACK);
board.getChildren().add(r);
}
}
board.getChildren().addAll(circle);
movementSetup();
keyPressed.addListener(((observableValue, aBoolean, t1) -> {
if(!aBoolean){
timer.start();
} else {
timer.stop();
}
}));
}
private void movementSetup() {
board.setOnKeyPressed(e -> {
if(e.getCode() == KeyCode.UP || e.getCode() == KeyCode.W ) {
zPressed.set(false);
sPressed.set(false);
aPressed.set(false);
wPressed.set(true);
}
if(e.getCode() == KeyCode.A || e.getCode() == KeyCode.LEFT) {
zPressed.set(false);
sPressed.set(false);
wPressed.set(false);
aPressed.set(true);
}
if(e.getCode() == KeyCode.Z || e.getCode() == KeyCode.DOWN) {
wPressed.set(false);
aPressed.set(false);
sPressed.set(false);
zPressed.set(true);
}
if(e.getCode() == KeyCode.S || e.getCode() == KeyCode.RIGHT) {
wPressed.set(false);
aPressed.set(false);
zPressed.set(false);
sPressed.set(true);
}
});
}
}
** I did the pane in scenebuilder which i inserted it into an anchorpane as well**
The fxml file is below (ui.fxml)
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.layout.Pane?>
<AnchorPane maxHeight="1000.0" maxWidth="1200.0" minHeight="0.0" minWidth="0.0" prefHeight="1000.0" prefWidth="1200.0" xmlns="http://javafx.com/javafx/17" xmlns:fx="http://javafx.com/fxml/1" fx:controller="fx.game.Controller">
<children>
<Pane fx:id="board" maxHeight="960.0" maxWidth="960.0" minHeight="0.0" minWidth="0.0" prefHeight="960.0" prefWidth="960.0">
<children>
<Button layoutX="367.0" layoutY="934.0" mnemonicParsing="false" onAction="#handleB" text="Button" />
</children>
</Pane>
</children>
</AnchorPane>
Lastly the main class
package fx.game;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import java.io.IOException;
public class HelloApplication extends Application {
#Override
public void start(Stage stage) throws IOException {
Parent root = FXMLLoader.load(getClass().getResource("ui.fxml"));
stage.setTitle("Hello World");
stage.setScene(new Scene(root));
stage.show();
}
public static void main(String[] args) {
launch();
}
}
Am really bad at game development
I might be doing it completely wrong
Anyone who can give me a better solution will be appreciated
From my limited understanding and testing, board.setOnKeyPressed isn't responding to key events, I used the Scene instead. You should also be taking into account onKeyReleased.
I don't know why you're starting and stoping the timer, just start it and on each, evaluate the state and make the changes that are required.
Your movement logic seems to be off as well. Get the circles current location, apply any movement to it as required, then determine if the new position is outside the acceptable bounds, adjust the position as needed and then update the circles position.
I also found that the Bounds the board would update based on the position of it's children, which made it hard to do bounds checking on, instead, I calculate the expected size based on the squareSize and the number of spots
For example...
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.geometry.Bounds;
import javafx.scene.Scene;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class App extends Application {
private BooleanProperty wPressed = new SimpleBooleanProperty();
private BooleanProperty aPressed = new SimpleBooleanProperty();
private BooleanProperty zPressed = new SimpleBooleanProperty();
private BooleanProperty sPressed = new SimpleBooleanProperty();
private BooleanBinding keyPressed = wPressed.or(aPressed).or(zPressed).or(sPressed);
private Circle circle = new Circle(20, 20, 20);
private Rectangle[][] grid;
private int size = 960;
private int spots = 16;
private int squareSize = size / spots;
AnimationTimer timer = new AnimationTimer() {
double deltaX = 2;
double deltaY = 2;
#Override
public void handle(long timestamp) {
double rectX = circle.getLayoutX();
Bounds bounds = board.getBoundsInLocal();
double width = squareSize * spots;
double height = squareSize * spots;
double diameter = circle.getRadius() * 2;
double x = circle.getLayoutX();
double y = circle.getLayoutY();
if (wPressed.get()) {
y -= deltaY;
}
if (zPressed.get()) {
y += deltaY;
}
if (aPressed.get()) {
x -= deltaX;
}
if (sPressed.get()) {
x += deltaX;
}
if (x >= (width - diameter)) {
x = width - diameter;
}
if (x < 0) {
x = 0;
}
if (y > (height - diameter)) {
y = height - diameter;
}
if (y < 0) {
y = 0;
}
circle.setLayoutX(x);
circle.setLayoutY(y);
}
};
private Pane board = new AnchorPane();
#Override
public void start(Stage stage) {
stage.setTitle("Dice Game");
setup();
Scene scene = new Scene(board);
movementSetup(scene);
stage.setScene(scene);
stage.sizeToScene();
stage.show();
}
private void movementSetup(Scene scene) {
scene.setOnKeyPressed(e -> {
zPressed.set(false);
sPressed.set(false);
aPressed.set(false);
wPressed.set(false);
if (e.getCode() == KeyCode.UP || e.getCode() == KeyCode.W) {
wPressed.set(true);
} else if (e.getCode() == KeyCode.A || e.getCode() == KeyCode.LEFT) {
aPressed.set(true);
}else if (e.getCode() == KeyCode.Z || e.getCode() == KeyCode.DOWN) {
zPressed.set(true);
}else if (e.getCode() == KeyCode.S || e.getCode() == KeyCode.RIGHT) {
sPressed.set(true);
}
});
}
protected void setup() {
grid = new Rectangle[spots][spots];
for (int i = 0; i < size; i += squareSize) {
for (int j = 0; j < size; j += squareSize) {
Rectangle r = new Rectangle(i, j, squareSize, squareSize);
grid[i / squareSize][j / squareSize] = r;
// Filling each grid with the cell image
r.setFill(Color.GRAY);
r.setStroke(Color.BLACK);
board.getChildren().add(r);
}
}
board.getChildren().addAll(circle);
timer.start();
}
public static void main(String[] args) {
launch();
}
}
nb: I'm a complete JavaFX noob, so there's probably better ways to approach this issue and maybe having a look at things like Introduction to JavaFX for Game Development (or other "javafx game development blogs" might provide better ideas
In my javafx project, i have a gridpane of cells with a main character and four enemies. The main character moves when the arrow keys are hit. The problem is that when the board is 4*4 and I hit an arrow key, it takes two seconds for the main character to move, and when the size of board is 10*10, after the first two arrow key hits nothing happens, and the third time gives me JavaFX Application Thread Out Of Memory Error: Java Heap Space.
I have no idea what is causing this problem. What object is getting newed so many times it fills all the RAM? Any solutions for how to fix this code?
package project.view;
import javafx.animation.FadeTransition;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.geometry.HPos;
import javafx.geometry.Pos;
import javafx.scene.*;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.io.IOException;
import java.net.URL;
import project.controller.GameController;
import project.model.*;
import project.transition.FlipTransition;
import project.view.components.CardView;
import javafx.scene.Parent;
import javafx.scene.Scene;
import static javafx.scene.input.KeyCode.DOWN;
public class GameView extends Application implements EventHandler<MouseEvent> {
public GridPane gameBoard;
public BorderPane borderPane;
private static CardView[][] cards = new CardView[GameBoard.getGameBoards().get(0).getMazeCreator().getBoard().length][GameBoard.getGameBoards().get(0).getMazeCreator().getBoard()[0].length()];
public GameBoard gameBoardInCode;
public static Stage stage;
public static Scene scene;
public static Timeline timeline;
#Override
public void start(Stage stage) throws Exception {Scene(FXMLLoader.load(getClass().getResource("/project/fxml/game_board.fxml")))
GameView.stage = stage;
URL url = getClass().getResource("/project/fxml/game_board.fxml");
Parent root = FXMLLoader.load(url);
System.out.println(url.toString());
Scene scene = new Scene(root);
stage.setScene(scene);
GameView.scene = scene;
scene.setOnKeyPressed(key -> {
if (key.getCode() == KeyCode.UP || key.getCode() == KeyCode.DOWN || key.getCode() == KeyCode.LEFT || key.getCode() == KeyCode.RIGHT) {
moveMainCharacterInView(key);
return;
}
});
stage.setTitle("New Game");
stage.show();
}
public static void main(String[] args) {
launch(args);
}
#FXML
public void initialize() {
int rows = GameBoard.getGameBoards().get(0).getMazeCreator().getBoard().length;
int columns = GameBoard.getGameBoards().get(0).getMazeCreator().getBoard()[0].length();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
CardView rectangle = getUpdatedCardRectangle(i, j);
gameBoard.add(rectangle, j, i);
cards[i][j] = rectangle;
}
}
GridPane.setHalignment(gameBoard, HPos.CENTER);
gameBoard.setAlignment(Pos.CENTER);
}
public static void updateBoard() {
int rows = GameBoard.getGameBoards().get(0).getMazeCreator().getBoard().length;
int columns = GameBoard.getGameBoards().get(0).getMazeCreator().getBoard()[0].length();
GridPane gameBoard = (GridPane) stage.getScene().lookup("#1");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
CardView rectangle = getUpdatedCardRectangle(i, j);
gameBoard.add(rectangle, j, i);
cards[i][j] = rectangle;
}
}
gameBoard.setAlignment(Pos.CENTER);
}
public static void moveMainCharacterInView(KeyEvent event) {
if (event.getCode() == KeyCode.UP) {
System.out.println("UP");
if (GameBoard.getGameBoards().size() != 0) {
GameBoard.getGameBoards().get(0).getMainCharacter().moveMainCharacter("up");
updateBoard();
}
} else if (event.getCode() == KeyCode.RIGHT) {
System.out.println("RIGHT");
if (GameBoard.getGameBoards().size() != 0) {
GameBoard.getGameBoards().get(0).getMainCharacter().moveMainCharacter("right");
updateBoard();
}
} else if (event.getCode() == KeyCode.LEFT) {
System.out.println("LEFT");
if (GameBoard.getGameBoards().size() != 0) {
GameBoard.getGameBoards().get(0).getMainCharacter().moveMainCharacter("left");
updateBoard();
}
} else if (event.getCode() == DOWN) {
System.out.println("DOWN");
if (GameBoard.getGameBoards().size() != 0) {
GameBoard.getGameBoards().get(0).getMainCharacter().moveMainCharacter("down");
updateBoard();
}
}
}
private static CardView getUpdatedCardRectangle(int i, int j) {
CardView rectangle = new CardView();
Card card = Card.getAllCards()[i][j];
if (GameBoard.getGameBoards().get(0).getMazeCreator().giveContentOfBoard(i, j, j + 1).equals("2")) {
card = new Card(CellSituation.Enemy_1, i, j);
} else if (GameBoard.getGameBoards().get(0).getMazeCreator().giveContentOfBoard(i, j, j + 1).equals("3")) {
card = new Card(CellSituation.Enemy_2, i, j);
} else if (GameBoard.getGameBoards().get(0).getMazeCreator().giveContentOfBoard(i, j, j + 1).equals("4")) {
card = new Card(CellSituation.Enemy_3, i, j);
} else if (GameBoard.getGameBoards().get(0).getMazeCreator().giveContentOfBoard(i, j, j + 1).equals("5")) {
card = new Card(CellSituation.Enemy_4, i, j);
} else if (GameBoard.getGameBoards().get(0).getMazeCreator().giveContentOfBoard(i, j, j + 1).equals("6")) {
card = new Card(CellSituation.MAINCHARACTER, i, j);
} else if (GameBoard.getGameBoards().get(0).getMazeCreator().giveContentOfBoard(i, j, j + 1).equals("*")) {
card = new Card(CellSituation.EMPTY, i, j);
} else if (GameBoard.getGameBoards().get(0).getMazeCreator().giveContentOfBoard(i, j, j + 1).equals("1")) {
card = new Card(CellSituation.UNPASSABLE, i, j);
} else if (GameBoard.getGameBoards().get(0).getMazeCreator().giveContentOfBoard(i, j, j + 1).equals("0")) {
card = new Card(CellSituation.PASSABLE, i, j);
}
rectangle.setFill(card.getFrontImage());
if (card.getCellSituation().equals(CellSituation.PASSABLE) || card.getCellSituation().equals(CellSituation.UNPASSABLE)) {
if (i % 2 == 0 && j % 2 == 1) {
rectangle.setHeight(3);
rectangle.setWidth(50);
}
if (i % 2 == 1 && j % 2 == 0) {
rectangle.setHeight(50);
rectangle.setWidth(3);
}
if (i % 2 == 0 && j % 2 == 0) {
rectangle.setHeight(3);
rectangle.setWidth(3);
}
} else {
rectangle.setHeight(50);
rectangle.setWidth(50);
}
rectangle.setI(card.getI());
rectangle.setJ(card.getJ());
return rectangle;
}
}
Can someone explain how to solve this? DeleteRows() method is not working as intended.
It's a Tetris game and I'm trying to delete rows. When the blocks move down, the blocks are still counted as 0 so new blocks go through them. But this occurs only in the top row of the moved blocks:
package application;
import java.util.*;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.event.EventHandler;
import javafx.scene.*;
import javafx.scene.input.*;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Tetris extends Application {
public static final int MOVE_AMOUNT = 25;
public static final int SIZE = 25;
public static int XLIMIT = SIZE * 10;
public static int YLIMIT = SIZE * 24;
public static int[][] GRID = new int[XLIMIT/SIZE][YLIMIT/SIZE];
private static Pane group = new Pane();
private static Shape object;
private static Scene scene = new Scene(group, XLIMIT, YLIMIT);
public static void main(String[] args) { launch(args); }
#Override public void start(Stage stage) throws Exception {
for(int[] a: GRID){
Arrays.fill(a, 0);
}
for(int i = 0; i <= XLIMIT; i+= SIZE){
Line a = new Line(i, 0, i, YLIMIT);
group.getChildren().add(a);
}
for(int i = 0; i <= YLIMIT; i+= SIZE){
Line a = new Line(0, i, XLIMIT, i);
group.getChildren().add(a);
}
for(int i = 0; i <= YLIMIT; i+= SIZE){
Text a = new Text("" + i);
a.setY(i);
group.getChildren().add(a);
}
for(int i = SIZE; i < XLIMIT; i+= SIZE){
Text a = new Text("" + i);
a.setY(10);
a.setX(i);
group.getChildren().add(a);
}
Shape a = TetrisHolder.createRect();
group.getChildren().addAll(a.a, a.b, a.c, a.d);
moveOnKeyPress(scene, a.a, a.b, a.c, a.d);
object = a;
stage.setScene(scene);
stage.show();
Timer myTimer=new Timer();
TimerTask task =new TimerTask() {
#Override
public void run() {
Platform.runLater(new Runnable(){
public void run(){
CheckDown(object);
}
});
}
};
myTimer.schedule(task,0,300);
}
private void moveOnKeyPress(Scene scene, Rectangle rect, Rectangle rect2, Rectangle rect3, Rectangle rect4) {
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override public void handle(KeyEvent event) {
Shape shape = new Shape(rect, rect2, rect3, rect4);
switch (event.getCode()) {
case RIGHT:
TetrisHolder.CheckRight(shape);
break;
case DOWN:
CheckDown(shape);
break;
case LEFT:
TetrisHolder.CheckLeft(shape);
break;
case UP:
//TetrisHolder.CheckTurn(shape);
break;
}
}
});
}
private void CheckTurn(Shape shape){
}
private void DeleteRows(Pane pane){
ArrayList<Node> rects = new ArrayList<Node>();
ArrayList<Integer> lines = new ArrayList<Integer>();
int full = 0;
for(int i = 0; i < GRID[0].length; i++){
for(int j = 0; j < GRID.length; j++){
if(GRID[j][i] == 1)
full++;
}
if(full == GRID.length)
lines.add(i/*+lines.size()*/);
full = 0;
}
for(Node node: pane.getChildren()) {
if(node instanceof Rectangle) {
rects.add(node);
}
}
if(lines.size() > 0)
do{
for(Node node: rects){
Rectangle a = (Rectangle)node;
if(a.getY() == lines.get(0)*SIZE){
GRID[(int)a.getX()/SIZE][(int)a.getY()/SIZE] = 0;
pane.getChildren().remove(node);
}
if(a.getY() < lines.get(0)*SIZE){
GRID[(int)a.getX()/SIZE][(int)a.getY()/SIZE] = 0;
a.setY(a.getY() + SIZE);
GRID[(int)a.getX()/SIZE][(int)a.getY()/SIZE] = 1;
}
}
lines.remove(0);
rects.clear();
for(Node node: pane.getChildren()) {
if(node instanceof Rectangle) {
rects.add(node);
}
}
} while(lines.size() > 0);
}
private void CheckDown(Shape shape){
if((shape.c.getY() == YLIMIT - SIZE) || checkA(shape) || checkB(shape) || checkC(shape) || checkD(shape)){
GRID[(int)shape.a.getX()/SIZE][(int)shape.a.getY()/SIZE] = 1;
GRID[(int)shape.b.getX()/SIZE][(int)shape.b.getY()/SIZE] = 1;
GRID[(int)shape.c.getX()/SIZE][(int)shape.c.getY()/SIZE] = 1;
GRID[(int)shape.d.getX()/SIZE][(int)shape.d.getY()/SIZE] = 1;
DeleteRows(group);
Shape a = TetrisHolder.createRect();
object = a;
group.getChildren().addAll(a.a, a.b, a.c, a.d);
moveOnKeyPress(shape.a.getScene(), a.a, a.b, a.c, a.d);
}
if(shape.c.getY() + MOVE_AMOUNT < YLIMIT){
int checka = GRID[(int)shape.a.getX()/SIZE][((int)shape.a.getY()/SIZE) + 1];
int checkb = GRID[(int)shape.b.getX()/SIZE][((int)shape.b.getY()/SIZE) + 1];
int checkc = GRID[(int)shape.c.getX()/SIZE][((int)shape.c.getY()/SIZE) + 1];
int checkd = GRID[(int)shape.d.getX()/SIZE][((int)shape.d.getY()/SIZE) + 1];
if(checka == 0 && checka == checkb && checkb == checkc && checkc == checkd){
shape.a.setY(shape.a.getY() + MOVE_AMOUNT);
shape.b.setY(shape.b.getY() + MOVE_AMOUNT);
shape.c.setY(shape.c.getY() + MOVE_AMOUNT);
shape.d.setY(shape.d.getY() + MOVE_AMOUNT);
}
}
}
private boolean checkA(Shape shape){
return (GRID[(int)shape.a.getX()/SIZE][((int)shape.a.getY()/SIZE) + 1] == 1);
}
private boolean checkB(Shape shape){
return (GRID[(int)shape.b.getX()/SIZE][((int)shape.b.getY()/SIZE) + 1] == 1);
}
private boolean checkC(Shape shape){
return (GRID[(int)shape.c.getX()/SIZE][((int)shape.c.getY()/SIZE) + 1] == 1);
}
private boolean checkD(Shape shape){
return (GRID[(int)shape.d.getX()/SIZE][((int)shape.d.getY()/SIZE) + 1] == 1);
}
}
This is the code. The problem is at DeleteRows() method.
I am trying to make a puzzle game but the problem is that I can't do the EventHandler setOnMouseClicked.Also I want to know how to make possible that to re-arrange the puzzle so it shows random images in every-coordinate. This is how far I got.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.GridPane;
import javafx.stage.Stage;
public class eliss extends Application{
#Override
public void start(Stage primaryStage) {
ImageView view[][] = new ImageView[5][5];
Image imag = new Image("http://images.cdn.autocar.co.uk/sites/autocar.co.uk/files/styles/gallery_slide/public/ferrari-laferrari-zfye-059_1.jpg?itok=hfLNxUD9",600,600,false,true);
GridPane pane = new GridPane();
pane.setAlignment(Pos.CENTER);
pane.setVgap(2);
pane.setHgap(2);
PuzzleImage(view, imag, pane);
Scene scene = new Scene(pane,1100,1100);
primaryStage.setTitle("Elis");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] x)
{
launch(x);
}
public void PuzzleImage( ImageView view[][],Image imag,GridPane pane)
{
for(int i=0;i<5;i++)
{
for(int j=0;j<5;j++)
{
if(j==4 && i==4) view[i][j]=null;
else{
view[i][j]=new ImageView(imag);
Rectangle2D rect = new Rectangle2D(120*i,120*j,120,120);
view[i][j].setViewport(rect);
pane.add(view[i][j], i, j);
}
}
}
}
}
What you are asking is too much for a question on StackOverflow. However, I got a little bit of spare time, so I quickly drafted up some code to demonstrate what you need:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javafx.animation.PathTransition;
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.Pane;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.stage.Stage;
import javafx.util.Duration;
public class PuzzleGame extends Application {
private Image image = new Image("http://images.cdn.autocar.co.uk/sites/autocar.co.uk/files/styles/gallery_slide/public/ferrari-laferrari-zfye-059_1.jpg?itok=hfLNxUD9",600,600,false,true);
private static double SCENE_WIDTH = 1024;
private static double SCENE_HEIGHT = 768;
public static int TILE_ROW_COUNT = 5;
public static int TILE_COLUMN_COUNT = 5;
public static double TILE_SIZE = 120;
public static double offsetX = (SCENE_WIDTH - TILE_ROW_COUNT * TILE_SIZE) / 2;
public static double offsetY = (SCENE_HEIGHT - TILE_COLUMN_COUNT * TILE_SIZE) / 2;
List<Cell> cells = new ArrayList<>();
#Override
public void start(Stage primaryStage) {
// create grid
for (int x = 0; x < TILE_ROW_COUNT; x++) {
for (int y = 0; y < TILE_COLUMN_COUNT; y++) {
// create tile
ImageView tile = new ImageView(image);
Rectangle2D rect = new Rectangle2D(TILE_SIZE * x, TILE_SIZE * y, TILE_SIZE, TILE_SIZE);
tile.setViewport(rect);
// consider empty cell, let it remain empty
if (x == (TILE_ROW_COUNT - 1) && y == (TILE_COLUMN_COUNT - 1)) {
tile = null;
}
cells.add(new Cell(x, y, tile));
}
}
// shuffle cells
shuffle();
// create playfield
Pane pane = new Pane();
// put tiles on playfield, assign event handler
for (int i = 0; i < cells.size(); i++) {
Cell cell = cells.get(i);
Node imageView = cell.getImageView();
// consider empty cell
if (imageView == null)
continue;
// click-handler: swap tiles, check if puzzle is solved
imageView.addEventFilter(MouseEvent.MOUSE_CLICKED, mouseEvent -> {
moveCell((Node) mouseEvent.getSource());
});
// position images on scene
imageView.relocate(cell.getLayoutX(), cell.getLayoutY());
pane.getChildren().add(cell.getImageView());
}
Scene scene = new Scene(pane, SCENE_WIDTH, SCENE_HEIGHT);
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* Swap images of cells randomly
*/
public void shuffle() {
Random rnd = new Random();
for (int i = 0; i < 1000; i++) {
int a = rnd.nextInt(cells.size());
int b = rnd.nextInt(cells.size());
if (a == b)
continue;
// skip bottom right cell swap, we want the empty cell to remain there
if( cells.get(a).isEmpty() || cells.get(b).isEmpty())
continue;
swap( cells.get(a), cells.get(b));
}
}
public void swap( Cell cellA, Cell cellB) {
ImageView tmp = cellA.getImageView();
cellA.setImageView(cellB.getImageView());
cellB.setImageView(tmp);
}
public boolean checkSolved() {
boolean allSolved = true;
for (Cell cell : cells) {
if (!cell.isSolved()) {
allSolved = false;
break;
}
}
System.out.println("Solved: " + allSolved);
return allSolved;
}
public void moveCell(Node node) {
// get current cell using the selected node (imageview)
Cell currentCell = null;
for (Cell tmpCell : cells) {
if (tmpCell.getImageView() == node) {
currentCell = tmpCell;
break;
}
}
if (currentCell == null)
return;
// get empty cell
Cell emptyCell = null;
for (Cell tmpCell : cells) {
if (tmpCell.isEmpty()) {
emptyCell = tmpCell;
break;
}
}
if (emptyCell == null)
return;
// check if cells are swappable: neighbor distance either x or y must be 1 for a valid move
int steps = Math.abs(currentCell.x - emptyCell.x) + Math.abs(currentCell.y - emptyCell.y);
if (steps != 1)
return;
System.out.println("Transition: " + currentCell + " -> " + emptyCell);
// cells are swappable => create path transition
Path path = new Path();
path.getElements().add(new MoveToAbs(currentCell.getImageView(), currentCell.getLayoutX(), currentCell.getLayoutY()));
path.getElements().add(new LineToAbs(currentCell.getImageView(), emptyCell.getLayoutX(), emptyCell.getLayoutY()));
PathTransition pathTransition = new PathTransition();
pathTransition.setDuration(Duration.millis(100));
pathTransition.setNode(currentCell.getImageView());
pathTransition.setPath(path);
pathTransition.setOrientation(PathTransition.OrientationType.NONE);
pathTransition.setCycleCount(1);
pathTransition.setAutoReverse(false);
final Cell cellA = currentCell;
final Cell cellB = emptyCell;
pathTransition.setOnFinished(actionEvent -> {
swap( cellA, cellB);
checkSolved();
});
pathTransition.play();
}
private static class Cell {
int x;
int y;
ImageView initialImageView;
ImageView currentImageView;
public Cell(int x, int y, ImageView initialImageView) {
super();
this.x = x;
this.y = y;
this.initialImageView = initialImageView;
this.currentImageView = initialImageView;
}
public double getLayoutX() {
return x * TILE_SIZE + offsetX;
}
public double getLayoutY() {
return y * TILE_SIZE + offsetY;
}
public ImageView getImageView() {
return currentImageView;
}
public void setImageView(ImageView imageView) {
this.currentImageView = imageView;
}
public boolean isEmpty() {
return currentImageView == null;
}
public boolean isSolved() {
return this.initialImageView == currentImageView;
}
public String toString() {
return "[" + x + "," + y + "]";
}
}
// absolute (layoutX/Y) transitions using the pathtransition for MoveTo
public static class MoveToAbs extends MoveTo {
public MoveToAbs(Node node) {
super(node.getLayoutBounds().getWidth() / 2, node.getLayoutBounds().getHeight() / 2);
}
public MoveToAbs(Node node, double x, double y) {
super(x - node.getLayoutX() + node.getLayoutBounds().getWidth() / 2, y - node.getLayoutY() + node.getLayoutBounds().getHeight() / 2);
}
}
// absolute (layoutX/Y) transitions using the pathtransition for LineTo
public static class LineToAbs extends LineTo {
public LineToAbs(Node node, double x, double y) {
super(x - node.getLayoutX() + node.getLayoutBounds().getWidth() / 2, y - node.getLayoutY() + node.getLayoutBounds().getHeight() / 2);
}
}
public static void main(String[] args) {
launch(args);
}
}
You can use Collections.shuffle to generate a random permutation of a List This can be used to place the tiles in a random order:
private static final int COLUMN_COUNT = 5;
private static final int ROW_COUNT = 5;
private static void fillGridPane(GridPane pane, ImageView[][] view, Image imag) {
List<ImageView> images = new ArrayList<>(24);
for (int i = 0; i < COLUMN_COUNT; i++) {
for (int j = 0, end = i == (COLUMN_COUNT - 1) ? ROW_COUNT - 1 : ROW_COUNT; j < end; j++) {
ImageView iv = new ImageView(imag);
images.add(iv);
view[i][j] = iv;
Rectangle2D rect = new Rectangle2D(120 * i, 120 * j, 120, 120);
iv.setViewport(rect);
}
}
Collections.shuffle(images);
Iterator<ImageView> iter = images.iterator();
for (int i = 0; i < COLUMN_COUNT; i++) {
for (int j = 0, end = i == (COLUMN_COUNT - 1) ? ROW_COUNT - 1 : ROW_COUNT; j < end; j++) {
pane.add(iter.next(), i, j);
}
}
}
The onMouseClicked event handler can be attached to the GridPane and MouseEvent.getTarget can be used to get the node that was clicked:
pane.setOnMouseClicked(event -> {
if (move(event)) {
if (checkWin()) {
new Alert(Alert.AlertType.INFORMATION, "You Win!").show();
}
}
});
private int emptyTileX = 4;
private int emptyTileY = 4;
private boolean move(MouseEvent event) {
Object target = event.getTarget();
if (target instanceof ImageView) {
ImageView iv = (ImageView) target;
int row = GridPane.getRowIndex(iv);
int column = GridPane.getColumnIndex(iv);
int dx = Math.abs(column - emptyTileX);
int dy = Math.abs(row - emptyTileY);
if ((dx == 0 && dy == 1) || (dx == 1 && dy == 0)) {
// swap image and empty tile, if they are next to each other
GridPane.setConstraints(iv, emptyTileX, emptyTileY);
emptyTileX = column;
emptyTileY = row;
return true;
}
}
return false;
}
To check the winning condition, you can simply check the positions of the ImageViews in the GridPane
private boolean checkWin() {
for (int i = 0; i < COLUMN_COUNT; i++) {
for (int j = 0, end = i == (COLUMN_COUNT - 1) ? ROW_COUNT - 1 : ROW_COUNT; j < end; j++) {
ImageView iv = view[i][j];
if (GridPane.getColumnIndex(iv) != i || GridPane.getRowIndex(iv) != j) {
return false;
}
}
}
return true;
}
for this application, I need to enter a number and display the numbers that when multiplied together will give you the number in question. For example, if you enter 42 then the labels for 6*7 and 7*6 would change color. I figured out how to get the answers but I cant quite figure out how to manipulate the labels in the multiplication table to change color. To give you an idea,
main class
package application;
import java.util.List;
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane pane = new BorderPane();
pane.setTop(getHbox1());
HBox prompt = new HBox(15);
prompt.setPadding(new Insets(15, 15, 15, 15));
prompt.setAlignment(Pos.TOP_CENTER);
prompt.getStyleClass().add("hbox2");
Label lblProblem = new Label("Enter problem: ");
prompt.getChildren().add(lblProblem);
TextField tfProblem = new TextField();
prompt.getChildren().add(tfProblem);
Button btnFindAnswer = new Button("Find answers");
btnFindAnswer.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() {
#Override
public void handle(Event arg0) {
int x = showFactors(tfProblem);
}
});
prompt.getChildren().add(btnFindAnswer);
pane.setCenter(prompt);
pane.setBottom(setUpGrid());
Scene scene = new Scene(pane, 550, 650);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("lab 7");
primaryStage.setScene(scene);
primaryStage.show();
}
private HBox getHbox1() {
HBox hbox = new HBox(15);
hbox.setPadding(new Insets(15, 15, 15, 15));
hbox.setAlignment(Pos.TOP_CENTER);
hbox.getStyleClass().add("hbox1");
Label lblProblem = new Label("Reverse Multiplication Table");
hbox.getChildren().add(lblProblem);
return hbox;
}
public GridPane setUpGrid() {
GridPane pane = new GridPane();
Label[][] labels = new Label[11][11];
for (int row = 0; row < 11; row++)
for (int col = 0; col < 11; col++) {
Label l = new Label();
setUpLabel(l, col, row);
labels[row][col] = l;
pane.add(l, col, row);
}
return pane;
}
public void setUpLabel(final Label l, final int col, final int row) {
l.setPrefHeight(50);
l.setPrefWidth(50);
l.setAlignment(Pos.CENTER);
l.setStyle("-fx-stroke-border: black; -fx-border-width: 1;");
String a = String.valueOf(row);
String b = String.valueOf(col);
if (row == 0 || col == 0) {
l.getStyleClass().add("gridBorders");
if(row == 0)
l.setText(b);
else if (col == 0)
l.setText(a);
} else {
l.setText(a + " * " + b);
l.getStyleClass().add("gridInside");
}
}
public int showFactors(TextField problem) {
FactorCalculator calc = new FactorCalculator();
int number = Integer.parseInt(problem.getText());
List<Integer> factors = calc.findFactor(number);
for(int i = 0; i < factors.size() - 1; i++) {
return factors.get(i);
}
return 0;
}
public static void main(String[] args) {
launch(args);
}
}
factorCalculator class
package application;
import java.util.ArrayList;
import java.util.List;
public class FactorCalculator {
public List<Integer> list = new ArrayList<Integer>();
public List<Integer> findFactor(int problem) {
int incrementer = 1;
if(problem % 2 != 0) {
incrementer = 2;
}
while(incrementer <= problem) {
if(problem % incrementer == 0) {
list.add(incrementer);
}
incrementer++;
}
return list;
}
}
application css
{
-fx-text-alignment: center;
}
.hbox1 {
-fx-background-color: gray;
}
.hbox2 {
-fx-background-color: white;
}
.gridBorders {
-fx-background-color: gray;
-fx-text-fill:#A3FF47;
-fx-border-style: solid;
-fx-border-width: 1;
-fx-stroke-border: black;
}
.gridInside {
-fx-background-color: red;
-fx-text-fill: white;
-fx-border-style: solid;
-fx-border-width: 1;
-fx-stroke-border: black;
}
.gridAnswer {
-fx-background-color: white;
-fx-text-fill: black;
}
Just use your style "gridAnswer" and set it
l.getStyleClass().add( "gridAnswer");
or remove it
l.getStyleClass().remove( "gridAnswer");
depending on your needs.
Edit: May I suggest a different approach?
Just create a custom cell which has all the information you need. Something like this:
private class AnswerCell extends Label {
int a;
int b;
int value;
public AnswerCell( int a, int b) {
this.a = a;
this.b = b;
this.value = a * b;
setText( a + " * " + b);
}
public boolean matches( int matchValue) {
return value == matchValue;
}
public void highlight() {
getStyleClass().add( "gridAnswer");
}
public void unhighlight() {
getStyleClass().remove( "gridAnswer");
}
}
In your setup method you simply add the cells and put them into a global list:
List<AnswerCell> answerCells = new ArrayList<>();
And to find the answers you do this:
for( AnswerCell cell: answerCells) {
cell.unhighlight();
}
for( AnswerCell cell: answerCells) {
if( cell.matches(number)) {
cell.highlight();
}
}
ReverseMultiplication.java
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package reversemultiplication;
import java.util.List;
import javafx.application.Application;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
/**
*
* #author reegan
*/
public class ReverseMultiplication extends Application {
#Override
public void start(Stage primaryStage) {
BorderPane pane = new BorderPane();
pane.setTop(getHbox1());
HBox prompt = new HBox(15);
prompt.setPadding(new Insets(15, 15, 15, 15));
prompt.setAlignment(Pos.TOP_CENTER);
prompt.getStyleClass().add("hbox2");
Label lblProblem = new Label("Enter problem: ");
prompt.getChildren().add(lblProblem);
TextField tfProblem = new TextField();
prompt.getChildren().add(tfProblem);
GridPane gridPane = setUpGrid();
GridpaneHelper gh = new GridpaneHelper(gridPane);
Button btnFindAnswer = new Button("Find answers");
btnFindAnswer.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<Event>() {
#Override
public void handle(Event arg0) {
List<int[]> x = showFactors(tfProblem);
for (int[] x1 : x) {
Node node = gh.getChildren()[x1[0]][x1[1]];
node.setStyle("-fx-background-color: green");
}
}
});
prompt.getChildren().add(btnFindAnswer);
pane.setCenter(prompt);
pane.setBottom(gridPane);
Scene scene = new Scene(pane, 550, 650);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setTitle("lab 7");
primaryStage.setScene(scene);
primaryStage.show();
}
private HBox getHbox1() {
HBox hbox = new HBox(15);
hbox.setPadding(new Insets(15, 15, 15, 15));
hbox.setAlignment(Pos.TOP_CENTER);
hbox.getStyleClass().add("hbox1");
Label lblProblem = new Label("Reverse Multiplication Table");
hbox.getChildren().add(lblProblem);
return hbox;
}
public GridPane setUpGrid() {
GridPane pane = new GridPane();
Label[][] labels = new Label[11][11];
for (int row = 0; row < 11; row++) {
for (int col = 0; col < 11; col++) {
Label l = new Label();
setUpLabel(l, col, row);
labels[row][col] = l;
pane.add(l, col, row);
}
}
return pane;
}
public void setUpLabel(final Label l, final int col, final int row) {
l.setPrefHeight(50);
l.setPrefWidth(50);
l.setAlignment(Pos.CENTER);
l.setStyle("-fx-stroke-border: black; -fx-border-width: 1;");
String a = String.valueOf(row);
String b = String.valueOf(col);
if (row == 0 || col == 0) {
l.getStyleClass().add("gridBorders");
if (row == 0) {
l.setText(b);
} else if (col == 0) {
l.setText(a);
}
} else {
l.setText(a + " * " + b);
l.getStyleClass().add("gridInside");
}
}
public List<int[]> showFactors(TextField problem) {
FactorCalculator calc = new FactorCalculator();
int number = Integer.parseInt(problem.getText());
System.out.println(number);
List<int[]> factors = calc.findFactor(number, 10);
System.out.println(factors);
return factors;
}
public static void main(String[] args) {
launch(args);
}
}
GridpaneHelper.java help gridpane node access.
package reversemultiplication;
import javafx.scene.Node;
import javafx.scene.layout.GridPane;
public class GridpaneHelper {
GridPane gridPane;
public GridpaneHelper(GridPane gridPane) {
this.gridPane = gridPane;
}
private int size() {
return gridPane.getChildren().size();
}
public int getColumnSize() {
int numRows = gridPane.getRowConstraints().size();
for (int i = 0; i < gridPane.getChildren().size(); i++) {
Node child = gridPane.getChildren().get(i);
if (child.isManaged()) {
int columnIndex = GridPane.getColumnIndex(child);
int columnEnd = GridPane.getColumnIndex(child);
numRows = Math.max(numRows, (columnEnd != GridPane.REMAINING ? columnEnd : columnIndex) + 1);
}
}
return numRows;
}
public int getRowSize() {
int numRows = gridPane.getRowConstraints().size();
for (int i = 0; i < gridPane.getChildren().size(); i++) {
Node child = gridPane.getChildren().get(i);
if (child.isManaged()) {
int rowIndex = GridPane.getRowIndex(child);
int rowEnd = GridPane.getRowIndex(child);
numRows = Math.max(numRows, (rowEnd != GridPane.REMAINING ? rowEnd : rowIndex) + 1);
}
}
return numRows;
}
public Node[] getColumnChilds(int columnNo) {
if (columnNo < getRowSize()) {
return getChildren()[columnNo];
}
return null;
}
public Node[] getRowChilds(int rowNo) {
Node n[] = new Node[getRowSize()];
if (rowNo <= getRowSize()) {
for (int i = 0; i < getRowSize(); i++) {
n[i] = getColumnChilds(i)[rowNo];
}
return n;
}
return null;
}
public Node[] getChildRowVia() {
Node n[] = new Node[size()];
int col = getColumnSize();
int arrIncre = 0;
for (int i = 0; i < col; i++) {
for (Node n1 : getRowChilds(i)) {
if (n1 != null) {
n[arrIncre] = n1;
arrIncre++;
}
}
}
return n;
}
public Node[][] getChildren() {
Node[][] nodes = new Node[getRowSize()][getColumnSize()];
for (Node node : gridPane.getChildren()) {
int row = gridPane.getRowIndex(node);
int column = gridPane.getColumnIndex(node);
nodes[row][column] = node;
}
return nodes;
}
public Integer postion(Node node, Pos pos) {
if (node != null) {
switch (pos) {
case Row:
return gridPane.getRowIndex(node);
case Column:
return gridPane.getColumnIndex(node);
}
}
return null;
}
enum Pos {
Row,
Column;
}
}
One new method added to FactorCalculator.java class file this help to how many combination are made.
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package reversemultiplication;
import java.util.ArrayList;
import java.util.List;
/**
*
* #author reegan
*/
class FactorCalculator {
public List<Integer> list = new ArrayList<Integer>();
private int problem = 0;
public List<int[]> findFactor(int problem, int limit) {
int incrementer = 1;
this.problem = problem;
while (incrementer <= limit) {
if (problem % incrementer == 0) {
list.add(incrementer);
}
incrementer++;
}
return combinational();
}
public List<int[]> combinational() {
List<int[]> arrays = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
for (int j = 0; j < list.size(); j++) {
if (list.get(i) * list.get(j) == problem) {
int[] inx = new int[2];
inx[0] = list.get(i);
inx[1] = list.get(j);
arrays.add(inx);
}
}
}
return arrays;
}
}
add your css file in your project ,but this example code not clear in previous set style.after i will tell this.
The answer from Roland/ItachiUchiha is good: here is another approach.
Define an IntegerProperty to hold the current value:
public class Main extends Application {
private final IntegerProperty value = new SimpleIntegerProperty();
// ...
}
Now just have each label observe the value:
public void setUpLabel(final Label l, final int col, final int row) {
value.addListener((obs, oldValue, newValue) -> {
if (col * row == newValue.intValue()) {
l.getStyleClass().add("gridAnswer");
} else {
l.getStyleClass().remove("gridAnswer");
}
});
// all previous code...
}
Finally, just set the value when the button is pressed:
btnFindAnswer.addEventHandler(ActionEvent.ACTION, new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent arg0) {
// you probably don't need this any more:
int x = showFactors(tfProblem);
value.set(Integer.parseInt(tfProblem.getText()));
}
});