|
|
Re: GEF5 export to SVG [message #1779513 is a reply to message #1778888] |
Mon, 08 January 2018 23:42 |
Ken Keefe Messages: 38 Registered: September 2009 |
Member |
|
|
Please help with this problem! I've been killing myself trying to dig through the code. I will say that DI is nice for writing concise code, but it is super brittle and hard to debug if you don't use code exactly the way it was intended.
Here are the problems I'm facing (using the latest commit in https://github.com/kenjkeefe/gef-mindmap-tutorial):
1. When I try to execute an export, I get an NPE at ITransformableContentPart.setVisualTransform() because getAdapter(TRANSFORM_PROVIDER_KEY) returns null. This is caused by the fact that the collection of adapters in the a part's AdaptableSupport is empty.
As near as I can tell, the adapter collection in AdaptableSupport should be populated when the MindMapNodePart is added to the LayeredRootPart. Which leads to...
2. I am unable to correctly create a LayeredRootPart. I cannot figure out how the GEF.MVC.FX code is doing it because I think it is being created by injection, and that code is incredibly difficult to decipher. If I could create a LayeredRootPart right, I think problem 1 would resolve itself.
Here is the export handler as it stands in the github repo. The createImageFromModel method is where things go off the rails. I want to be able to generate an image directly from a model without having to display the image on the screen. To do this, I created a separate module, domain, injector, scene, etc. I am guessing that this is where I am doing something wrong. Please help! Thanks!
public class SVGExportHandler {
public SVGExportHandler() {
}
private Bounds createImageFromModel(SimpleMindMap mindMap, SVGGraphics2D svgGenerator) {
SimpleMindMapModule module = new SimpleMindMapModule();
Injector injector = Guice.createInjector(module);
IDomain domain = injector.getInstance(IDomain.class);
Parent canvas = domain.getAdapter(AdapterKey.get(IViewer.class, IDomain.CONTENT_VIEWER_ROLE)).getCanvas();
new Scene(canvas);
domain.activate();
MindMapPartsFactory partsFactory = injector.getInstance(MindMapPartsFactory.class);
IContentPart<? extends Node> rootPart = partsFactory.createContentPart(mindMap, null);
rootPart.setContent(mindMap);
loadDescenantParts(rootPart, partsFactory);
Bounds size = rootPart.getVisual().getLayoutBounds();
return size;
}
public void execute() {
String homeDir = System.getProperty("user.home");
final File svgFile = new File(homeDir, "export.svg");
DOMImplementation domImpl = GenericDOMImplementation.getDOMImplementation();
Document document = domImpl.createDocument(null, "svg", null);
try {
OutputStreamWriter out = new OutputStreamWriter(new FileOutputStream(svgFile), "UTF-8");
SVGGraphics2D svgGenerator = new SVGGraphics2D(document);
// I want to show how to do this creation directly from a new model separate
// from anything currently displayed visually.
SimpleMindMapExampleFactory fac = new SimpleMindMapExampleFactory();
SimpleMindMap mindMap = fac.createComplexExample();
Bounds size = createImageFromModel(mindMap, svgGenerator);
Element root = svgGenerator.getRoot();
root.setAttributeNS(null, "width", Double.toString(size.getWidth()));
root.setAttributeNS(null, "height", Double.toString(size.getHeight()));
svgGenerator.stream(root, out);
out.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// There has to be a better GEF5 way of doing this...
private void loadDescenantParts(IContentPart<? extends Node> part, MindMapPartsFactory partsFactory) {
for (Object child : part.getContentChildrenUnmodifiable()) {
IContentPart<? extends Node> childPart = partsFactory.createContentPart(child, null);
childPart.setContent(child);
part.addChild(childPart);
loadDescenantParts(childPart, partsFactory);
}
}
}
[Updated on: Mon, 08 January 2018 23:43] Report message to a moderator
|
|
|
Re: GEF5 export to SVG [message #1785405 is a reply to message #1779513] |
Fri, 13 April 2018 13:47 |
|
Hi Ken,
first of all, you should not have to set adapters by yourself. Instead, the module should configure the adapters.
Secondly, you should not create the parts in-place, but rather have a viewer and set its contents. The synchronisation will create all content parts for you.
You should try with the same setup that you use for the mind map application.
W.r.t. LayeredRootPart, the root part is configured to be registered as an adapter for a viewer. You can see this inside the module configuration, for example, within MvcFxModule, there is a method bindRootPartAsContentViewerAdapter() that establishes a binding to IRootPart, which is resolved by the method bindIRootPart() that binds IRootPart to LayeredRootPart.
h2h
Matthias
|
|
|
Powered by
FUDForum. Page generated in 0.03461 seconds