Home » Eclipse Projects » GEF » Resize of SVGPaths
Resize of SVGPaths [message #1805832] |
Thu, 25 April 2019 07:48 |
Sebastian Heinrich Messages: 28 Registered: July 2018 |
Junior Member |
|
|
Good Morning
To be honest, I don't know if my question is actually a JavaFX or a GEF question.
I give it a try here, but if its not placed correct then just tell me.
Many thanks in advance for your help :-)
I have a Visual class that has a constructor as follows:
public Visual() {
super();
super.setSnapToPixel(true);
nameShape = new GeometryNode<>(new RoundedRectangle(DEFAULT_LOCATION_X, DEFAULT_LOCATION_Y, SCHALTER_WIDTH_NAME,
SCHALTER_HEIGHT_NAME, 8, 8));
nameShape.setFill(Color.LIGHTGRAY);
nameShape.setStroke(Color.BLACK);
shape = new GeometryNode<>(new RoundedRectangle(DEFAULT_LOCATION_X, DEFAULT_LOCATION_Y, CSCHALTER_WIDTH,
CSCHALTER_HEIGHT - SCHALTER_HEIGHT_NAME, 8, 8));
shape.setFill(Color.WHITE);
shape.setStroke(Color.BLACK);
circle = new SVGPath();
curve1 = new SVGPath();
curve2 = new SVGPath();
configureSVGPath(circle, Color.BLACK, DEFAULT_WIDTH_SVGELEMENTS, null, 0.0, 1.0, 21.0, FULL_CIRCLE);
configureSVGPath(curve1, Color.BLACK, DEFAULT_WIDTH_SVGELEMENTS, null, 0.0, 1.0, 21.0, CURVE_TOP_TO_LEFT);
configureSVGPath(curve2, Color.BLACK, DEFAULT_WIDTH_SVGELEMENTS, null, 0.0, 1.0, 21.0, CURVE_BOTTOM_TO_RIGHT);
Region circleShape = new Region();
circleShape.setShape(circle);
Region curve1Shape = new Region();
curve1Shape.setShape(curve1);
Region curve2Shape = new Region();
curve2Shape.setShape(curve1);
SVGGroup = new Group(circleShape, curve1Shape, curve2Shape);
schalterName = new Text();
schalterName.setLayoutX(3);
schalterName.setLayoutY(SCHALTER_HEIGHT_NAME / 1.5);
setMinSize(USE_COMPUTED_SIZE, USE_COMPUTED_SIZE);
setGeometry(shape.getGeometry());
// ensure shape and labels are resized to fit this visual
shape.prefWidthProperty().bind(widthProperty());
shape.prefHeightProperty().bind(heightProperty());
nameShape.prefWidthProperty().bind(widthProperty());
getChildren().addAll(new Group(shape), new Group(nameShape), new Group(schalterName), SVGGroup);
}
I want now to implement resizing of GEF content. I configured the module with resize policy etc.
I assume thats correct done because the Regions (e.g. nameShape) are resizing properly.
What is not resizing is the SVGPath stuff.
I got from the internet the hint to put the SVGPaths into a Region and add them as a shape (This is contained in code above). But if I bind the corresponding shapes e.g. like this
circleShape.prefHeightProperty().bind(heightProperty());
nothing happens at resizing.
This is how it looks in default state
This is how it looks at resizing
I know that one can resize SVGPaths with setScaleX/Y (and binding with scaleProperty) and setTranslateX/Y.
My actual question is now if there is an easier way to resize shapes that contain SVGPaths objects? Just from the point of view that SVG stuff is made to be resized there should be a possiblity?!
My first (and maybe naive) assumption was that with ResizePolicy it will work automatically. But this is obviously not the case.
Many thanks for help in advance!
Best regards
Sebastian
|
|
|
Re: Resize of SVGPaths [message #1805846 is a reply to message #1805832] |
Thu, 25 April 2019 11:33 |
|
Hi Sebastian,
IMHO it is totally fine to discuss this question here. GEF is tightly coupled with JavaFX anyway.
I want to start with what GEF is doing for you when you are using ResizePolicy.
So, the policy creates a ResizeOperation, which is calling setVisualSize() on the IResizableVisualPart. Therefore, you are able to execute any custom logic in response to resize. Moreover, there is a default implementation of the setVisualSize() method [1]:
/**
* Resizes the visual of this {@link IResizableContentPart} to the given
* size.
*
* @param totalSize
* The new size for this {@link IResizableContentPart}'s visual.
*/
public default void setVisualSize(Dimension totalSize) {
if (getVisual() instanceof Region) {
// A Region should not be resized directly. Instead, its size
// constraints should be adjusted so that it will be resized to the
// desired size during the next layout pass.
((Region) getVisual()).setPrefSize(totalSize.width,
totalSize.height);
((Region) getVisual()).autosize();
} else {
// resize manually
getVisual().resize(totalSize.width, totalSize.height);
}
}
As you can see, in case your visual extends Region, its preferred size will be adjusted for you. Therefore, you can set up the scaling for your SVGPath objects in dependence on the Region's actual size.
You have probably already found this SO post [2] where an example is given w.r.t. scaling the SVGPath. Doing this adjustment in response to size changes can be done using a ChangeListener for the width and height properties of the region.
The following is demonstrating this, however, it might not be safe in corner cases, i.e. SVGPath reaching out of the region, causing resize problems, or corner cases, e.g. size of zero.
public class TestPathResizeApp extends Application {
public static void main(String[] args) {
launch();
}
@Override
public void start(Stage mw) throws Exception {
Region region = new Region();
Scene scene = new Scene(region, 400, 300);
region.setBackground(new Background(new BackgroundFill(Color.BLACK, CornerRadii.EMPTY, Insets.EMPTY)));
SVGPath svgPath = new SVGPath();
// example svg path taken from StackOverflow https://stackoverflow.com/questions/38953921/how-to-set-the-size-of-a-svgpath-in-javafx
svgPath.setContent("M 289.00,74.00 C 299.18,61.21 307.32,52.80 320.00,42.42 331.43,33.07 343.66,26.03 357.00,19.84 427.64,-12.98 509.92,2.91 564.42,58.28 583.93,78.10 595.94,99.15 605.58,125.00 607.76,130.86 611.37,144.75 612.54,151.00 613.15,154.23 613.28,160.06 615.58,162.44 617.49,164.42 624.11,165.84 627.00,166.86 634.80,169.62 639.97,172.04 647.00,176.42 673.69,193.07 692.76,221.39 695.83,253.00 700.60,302.03 676.64,345.41 630.00,364.00 621.17,367.52 608.48,370.99 599.00,371.00 599.00,371.00 106.00,371.00 106.00,371.00 96.50,370.99 87.00,368.97 78.00,366.00 36.29,352.22 6.21,312.25 6.00,268.00 5.77,219.90 34.76,179.34 81.00,165.02 96.78,160.14 107.02,161.00 123.00,161.00 124.59,150.68 130.49,137.79 136.05,129.00 150.70,105.88 173.22,88.99 200.00,82.65 213.13,79.55 219.79,79.85 233.00,80.00 247.37,80.17 264.61,85.94 277.00,93.00 279.11,86.37 284.67,79.45 289.00,74.00 Z");
region.setShape(svgPath);
// bind size of region to size of scene
region.prefWidthProperty().bind(scene.widthProperty());
region.prefHeightProperty().bind(scene.heightProperty());
// handle width changes
Consumer<Number> scaleToWidth = (width) -> {
svgPath.setScaleX(width.doubleValue() / svgPath.prefWidth(-1));
};
region.widthProperty().addListener((obs, oldValue, width) -> {
scaleToWidth.accept(width);
});
// initial width
double currentWidth = region.getWidth();
scaleToWidth.accept(currentWidth > 0 ? currentWidth : 1);
// handle height changes
Consumer<Number> scaleToHeight = (height) -> {
svgPath.setScaleY(height.doubleValue() / svgPath.prefHeight(-1));
};
region.heightProperty().addListener((obs, oldValue, height) -> {
scaleToHeight.accept(height);
});
// initial height
double currentHeight = region.getHeight();
scaleToHeight.accept(currentHeight > 0 ? currentHeight : 1);
mw.setScene(scene);
mw.show();
}
}
Best regards,
Matthias
[1] https://github.com/eclipse/gef/blob/f2eaba29f921dbf04d4999f7ba98eee7b64934f3/org.eclipse.gef.mvc.fx/src/org/eclipse/gef/mvc/fx/parts/IResizableContentPart.java#L66
[2] https://stackoverflow.com/questions/38953921/how-to-set-the-size-of-a-svgpath-in-javafx
|
|
|
Goto Forum:
Current Time: Wed Dec 11 22:28:09 GMT 2024
Powered by FUDForum. Page generated in 0.02628 seconds
|