For loop for program? - java

so I am writing a program about the monte carlous math problem and I am doing the visual side of it. I mostly have everything set, the only issue is that I can't put the pixels in a loop for some reason. Any help? I've already tried a for loop though.
public class Main extends Application {
#Override
public void start(Stage primaryStage)
{
int width = 1;
int random = ((int)Math.random()*400)+1;
// Create the Colors
Color white = Color.web("rgb(255,255,255)");
Color black = Color.web("rgb(0,0,0)");
//making the square
Rectangle square = new Rectangle(115,50,400,400);
square.setFill(black);
square.setStroke(white);
square.setStrokeWidth(width);
//Drawing the Circle and pixels
Circle circle = new Circle();
Circle pixel = new Circle();
//Setting the properties of the circle
circle.setCenterX(315.0f); //moves the cirlce left or right
circle.setCenterY(250.0f); //moves the circle up and down
circle.setRadius(200.0f);
circle.setFill(black);
circle.setStroke(white);
circle.setStrokeWidth(width);
//setting properties of the pixels
for(int i = 0; i<1000; i++)
{
pixel.setCenterX((int)(Math.random()*400)+1);
pixel.setCenterY((int)(Math.random()*400)+1);
pixel.setRadius(1);
pixel.setFill(white);
}
//Creating a Group object
Group Root = new Group(circle);
Pane pane = new Pane();
pane.getChildren().addAll(square,circle,pixel);
Scene scene = new Scene(pane,630,500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args)
{
launch(args);
}
}

Code
public class PixelLoop extends Application {
#Override
public void start(Stage primaryStage) {
int width = 1;
int random = ((int)Math.random()*400)+1;
// Create the Colors
Color white = Color.web("rgb(255,255,255)");
Color black = Color.web("rgb(0,0,0)");
//making the square
Rectangle square = new Rectangle(115,50,400,400);
square.setFill(black);
square.setStroke(white);
square.setStrokeWidth(width);
//Drawing the Circle and pixels
Circle circle = new Circle();
//Setting the properties of the circle
circle.setCenterX(315.0f); //moves the cirlce left or right
circle.setCenterY(250.0f); //moves the circle up and down
circle.setRadius(200.0f);
circle.setFill(black);
circle.setStroke(white);
circle.setStrokeWidth(width);
//Creating a Group object
Group Root = new Group(circle);
Pane pane = new Pane();
pane.getChildren().addAll(square,circle);
//setting properties of the pixels
for(int i = 0; i<1000; i++) {
Circle pixel = new Circle();
pixel.setCenterX((int)(Math.random()*400)+1);
pixel.setCenterY((int)(Math.random()*400)+1);
pixel.setRadius(1);
pixel.setFill(white);
pane.getChildren().add(pixel);
}
Scene scene = new Scene(pane,630,500);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) { Application.launch(args); }
}
In the beginning there was the problem that you overwrote your object over and over again. That is the reason why there was just one pixel.
As #Tobias Brösamle said, you should create a new object every time you pass through the loop and then add it to the pane.
If you want negativ Coordinates try this

Related

Rectangle with Gradient Color in javafx

I am using anchorpane in my javafx application. I want to draw a rectangle and fill it with gradient color like this: the left side of the rectangle is blue and the right side is red and I want it to seem that from left to right, the blue color decreases and red color increases.
I know how to put a rectangle ( how to use the Rectangle class in javafx ) but I don't know how to fill it this way. Any ideas?
See docs on linear gradients.
public class Gradient extends Application {
public static final double S = 100;
#Override
public void start(Stage stage) {
Stop[] stops = new Stop[] {
new Stop(0, Color.BLUE),
new Stop(1, Color.RED)
};
LinearGradient gradient = new LinearGradient(
0, 0,
1, 0,
true,
CycleMethod.NO_CYCLE,
stops
);
Rectangle rectangle = new Rectangle(S, S, gradient);
stage.setScene(new Scene(new Group(rectangle)));
stage.show();
}
public static void main(String[] args) {
launch();
}
}

Java AnimationTimer content not showing

I'm trying to learn how JavaFX animations work, so I've tried to create an animation with Earth moving in a circle, based on this tutorial: https://gamedevelopment.tutsplus.com/tutorials/introduction-to-javafx-for-game-development--cms-23835.
For some reason, the scene I want to show is set in the stage, but the graphics or animations aren't. I'm pretty sure this one is trivial, I just can't seem to find the reason. Here's my Main class code:
public class Main extends Application {
private static Stage stage;
private static Window window;
private static Scene scWindow;
#Override
public void start(Stage primaryStage) {
stage = primaryStage;
stage.setTitle("Animation");
showWindow();
stage.show();
}
public static void showWindow() {
window = new Window();
scWindow = new Scene(window, 400, 400);
stage.setScene(scWindow);
}
public static void main(String[] args) {
launch(args);
}
}
and this is the Window class code:
public class Window extends BorderPane {
final long startNanoTime = System.nanoTime();
Image earth = new Image("http://icdn.pro/images/en/g/o/google-earth-icone-8927-128.png");
Image space = new Image("https://space-facts.com/wp-content/uploads/magellanic-clouds.png");
GraphicsContext gc;
public Window() {
Group root = new Group();
Canvas canvas = new Canvas(512, 512);
gc = canvas.getGraphicsContext2D();
root.getChildren().add(canvas);
gc.setFill(Color.BLACK);
Anim a = new Anim();
a.start();
}
private class Anim extends AnimationTimer {
public void handle(long currentNanoTime)
{
double t = (currentNanoTime - startNanoTime) / 1000000000.0;
double x = 232 + 128 * Math.cos(t);
double y = 232 + 128 * Math.sin(t);
gc.drawImage( space, 0, 0 );
gc.drawImage( earth, x, y );
}
}
}
There's no exception thrown or anything, I have no idea what's wrong.
EDIT:
I know that I haven't put anything in the setCenter/Left etc. in the constructor, so actually if it is the reason, how should I put the animation e.g. on the center of the border pane?
You forgot to add root to the scene. Add something like
setCenter(root);
to the constructor of Window.
Or simply use the Canvas as center:
public Window() {
Canvas canvas = new Canvas(512, 512);
gc = canvas.getGraphicsContext2D();
setCenter(canvas);
gc.setFill(Color.BLACK);
Anim a = new Anim();
a.start();
}

Joining points with javaFX

I wrote the following code for adding and deleting points or circles with mouse events. The next step is joining them with a line while I'm creating them (creating a polygon). I'm completely stuck and do not know where to start. I am looking for documentation but I will appreciate if somebody could point me in the right direction.
package application;
//import all needed classes
import javafx.collections.ObservableList;
import javafx.scene.input.MouseButton;
import javafx.application.Application;
import javafx.scene.shape.Circle;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Node;
public class Main extends Application {
// using the base class of layout panes
Pane pane = new Pane();
#Override
public void start(Stage primaryStage) {
// what to do when the mouse is clicked
pane.setOnMouseClicked(e -> {
double drawX = e.getX();// position of mouse in X axle
double drawY = e.getY();// position of mouse in y axle
if (e.getButton() == MouseButton.PRIMARY) {// get the position of the mouse point when user left click
Circle circle = makeCircle(drawX, drawY);// using the makeCircle method to draw the circle where the mouse is at the click
pane.getChildren().add(circle);
} else if (e.getButton() == MouseButton.SECONDARY) {
deleteCircle(drawX, drawY);// using the deleteCircle function to delete the circle if right click on the circle
}
});
// container to show all context in a 500px by 500px windows
try {
Scene scene = new Scene(pane, 500, 500);// size of the scene
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
// method to draw the circle when left click
private Circle makeCircle(double drawX, double drawY) {
Circle circle = new Circle(drawX, drawY, 7, Color.CORAL);// create the circle and its properties(color: coral to see it better)
circle.setStroke(Color.BLACK);// create the stroke so the circle is more visible
return circle;
}
// method to delete the circle using the ObservableList class
private void deleteCircle(double deletX, double deleteY) {
// loop to create my list of circles 'til this moment
ObservableList<Node> list = pane.getChildren();
for (int i = list.size() - 1; i >= 0; i--) {
Node circle = list.get(i);
// checking which circle I want to delete
if (circle instanceof Circle && circle.contains(deletX, deleteY)) {
pane.getChildren().remove(circle);
break;
}
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
I would add a change listener to the children of your pane, add a polygon to the pane and if there are more then 2 Circles, you redraw the polygon:
public class Main extends Application {
// using the base class of layout panes
Pane pane = new Pane();
Polygon polygon = new Polygon();
#Override
public void start(Stage primaryStage) {
// what to do when the mouse is clicked
pane.setOnMouseClicked(e -> {
double drawX = e.getX();// position of mouse in X axle
double drawY = e.getY();// position of mouse in y axle
if (e.getButton() == MouseButton.PRIMARY) {// get the position of the mouse point when user left click
Circle circle = makeCircle(drawX, drawY);// using the makeCircle method to draw the circle where the mouse is at the click
pane.getChildren().add(circle);
} else if (e.getButton() == MouseButton.SECONDARY) {
deleteCircle(drawX, drawY);// using the deleteCircle function to delete the circle if right click on the circle
}
});
pane.getChildren().add(polygon);
pane.getChildren().addListener(new ListChangeListener<Node>() {
#Override
public void onChanged(Change<? extends Node> c) {
int numOfCircles = pane.getChildren().size() - 1;
if ( numOfCircles >= 2 ) {
polygon.setStroke(Color.BLACK);
polygon.getPoints().clear();
for ( int i = 0; i <= numOfCircles; i++ ) {
Node node = pane.getChildren().get(i);
if ( node.getClass() == Circle.class ) {
polygon.getPoints().addAll(
((Circle) node).getCenterX(),
((Circle) node).getCenterY()
);
}
}
System.out.println(polygon.getPoints());
}
}
});
// container to show all context in a 500px by 500px windows
try {
Scene scene = new Scene(pane, 500, 500);// size of the scene
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
// method to draw the circle when left click
private Circle makeCircle(double drawX, double drawY) {
Circle circle = new Circle(drawX, drawY, 7, Color.CORAL);// create the circle and its properties(color: coral to see it better)
circle.setStroke(Color.BLACK);// create the stroke so the circle is more visible
return circle;
}
// method to delete the circle using the ObservableList class
private void deleteCircle(double deletX, double deleteY) {
// loop to create my list of circles 'til this moment
ObservableList<Node> list = pane.getChildren();
for (int i = list.size() - 1; i >= 0; i--) {
Node circle = list.get(i);
// checking which circle I want to delete
if (circle instanceof Circle && circle.contains(deletX, deleteY)) {
pane.getChildren().remove(circle);
break;
}
}
}
public static void main(String[] args) {
Application.launch(args);
}
}
You can also not use the change listener, but call the redraw whenever you add or delete a circle. In addition you can also add an onclick listener to each circle calling the delete function and deleting in a more efficient manner:
public class Main extends Application {
// using the base class of layout panes
Pane pane = new Pane();
Polygon polygon = new Polygon();
#Override
public void start(Stage primaryStage) {
// what to do when the mouse is clicked
pane.setOnMouseClicked(e -> {
double drawX = e.getX();// position of mouse in X axle
double drawY = e.getY();// position of mouse in y axle
if (e.getButton() == MouseButton.PRIMARY) {// get the position of the mouse point when user left click
Circle circle = makeCircle(drawX, drawY);// using the makeCircle method to draw the circle where the mouse is at the click
pane.getChildren().add(circle);
circle.setOnMouseClicked( event -> {
deleteCircle(circle);
// consume event so that the pane on click does not get called
event.consume();
});
redrawPolygon();
}
});
polygon = new Polygon();
polygon.setFill(Color.TRANSPARENT);
polygon.setStroke(Color.BLACK);
pane.getChildren().add(polygon);
// container to show all context in a 500px by 500px windows
try {
Scene scene = new Scene(pane, 500, 500);// size of the scene
primaryStage.setScene(scene);
primaryStage.show();
} catch (Exception e) {
e.printStackTrace();
}
}
// method to draw the circle when left click
private Circle makeCircle(double drawX, double drawY) {
Circle circle = new Circle(drawX, drawY, 7, Color.CORAL);// create the circle and its properties(color: coral to see it better)
circle.setStroke(Color.BLACK);// create the stroke so the circle is more visible
return circle;
}
private void redrawPolygon() {
int numOfCircles = pane.getChildren().size() - 1;
if ( numOfCircles > 0 ) {
polygon.getPoints().clear();
for ( int i = 0; i <= numOfCircles; i++ ) {
Node node = pane.getChildren().get(i);
if ( node.getClass() == Circle.class ) {
polygon.getPoints().addAll(
((Circle) node).getCenterX(),
((Circle) node).getCenterY()
);
}
}
}
}
private void deleteCircle(Circle circle){
pane.getChildren().remove(circle);
redrawPolygon();
}
public static void main(String[] args) {
Application.launch(args);
}
}
If you want to only use one click handler you could also do it this way:
pane.setOnMouseClicked(e -> {
if ( e.getTarget().getClass() == Circle.class ) {
deleteCircle((Circle)e.getTarget());
} else {
Circle circle = makeCircle(e.getX(), e.getY());// using the makeCircle method to draw the circle where the mouse is at the click
pane.getChildren().add(circle);
redrawPolygon();
}
});

Explicit positioning a Pane

I'm trying to create a basic UML diagramming tool with JavaFX.
First I did this:
public class Asd extends Application {
Double WINDOW_HEIGHT = (double) 400;
Double WINDOW_WIDTH = (double) 800;
Double RECTANGLE_DEFAULT_HEIGHT = (double) 50;
Double RECTANGLE_DEFAULT_WIDTH = (double) 100;
#Override
public void start(Stage stage) throws Exception {
final Pane root = new Pane();
Rectangle background = new Rectangle(WINDOW_WIDTH, WINDOW_HEIGHT,
Color.WHITE);
root.getChildren().add(background);
Scene scene = new Scene(root, WINDOW_WIDTH, WINDOW_HEIGHT);
// On window click
root.setOnMousePressed(new EventHandler<MouseEvent>() {
public void handle(MouseEvent mouseEvent) {
Rectangle rect = new Rectangle();
rect.setX(mouseEvent.getX());
rect.setY(mouseEvent.getY());
rect.setWidth(RECTANGLE_DEFAULT_WIDTH);
rect.setHeight(RECTANGLE_DEFAULT_HEIGHT);
rect.setFill(null);
rect.setStroke(Color.BLACK);
root.getChildren().add(rect);
}
});
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}
With that, I can draw a rectangle (that would represent a UML Class) in the exact point I click.
Now I want to add text. If instead of
root.getChildren().add(rect);
I do
Text text = new Text("mockText");
StackPane stackPane = new StackPane();
stackPane.getChildren().addAll(rect, text);
root.getChildren().add(stackPane);
the text is placed in the center of the rectangle, but all rectangles are positioned at coordinates (0,0)
So, any way to change the position of each StackPane? Or any alternative to add text to the rectangles directly without using StackPane?
OK, got it. Layout elements have methods setLayoutX & setLayoutY that can be used in cases like this one, so I don't need anymore Rectangle.setX/setY & finally the handle method should be:
public void handle(MouseEvent mouseEvent) {
Rectangle rect = new Rectangle();
rect.setWidth(RECTANGLE_DEFAULT_WIDTH);
rect.setHeight(RECTANGLE_DEFAULT_HEIGHT);
rect.setFill(null);
rect.setStroke(Color.BLACK);
Text text = new Text("mockText");
StackPane stackPane = new StackPane();
stackPane.getChildren().addAll(rect, text);
stackPane.setLayoutX(mouseEvent.getX());
stackPane.setLayoutY(mouseEvent.getY());
root.getChildren().add(stackPane);
}

How to make a node move whenever mouse is move over the scene (in JavaFX)?

I have written a small JavaFX program in which a Rectangle node is made to moved whenever mouse cursor is moved over the scene containing the rectangle. Here is my code:
public class MovedObjectWhenMouseMoved extends Application{
double nodeX;
double currentMousePos;
double oldMousePos = 0.0;
public static void main(String[] arg){
launch(arg);
}
#Override
public void start(Stage stage) throws Exception {
final Rectangle rect = new Rectangle(50, 50, Color.RED);
rect.setX(20);
rect.setY(20);
AnchorPane anchorPane = new AnchorPane();
anchorPane.getChildren().add(rect);
Scene scene = new Scene(anchorPane,500,500,Color.GREEN);
stage.setScene(scene);
stage.show();
scene.setOnMouseMoved(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
currentMousePos = mouseEvent.getX();
if(currentMousePos>oldMousePos){
rect.setX(rect.getX()+1); // Move right
}else if(currentMousePos<oldMousePos){
rect.setX(rect.getX()-1); // Move Left
}
oldMousePos = currentMousePos;
}
});
}
}
But here the problem is that the node speed is not same as the mouse speed.
How can I rectify this problem? Also please let me know if there is any better approach.
Mouse can change position on more then 1 pixel.
Try this code for handle:
currentMousePos = mouseEvent.getX();
double dX = currentMousePosition - oldMousePos;
rect.setX(rect.getX() + dX);
oldMousePos = currentMousePos;

Categories

Resources