Přeskočit na hlavní obsah

Getting confused with JavaFX Canvas


As I am working on a new MapViewer component for AgroSense (it is fork, but very modified, of abandoned project swingx-ws) I am facing some strange behavior of JavaFX components, which I have never met in Swing. It is a combination of StackPane, Canvas and painting images in the Canvas.  

And what was the problem?

Having Canvas in StackPane and some components, for example BorderPane with Buttons and Slider, on top of it, components in upper layer of StackPane tend to disappear, especially when moving mouse over other components. The component with focus or with mouse over it looks good, but other disapear.

As I was searching for the root cause of trouble, I tested some combinations of painting in Canvas (GraphicsContext.fillRect(), GraphicsContext.drawImage() etc.) and only drawing of image was troubled. And when the Pane with components wasn’t over the painted image, the problem was gone.

Searching for the problem

But how to find out what is going wrong? When painting, debugger is useless and putting System.out.println() to every suspicious method is lengthy and rarely give some valuable results. I even experimented with styles and after removing all hover behavior the problem was almost gone! 

This really isn’t a solution, but can lead you to the real cause of trouble. Now I know it is related with drawing styles, maybe.

Read the Javadoc!

Honestly, how many of you read Javadoc of every class, you intend to use? I know, it depends :-) Starting with Canvas, there is a lot of reading, so I started from the bottom with Node class. And there it was, almost at the beginning: the blendMode.

The Javadoc for this field says:

The BlendMode used to blend this individual node into the scene behind it. If this node happens to be a Group then all of the children will be composited individually into a temporary buffer using their own blend modes and then that temporary buffer will be composited into the scene using the specified blend mode.
    
    
And the BlendMode enum Javadoc:

A blending mode defines the manner in which the inputs of a Blend effect are composited together or how a Node is blended into the background of a scene.

Well, it doesn’t look it should solve my problem, but looks interesting, so why not to give it a try. Not sure, which value of BlendMode enum to use, I decided to try one after another. 

I really, really recommend you to read Javadoc of this enum to really understand which one to use. Different values give you very different results – yellow image, negative image etc. it depends on the image and background of the scene. 

My winner is BlendMode.MULTIPLY.

This solved my problem, but now I have to find out why this special combination of components and settings behaves so strangely. But it will be topic for another story.

Conclusion

If you have some issues with painting, check the BlendMode setting and try to read Javadoc before you run in some trouble. It takes some time, but at the end of the day, it can save you much more time and troubles.

Populární příspěvky z tohoto blogu

CPU killer in Java with JavaFX GUI client

Motivation Few weeks ago I was searching for a source of a bug in one of our applications. The QA team suspected that slow computer could be a reason for this. You know that - developers have Core i7 CPU with 8 GB RAM (at least some of us :-) ) and never realize, that users can have slow machine, which reacts differently . And for that tiny moment you would need slow computer, just to see how it works and whether you can break it. But how to achieve this? The QA team does that by creating a virtual machine and setting it very low resources, so it acts very slow. Another option is to use some kind of CPU killer – those are great pieces of software, doing exactly what it sounds – killing your CPU. There are tons of complete solutions out there, but I didn’t want to deal with the licensing and our IT stuff yelling at me, what is that software that I installed by myself again. So I decided to break the rule “ Don’t reinvent the wheel ” again. Requirements At first, here is a list ...

Using JavaFX with Maven

JavaFX is exciting new framework from Oracle, which should replace Swing one day. But unfortunatelly it is not added to Java classpath, so we need to add it manually. And because I use Maven for all my projects (right now experimenting Gradle) we want to add it as a Maven dependency.  But javaFX jar is not in any public maven repository, thus we have to install it manually to local repository. This command does the installation: mvn install:install-file -Dfile=jfxrt.jar -DgroupId=com.oracle -DartifactId=javafx -Dversion=2.2.3 -Dpackaging=jar The command was executed in the directory, where the file  jfxrt.jar  is located (on Windows the path would be something like  c:\Program Files\Java\jdk1.7.0_09\jre\lib ) otherwise the full path has to be supplied. Latest version of JavaFX runtime is 2.2.3 (included in JDK 7u9) Once the installation is done, we can use regular maven dependency attribute: <dependency> <groupId>com.oracle</g...

Checking internet connection and connection to a particular server in Java

In AgroSense we need to know, if the computer is connected to the internet or not. And we don’t want to bother the user by throwing UnknownHostException or IOException also. So we need two things: Check the connection Notify everybody interested, that the connectivity changed When the first point is successfully implemented, the second one is easy – it is just a listener, so we will look only at the connectivity check problem. Solution For checking internet connectivity you need some host address. You will probably use the address, which you actually call, in our case it is www.openstreetmap.org. In first step, we check, if there is some internet connection, this is done in a method isOnlineFastCheck: private boolean isOnlineFastCheck() {         boolean check = false;         try {             InetAddress.getByName(hostName);             check = true;     ...