multiple windows not showing up upon execution ( 1 out of 3) - javafx

quick question,
why are my multiple windows not appearing from this code?
also any tips on how to make the circle's diameter increase only by the stage's resolution when the window is increased in size; anyway of doing this internally through "circ3."
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class Circles extends Application {
#Override
public void start(Stage primaryStage){
Pane pane = new Pane();
Circle circ = new Circle();
circ.setStroke(Color.DARKBLUE);
circ.setFill(Color.YELLOW);
circ.centerXProperty().bind(pane.widthProperty().divide(10));
circ.centerYProperty().bind(pane.heightProperty().subtract(20));
circ.centerXProperty().bind(pane.widthProperty().subtract(20));
circ.setRadius(20);
pane.getChildren().add(circ);
Scene scene = new Scene(pane, 500, 200);
primaryStage.setTitle("Bottom Right");
primaryStage.setScene(scene);
primaryStage.show();
Pane pane2 = new Pane();
Circle circ2 = new Circle();
circ2.setStroke(Color.PEACHPUFF);
circ2.setFill(Color.YELLOWGREEN);
circ2.centerXProperty().bind(pane2.widthProperty().divide(2));
circ2.centerYProperty().bind(pane2.heightProperty().subtract(20));
circ2.setRadius(20);
pane2.getChildren().add(circ2);
Scene scene2 = new Scene(pane2, 200, 500);
primaryStage.setTitle("Bottom Centered");
primaryStage.setScene(scene2);
primaryStage.show();
Pane pane3 = new Pane();
Circle circ3 = new Circle();
circ3.setStroke(Color.PEACHPUFF);
circ3.setFill(Color.YELLOWGREEN);
circ3.centerXProperty().bind(pane3.widthProperty().subtract(150));
circ3.centerYProperty().bind(pane3.heightProperty().divide(2));
circ3.setRadius(150);
//size (circle diameter) needs to scale with width resolution
pane3.getChildren().add(circ3);
//boilerplate
Scene scene3 = new Scene(pane3, 300, 500);
primaryStage.setTitle("Radius / Width ");
primaryStage.setScene(scene3);
primaryStage.show();
}
public static void main(String[] args) {
Application.launch(args);
}
}

You can make the circle change size with the window size using bindings:
Pane pane3 = new Pane();
Circle circ3 = new Circle();
circ3.setStroke(Color.PEACHPUFF);
circ3.setFill(Color.YELLOWGREEN);
circ3.centerXProperty().bind(pane3.widthProperty().divide(2));
circ3.centerYProperty().bind(pane3.heightProperty().divide(2));
circ3.radiusProperty().bind(pane3.widthProperty().divide(2));

Related

JavaFX AnchorPane maxHeight ignored with clipped Circle

