Using Java and SWT, I am trying to display a map (provided as an image) and mark points on it. First idea is to use a canvas, draw the image (scaled to the largest possible size for this canvas) and then draw the markings (fixed size) to the scaled coordinates. However I would also like to zoom in and move the image, and would prefer not to develop all this functionality from scratch. However I am not having much luck finding an existing solution, though I would guess there should be something out there.
The criteria would be:
based on SWT (or compatible)
allows exchange of the image (possibly with different sizes)
handles user interaction (selection a point on the image, zooming in/out of the image)
Does anybody know a standard/common solution?
Depending on how complex your system will potentially grow, maybe using GEF is an option.
The whole rendering is done on SWT.Canvas and it provides Zooming/Scrolling/Moving out of the Box.
Downside: Its dependant on RCP, so this is likely to be only an option if you need to build an otherwise complex application - in all other cases GEF will be quite heavyweight to set up.
Related
I'm looking for some way to set background image with barrel distortion effect(FishEye/FOV) for node using JavaFX. I found algorithm with pixel manipulation, but I want to find some another way(some hack) for reach it. This effect will be use for create node background high definition image changing animation(animation wil be change factor(power/value/degree?)) of this effect.
I'd like to offer an alternative approach which is much more efficient (real-time capable). Any solution which is based on direct pixel manipulations is doomed to be very inefficient especially for a "high definition image".
Instead I'd propose to use a TriangleMesh for this and use the image as its texture. You can then apply any kind of distortion you like by just manipulating the texture coordinates. This approach can be easily integrated into any 2D graphics via the JavaFX scene graph.
I am actively using this concept for on-the-fly reprojection of raster map tiles, so I know it works.
I will answer this question in the spirit that it was asked, i.e. no code.
JavaFX has an effect framework.
There is no in-built fisheye effect.
You could create your own custom fisheye effect implementation and plug it into the effect framework if you are a skilled developer.
Easier would be to apply your algorithm using a WritableImage with a PixelWriter or Canvas. Perhaps that could even plug into the effect framework (if you actually needed to do that, which you probably don't) using an ImageInput.
For an example of applying an algorithm to the pixels in an input image see:
Reduce number of colors and get color of a single pixel
Of course, you would use a fisheye algorithm (coded for JavaFX instead of the linked implementations) for a fisheye transform.
To animate use an AnimationTimer or, again for skilled developers, create a custom transition that plugs into the JavaFX animation framework.
You can add properties to your custom effect and manipulate them using additional properties defined on the custom transition you create.
Providing a complete solution is out of scope for a StackOverflow answer. To get help with individual tasks, split the problem up into different pieces, e.g. creating a custom effect, manipulating pixels to create a fisheye, animating an effect on an image or timeline, etc. Write the code and ask questions about the actual code with a minimal example for the problem portion you are trying to solve when you get stuck.
Actually, my work is based on displaying a diagram in the screen, and while zooming in/out, the information in the diagram becomes more/less (just like Google Map).
May anyone guide to a 2D Graphics API that can allow me zoom in/out my drawings in Java easily?
I have used Graphics2D with AffineTransform, but showing more/less details in the diagram is somehow difficult using these stuff. I actually mean that Java Graphics API does not help in showing more/less details, positioning them, changing their size, etc. I have to write code for everything and every change in my design requires too much effort to modify my code.
You should use the MVC pattern where the diagram class representing the diagram with all the details is your model, the displayed image is your view and the zoom buttons/wheel are your controllers.
Here are some quick ideas:
You could have some method that builds the rendered image always using the same "internal" size, with more or less details depending on the zoom required and then use the AffineTransform to enlarge it (which is the easiest way to zoom an image as far as I know). Each time the zoom is changed this method is invoked passing the new zoom and the image is rebuilt.
If this is not feasible (e.g. because the coordinates of the additional information are not easy to compute on a small image) you can try the other way round: first build the basic image, enlarge it, then use the method to incrementally add new informations to this image. You can even cache the images built from smaller zoom values to speed up the process.
I want to develop an app where the user should be able to draw objects (circles/elipses), connect them via lines/arrows and drag/drop them, add text to them etc.
Of course I also have to write eventHandling.
What is most suitable for that? Would you rather go for gwt-graphics or GWTCanvas?
Based on that what i know, GWT-Graphics is based on SVG. while GWTCanvas(which is actually part of GWT main line) is based on canvas element.
now, quick comparsion.
For all drag and drop thing, SVG was much easier and quicker (when o was testing drag and drop when i had large abount of elements, my program based on canvas was much slower than similar stuff based on SVG
Other advantage of SVG based library is canvas is not supported y all browsers (actualy older versions of ie imight have some issues)
from the other hand,
canvas is much quicker while you need to draw massive number of objects, canvas is definietly your choice.
I would personally go with gwt-graphics. It is the one I know better, it gives as much control over graphics as was needed to me (and I think you too) and most of the events are already implemented, so the logic you will need to write will be minimal.
On the other hand SVG is not well supported by IExplorer and if the vectors become numerous you will have compatibility problems.
The Canvas if HTML 5 and will give you pixel level control - which I assume is not the case in your project - but will also lead to a - no workarounds - approach which is a pro.
In conclusion, I think it depends on the level of control you want the user to have while using the canvas and the level of work you want to do on your part.
I'm in the process of writing a custom heatmap generator. I'm wondering what the fastest way is to draw boxes (up to around 1 million) in Java. Most questions I've found have concentrated on dynamic images (like in games), and I'm wondering if there's a better way to go for static images. I've tried using swing (via a GridLayout and adding a colored canvas to each box), drawing directly on the panel with Graphics2D, and also by using the Processing libraries. While Processing is pretty fast and generates a clean image, the window seems to have problems keeping it; it generates different parts of the image whenever you minimize, move the windows, etc.
I've heard of OpenGL, but I've never touched it, and I wanted some feedback as to whether that (or something else) would be a better approach before investing time in it.
For static images, I paint them to a BufferedImage (BI) and then draw that via Graphics2D.
I keep a boolean that tells me whether the BI is up to date. That way I only incur the expensive painting cost once. If you want to get fancy, you can scale the BI to handle minor resizing. For a major resizing you'll probably want to repaint the BI so as not to introduce artifacts. It's also useful for overlaying data (such as cross hairs, the value under the cursor, etc) as you're only painting the BI and the data.
I am looking for ways to zoom in a Java Swing application. That means that I would like to resize all components in a given JPanel by a given factor as if I would take an screenshot of the UI and just applied an "Image scale" operation. The font size as well as the size of checkboxes, textboxes, cursors etc. has to be adjusted.
It is possible to scale a component by applying transforms to a graphics object:
protected Graphics getComponentGraphics(Graphics g) {
Graphics2D g2d=(Graphics2D)g;
g2d.scale(2, 2);
return super.getComponentGraphics(g2d);
}
That works as long as you don't care about self-updating components. If you have a textbox in your application this approach ceases to work since the textbox updates itself every second to show the (blinking) cursor. And since it doesn't use the modified graphics object this time the component appears at the old location. Is there a possibility to change a components graphics object permanently? There is also a problem with the mouse click event handlers.
The other possibility would be to resize all child components of the JPanel (setPreferredSize) to a new size. That doesn't work for checkboxes since the displayed picture of the checkbox doesn't change its size.
I also thought of programming my own layout manager but I don't think that this will work since layout managers only change the position (and size) of objects but are not able to zoom into checkboxes (see previous paragraph). Or am I wrong with this hypothesis?
Do you have any ideas how one could achieve a zoomable Swing GUI without programming custom components? I looked for rotatable user interfaces because the problem seems familiar but I also didn't find any satisfying solution to this problem.
Thanks for your help,
Chris
You could give a try to the JXLayer library.
There are several tools in it, which could help you to make a zoom. Check the examples shown here. I would recommend you to read more about the TransformUI, from this library. From the example, it seems like it could help solving your problem.
Scaling the view is easy enough; transforming mouse coordinates is only slightly more difficult. Here's an elementary example. I'd keep JComponents out, although it might make sense to develop an analogous ScaledComponent that knows about the geometry. That's where #Gnoupi's suggestion of using a library comes in.
hey you can try this if you want to zoom a image like any other image viewer the use a JPanel draw an image using drawImage() method now create a button and when you click the button increase the size of the panel on the frame it appears as if the image is being viewed in Zoom
You might find Piccolo2D.java API useful: http://code.google.com/p/piccolo2d/
It is very simple.
It touts in particular its smooth zooming. You essentially make a "canvas" that can contain various elements, and can then zoom by just holding right-click and panning the mouse back and forth.
I worked on a team that used it to create this: http://sourceforge.net/apps/mediawiki/guitar/index.php?title=WebGuitar#EFG.2FGUI_Visualizer
The nodes you see there are clickable links themselves.
Since Java 9, there are VM arguments (actually meant to be used for high dpi scaling) that can render a application with a higher scaling factor:
java -Dsun.java2d.uiScale=2.0 -jar MyApplication.jar
Or:
java -Dsun.java2d.win.uiScaleX=2.0 -Dsun.java2d.win.uiScaleY=2.0 -jar MyApplication.jar