Javafx - Text Animation not smooth on Embedded Device - java

We are currently working on a JavaFX Project for which we need to implement Text animation like movement from Left to Right with variant speeds. Execution environment for the application is an Embedded device - Stick PC.
We have used Translate Transition API https://docs.oracle.com/javase/8/javafx/api/javafx/animation/TranslateTransition.html for achieving animation effect but we are facing smoothness issues in it. Text is moving with jerks and movement speed is slow compared to animation in Laptop/Desktop
package application;
import javafx.animation.Interpolator;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.CacheHint;
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.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;
import javafx.stage.Stage;
public class SampleAnimationTest extends Application {
// private final Logger logger = Logger.getLogger("genLog");
#Override
public void start(Stage primaryStage) throws Exception {
StackPane group = new StackPane();
Rectangle rectangle = new Rectangle();
rectangle.setHeight(1080);
rectangle.setWidth(1920);
rectangle.setFill(Color.WHITE);
rectangle.setTranslateX(0);
rectangle.setTranslateY(0);
rectangle.setCache(true);
rectangle.setCacheHint(CacheHint.SPEED);
Text text = new Text("THIS IS A LONG TEXT FOR TESTING TEXT ANIMATION IN JAVAFX");
text.setFill(Color.BLACK);
text.setUnderline(false);
text.setFont(Font.font("Meiryo", 509.3899));
text.setTextAlignment(TextAlignment.CENTER);
text.setCache(true);
text.setCacheHint(CacheHint.SPEED);
TranslateTransition tt = new TranslateTransition();
tt.setNode(text);
Rectangle rClip = new Rectangle();
rClip.setWidth(rectangle.getWidth());
rClip.setHeight(rectangle.getHeight());
rClip.translateXProperty().bind(rectangle.translateXProperty());
group.getChildren().add(rectangle);
group.getChildren().add(text);
group.setClip(rClip);
Group group2 = new Group();
group2.getChildren().add(group);
Scene scene = new Scene(group2, 1920, 1080);
primaryStage.setMaximized(true);
primaryStage.setTitle("Decorations Example");
primaryStage.setScene(scene);
primaryStage.show();
tt.fromXProperty().bind(rectangle.translateXProperty().add(rectangle.getLayoutBounds().getWidth()));
tt.toXProperty().bind(rectangle.translateXProperty().subtract(text.getLayoutBounds().getWidth()));
tt.setRate(0.077364);
tt.setInterpolator(Interpolator.LINEAR);
tt.setCycleCount(Timeline.INDEFINITE);
tt.playFromStart();
}
public static void main(String[] args) {
launch(args);
}
}

Related

Why cant i add images to my JavaFX Project? [duplicate]

