JavaFX grid help

Hi. I’ve tried to search for this topic so I don’t repeat a question, but I didn’t have any luck. I’m new here, so please don’t crucify me if this is an accidental repeat. :grimacing:

I’m working on a final project for my OOP/Java class and I’m stuck. I can create the grid (game board) and create my ‘ship’ (1x5 grid of red tiles) within the game board. While I can hard code the location change, I cannot seem to figure out how to get the ‘ship’ to place at the clicked tile, instead of (0,0). I’m sure this is an incredibly obvious fix, but I can’t manage to figure it out. Can anyone help? This code is messy/redundant I’m sure - I’ll work on streamlining later. Right now I’m just trying to figure out this click/placement issue.

import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

public class practice extends Application
{
	private Tiles[][] gameBoard = new Tiles[9][9];	//sets size for game board
	private Ships[][] carrier = new Ships[1][5];
	
	boolean clicked = false;
	
	Pane root = new Pane();
	@Override
	public void start(Stage stage) throws Exception
	{
		stage.setScene(new Scene(createGame()));
		stage.show();
	}
	
	private Parent createGame()
	{
		root.setPrefSize(450, 450);
		
		for (int i = 0; i < gameBoard.length; i++)
		{
			for (int j = 0; j < gameBoard[i].length; j++)
			{
				Tiles tile = new Tiles();
				tile.setTranslateX(i * 50);
				tile.setTranslateY(j * 50);
				
				root.getChildren().add(tile);
				
				gameBoard[i][j] = tile;
				
				tile.setOnMouseClicked(event ->
				{
					if (event.getButton() == MouseButton.PRIMARY)
					{
						clicked = true;
						
						for (int row = 0; row < 5; row++)
						{
							for (int column = 0; column < 1; column++)
							{
								Ships ship = new Ships();
								ship.setTranslateX(row * 50);
								ship.setTranslateY(column * 50);
								root.getChildren().add(ship);
							}
						}
					}
					else if (event.getButton() == MouseButton.SECONDARY)
					{
						if (clicked == false)
						{
						for (int row = 0; row < 1; row++)
						{
							for (int column = 0; column < 5; column++)
							{
								Ships ship = new Ships();
								ship.setTranslateX(row * 50);
								ship.setTranslateY(column * 50);
								root.getChildren().add(ship);
							}
						}
						}
					}
					
				});
				
			}
		}
		return root;		
	}
	
	private class Ships extends GridPane
	{
		public Ships()
		{
			Rectangle gameTile = new Rectangle(50,50);
			gameTile.setFill(Color.RED);
			gameTile.setStroke(Color.BLACK);
			
			getChildren().addAll(gameTile);
			
			
		}
	}
	
	
	private class Tiles extends GridPane
	{
		
		
		public Tiles()
		{
			Rectangle gameTile = new Rectangle(50,50);
			gameTile.setFill(Color.LIGHTBLUE);
			gameTile.setStroke(Color.BLACK);
			
			getChildren().addAll(gameTile);
		}	
	}
	
	

	/*main method that executes launch*/
	public static void main(String[] args)
	{
		launch(args);
	}	
}

Hello!

This may not be the best way to do it, but it’s how I solved something similar in the past.

Assuming Your grid is at position 0, 0 (x, y) and You have the size of the cells, then You could calculate the position like this:

// Grid of 3 x 3
cellCount = 3
cellW = 30 // Cell width
cellH = 30 // Cell height
gridStartX = 0 // The X position of the grid
gridStartY = 0 // The Y position of the grid

// Max grid width
maxW = cellW * cellCount // 90

// Max grid height
maxH = cellH * cellCount // 90

if (clickX >= gridStartX && clickX <= maxW && clickY >= gridStartY && clickY <= maxH)
    Clicked inside the grid, hence calculate which cell was clicked

// To actually calculate the clicked cell, one would write something like this:
// (This would go inside the previous if)
Math.floor(clickX / cellW)
Math.floor(clickY / cellH)

// So, if clickX = 40
// and clickY = 60
column = Math.floor(40 / 30)
// 40/30 = 1.3, rounded down = 1
row = Math.floor(60 / 30)
// 60/30 = 2
// We got cell(1, 2)

This is not Java (it’s pseudo-code, actually), but should not be that hard to implement :slight_smile:.

Tell me if this helps :stuck_out_tongue:,

Regards!

Thank you! I’ll play with this today and see what I can do with it. We’ve just started doing GUI with JavaFX so I’m definitely working through a learning curve lol.

1 Like