So I have a displayed Line, which I now want to move to a new locations by animation. TranslateTransition only uses one pair of X and Y coordinates, whereas a Line has two sets of coordinates, one for the start and one for the end of the Line. Is there anyway to specify a TranslateTransition for a Line?
I know about binding a Line (which I can't easily figure out how to apply in my case), but is there a general TranslateTransition solution I can apply to a Line (I know the new start and end coordinates where I want the Line to move to .. so this might be the easiest way, if there is a way ...)
This example shows how to use TranslateTransition using a Line.
import javafx.animation.ParallelTransition;
import javafx.animation.Timeline;
import javafx.animation.TranslateTransition;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import javafx.util.Duration;
/**
*
* #author blj0011
*/
public class JavaFXTestingGround extends Application{
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
Line line = new Line(10, 10, 10, 40);
TranslateTransition translateTransition = new TranslateTransition(Duration.seconds(6),line);
translateTransition.setFromX(10);
translateTransition.setToX(380);
translateTransition.setCycleCount(Timeline.INDEFINITE);
translateTransition.setAutoReverse(true);
Line line1 = new Line(10, 60, 10, 90);
Line line2 = new Line(10, 60, 40, 60);
Line line3 = new Line(40, 60, 40, 90);
Line line4 = new Line(10, 90, 40, 90);
Group group = new Group(line1, line2, line3, line4);
TranslateTransition translateTransition2 = new TranslateTransition(Duration.seconds(6),group);
translateTransition2.setFromX(10);
translateTransition2.setToX(380);
translateTransition2.setCycleCount(Timeline.INDEFINITE);
translateTransition2.setAutoReverse(true);
ParallelTransition parallelTransition = new ParallelTransition(translateTransition, translateTransition2);
parallelTransition.play();
Pane root = new Pane(line, group);
root.setPrefSize(500, 500);
// Show the stage
primaryStage.setScene(new Scene(root));
primaryStage.setTitle("TableColumnGrow Sample");
primaryStage.show();
}
}
Updated Code: I added a Group to the example.
Related
When I run the program, the text appears in the center of the image. I want to move it to the bottom right corner, but nothing happens when I try to change the position. I'm not sure how to set the position of the text.
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.scene.text.Text;
import javafx.scene.text.Font;
public class Art extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage primaryStage) {
//this will create a canvas with a width of 400px and height of 200px
StackPane pane = new StackPane();
Scene scene = new Scene(pane, 400, 250);
primaryStage.setScene(scene);
primaryStage.show();
//draw three ellipses with different colors
Ellipse e1 = new Ellipse(150, 0, 100, 25);
e1.setFill(Color.PINK);
Ellipse e2 = new Ellipse(75, 25, 75, 25);
e2.setFill(Color.DARKGRAY);
Ellipse e3 = new Ellipse(0, 50, 40, 25);
e3.setFill(Color.GRAY);
/*this will set the color, font and size of the text and place it at the
lower right corner*/
Text t1 = new Text(150, 300, "text");
t1.setFont(Font.font("Century Gothic", 14));
t1.setStroke(Color.BLACK);
//display the stage
pane.getChildren().addAll(e1, e2, e3, t1);
primaryStage.setScene(scene);
primaryStage.show();
}
}
As #Slaw suggested in his comment to your question, the below code uses several different layouts to achieve what you want. I suggest you refer to the javadoc for details on how they work.
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.NodeOrientation;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Ellipse;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class Art extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
StackPane pane = new StackPane();
// draw three ellipses with different colors
Ellipse e1 = new Ellipse(150, 0, 100, 25);
e1.setFill(Color.PINK);
Ellipse e2 = new Ellipse(75, 25, 75, 25);
e2.setFill(Color.DARKGRAY);
Ellipse e3 = new Ellipse(0, 50, 40, 25);
e3.setFill(Color.GRAY);
/*
* this will set the color, font and size of the text and place it at the lower
* right corner
*/
Text t1 = new Text(150, 300, "text");
t1.setFont(Font.font("Century Gothic", 14));
t1.setStroke(Color.BLACK);
FlowPane flow = new FlowPane(t1);
flow.setNodeOrientation(NodeOrientation.RIGHT_TO_LEFT);
flow.setPadding(new Insets(0.0d, 0.0d, 20.0d, 20.0d));
// display the stage
pane.getChildren().addAll(e1, e2, e3);
BorderPane root = new BorderPane(pane);
root.setBottom(flow);
Scene scene = new Scene(root, 400, 250);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I want to draw a line passing through a circle. However, I do not want the line to be shown while its inside the circle. How can I accomplish this? Note that I'm drawing the circle first and then the line.
I used a couple of things like:
Circle.setOpacity to 1, which didn't help!
Used line.toBack() after adding the circle and line in the same group. This didnt help either
line.toBack()
line.toFront()
import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.*;
import javafx.stage.Stage;
public class LineUnderCircle extends Application {
#Override
public void start(Stage stage) throws Exception {
Line line = new Line(10, 10, 50, 50);
line.setStrokeWidth(3);
Circle left = new Circle(10, 10, 8, Color.FORESTGREEN);
Circle right = new Circle(50, 50, 8, Color.FIREBRICK);
Button lineToBack = new Button("Line to back");
lineToBack.setOnAction(e -> line.toBack());
Button lineToFront = new Button("Line to front");
lineToFront.setOnAction(e -> line.toFront());
Pane shapePane = new Pane(line, left, right);
HBox controlPane = new HBox(10, lineToBack, lineToFront);
VBox layout = new VBox( 10, controlPane, shapePane);
layout.setPadding(new Insets(10));
stage.setScene(new Scene(layout));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
I want to change the size of a line using a button so later I can make the line look like it is rotating... Here is the code I have so far:
package JavaFXApplication14;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.GridPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class JavaFXApplication14 extends Application
{
public static void main(String[] args)
{
launch(args);
}
int x = 200;
#Override public void start(Stage primaryStage) throws Exception
{
final GridPane grid = new GridPane();
grid.setAlignment(Pos.CENTER);
grid.setHgap(100);
grid.setVgap(100);
grid.setPadding(new Insets(10, 10, 10, 10));
Scene scene = new Scene(grid, 600, 400); //Color.BLACK ?
primaryStage.setScene(scene);
primaryStage.setTitle("4D");
primaryStage.show();
Line ln = new Line(100, 200, x, 200);
ln.setStroke(Color.BLUE);
ln.setStrokeWidth(5);
grid.add(ln, 0, 0);
Button btn = new Button("X-Y");
grid.setHalignment(btn, HPos.CENTER);
btn.setOnAction(e -> btn_Click());
grid.add(btn, 0, 1);
}
public void btn_Click()
{
x = x + 50;
}
}
Also, sometimes when I use the following line of code the color of the background does not change.
Scene scene = new Scene(grid, 600, 400, Color.BLACK);
What is the reason for that?
The button works very well you can test it, but here you only set a new value to x and nothing else, in other words you don't update the position x2 of your Line.You can dot that by making your variable ln accessible and updating its value EndX:
//before the method start
Line ln;
//Inside your btn_click() method add
ln.setEndX(x);
But it will only increase the size of your line (Horizontally) and not rotate it. with a little research explained here and following what I told you in the comment you can do this easily based on the axis of rotation (startX & startY) and the points to be rotated (endX & endY):
public class Launcher extends Application{
private Pane root = new Pane();
private Scene scene;
private Button btn = new Button("Test");
private Line line;
#Override
public void start(Stage stage) throws Exception {
line = new Line(200,200,200,100);
line.setStroke(Color.BLACK);
line.setStrokeWidth(5);
btn.setOnAction(e -> rotate());
root.getChildren().addAll(btn,line);
scene = new Scene(root,500,500);
stage.setScene(scene);
stage.show();
}
private void rotate(){
double x1 = line.getEndX() - line.getStartX();
double y1 = line.getEndY() - line.getStartY();
//The more you reduce the angle the longer the rotation
double x2 = x1 * Math.cos(0.1) - y1 * Math.sin(0.1);
double y2 = x1 * Math.sin(0.1) + y1 * Math.cos(0.1);
line.setEndX(x2+ line.getStartX());
line.setEndY(y2+ line.getStartY());
}
public static void main(String[] args) {
launch(args);
}
}
Note: In your example you use a GridPane, so you will be restricted to its functioning, Good luck !
i have a problem with the scaling ability for my shapes. I want to use a coordinate system so drawn by my own which holds some shapes. These shapes needs a scaling function. After scaling the shapes they would move because the scaling takes place at the center of each shape. To react on this movement i recalculate the origin. But if i scale many times the shape still move away from origin. i dont know why. Can anyone explain this behavior?
Further i try to recalculate the stroke width to stay 1px.
Thank you!
My code:
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polyline;
import javafx.stage.Stage;
public class ScaleTest extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Pane root = new Pane();
Scene scene = new Scene(root, 800, 600, Color.WHITE);
stage.setScene(scene);
Polyline line1 = new Polyline(new double[] { 50, 50, 50, 150, 150, 150,
150, 50, 50, 50 });
line1.setStrokeWidth(1);
Group polylines = new Group();
polylines.getChildren().add(line1);
Line xAxis = new Line(0, 50, 800, 50);
Line yAxis = new Line(50, 0, 50, 800);
root.setScaleY(-1);
root.getChildren().addAll(xAxis, yAxis);
root.getChildren().add(polylines);
scene.setOnScroll(new EventHandler<ScrollEvent>() {
#Override
public void handle(ScrollEvent event) {
double scale = 0;
if (event.getDeltaY() < 0) {
scale = -0.1;
} else {
scale = 0.1;
}
Bounds beforeScaling = polylines.getBoundsInParent();
polylines.setScaleX(polylines.getScaleX() + scale);
polylines.setScaleY(polylines.getScaleY() + scale);
Bounds afterScaling = polylines.getBoundsInParent();
polylines.setTranslateX(polylines.getTranslateX()
+ beforeScaling.getMinX() - afterScaling.getMinX());
polylines.setTranslateY(polylines.getTranslateY()
+ beforeScaling.getMinY() - afterScaling.getMinY());
//optional
line1.setStrokeWidth(1/polylines.getScaleX());
}
});
stage.show();
}
}
I'm not sure why it is "drifting" - possibly it is just accumulating rounding errors. An easier approach anyway is to use a Scale transformation. With this you can specify the "pivot" point about which the scale occurs.
import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.input.ScrollEvent;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.Polyline;
import javafx.scene.transform.Scale;
import javafx.stage.Stage;
public class ScaleTest extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
Pane root = new Pane();
Scene scene = new Scene(root, 800, 600, Color.WHITE);
stage.setScene(scene);
Polyline line1 = new Polyline(new double[] { 50, 50, 50, 150, 150, 150,
150, 50, 50, 50 });
line1.setStrokeWidth(1);
Group polylines = new Group();
polylines.getChildren().add(line1);
Line xAxis = new Line(0, 50, 800, 50);
Line yAxis = new Line(50, 0, 50, 800);
root.setScaleY(-1);
root.getChildren().addAll(xAxis, yAxis);
root.getChildren().add(polylines);
Scale scale = new Scale();
scale.setPivotX(50);
scale.setPivotY(50);
polylines.getTransforms().add(scale);
scene.setOnScroll(new EventHandler<ScrollEvent>() {
#Override
public void handle(ScrollEvent event) {
double scaleDelta = 0;
if (event.getDeltaY() < 0) {
scaleDelta = -0.1;
} else {
scaleDelta = 0.1;
}
scale.setX(scale.getX() + scaleDelta);
scale.setY(scale.getY() + scaleDelta);
//optional
line1.setStrokeWidth(1/scale.getX());
}
});
stage.show();
}
}
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class LinesTest extends Application {
#Override
public void start(Stage stage) throws Exception {
final AnchorPane root = new AnchorPane();
final Line line1 = new Line(20, 10, 300, 10);
final Line line2 = new Line(250, 10, 400, 10);
root.getChildren().addAll(line1, line2);
stage.setTitle("Lines Test");
stage.setScene(new Scene(root, 500, 500));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
If you run the code above you could mention that two lines overlapping create another color. Is it possible to prevent this behavior?
You can prevent it in 2 ways:
1) Use setSnapToPixel
final AnchorPane root = new AnchorPane();
root.setSnapToPixel(true);
2) Or, define lines' startY and endY values as half:
final Line line1 = new Line(20, 10.5, 300, 10.5);
final Line line2 = new Line(250, 10.5, 400, 10.5);
For the technical details of these I will leave to jewelsea's great answers:
What are a line's exact dimensions in JavaFX 2?
How to draw a crisp, opaque hairline in JavaFX 2.2?