Change rotation base of a javafx line - javafx

Is there a way to rotate a line but instead of rotating from its center it rotates from its left end. I'm creating a clock but with rotatetransition the lines rotate from their center.
Codigo de rotacion:
Line contFH = new Line();
contFH.setPrefSize(150, 20);
contFH.setRotate(90);
RotateTransition r1 = new RotateTransition(Duration.seconds(10),contFH);
r1.setByAngle(360);
r1.setInterpolator(Interpolator.LINEAR);
r1.play();
I made the following changes and now I get the result I want, but this little problem is generated:
the line moves from its axis out of the small circle in the center.
Is there a way to keep it from moving on its axis when rotating?
Thanks for the help!

Create a Rotate and add it to the line's transformations. Then animate the angle:
Line contFH = new Line();
// This doesn't compile, not sure what you're doing here:
// contFH.setPrefSize(150, 20);
//contFH.setRotate(90);
Rotate rotate = new Rotate(90, contFH.getStartX(), contFH.getStartY());
contFH.getTransforms().add(rotate);
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(rotate.angleProperty(), 90)),
new KeyFrame(Duration.seconds(10), new KeyValue(rotate.angleProperty(), 450)
);
timeline.play();

Related

How to place a Plane geometry button on top of a row of cubes without displacing the button along z axis?

I have a grid of cubes and I need to show a button while hovering over a row. I have created the button with a plane geometry but while setting is position.y such that it stands right on top of the row, it displaces along the z axis and appears against another row at the back giving the wrong appearance. Please see the code below for the button and also a screenshot of the issue. The white button should appear right on top of the orange row.
I have tried to do what this post talks about. But inspite of all that, I am unable to fix it. Not sure why making the object high enough should affect the depth. I have not added any translation or rotation to it. Please help.
function createButtonForEachRow(numCols, width, offsetX, rowIndex, cubeSize , cubePadding)
{
var geometry = new THREE.PlaneGeometry( width, 1);
var material = new THREE.MeshBasicMaterial( {map: buttonTexture, side:THREE.DoubleSide } );
material.map.minFilter = THREE.LinearFilter;
var plane = new THREE.Mesh(geometry, material);
var referenceZPos = 1- (rowIndex * (cubeSize + cubePadding));
plane.position.x = offsetX + cubeSize + cubePadding * numCols + 3 ;
plane.position.y = cubeSize*3;
plane.position.z = referenceZPos;
// plane.rotation.x = 3 * Math.PI/2;
plane.visible = false;
return plane;
}
Screenshot
Creating 2 scenes and adding the button on the second scene worked. The link mentioned in the question actually worked. I had forgotten to set autoclear to false.

Add a node in the middle of a line java fx

