Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Eclipse Projects » GEF » Resize of SVGPaths
Resize of SVGPaths [message #1805832] Thu, 25 April 2019 07:48 Go to next message
Sebastian Heinrich is currently offline Sebastian HeinrichFriend
Messages: 24
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  index.php/fa/35401/0/
This is how it looks at resizing index.php/fa/35402/0/

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 Go to previous message
Matthias Wienand is currently offline Matthias WienandFriend
Messages: 230
Registered: March 2015
Senior Member
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
Previous Topic:Is Draw2D deprecated?
Next Topic:HoverFeedbackPart
Goto Forum:
  


Current Time: Tue Sep 27 17:57:53 GMT 2022

Powered by FUDForum. Page generated in 0.02766 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top