I have an AnchorPane which contains a clipped circle. I set a maximum height to the anchorpane, so that if the circle's y position is high, the circle won't be displayed. The problem is that when the circle goes to the lower part of the anchorpane, it increases it's height. This should not be happening.
This happens even before the clipped element reaches the lower part of the anchorpane. Once the "invisible" part of the circle reaches the lower part, it starts increasing it's height.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.RadialGradient;
import javafx.scene.paint.Stop;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
public class Init extends Application {
private AnchorPane canvasContainer;
private AnchorPane mainPane;
#Override
public void start(Stage stage) throws Exception {
canvasContainer = new AnchorPane();
mainPane = new AnchorPane();
Scene scene = new Scene(mainPane, 800, 700);
stage.setScene(scene);
canvasContainer.setPrefWidth(600.0d);
canvasContainer.setPrefHeight(500.0d);
//IGNORED
canvasContainer.setMaxHeight(canvasContainer.getPrefHeight());
canvasContainer.setLayoutX(14.0d);
canvasContainer.setLayoutY(14.0d);
canvasContainer.setStyle("-fx-border-color: black; -fx-border-width: 1 1 1 1;");
RadialGradient gradient = new RadialGradient(0, 0, 0.5, 0.5, 1, true, CycleMethod.NO_CYCLE, new Stop[] {
new Stop(0, Color.ORANGE),
new Stop(0.2, Color.YELLOW),
new Stop(0.5, Color.TRANSPARENT)
});
//I AM MODIFYING THIS VALUE
int y = 500;
Circle circleGradient = new Circle(200, y, 50);
circleGradient.setFill(gradient);
Rectangle rect = new Rectangle(200 - 50, y - 50, 1000, 50/2);
circleGradient.setClip(rect);
canvasContainer.getChildren().addAll(circleGradient);
mainPane.getChildren().add(canvasContainer);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I had the same issue when I was trying to make a circle grow so it would fill a rectangle which was a small area of my Scene. The filling animation worked great but the maxHeight and maxWidth of your canvasContainer are ignored. In my case that ended up with the area growing and destroying everything nearby.
Solution : add the circle to the mainPane and not canvasContainer

JavaFx canvas mouse events

I would like to intercept mouse events on canvas only where I've drawn some shape, but in all other transparent area I would like to have behaviour like with property mouseTransparent true.
I can achieve that with ImageView, transparent areas doesn't intercept mouse events.
public void start(Stage primaryStage) throws Exception {
primaryStage.setTitle("Drawing Operations Test");
Pane root = new Pane();
root.setStyle("-fx-background-color: #C9E3AF");
root.setMinSize(1000, 1000);
root.setOnMouseClicked(event -> {
System.out.println("Clicked on root pane");
});
Canvas canvas1 = new Canvas(512, 512);
canvas1.getGraphicsContext2D().setFill(Color.BLACK);
canvas1.getGraphicsContext2D().fillRect(250, 250, 250, 250);
canvas1.setOnMouseClicked(event -> {
System.out.println("Clicked on canvas1");
});
canvas1.setPickOnBounds(false);
Canvas canvas2 = new Canvas(512, 512);
canvas2.getGraphicsContext2D().setFill(Color.RED);
canvas2.getGraphicsContext2D().fillRect(200, 200, 250, 250);
canvas2.setOnMouseClicked(event -> {
System.out.println("Clicked on canvas2");
});
canvas2.setPickOnBounds(false);
SnapshotParameters param1 = new SnapshotParameters();
param1.setFill(Color.TRANSPARENT);
WritableImage image1 = canvas1.snapshot(param1, new WritableImage(512, 512));
SnapshotParameters param2 = new SnapshotParameters();
param2.setFill(Color.TRANSPARENT);
WritableImage image2 = canvas2.snapshot(param2, new WritableImage(512, 512));
ImageView view1 = new ImageView(image1);
view1.setOnMouseClicked(event -> {
System.out.println("Clicked on view1");
});
view1.setPickOnBounds(false);
ImageView view2 = new ImageView(image2);
view2.setOnMouseClicked(event -> {
System.out.println("Clicked on view2");
});
view2.setPickOnBounds(false);
// ImageView test
// root.getChildren().addAll(view1, view2);
// Canvas test
root.getChildren().addAll(canvas1, canvas2);
Scene sc = new Scene(root);
primaryStage.setScene(sc);
primaryStage.setX(0);
primaryStage.setY(0);
primaryStage.show();
}
Is it even possible with Canvas?
As far as I'm concerned it is impossible to achieve using Canvas, but using Group and Shapes within gives you all the features of Canvas plus behaviour you expect.
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.stage.Stage;
public class ShapesApp extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Circle circle = new Circle(100);
circle.setFill(Color.BLUE);
Group group = new Group(circle);
group.setOnMouseMoved(System.out::println);
StackPane stackPane = new StackPane(group);
stackPane.setPrefSize(400, 400);
stage.setScene(new Scene(stackPane));
stage.show();
}
}

Lengthen Javafx Sliders in GridPane