This question already has an answer here:
How do I determine the correct path for FXML files, CSS files, Images, and other resources needed by my JavaFX Application?
(1 answer)
Closed 11 months ago.
I get the same error again and again when i try to add images to my JavaFX.
Error: at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
(more lines follow).
It must be related to the path to the images that I specified. I have already read through the general "path" tutorial on StackOverflow without success.
I just want to make a simple scrollBar which enables scrolling through some Images i added to a VBox.
Heres my directory:
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.geometry.Orientation;
import javafx.geometry.Pos;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.Shadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.stage.Stage;
public class Scrollbar3 extends Application {
// Variablen
final ScrollBar scrollbar = new ScrollBar();
final String[] images = {
"Bilder/bild0.jpg", // 0
"Bilder/bild1.jpg",
"Bilder/bild2.jpg",
"Bilder/bild3.jpg",
"Bilder/bild4.jpg",
};
DropShadow shadow = new DropShadow();
final VBox vbox = new VBox();
#Override
public void start(Stage primaryStage) throws Exception {
// Scene / root
Group root = new Group();
Scene scene = new Scene(root, 400, 400);
root.getChildren().addAll(vbox, scrollbar);
// Effekt
shadow.setColor(Color.BLACK);
shadow.setOffsetX(10);
shadow.setOffsetY(10);
// VBox
vbox.setLayoutX(5);
vbox.setSpacing(10);
vbox.setPadding(new Insets(20));
// Scrollbar
scrollbar.setLayoutX(scene.getWidth() - scrollbar.getWidth());
scrollbar.setOrientation(Orientation.VERTICAL);
scrollbar.setPrefHeight(400);
scrollbar.setMax(2000);
// Bilder
for(int i = 0; i < images.length; i++) {
final ImageView imageView = new ImageView(new Image(images[i]));
imageView.setEffect(shadow);
vbox.getChildren().add(imageView);
}
// Eventhanlding / Listener
scrollbar.valueProperty().addListener(new ChangeListener<Number>() {
#Override
public void changed(ObservableValue<? extends Number> observableValue, Number oldValue, Number newValue) {
vbox.setLayoutY(-newValue.doubleValue());
}
});
// Stage
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
It looks like you are treating your images as resource images because they are contained in the source folder.
Change the line with the image creation to
final ImageView imageView = new ImageView(new Image(this.getClass().getResourceAsStream(images[i])));
and add an "/" in front of your image paths.

How to use both JavaFX Scene Builder while still have the choice to design root with code?

I wanted to give SceneBuilder a try because its pain to center objects manually (in code). Unfortunately root is taken from me when I use FXML, so I can't set group as root. What I want to do is to operate on canvas (that is added to root group) while still having SceneBuilder FXML file working.
For example when Ive set root sceneBuilder FXML file then i couldnt add sprites to it in code. Vice versa when I have set root as group then the application wasnt making use of FXML file.
How to connect these? Below is code with use of group as root. I have added sprite, which is not visible in SceneBuilder. Also the button made in SceneBuilder is not visible after compiling the application.
Code:
package zegelardo;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.application.Application;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.Group;
import javafx.scene.canvas.Canvas;
import javafx.scene.canvas.GraphicsContext;
import javafx.scene.image.Image;
import javafx.scene.paint.Color;
import javafx.scene.text.Font;
import javafx.scene.text.FontWeight;
import javafx.animation.AnimationTimer;
import javafx.event.EventHandler;
import javafx.scene.input.KeyEvent;
import javafx.scene.control.Button;
import java.util.ArrayList;
import java.util.Iterator;
public class Zegelardo extends Application {
#Override
public void start(Stage stage) throws Exception {
Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
Group rootx = new Group();
Scene scene = new Scene(rootx);
scene.setFill(Color.BLACK);
stage.setScene(scene);
stage.setTitle("Zegelardo");
Sprite tlo = new Sprite();
tlo.setImage("test55.gif");
tlo.setPosition(0, 0);
Canvas canvas = new Canvas( 800, 400 );
rootx.getChildren().add(canvas);
GraphicsContext gc = canvas.getGraphicsContext2D();
// gc.clearRect(0, 0, 1000,800);
// briefcase.render( gc );
tlo.render(gc);
// Group leaf = new Group();
// root.getChildren().add(canvas);
// Canvas canvas = new Canvas( 800, 400 );
//leaf.getChildren().add( canvas );
stage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}

How to make a Button on a JavaFX's browser?

I'm trying to make a "launcher" with javafx.
This is my code :
I'm not shure you have to read all of this code, this code is here.
I'm trying to put a javaFX "play" button (i know how to make a button and how to set up an onclick event but i don't know where to add it :/)
Have you got an idea ? Thx.
package fr.whiteplay.main.launcher;
public class Launcher{
private static WebViewSample launcher;
private static String[] a;
public static void main(String[] args){
launcher = new WebViewSample();
a = args;
}
public static void start(){
launcher.go(a);
}
}
package fr.whiteplay.main.launcher;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
public class WebViewSample extends Application{
private Browser browser;
private Scene scene;
public void start(Stage stage){
// create the scene
stage.setTitle("WhitePlay");
browser = new Browser();
scene = new Scene(browser, 992, 620, Color.web("#000000"));
stage.setScene(scene);
stage.show();
}
public static void go(String[] args){
launch(args);
}
}
package fr.whiteplay.main.launcher;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
class Browser extends Region{
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
public Browser(){
getStyleClass().add("browser");
webEngine.load("http://www.whiteplay.fr/launcher/index.html");
getChildren().add(browser);
}
private Node createSpacer(){
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
return spacer;
}
protected void layoutChildren(){
layoutInArea(browser, 0, 0, getWidth(), getHeight(), 0, HPos.CENTER, VPos.CENTER);
}
}
Instead of the browser itself, the scene root must be a structured panel, which contains the browser, the button, and whatever else.
The simplest example is to replace your WebViewSample.start() method with the following:
public void start(Stage stage){
// create the scene
stage.setTitle("WhitePlay");
browser = new Browser();
BorderPane root = new BorderPane();
root.setCenter(browser);
Button button = new Button("Play");
root.setBottom(button);
button.setOnAction(a -> System.out.println("Play"));
scene = new Scene(root, 992, 620, Color.web("#000000"));
stage.setScene(scene);
stage.show();
}
Check this page for further reference on various layouts options, and how to work with them.

Set up Canvas layouts

How I will get white rectangle in the middle of scene. I wanna preserve my own code and the height and width of it. Probably it should be use to set X and Y layouts. but I do not know how. When I set them, it resize it from upper left corner.
Code:
Pane paneCanvas = new Pane();
final Canvas canvas = new Canvas();
paneCanvas.setStyle("-fx-background-color: white;");
canvas.setHeight(32);
canvas.setWidth(32);
paneCanvas.getChildren().add(canvas);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
Try this example ... for position in middle of scene you can calculate width this formula:
layoutxcanvas=(widthscene/2)-(widthcanvas/2)
layoutycanvas=(heightscene/2)-(heightcanvas/2)
import java.awt.Graphics2D;
import java.awt.Paint;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
public class JavaFXApplication1 extends Application {
#Override
public void start(Stage primaryStage) {
Pane paneCanvas = new Pane();
final Canvas canvas = new Canvas();
paneCanvas.setStyle("-fx-background-color: black;");
canvas.setHeight(32);
canvas.setWidth(32);
canvas.getGraphicsContext2D().setFill(Color.WHITE);
canvas.getGraphicsContext2D().fillRect(0, 0, 32, 32);
canvas.setLayoutX((300/2)-(32/2));
canvas.setLayoutY((300/2)-(32/2));
paneCanvas.getChildren().add(canvas);
Scene scene=new Scene(paneCanvas,300,300);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}

Updating the location of a sprite on StackPane JavaFX

I have a question regarding JavaFX. I taught myself Java and now I'm learning JavaFX.
I've been trying to update the location of a 50x50 black block on the screen. I have a YAxis variable that when I change changes the location of the block.
I want the block to "flow" down the screen similar to Tetris.
My code is messy, as I'm just messing around with it, so please excuse that:
package gamefx;
import javafx.animation.Animation;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
public class GameFX extends Application {
public Image img = new Image("Block1.png");
public ImageView image = new ImageView(img);
public int YAxis = -200;
#Override
public void start(Stage primaryStage) throws InterruptedException{
primaryStage.setTitle("Game");
StackPane stckp1 = new StackPane();
Scene scn = new Scene(stckp1, 700, 700);
primaryStage.setScene(scn);
primaryStage.show();
image.setTranslateY(YAxis);
stckp1.getChildren().add(image);
}
}
Since you want to see your block moving, you need an animation. See Oracle tutorial for more information.
A sample code, quickly written:
TranslateTransition tt = new TranslateTransition(Duration.millis(2000), image);
tt.setByY(yAxis);
tt.setCycleCount(1);
tt.play();
Side-note: Variable names shall not start with an upper-case letter. Use yAxis instead of YAxis.

Categories

Resources