When running the following code, produces just a blank window as in no visible circles are being drawn. It is expected to produce randomly placed black circles on the window.
Here is my code:
package circles;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.stage.Stage;
import java.util.Random;
import javafx.scene.paint.Color;
public class Circles extends Application {
private Canvas canvas = new Canvas(400, 400);
#Override
public void start(Stage primaryStage) {
VBox root = new VBox();
root.getChildren().add(canvas);
Scene scene = new Scene(root);
primaryStage.setTitle("Draw Circles");
primaryStage.setScene(scene);
primaryStage.show();
}
private void drawCircles() {
// radius of the circles
final int RADIUS = 20;
Random rand = new Random();
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
gc.setFill(Color.WHITESMOKE);
for (int i =0; i <50;i++) {
int x = rand.nextInt(400);
int y = rand.nextInt(400);
gc.fillOval(x, y, RADIUS, RADIUS);
}
}
public static void main(String[] args) {
Circles x = new Circles();
x.drawCircles();
launch(args);
}
}
The Application.launch(...) method creates an instance of the application class, and (after some other work) calls start() on it.
In your code, you first create an instance of your application class Circles, call drawCircles() on it, and then you call Application.launch(...). This causes a second instance of Circles to be created, and start() to be invoked on that second instance.
Consequently, drawCircles() is not called on the same object as start(), and so the circles are drawn on a canvas that is never displayed.
Simply move the call to drawCircles() to the start() method:
package circles;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.stage.Stage;
import java.util.Random;
import javafx.scene.paint.Color;
public class Circles extends Application {
private Canvas canvas = new Canvas(400, 400);
#Override
public void start(Stage primaryStage) {
VBox root = new VBox();
root.getChildren().add(canvas);
drawCircles();
Scene scene = new Scene(root);
primaryStage.setTitle("Draw Circles");
primaryStage.setScene(scene);
primaryStage.show();
}
private void drawCircles() {
// radius of the circles
final int RADIUS = 20;
Random rand = new Random();
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
gc.setFill(Color.WHITESMOKE);
for (int i =0; i <50;i++) {
int x = rand.nextInt(400);
int y = rand.nextInt(400);
gc.fillOval(x, y, RADIUS, RADIUS);
}
}
public static void main(String[] args) {
launch(args);
}
}
Related
I have a question that as per object concerns the Canvas and its GraphiContext.
In the following code I have reported a JavaFX Application that has the Canvas as its main object.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class canvasSVG extends Application{
private Double angle = 0.0;
#Override
public void start(Stage stage) {
Canvas canvas = new Canvas(500, 500);
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.setFill(Color.GREEN);
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
String svgPath = "m 0 10 v -24 M 0 -14 L 8 -16 M -2 10 h 4 l -2 5 l -2 -5";
canvas.setOnMousePressed(e->{
if(e.getButton()==MouseButton.PRIMARY) {
System.out.println("PUT: "+ angle);
gc.save();
gc.setStroke(Color.BLUE);
gc.translate(250,250);
gc.rotate(angle);
gc.scale(10, 10);
gc.appendSVGPath(svgPath);
gc.stroke();
angle = angle+50;
gc.restore();
}
});
canvas.setOnMouseClicked(e->{
if(e.getButton()==MouseButton.SECONDARY) {
System.out.println("CLEAN "+ angle);
gc.clearRect(0, 0, canvas.getWidth(), canvas.getHeight());
gc.setFill(Color.GREEN);
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
}
});
StackPane pane = new StackPane(canvas);
Scene scene = new Scene(pane);
stage.setTitle("Canvas Demo");
stage.setScene(scene);
stage.sizeToScene();
stage.centerOnScreen();
stage.show();
}
public static void main(String[] args) {
launch(canvasSVG.class);
}
}
On clicking with the left mouse button I add the SVG path to the canvas and on clicking with the right mouse button I remove it from the canvas.
The problem is that once the rotation has happened the first time, the angle of the geometric figure in the canvas doesn't change.
The method appendSVGPath() specifies: "The coordinates are transformed by the current transform as they are added to the path and unaffected by subsequent changes to the transform." As an alternative, rotate the enclosing Canvas as shown below. Also consider this alternate approach to scaling SVGPath.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseButton;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
/** #see https://stackoverflow.com/a/70945900/230513 */
public class CanvasSVG extends Application {
private static final double DIM = 400;
private static final Color BG = Color.GREEN;
private final Canvas canvas = new Canvas(DIM, DIM);
private final GraphicsContext gc = canvas.getGraphicsContext2D();
private Double angle = 0.0;
#Override
public void start(Stage stage) {
clear();
draw();
canvas.setOnMousePressed(e -> {
if (e.getButton() == MouseButton.PRIMARY) {
draw();
angle += 50;
canvas.setRotate(angle);
} else if (e.getButton() == MouseButton.SECONDARY) {
clear();
angle = 50.0;
}
});
StackPane pane = new StackPane(canvas);
pane.setBackground(new Background(new BackgroundFill(
BG, CornerRadii.EMPTY, Insets.EMPTY)));
Scene scene = new Scene(pane);
stage.setTitle("Canvas Demo");
stage.setScene(scene);
stage.centerOnScreen();
stage.show();
}
private void draw() {
String svgPath = "m 0 10 v -24 M 0 -14 L 8 -16 M -2 10 h 4 l -2 5 l -2 -5";
gc.save();
gc.setStroke(Color.BLUE);
gc.translate(DIM / 2, DIM / 2);
gc.scale(10, 10);
gc.appendSVGPath(svgPath);
gc.stroke();
gc.restore();
}
private void clear() {
gc.setFill(BG);
gc.fillRect(0, 0, canvas.getWidth(), canvas.getHeight());
}
public static void main(String[] args) {
launch(CanvasSVG.class);
}
}
I'm want to be able to drag-to-draw a line that ends in the center of each of two nodes (circles). I have two event handlers that I'm thinking listen for new mouse clicks, but whenever I click, nothing happens.
Here is the Start method:
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.input.MouseEvent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.shape.Line;
import javafx.scene.shape.Circle;
import javafx.scene.Group;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.layout.Pane;
#Override
public void start(Stage primaryStage) {
Group root = new Group();
Canvas canvas = new Canvas(500,500);
GraphicsContext gc = canvas.getGraphicsContext2D();
//Draw Circles onto a Pane:
Pane overlay = new Pane();
for (int i = 50; i < xDim; i+=50) {
for (int j = 50; j < yDim; j+=50) {
Circle c1 = new Circle();
c1.setCenterX(i);
c1.setCenterY(j);
c1.setRadius(5);
overlay.getChildren().add(c1);
}
}
drawLine(overlay);
root.getChildren().addAll(canvas,overlay);
primaryStage.setScene(new Scene(root, 500, 500));
primaryStage.show();
}
And here is drawLine():
Line l = new Line();
overlay.addEventHandler(MouseEvent.MOUSE_PRESSED,
new EventHandler<MouseEvent>() {
public void handle(MouseEvent t) {
if (t.getSource() instanceof Circle) {
Circle p = ((Circle) (t.getSource()));
double circleX = p.getCenterX();
double circleY = p.getCenterY();
l.setStartX(circleX);
l.setStartY(circleY);
} else {
Node p = ((Node) (t.getSource()));
double orgTranslateX = p.getTranslateX();
double orgTranslateY = p.getTranslateY();
}
}
});
overlay.addEventHandler(MouseEvent.MOUSE_RELEASED,
new EventHandler<MouseEvent>() {
public void handle(MouseEvent t) {
if (t.getSource() instanceof Circle) {
Circle p = ((Circle) (t.getSource()));
double circleX = p.getCenterX();
double circleY = p.getCenterY();
l.setEndX(circleX);
l.setEndY(circleY);
overlay.getChildren().add(l);
} else{}
}
});
};
You can see draw line has two different event handlers, one for a click and one for release, and the only thing that changes is myLine.setEndX().
Any help would be appreciated! I apologize in advance for any unknown transgressions.
In the application I need to create, I have a series of points which are connected by lines. I need to only see the line part of the graph and hide the points. However, I need to mark certain points by clicking on the appropriate places in the graph. In the code I have written I am either able to hide the points and not able to mark or I am able to mark but not hide the rest of the points. What do I do to hide the points and mark the required points?
package application;
import java.awt.Dimension;
import java.awt.Toolkit;
//import java.beans.EventHandler;
import java.util.ArrayList;
import javafx.event.EventHandler;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.Scene;
import javafx.scene.chart.Axis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.layout.Priority;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Main extends Application {
public XYChart.Data<Integer, Integer> k = new XYChart.Data();
public XYChart.Series series;
String pth;
public ObservableList<XYChart.Data<Integer, Integer>> dat = FXCollections.<XYChart.Data<Integer, Integer>>observableArrayList();
public int c = 0;
ArrayList<Integer> myListx = new ArrayList<Integer>();
public void start(Stage stage) {
stage.setTitle("Line Chart Sample");
final NumberAxis xAxis = new NumberAxis();
final NumberAxis yAxis = new NumberAxis();
xAxis.setLabel("Samples");
yAxis.setLabel("Data");
final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis);
lineChart.setCreateSymbols(false);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
int width = (int) screenSize.getWidth();
int height = (int) screenSize.getHeight();
StackPane spLineChart = new StackPane();
spLineChart.getChildren().add(lineChart);
while (c < 20) {
k = new XYChart.Data<Integer, Integer>(c++, c * 6);
dat.add(k);
k.setNode(new Node(c));
}
series = new XYChart.Series("IMU Data", dat);
lineChart.getData().addAll(series);
xAxis.setVisible(true);
yAxis.setVisible(true);
spLineChart.setVisible(true);
StackPane spButton = new StackPane();
StackPane sp = new StackPane();
VBox vbox = new VBox();
VBox.setVgrow(spLineChart, Priority.ALWAYS);
vbox.getChildren().addAll(sp, spLineChart, spButton);
Scene scene = new Scene(vbox, width, height - 500);
stage.setScene(scene);
stage.show();
}
class Node extends StackPane {
Node(int priorValue) {
final Circle circle = createData();
setOnMouseClicked(new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent mouseEvent) {
if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
getChildren().setAll(circle);
myListx.add(priorValue);
} else if (mouseEvent.getButton().equals(MouseButton.SECONDARY)) {
getChildren().clear();
myListx.remove(new Integer(priorValue));
}
}
;
});
}
private Circle createData() {
Circle circle = new Circle();
circle.setFill(Color.BLACK);
circle.setStroke(Color.BLACK);
circle.setRadius(4);
return circle;
}
}
public static void main(String[] args) {
launch(args);
}
}
Use this modified Node class. Where on-mouse click event, it toggles the effect as per the existence of its children.
class Node extends StackPane {
Node(int priorValue) {
setOnMouseClicked(event -> {
if (getChildren().isEmpty()) {
final Circle circle = createData();
getChildren().setAll(circle);
} else {
getChildren().clear();
}
myListx.add(priorValue);
});
}
private Circle createData() {
Circle circle = new Circle();
circle.setFill(Color.BLACK);
circle.setStroke(Color.BLACK);
circle.setRadius(4);
return circle;
}
}
Note: You may consider renaming your class Node as it clashes with Node.
I'm trying to create a program, which should draw a rectangle on a canvas based on two left mouse clicks and clears the canvas with one right click.
The rectangle should be created in a way, where the first mouse click simulates one corner of the rectangle, and the next mouse click simulates the diagonal corner of the rectangle compared to the first mouse click.
I'm stuck on how to store the coordinates for the first mouse click, and then put the second mouse click to good use, as the rectangle per definition is created based on only 1 set of coordinates, which is the upper-left corner of the rectangle.
Right now, all my code does is that it draws fixed sized rectangles (50x25) which obviously isn't what I want. This is just to see if the clearing part works.
This is what I've got so far:
package application;
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class DrawRectangle extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Title");
Canvas canv = new Canvas(500, 400);
GraphicsContext gc = canv.getGraphicsContext2D();
EventHandler<MouseEvent> event = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event) {
if (event.getButton() == MouseButton.PRIMARY) {
double x = event.getX();
double y = event.getY();
gc.setFill(Color.BLUE);
gc.fillRect(x, y, 50, 25);
}
}
};
canv.addEventHandler(MouseEvent.MOUSE_CLICKED, event);
EventHandler<MouseEvent> event2 = new EventHandler<MouseEvent>() {
#Override
public void handle(MouseEvent event2) {
if (event2.getButton() == MouseButton.SECONDARY) {
gc.clearRect(0, 0, 500, 400);
}
}
};
canv.addEventHandler(MouseEvent.MOUSE_CLICKED, event2);
StackPane root = new StackPane();
root.getChildren().add(canv);
primaryStage.setScene(new Scene(root, 500, 400));
primaryStage.show();
}
}
I don't know if it matters which corners of the rectangle the mouse clicks should simulate, maybe someone got any ideas?
Best regards and happy new year
Just save the first click point in a member variable, then use it and reset it when the user makes a second click point.
Note: the sample code below uses a switch expression from Java 13+. If switch expressions are not available in your Java version, convert it to a standard switch statement or if/else clauses.
import javafx.application.Application;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.canvas.*;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class DrawRectangle extends Application {
private static final int W = 500;
private static final int H = 400;
private Point2D savedPoint = null;
#Override
public void start(Stage stage) {
Canvas canvas = new Canvas(W, H);
GraphicsContext gc = canvas.getGraphicsContext2D();
canvas.setOnMouseClicked(event -> {
switch (event.getButton()) {
case PRIMARY -> handlePrimaryClick(gc, event);
case SECONDARY -> gc.clearRect(0, 0, W, H);
}
});
stage.setResizable(false);
stage.setScene(new Scene(new StackPane(canvas), W, H));
stage.show();
}
private void handlePrimaryClick(GraphicsContext gc, MouseEvent event) {
Point2D clickPoint = new Point2D(event.getX(), event.getY());
if (savedPoint == null) {
savedPoint = clickPoint;
} else {
Rectangle2D rectangle2D = getRect(savedPoint, clickPoint);
gc.setFill(Color.BLUE);
gc.fillRect(
rectangle2D.getMinX(),
rectangle2D.getMinY(),
rectangle2D.getWidth(),
rectangle2D.getHeight()
);
savedPoint = null;
}
}
private Rectangle2D getRect(Point2D p1, Point2D p2) {
return new Rectangle2D(
Math.min(p1.getX(), p2.getX()),
Math.min(p1.getY(), p2.getY()),
Math.abs(p1.getX() - p2.getX()),
Math.abs(p1.getY() - p2.getY())
);
}
public static void main(String[] args) {
launch(args);
}
}
I am working on a javafx program to create three buttons which are "circle", "ellipse" and "reverse". The circle button is the first thing shown when the program is run, the reverse button is supposed to correspond with the movement of the rectangle around the circle. I am having trouble getting the reverse button to work, I set autoReverse to true but it isn't doing anything. My second issue with the code is when the ellipse button is clicked the class MyEllipse isn't showing the ellipse shape like it is supposed to and it's not removing the circle animation from the pane. I tried to create a new pane in the EventHandler for the buttonellipse but I am assuming that isn't the correct way to do it. Any help on these two issues would be greatly appreciated.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.animation.PathTransition;
import javafx.scene.paint.Color;
import javafx.animation.Timeline;
import javafx.scene.shape.Circle;
import javafx.util.Duration;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Ellipse;
import javafx.scene.control.Button;
import javafx.event.ActionEvent;
import javafx.scene.layout.HBox;
import javafx.event.EventHandler;
import javafx.stage.Stage;
public class exam3b extends Application {
#Override
public void start(Stage primaryStage) {
Rectangle rectangle = new Rectangle (0, 0, 25, 50);
rectangle.setFill(Color.ORANGE);
Circle circle = new Circle(115, 90, 45);
circle.setFill(Color.WHITE);
circle.setStroke(Color.BLACK);
PathTransition pt = new PathTransition();
pt.setDuration(Duration.millis(4000));
pt.setPath(circle);
pt.setNode(rectangle);
pt.setOrientation(
PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pt.setCycleCount(Timeline.INDEFINITE);
pt.setAutoReverse(false);
pt.play();
circle.setOnMousePressed(e -> pt.pause());
circle.setOnMouseReleased(e -> pt.play());
HBox panel = new HBox(10);
panel.setAlignment(Pos.BOTTOM_CENTER);
Button button = new Button("Circle");
Button buttonellipse = new Button("Ellipse");
Button reverse = new Button("Reverse");
panel.getChildren().addAll(button,buttonellipse,reverse);
button.setOnAction(new EventHandler<ActionEvent>()
{
#Override
public void handle(ActionEvent e)
{
reverse.setVisible(true);
}
});
reverse.setOnAction(new EventHandler<ActionEvent>() //supposed to make rectangle move in reverse direction
{
#Override
public void handle(ActionEvent e)
{
pt.setAutoReverse(true);
}
});
buttonellipse.setOnAction(new EventHandler<ActionEvent>() //button to make ellipse appear from class MyEllipse, reverse button is supposed to disappear
{
#Override
public void handle(ActionEvent e)
{
reverse.setVisible(false);
Pane ellipse = new Pane();
ellipse.getChildren().add(new MyEllipse());
}
});
Pane pane = new Pane();
pane.getChildren().addAll(panel,circle,rectangle);
Scene scene = new Scene(pane, 350, 250);
primaryStage.setTitle("exam3b");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class MyEllipse extends Pane
{
private void paint() {
getChildren().clear();
for (int i = 0; i < 16; i++) {
Ellipse e1 = new Ellipse(getWidth() / 2, getHeight() / 2,
getWidth() / 2 - 50, getHeight() / 2 - 50);
e1.setStroke(Color.color(Math.random(), Math.random(),
Math.random()));
e1.setFill(Color.WHITE);
e1.setRotate(i * 180 / 16);
getChildren().add(e1);
}
}
#Override
public void setWidth(double width) {
super.setWidth(width);
paint();
}
#Override
public void setHeight(double height) {
super.setHeight(height);
paint();
}
}
You had an issue with how you were using MyEllipse, in that you were never adding it to your root pane nor were you settign the width/height (which leads to your paint method being called). I renamed your root pane to 'root'. Created an instance of 'MyEllipse', and in the 'Ellipse' button i add the instance of 'MyEllipse' to the root pane.
import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.animation.PathTransition;
import javafx.scene.paint.Color;
import javafx.animation.Timeline;
import javafx.scene.shape.Circle;
import javafx.util.Duration;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Ellipse;
import javafx.scene.control.Button;
import javafx.event.ActionEvent;
import javafx.scene.layout.HBox;
import javafx.event.EventHandler;
import javafx.stage.Stage;
public class exam3b extends Application {
#Override
public void start(Stage primaryStage) {
Rectangle rectangle = new Rectangle(0, 0, 25, 50);
rectangle.setFill(Color.ORANGE);
Circle circle = new Circle(115, 90, 45);
circle.setFill(Color.WHITE);
circle.setStroke(Color.BLACK);
PathTransition pt = new PathTransition();
pt.setDuration(Duration.millis(4000));
pt.setPath(circle);
pt.setNode(rectangle);
pt.setOrientation(
PathTransition.OrientationType.ORTHOGONAL_TO_TANGENT);
pt.setCycleCount(Timeline.INDEFINITE);
pt.setAutoReverse(true);
pt.play();
circle.setOnMousePressed(e -> pt.pause());
circle.setOnMouseReleased(e -> pt.play());
HBox panel = new HBox(10);
panel.setAlignment(Pos.BOTTOM_CENTER);
Button button = new Button("Circle");
Button buttonellipse = new Button("Ellipse");
Button reverse = new Button("Reverse");
panel.getChildren().addAll(button, buttonellipse, reverse);
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent e) {
reverse.setVisible(true);
}
});
reverse.setOnAction(new EventHandler<ActionEvent>() //supposed to make rectangle move in reverse direction
{
#Override
public void handle(ActionEvent e) {
pt.setAutoReverse(true);
}
});
Pane root = new Pane();
MyEllipse myEllipse = new MyEllipse();
myEllipse.setWidth(200);
myEllipse.setHeight(400);
buttonellipse.setOnAction(new EventHandler<ActionEvent>() //button to make ellipse appear from class MyEllipse, reverse button is supposed to disappear
{
#Override
public void handle(ActionEvent e) {
// reverse.setVisible(false);
if (root.getChildren().contains(myEllipse)) {
root.getChildren().remove(myEllipse);
} else {
System.out.println("adding ellipse");
root.getChildren().add(myEllipse);
}
}
});
root.getChildren().addAll(panel, circle, rectangle);
Scene scene = new Scene(root, 350, 250);
primaryStage.setTitle("exam3b");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class MyEllipse extends Pane {
public MyEllipse() {
}
private void paint() {
getChildren().clear();
for (int i = 0; i < 16; i++) {
Ellipse e1 = new Ellipse(getWidth() / 2, getHeight() / 2,
getWidth() / 2 - 50, getHeight() / 2 - 50);
e1.setStroke(Color.color(Math.random(), Math.random(),
Math.random()));
e1.setFill(Color.WHITE);
e1.setStrokeWidth(1);
e1.setRotate(i * 180 / 16);
getChildren().add(e1);
}
}
#Override
public void setWidth(double width) {
super.setWidth(width);
paint();
}
#Override
public void setHeight(double height) {
super.setHeight(height);
paint();
}
}