Whatever I try, the slider refuses to lengthen/stretch horizontally. My theory is that the GridPane cell sizes are overriding the slider's x coordinate. Any solutions?
here's my entire class:
public class MoodMeter extends GridPane {
public MoodMeter() {
GridPane grid = new GridPane();
grid.setAlignment(Pos.TOP_CENTER);
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(25, 25, 25, 25));
Slider slider = new Slider(-100, 100, 0);
slider.setOrientation(Orientation.HORIZONTAL);
slider.setMaxWidth(100);
slider.setBlockIncrement(100);
setHgrow(slider, Priority.ALWAYS);
grid.add(slider, 1, 0);
Scene scene = new Scene(grid, 700, 100);
Stage stage = new Stage();
stage.setTitle("Diary Mood Meter");
stage.setScene(scene);
stage.setResizable(false);
stage.show();
Rectangle2D desktop = Screen.getPrimary().getVisualBounds();
stage.setY(((desktop.getMaxY() + desktop.getMinY()) / 2) + 200);
}
}
And this is the result:
(not enough population)
http://i.imgur.com/cfvdKIM.png
Solved.
Changed
slider.setMaxWidth(100);
slider.setBlockIncrement(100);
to
slider.setMaxWidth(1000);
slider.setBlockIncrement(1000);
Without knowing the rest of your GridPane code setup, there are several ways to achieve that:
set slider.setMaxWidth(Double.MAX_VALUE)
add ColumnConstraints for horizontal resizing to the GridPane
set the Hgrow of your slider accordingly.
Just set the hgrow property for the slider to ALWAYS:
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Label;
import javafx.scene.control.Slider;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.Priority;
import javafx.stage.Stage;
public class SliderInGridPane extends Application {
#Override
public void start(Stage primaryStage) {
GridPane root = new GridPane();
root.add(new Label("Value:"), 0, 0);
Slider slider = new Slider(0, 100, 50);
GridPane.setHgrow(slider, Priority.ALWAYS);
root.add(slider, 1, 0);
primaryStage.setScene(new Scene(root, 250, 75));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Binding a Shape class to the StackPane height

Scenario : A Stage contains a Scene.The Scene contains a StackPane. The height and width of the StackPane and Scene are bind together. The StackPane contains a Shape which is a union of Rectangle and Shape.
Issue - I am facing issue while binding a Shape class to the height of StackPane. How to bind a particular part of Shape class or the complete Shape class in my example?
Requirement - I have 2 requirements.
When I maximize the stage, the StackPane gets increased since the
height and width are bind to Scene but the Shape doesnt increase. I
need both the Shape's(smallShape and bigRectangle) to increase
in terms of height only.
When I maximize the stage the StackPane should increase as well as only the bigger rectangle height should increase but not the other small rectangle i.e bigRectangle height should increase only.
Below is my code snippet
package application;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.RectangleBuilder;
import javafx.scene.shape.Shape;
import javafx.stage.Stage;
public class BindingShape extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
StackPane stackPane = new StackPane();
stackPane.setPrefHeight(200);
stackPane.setPrefWidth(200);
stackPane.setStyle("-fx-background-color: BEIGE");
Shape smallShape = RectangleBuilder.create()
.x(0)
.y(3)
.arcWidth(6)
.arcHeight(6)
.width(50) // allow overlap for union of tab and content rectangle
.height(50)
.build();
Rectangle bigRectangle = RectangleBuilder.create()
.x(25)
.y(0)
.arcWidth(10)
.arcHeight(10)
.width(100)
.height(100)
.build();
Shape unionShape = Shape.union(smallShape, bigRectangle);
unionShape.setFill(Color.rgb(0, 0, 0, .50));
unionShape.setStroke(Color.BLUE);
Group shapeGroup = new Group();
shapeGroup.getChildren().add(unionShape);
stackPane.getChildren().add(shapeGroup);
Group paneGroup = new Group();
paneGroup.getChildren().add(stackPane);
Scene scene = new Scene(paneGroup, 400, 400,Color.LIGHTSKYBLUE);
stackPane.prefHeightProperty().bind(scene.heightProperty().divide(2));
stackPane.prefWidthProperty().bind(scene.widthProperty().divide(2));
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Please let me know the solution. Thanks in advance.
As the union cannot be resized in parts, I would rebuild the union if the container has been resized like in:
public class BindStackPaneToScene extends Application {
Shape union;
Shape makeShape(double w, double h) {
Rectangle smallShape = new Rectangle(0, 3, 50, 50);
smallShape.setArcHeight(6);
smallShape.setArcWidth(6);
Rectangle bigRectangle = new Rectangle(25, 3, w/2, h/2);
bigRectangle.setArcHeight(10);
bigRectangle.setArcWidth(10);
Shape unionShape = Shape.union(smallShape, bigRectangle);
unionShape.setFill(Color.rgb(0, 0, 0, .50));
unionShape.setStroke(Color.BLUE);
return unionShape;
}
#Override
public void start(Stage primaryStage) throws Exception {
StackPane stackPane = new StackPane();
stackPane.setPrefHeight(200);
stackPane.setPrefWidth(200);
stackPane.setStyle("-fx-background-color: BEIGE");
union = makeShape(200,200);
Group shapeGroup = new Group();
shapeGroup.getChildren().add(union);
stackPane.getChildren().add(shapeGroup);
stackPane.heightProperty().addListener((p, o, n) -> {
if (union != null) shapeGroup.getChildren().remove(union);
union = makeShape(stackPane.getWidth(), n.doubleValue());
shapeGroup.getChildren().add(union);
});
Group paneGroup = new Group();
paneGroup.getChildren().add(stackPane);
Scene scene = new Scene(paneGroup, 400, 400,Color.LIGHTSKYBLUE);
stackPane.prefHeightProperty().bind(scene.heightProperty().divide(1));
stackPane.prefWidthProperty().bind(scene.widthProperty().divide(1));
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Fade Effect with JavaFX

Im trying to realize a special FadeTransition effect. But I have no idea how I can manage it. For some node I would like to increase the opacity from left to right (for example in Powerpoint, you can change the slides with such an effect). Here is an easy example for rectangles. But the second one should fadeIn from left to right (the opacity should increase on the left side earlier as on the right side). With timeline and KeyValues/KeyFrames I found also no solution.
Thanks in advance.
Rectangle rec2;
#Override
public void start(Stage stage) {
Group root = new Group();
Scene scene = new Scene(root, 400, 300, Color.BLACK);
stage.setTitle("JavaFX Scene Graph Demo");
Pane pane = new Pane();
Button btnForward = new Button();
btnForward.setText(">");
btnForward.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
FadeTransition ft = new FadeTransition(Duration.millis(2000), rec2);
ft.setFromValue(0.);
ft.setToValue(1.);
ft.play();
}
});
Rectangle rec1 = new Rectangle(0, 0, 300,200);
rec1.setFill(Color.RED);
rec2 = new Rectangle(100, 50, 100,100);
rec2.setFill(Color.GREEN);
rec2.setOpacity(0.);
pane.getChildren().addAll(rec1,rec2);
root.getChildren().add(pane);
root.getChildren().add(btnForward);
stage.setScene(scene);
stage.show();
}
Define the fill of the rectangle using css with a linear gradient which references looked-up colors for the left and right edges of the rectangle. (This can be inline or in an external style sheet.)
Define a couple of DoublePropertys representing the opacities of the left and right edge.
Define the looked-up colors on the rectangle or one of its parents using an inline style bound to the two double properties.
Use a timeline to change the values of the opacity properties.
import javafx.animation.KeyFrame;
import javafx.animation.KeyValue;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.beans.binding.Bindings;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import javafx.util.Duration;
public class FadeInRectangle extends Application {
#Override
public void start(Stage primaryStage) {
Group root = new Group();
Scene scene = new Scene(root, 400, 300, Color.BLACK);
primaryStage.setTitle("JavaFX Scene Graph Demo");
Pane pane = new Pane();
Rectangle rec1 = new Rectangle(0, 0, 300,200);
rec1.setFill(Color.RED);
Rectangle rec2 = new Rectangle(100, 50, 100,100);
rec2.setStyle("-fx-fill: linear-gradient(to right, left-col, right-col);");
final DoubleProperty leftEdgeOpacity = new SimpleDoubleProperty(0);
final DoubleProperty rightEdgeOpacity = new SimpleDoubleProperty(0);
root.styleProperty().bind(
Bindings.format("left-col: rgba(0,128,0,%f); right-col: rgba(0,128,0,%f);", leftEdgeOpacity, rightEdgeOpacity)
);
Button btnForward = new Button();
btnForward.setText(">");
btnForward.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(leftEdgeOpacity, 0)),
new KeyFrame(Duration.ZERO, new KeyValue(rightEdgeOpacity, 0)),
new KeyFrame(Duration.millis(500), new KeyValue(rightEdgeOpacity, 0)),
new KeyFrame(Duration.millis(1500), new KeyValue(leftEdgeOpacity, 1)),
new KeyFrame(Duration.millis(2000), new KeyValue(rightEdgeOpacity, 1)),
new KeyFrame(Duration.millis(2000), new KeyValue(leftEdgeOpacity, 1))
);
timeline.play();
}
});
pane.getChildren().addAll(rec1,rec2);
root.getChildren().add(pane);
root.getChildren().add(btnForward);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}

Resources