I'm surprised to see that this hasn't been done, or at least my research says so.
I have a Canvas with RowLayout and a bunch of Labels.
The title is pretty straight forward: I want to reorder my labels using DND.
Please don't tell me I have to engineer my own algorithm for calculating bounds and sizes and stuff like that.
Later edit:
I'm considering using Zest, but again, I can't find any example where graph nodes are snapped to eachother.
I did something like this about a year ago.
My method of solving this problem was to use a data model to hold the label information. Use the canvas.getChildren() and search for a separator composite between each object or the label that you dropped on top of. When a drag and drop operation was completed you would search for the item that you dropped on and move the reference to the appropriate position in the model. Then reset the information on each label. Only requirement to do this is to keep a data structure with the label info and a reference to the canvas.
In other words, I'm trying to do something with JavaFX like what Batik allows you to do with Swing.
I want to be able to capture the appearance of an arbitrary node in my JavaFX UI, much like Node.snapshot() does, except that I need my image in a vector format like SVG, not a raster image. (And inserting a raster snapshot of my node into an SVG image is not good enough; it needs to be a proper, scalable vector image.)
This is a long-term project, so I'm even willing to go as far as implementing my own GraphicsContext, or whatever the equivalent is in JavaFX's retained mode API.
Does anyone know if there is a way to do this? Is what I'm hoping to do even possible in JavaFX?
I started to write a JavaFx Node to SVG converter which "extends" the ShapeConverter from Gerrit Grunwald which only converts Shape geometries:
https://github.com/stefaneidelloth/JavaFxNodeToSvg
... and stopped it after a certain amount of frustration.
Please feel free to improve it, add features and fix bugs.
The converter works for simple Node examples but fails for advanced examples like a Chart. My failed converter might serve you as a starting point. The current state is illustrated by the following figures. The left side shows the original JavaFx node and the right side shows the resulting svg output.
Simple node example (works):
Chart example (does not work):
The corresponging svg files are available here:
https://github.com/stefaneidelloth/JavaFxNodeToSvg/tree/master/output
Some further notes
In addition to the positioning problems that are illustrated by the Chart example above, some further issues have to be considered:
JavaFx provides more css functionality than the SVG standard elements. For example a (rectangular) JavaFx Region can have individual line styles for each of the four border lines. Such a Region can not simply be converted to a SVG rect. Instead, the four border lines of the Region need to be drawn individually. Furthermore, each end of such a border line can have two individual edge radii: a vertical radius and a horizontal radius. In order to convert the "four" border lines to corresponding SVG lines ... it might be necessary to further split the border line: draw two rounded parts and a straight part for each of the four border lines. Therefore, in some cases there might be 12 SVG path elements to draw the border of a single JavaFx Region. In addition, the background fill of the Region can have different radii than the border of the Region. Drawing the background of the Region might requires some more SVG elements. Therefore, even the conversion of a "rectangular Region" can get quite complex.
Please also note that JavaFx nodes might be animated. For example the opacity of a line is 0 at the beginning and fades to another value after a few milliseconds.
FadeTransition ft = new FadeTransition(Duration.millis(250), borderline);
ft.setToValue(0);
ft.play();
Therefore it only makes sense to convert Nodes where animations are disabled or to wait until the Nodes are in a stable state.
I would be very happy if the conversion of JavaFx Charts works one day, so that I can use JavaFx plotting with SVG export in one of my projects.
I decided to stop the development of the converter for the time being and to investigate the plotting and SVG export with JavaScript libraries (d3) instead. If that strategy turns out to be even worse, I might come back to the JavaFxNodeToSvgConverter.
Edit
The plotting with d3.js works very well and I decided not to use JavaFx for the purpose of plotting/svg creation. https://github.com/stefaneidelloth/javafx-d3
There is a simple JavaFX shape to SVG string converter, it will only convert basic shapes without css applied, not arbitrary nodes, but perhaps that might be all you need.
There is an open bug request in JFX JIRA at
https://javafx-jira.kenai.com/browse/RT-38559
(registration required; you can vote for the issue then). It currently says
Consider for a future version.
And is marked for version 9.
The idea is that if you are able to convert the JavaFX Nodes tree structure to a series of Graphics2D orders, then you can use Batik which has a Graphics2D driver.
The thing is that converting the JavaFX tree structure to Graphics2D orders is not as difficult as you might think (even if you process the CSS properties of the Nodes).
Some readers suggested that I should include some code, and not just the link to the library and pictures of it working. It is not so easy to do, because even if it is not so difficult to do, it still has 5000 lines of code.
How to perform the conversion:
you must have a Graphics2D to convert to SVG (for example the Batik SVGGraphics2D class);
iterate through the JavaFX structure;
for each Node in the structure, first convert the current javaFX transforms on this Node to an AffineTransform, and apply the transformation to the Node (you must do it in a Stack to be sure to revert to the initial AffineTransform at the end of the Node);
and for each Node, you have to transform to the appropriate Graphics2D orders.
Note that you don't need to support a lot of Node types, mainly:
Regions (controls are a special type of Region which can have an associated Graphics)
Groups
Shapes (Text, Rectangle, etc...)
ImageView for images
You may also need to take care of the Node Clipping to apply the associated Clipping in the Graphics2D.
Also you will have to take care of the CSS properties of the Node.
For all its worth, the library I used (which apllies this algorithm) is here: http://sourceforge.net/projects/jfxconverter/
The idea is that if you are able to convert the JavaFX Nodes tree structure to a series of Graphics2D orders, then you can use Batik which has a Graphics2D driver.
The thing is that converting the JavaFX tree structure to Graphics2D orders is not as difficult as you might think (even if you process the CSS properties of the Nodes).
You should create a SVGGraphics2D from a new empty SVGDocument, for example:
Document doc = SVGDOMImplementation.getDOMImplementation().createDocument(SVGDOMImplementation.SVG_NAMESPACE_URI, "svg", null);
SVGGraphics2D g2D = new SVGGraphics2D(doc);
Then you get the root node of the Scene you want to convert, and for this node, you get the type of the Node, which can be a Shape, Control, Region, ImageView, Group, SubScene, Shape3D
Depending on each node, you can get the characteristics of the node. For example, for a Shape, if its a Line, you can drawthe line in the SVGGraphics2D. For example:
g2D.drawLine((int) line.getStartX(), (int) line.getStartY(), (int) line.getEndX(), (int) line.getEndY());
Note that you will also need to take care of the transforms applied to the node, and the fill or draw of the Node.
Then you iterate on the Node children and do the same thing recursively.
At the end you should be able to save the document in SVG as Batik allows to do it natively.
I'm doing a college project which I must finish in 3 months. And I have 8 hours a week to spend in that project.
The project consists in doing a graphical interface that shows many rectangles next to each other which should be movable. It should be very similar to the tabs in the chrome browser, where you can drag them to which ever position you want.
In addition to that there should be arrows connecting one rectangle to the other. And these arrows should still connect the same rectangles even when I change the order of the rectangles. The image below illustrates what I'm saying.
The image shows before and after one of the rectangles being dragged.
Since Java is my first language, I would like to use it.
My question is: What framework, APIs should I use to do this project. What will be the easiest and fastest way to do it? Should I use Swing? or JavaFX? or GWT? or other alternative?
Is there an API for handling arrows connecting objects? Maybe one used for representing graphs may be ok.
Edit: I don't know anything about Swing and neither about JavaFX. So which one would be more worthwhile learning given that I don’t have too much time this semester because I’m very busy?
This shouldn't be too hard to write from scratch.
Use this site : http://www.codeproject.com/Articles/116088/Draggable-Components-in-Java-Swing for the drag-able components
Draw arrows with some kind of parameterization (math formula) for half of an oval. Pass the draw path into a java.awt.Graphics2D pen object.
You might want to check Java Universal Network/Graph Framework.
It has some extensive support for making editable graphs while maintaining relationship among nodes and edges.
What you can do is change the icon of node to a squared rectagnle, while add logic to plot them in a straight axis so that it would look the way you want, plus it would be editable while linked arrows will remain where they should be.
But incase you don't have experience with Swing, better start learning the basis of SWING first, as JUNG framework pretty much requires some good basic knowledge of swing itself.
I want to virtualize my network simulations and need to plot the nodes in the network. Each node has a pre-defined location and I need to plot the nodes into the correct coordination.
I am using JUNG: http://jung.sourceforge.net/applet/index.html
Any suggestions?
Thanks!
I recently solved this problem by writing my own rendering Layout for JUNG.
As base for my derived layout I used the Circle Layout, which is pretty simple. In there you will see that JUNG does a setLocation(Dimension d) for every Vertex, which is pretty much what you are looking for, I guess. Just take a look at the source of the CircleLayout.
Then you could use a custom Vertex object, which stores the coordinates you want the vertex to have, which is then read by your custom layout.
I'm looking to use the java2d API to make a graph in which users can manipulate certain features using their mouse - such as the scale used for an axis or move around the different points plotted on the graph.
So far all I have found is the drawX methods on a Graphics2D object, however there does not seem to be an easy way to capture a user clicking on one of these and moving it so that I can redraw the graph.
Can anyone suggest the best/easiest way to implement this? Just looking for a point in the right direction.
Not reinventing the wheel is always the best way, there are plenty of excellent libraries you can use: http://www.jfree.org/jfreechart/
If you are looking to implement this yourself, you would listen to mouse events on whatever component you're actually using to display your chart (say a JPanel), and then would have to convert between screen and chart coordinates to figure out what you need to change.