I am currently trying to make an 8x8 board and cannot seem to figure out why my rectangle objects are not showing. I am trying to figure out the logic behind one row before I do it multiple times to get the whole board. Below is my current code:
import javafx.application.*;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.layout.TilePane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Board extends Application {
public static void main(String[] args) {
launch();
}
public void start(Stage ps) {
TilePane tp = new TilePane();
Pane p = new Pane();
for (int column = 0; column > 8; column++) {
// This loop is used to determine the center of the rectangle
for (int x = 10; x < 160; x += 20) {
Rectangle r = new Rectangle();
r.setWidth(20);
r.setHeight(20);
r.setX(x);
r.setY(10);
if (column == 0 || column % 2 == 0) {
r.setFill(Color.BLACK);
}
else {
r.setFill(Color.GREY);
}
tp.getChildren().add(r);
}
}
p.getChildren().add(tp);
Scene s = new Scene(p, 160, 160);
ps.setScene(s);
ps.setTitle("PP2 Halma Project");
ps.show();
}
}
for (int column = 0; column > 8; column++) - This will never happen because 0 can never be more than 8.
r.setX(x) - I don't think you would need this. You should let TilePane layout the rectangles for you; you just need to define a size for it.
Pane p = new Pane() - Personally, I think this is redundant. Using just TilePane without it will work just fine. This will not cause your program to bug, though.
Related
I am working on an exercise that is asking me to do the following;
Create a GridPane
Set the pane’s horizontal and vertical gap to zero
Set the pane’s grid line visibility to true
Use nested FOR loops to create and add buttons to the pane (loops
starts from 0 to 10)
Each button must be labeled with any number between 0 to 99
Color the buttons based on the following rules:
a. If the color’s label is divisible by 2, then change the color to Blue
b. If the color’s label is divisible by 3, then change the color to
Yellow
c. If the color’s label is divisible by 6, then change the color to Green
Add the pane to a scene
Add the scene to a stage, then display the Stage
I have everything set up, just not sure how to read the value generated by Math.random and do assign a specific color to that button.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.GridPane;
import javafx.scene.control.Button;
import javafx.scene.paint.Color;
public class Exercise8GridPane extends Application {
#Override
public void start(Stage primary) {
primary.setTitle("Exercise 8");
GridPane gp = new GridPane();
gp.setHgap(0);
gp.setVgap(0);
gp.setGridLinesVisible(true);
for (int k = 0; k < 10; k++) {
for (int l = 0; l < 10; l++) {
Button btn = new Button(String.valueOf((int)(Math.random() * 100)));
// if / 3 == 0){
btn.setStyle("-fx-base:red;-fx-text-fill:yellow");
gp.add(btn, l, k);
}
}
Scene s = new Scene(gp);
primary.setScene(s);
primary.show();
}
public static void main(String[] args) {
launch(args);
}
}
The java.lang.Math.random() returns a double value with a positive sign, greater than or equal to 0.0 and less than 1.0. This new pseudorandom-number generator is used thereafter for all calls to this method and is used nowhere else.
There are countless ways to read it.
I would recommend doing something like
int RED = (int) (Math.random() * 256);
// Note that Math.random() returns a value less than 1.0
int BLUE = ...
It's difficult to get three values from one number, so I think this will work well.
I'm trying to recreate the "snake" game using GridPane in JavaFX. My code seems to run properly except for this specific error, where anytime I use my keys to traverse the green node (titled head) toward the yellow node (titled food), the rows or columns of the grid seem to shorten by one unit, causing the grid to collapse in some manner. Is there a way to stop the GridPane from resizing? Below is my code:
package snake;
import java.util.ArrayList;
import java.util.Random;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.input.KeyCode;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.TilePane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Modality;
import javafx.stage.Stage;
public class snakemain extends Application {
Random random = new Random();
int posX = random.nextInt(21), posY = random.nextInt(21), foodposX = random.nextInt(24), foodposY = random.nextInt(24);
public static void main(String... args) {
launch(args);
}
public void start(Stage stage) {
//Creates Scene and stage setting + gridpane
stage.setTitle("Snake by Yeldor");
GridPane gridpane = new GridPane();
Random random = new Random();
Scene scene = new Scene(gridpane, 500, 500);
scene.setFill(Color.WHITE);
gridpane.setGridLinesVisible(true);
gridpane.setHgap(20);
gridpane.setVgap(20);
//creates head of snake, Arraylist of snakes body parts, and food consumable for snake
ArrayList<Rectangle> snakeBody = new ArrayList<Rectangle>();
Rectangle head = new Rectangle(20,20,Color.GREEN.brighter().brighter());
//invisible block to manage grid
Rectangle food = new Rectangle(20,20, Color.YELLOW.brighter().brighter());
//adds rectangles to grippane
gridpane.add(head, posX, posY);
gridpane.add(food, foodposX, foodposY);
//makes food non mangaged by the gridpane
scene.setOnKeyPressed(e ->
{
String s = e.getCode().toString();
try {
switch(s) {
case "W": gridpane.getChildren().remove(head);
gridpane.add(head, posX, --posY);
break;
case "A": gridpane.getChildren().remove(head);
gridpane.add(head, --posX, posY);
break;
case "S": gridpane.getChildren().remove(head);
gridpane.add(head, posX, ++posY);
break;
case "D": gridpane.getChildren().remove(head);
gridpane.add(head, ++posX, posY);
break;
}
if (posX == 24 || posY == 24 || posX == -1 || posY == -1) {
missionFailed();
stage.close();
}
}
catch(IllegalArgumentException error) {
missionFailed();
stage.close();
}
});
stage.setScene(scene);
stage.show();
}
void missionFailed() {
Stage failedPopup = new Stage();
failedPopup.setTitle("You Died!");
failedPopup.initModality(Modality.APPLICATION_MODAL);
Button OK = new Button("OK");
Group group = new Group();
Scene miniScene = new Scene(group, 150, 100);
group.getChildren().add(OK);
failedPopup.setScene(miniScene);
failedPopup.show();
OK.setOnMouseClicked(q -> {
failedPopup.close();
});
}
}
Using hgap and vgap does not modify the column size, it modifies the space between columns. If you e.g. place the Rectangles next to each other horizontally (same row index, column index differing by 1), the distance between both nodes is vgap; there are exactly 2 columns that are filled and have a width != 0. Now move the Rectangles to the same cell and only a single column with a width != 0 leading to unexpected results.
Instead you should restrict the size of the rows/columns:
// gridpane.setHgap(20);
// gridpane.setVgap(20);
int rows = 500 / 20;
int columns = 500 / 20;
RowConstraints rConstraints = new RowConstraints(20);
ColumnConstraints cConstraints = new ColumnConstraints(20);
for (int i = 0; i < columns; i++) {
gridpane.getColumnConstraints().add(cConstraints);
}
for (int i = 0; i < rows; i++) {
gridpane.getRowConstraints().add(rConstraints);
}
Another Solution that worked for me was to fill up the whole Area with transparent Rectangulars and just set the color of the Rectangulars used at the moment.
I am new in processing and java, I have some exercise to display 100 ellipses but the screen size is (900, 600), and I want break 100 in 10 lines of 10, but I don't know how to break line in processing , I already use translate(https://processing.org/reference/translate_.html),but it doesn't work.
//function
void draw(){
smooth();
noStroke();
fill(23,43,208,200);// cor azul
ellipse(posX,posY,12,10);
noStroke();
fill(242,76,39);//cor vermelho
ellipse(posX,posY,12,10);
}
for (int i=1; i<ellipses.length; i++)
{
for (int j=i; j<ellipses.length; j++)
{
if(j%10==0)
ellipses[i].draw();//calling function
}
}
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.shape.Ellipse;
import javafx.stage.Stage;
public class T15DrawEllipses extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) throws Exception {
Group group = new Group();
Scene scene = new Scene(group, 900, 600);
for (int row = 0; row < 10; row++) {
for (int col = 0; col < 10; col++) {
Ellipse e = new Ellipse();
e.setCenterX(44 + col * 90);
e.setCenterY(29 + row * 60);
e.setRadiusX(45);
e.setRadiusY(30);
group.getChildren().add(e);
}
}
primaryStage.setScene(scene);
primaryStage.show();
}
}
A complete example of 10 rows/columns with ellipses.
The best thing you can do when you have questions like this is to get out a piece of graph paper, and draw out a bunch of examples until you notice a pattern. What is the X,Y position of every cirlce you want to draw? What is the X value of the first row, the second row, the third row? What is the Y value of the first column, the second column, the third column?
You should also get into the habit of breaking your problem down into smaller pieces and taking those pieces on one at a time. For example, instead of trying to draw 100 circles in a grid, why don't you just try to draw 10 circles in a single row? Create a function that draws a row of circles. Then try calling that function multiple times to create your grid of circles.
If you get stuck on a specific step, you can ask a more specific question along with a MCVE. Good luck.
Is it possible to make all GridPane's grid lines permanently visible without using setGridLinesVisible()?
I know that setGridLinesVisible() is for debugging purposes only, and I want to show grid lines for the end-user's convenience.
Also, I need to work on a Pane container and not a Canvas.
My program is able to add, delete, modify, move, etc. shape objects and groups on a Pane type or a Pane subtype parent container.
Thanks
Doing this depends a bit on how you have things set up. From the description of your application, when I've experimented with similar things I always found it convenient to fill the grid with empty Panes of some kind to act as the cells, and then to manipulate their content based on the data in the model. If you use this approach, you can use some CSS to put borders (e.g. using nested backgrounds) on the "cells", which will give the effect of grid lines.
Here's a simple example of this approach:
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.scene.Scene;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.scene.layout.RowConstraints;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class GridPaneWithLines extends Application {
private StackPane createCell(BooleanProperty cellSwitch) {
StackPane cell = new StackPane();
cell.setOnMouseClicked(e -> cellSwitch.set(! cellSwitch.get() ));
Circle circle = new Circle(10, Color.CORNFLOWERBLUE);
circle.visibleProperty().bind(cellSwitch);
cell.getChildren().add(circle);
cell.getStyleClass().add("cell");
return cell;
}
private GridPane createGrid(BooleanProperty[][] switches) {
int numCols = switches.length ;
int numRows = switches[0].length ;
GridPane grid = new GridPane();
for (int x = 0 ; x < numCols ; x++) {
ColumnConstraints cc = new ColumnConstraints();
cc.setFillWidth(true);
cc.setHgrow(Priority.ALWAYS);
grid.getColumnConstraints().add(cc);
}
for (int y = 0 ; y < numRows ; y++) {
RowConstraints rc = new RowConstraints();
rc.setFillHeight(true);
rc.setVgrow(Priority.ALWAYS);
grid.getRowConstraints().add(rc);
}
for (int x = 0 ; x < numCols ; x++) {
for (int y = 0 ; y < numRows ; y++) {
grid.add(createCell(switches[x][y]), x, y);
}
}
grid.getStyleClass().add("grid");
return grid;
}
#Override
public void start(Stage primaryStage) {
int numCols = 5 ;
int numRows = 5 ;
BooleanProperty[][] switches = new BooleanProperty[numCols][numRows];
for (int x = 0 ; x < numCols ; x++) {
for (int y = 0 ; y < numRows ; y++) {
switches[x][y] = new SimpleBooleanProperty();
}
}
GridPane grid = createGrid(switches);
StackPane root = new StackPane(grid);
Scene scene = new Scene(root, 600, 600);
scene.getStylesheets().add("grid-with-borders.css");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
and the CSS (grid-with-borders.css):
.root {
-fx-padding: 20 ;
cell-color: white ;
cell-border-color: black ;
}
.grid {
/* 1 pixel border around the top and right of the grid: */
-fx-background-color: cell-border-color, cell-color ;
-fx-background-insets: 0, 1 1 0 0 ;
-fx-padding: 1 ;
}
.cell {
/* 1 pixel border around the left and bottom of each cell: */
-fx-background-color: cell-border-color, cell-color ;
-fx-background-insets: 0, 0 0 1 1 ;
}
If you are trying to use fxml you can try this:
<GridPane GridPane.columnIndex="1" GridPane.rowIndex="0" gridLinesVisible="true">
For every children use:
-fx-border-color: black;
-fx-border-width: 0 0 1 1;
This can be achieved with the yourChildNode.setStyle(css) method for example.
Should one cell contain multiple layouts wrap them in one AnchorPane and apply the CSS on the AnchorPane.
I am learning Javafx and am having trouble getting my for loop to create a new rectangle on each iteration. When I run the program it creates one rectangle at the top left position and that is it. My goal is to create a grid of rectangles based on the amount of columns, rows, pixels wide, and pixels tall specified. Everything is tested to work besides the creation of rectangles.
for(int i = 0; i < columns; ++i)
{//Iterate through columns
for(int j = 0; j < rows; ++j)
{//Iterate through rows
Color choice = chooseColor(rectColors);
//Method that chooses a color
rect = new Rectangle(horizontal*j, vertical*i, horizontal, vertical);
//Create a new rectangle(PosY,PosX,width,height)
rect.setStroke(choice);
//Give rectangles an outline so I can see rectangles
root.getChildren().add(rect);
//Add Rectangle to board
}
}
I am trying to figure out why the rectangles aren't being created. Any help would be greatly appreciated.
I used the same program which you had.
Try with this and check where you made the mistake. Also check the values you initialized.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class RectangleDemo extends Application{
#Override
public void start(Stage stage) {
AnchorPane root = new AnchorPane();
Scene scene = new Scene(root);
stage.setScene(scene);
int columns = 20, rows = 10 , horizontal = 20, vertical = 20;
Rectangle rect = null;
for(int i = 0; i < columns; ++i)
{//Iterate through columns
for(int j = 0; j < rows; ++j)
{//Iterate through rows
// Color choice = chooseColor(rectColors);
//Method that chooses a color
rect = new Rectangle(horizontal*j, vertical*i, horizontal, vertical);
//Create a new rectangle(PosY,PosX,width,height)
rect.setStroke(Color.RED);
//Give rectangles an outline so I can see rectangles
root.getChildren().add(rect);
//Add Rectangle to board
}
}
scene.setRoot(root);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I hope it will help you...