I have a line and I want a square with text inside of the square to be placed in the middle of this line.
I have created the square with text using a stack pane. This line is draggable so I want the square to stay in the middle of this line when it is being dragged.
I tried:
weightSquare.layoutXProperty().bind((line.startXProperty().add(line.endXProperty())).divide(2).add(line.translateXProperty()));
weightSquare.layoutYProperty().bind((line.startYProperty().add(line.endYProperty())).divide(2).add(line.translateXProperty()));
where weightSquare is a StackPane containing a rectangle and text.
Currently, the weightSquare is near the middle of the line but not perfectly in the middle. When the line moves around the weightSquare stays relatively near the middle of the line but sometimes goes off the line slightly.
I want something like this:
Example of what I want
Thank you.
Assuming no transformations have been applied to the line or the StackPane, you can calculate the position of the StackPane based on the line properties like this
stackPane.layoutX = (line.startX + line.endX - stackPane.width) / 2;
(Procede accordingly for y coordinates.)
transformX and transformY could simply be added, but general transforms would require you to
Listen to changes of the transforms
Use localToParent on the start/end coordinates of the line to get the location in the parent.
I recommend using Bindings.createDoubleBindings for complicate double bindings btw, since this makes the formula for calculating the values much easier to read.
Example
I use a Label, since this provides background/border functionality too.
#Override
public void start(Stage primaryStage) throws IOException {
Label label = new Label();
label.setStyle("-fx-background-color: white; -fx-border-color: black;");
label.setPadding(new Insets(2, 4, 2, 4));
Line line = new Line(300, 300, 300, 100);
label.layoutXProperty().bind(Bindings.createDoubleBinding(
() -> (line.getStartX() + line.getEndX() - label.getWidth()) / 2,
line.startXProperty(), line.endXProperty(), label.widthProperty()));
label.layoutYProperty().bind(Bindings.createDoubleBinding(
() -> (line.getStartY() + line.getEndY() - label.getHeight()) / 2,
line.startYProperty(), line.endYProperty(), label.heightProperty()));
DoubleProperty angle = new SimpleDoubleProperty();
line.endXProperty().bind(Bindings.createDoubleBinding(() -> 300 + 200 * Math.sin(angle.get()), angle));
line.endYProperty().bind(Bindings.createDoubleBinding(() -> 300 + 200 * Math.cos(angle.get()), angle));
Timeline timeline = new Timeline(
new KeyFrame(Duration.ZERO, new KeyValue(angle, 0d, Interpolator.LINEAR)),
new KeyFrame(Duration.seconds(10), new KeyValue(angle, Math.PI * 2, Interpolator.LINEAR)));
timeline.setCycleCount(Animation.INDEFINITE);
label.textProperty().bind(timeline.currentTimeProperty().asString());
timeline.play();
Scene scene = new Scene(new Pane(line, label), 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}

Rectangle with rounded corner as ProgressBar using Path

i need to draw rectangle rounded corner with progressbar in javafx.
i already did some code which draw rectangle with corner.
but how do i show progress effect.
Following are the example which I am trying to imitate.
http://jsfiddle.net/m1erickson/P2qTq/
there is any other way to do this. guide me thank you.
void drawLine(double x1,double y1,double x2,double y2) {
MoveTo move= new MoveTo(x1, y1);
path.getElements().add(move);
LineTo line= new LineTo(x2,y2);
path.getElements().add(line);
path.setStroke(Paint.valueOf("#000000"));
}
void drawCorner(double x0,double y0,double x1,double y1) {
QuadCurveTo quadCurveTo=new QuadCurveTo();
quadCurveTo.setX(x0);
quadCurveTo.setY(y0);
quadCurveTo.setControlX(x1);
quadCurveTo.setControlY(y1);
path.getElements().add(quadCurveTo);
}
Group group=new Group();
double angleTRX=offsetX+horizontalLength+cornerRadius;
double angleTRY=offsetY+cornerRadius;
double TRCornerX=offsetX+horizontalLength+cornerRadius;
double TRCornerY=offsetY;
double bottomRY=angleTRY+verticalLength;
//draw top line
drawLine(offsetX, offsetY, offsetX + horizontalLength, offsetY);
//draw top right corner
drawCorner(angleTRX, offsetY+cornerRadius, TRCornerX, offsetY);
//draw right line
drawLine(angleTRX,angleTRY, angleTRX,bottomRY);
//draw bottom right corner
drawCorner(offsetX+horizontalLength,offsetY+verticalLength+cornerRadius*2,
offsetX+horizontalLength+cornerRadius,offsetY+verticalLength+cornerRadius*2);
//draw bottom line
drawLine(offsetX+horizontalLength,offsetY+verticalLength+cornerRadius*2,
offsetX,offsetY+verticalLength+cornerRadius*2);
//draw left bottom corner
drawCorner(offsetX-cornerRadius,offsetY+verticalLength+cornerRadius,
offsetX-cornerRadius,offsetY+verticalLength+cornerRadius*2);
//draw left line
drawLine(offsetX-cornerRadius,offsetY+verticalLength+cornerRadius,
offsetX-cornerRadius,offsetY+cornerRadius);
//draw top left corner
drawCorner(offsetX,offsetY,offsetX-cornerRadius,offsetY);
group.getChildren().add(path);
--> Update <--
i found another way to do it. using Rectangle with stroke-offset.
but still facing one issue stroke are starting from clockwise.
Rectangle rectangle= new Rectangle();
rectangle.setX(offsetX);
rectangle.setY(offsetY);
rectangle.setArcHeight(cornerRadius);
rectangle.setArcWidth(cornerRadius);
rectangle.setWidth(200);
rectangle.setHeight(200);
rectangle.setStroke(Paint.valueOf("#000000"));
rectangle.setFill(Paint.valueOf("#ffffff"));
rectangle.setStrokeWidth(5);
rectangle.setStrokeMiterLimit(5);
rectangle.setSmooth(true);
rectangle.setStrokeLineCap(StrokeLineCap.ROUND);
rectangle.setStrokeLineJoin(StrokeLineJoin.ROUND);
double length=rectangle.getWidth()*2+rectangle.getHeight()*2;
//set stroke dash length
rectangle.getStrokeDashArray().addAll(length);
//display empty stroke/border
rectangle.setStrokeDashOffset(length);
group.getChildren().add(rectangle);
container.add(group,0,0);
slider.valueProperty().addListener((observable, oldValue, newValue) -> {
rectangle.setStrokeDashOffset(length-(length*(newValue.doubleValue()/100)));
});
if you know better solution then please let me know.
i solved it using Rectangle and stroke-dash-offset. this might help others and save its valuable time.
Rectangle rectangle= new Rectangle();
rectangle.setX(offsetX);
rectangle.setY(offsetY);
rectangle.setWidth(200);
rectangle.setHeight(200);
rectangle.setStroke(Paint.valueOf("#000000"));
rectangle.setFill(Color.TRANSPARENT);
rectangle.setStrokeWidth(5);
rectangle.setStrokeMiterLimit(5);
rectangle.setSmooth(true);
rectangle.setStrokeLineCap(StrokeLineCap.ROUND);
// rectangle.setStrokeLineJoin(StrokeLineJoin.ROUND);
double length=rectangle.getWidth()*2+rectangle.getHeight()*2;
//set stroke dash length
rectangle.getStrokeDashArray().addAll(length);
//display empty stroke/border
rectangle.setStrokeDashOffset(length);
group.getChildren().add(rectangle);
container.add(group,0,0);
slider.valueProperty().addListener((observable, oldValue, newValue) -> {
double offset=length-((length*(newValue.doubleValue()/100)));
rectangle.setStrokeDashOffset(-offset);
});

JavaFX - Get Coordinates of Node Relative to its Parent

I am making a simple graphical interface for saving previously generated images. All images come to me square but I want to allow for some cropping functionality (more precisely cutting off equal parts from the bottom and top of the image). I want to do this by allowing the user to drag a shaded region over the image which will tell the user that this region will be cropped out. See the below image for details. To enable this drag functionality I have added small triangles that I want the user to drag which in turn will move the shaded regions about. However the coordinates for the triangles are all weird and seem nonsensical. Therefor I was wondering what the best way is to get the coordinates of the triangles in relation to the ImageView (or their first common parent node) in terms of ImageView-side-lengths. So if the triangle is in the center its coordinates are [0.5, 0.5] for instance.
The Image view will be moving around inside the scene and will also be changing size so it is vital that I can get the coordinates relative to not only the ImageView but also to the size of the ImageView.
Here is also the surrounding hierarchy of nodes if that helps. The Polygons are the triangles and the regions are the rectangles.
Thanks for all forms of help!
Node.getBoundsInParent returns the bounds of a node in it's parent coordinates. E.g. polygon.getBoundsInParent() would return the bounds in the VBox.
If you need to "go up" one additional step, you can use parent.localToParent to do this. vBox.localToParent(boundsInVbox) returns the bounds in the coordinate system of the AnchorPane.
To get values relative to the size of the image, you simply need to divide by it's size.
The following example only allows you to move the cover regions to in one direction and does not check, if the regions intersect, but it should be sufficient to demonstrate the approach.
The interesting part is the event handler of the button. It restricts the viewport of the second image to the part of the first image that isn't covered.
private static void setSideAnchors(Node node) {
AnchorPane.setLeftAnchor(node, 0d);
AnchorPane.setRightAnchor(node, 0d);
}
#Override
public void start(Stage primaryStage) {
// create covering area
Region topRegion = new Region();
topRegion.setStyle("-fx-background-color: white;");
Polygon topArrow = new Polygon(0, 0, 20, 0, 10, 20);
topArrow.setFill(Color.WHITE);
VBox top = new VBox(topRegion, topArrow);
top.setAlignment(Pos.TOP_CENTER);
topArrow.setOnMouseClicked(evt -> {
topRegion.setPrefHeight(topRegion.getPrefHeight() + 10);
});
// create bottom covering area
Region bottomRegion = new Region();
bottomRegion.setStyle("-fx-background-color: white;");
Polygon bottomArrow = new Polygon(0, 20, 20, 20, 10, 0);
bottomArrow.setFill(Color.WHITE);
VBox bottom = new VBox(bottomArrow, bottomRegion);
bottom.setAlignment(Pos.BOTTOM_CENTER);
bottomArrow.setOnMouseClicked(evt -> {
bottomRegion.setPrefHeight(bottomRegion.getPrefHeight() + 10);
});
Image image = new Image("https://upload.wikimedia.org/wikipedia/commons/thumb/e/ec/Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg/402px-Mona_Lisa%2C_by_Leonardo_da_Vinci%2C_from_C2RMF_retouched.jpg");
ImageView imageView = new ImageView(image);
setSideAnchors(top);
setSideAnchors(bottom);
setSideAnchors(imageView);
AnchorPane.setTopAnchor(top, 0d);
AnchorPane.setBottomAnchor(bottom, 0d);
AnchorPane.setTopAnchor(imageView, 0d);
AnchorPane.setBottomAnchor(imageView, 0d);
AnchorPane container = new AnchorPane(imageView, top, bottom);
ImageView imageViewRestricted = new ImageView(image);
Button button = new Button("restrict");
button.setOnAction(evt -> {
// determine bouns of Regions in AnchorPane
Bounds topBounds = top.localToParent(topRegion.getBoundsInParent());
Bounds bottomBounds = bottom.localToParent(bottomRegion.getBoundsInParent());
// set viewport accordingly
imageViewRestricted.setViewport(new Rectangle2D(
0,
topBounds.getMaxY(),
image.getWidth(),
bottomBounds.getMinY() - topBounds.getMaxY()));
});
HBox root = new HBox(container, button, imageViewRestricted);
root.setFillHeight(false);
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}

Drawing line in flash- via Action script

I need to draw a line in ActionScript(based on calculated conditions for length and rotation)
I tried the following code- the triangle with the fill appears- but not the line with the lineStyle- Could you pls help me out on this... c is defined as UIComponent
var myShape:Shape=new Shape();
myShape.graphics.moveTo(100,100);
myShape.graphics.lineTo(200,200);
myShape.graphics.lineStyle(2,0xFF0000,.75);
c.addChild(myShape);
var triangleHeight:uint = 100;
var triangle:Shape = new Shape();
// red triangle
triangle.graphics.beginFill(0xFF0000);
triangle.graphics.moveTo(triangleHeight/2, 200);
triangle.graphics.lineTo(triangleHeight, triangleHeight);
triangle.graphics.lineTo(0, triangleHeight);
triangle.graphics.lineTo(triangleHeight/2, 200);
c.addChild(triangle);
You should declare line style before your drawing.

Resources