Working with NetBeans 7.3 and JavaFX 8

Maybe you want to work with the latest version of NetBeans, currently 7.3. But also with the early access of JDK 8 in order to play with the latest features of JavaFX. The thing is that NetBeans will not launch your JavaFX application, even if you are using JDK 7. Indeed you will get an exception dealing with Nashorn.

java.lang.VerifyError: Code generation bug in "runScript": likely stack misaligned: java.lang.ArrayIndexOutOfBoundsException: 0 <eval>
	at jdk.nashorn.internal.codegen.CodeGenerator.leave(CodeGenerator.java:1003)
	at jdk.nashorn.internal.ir.FunctionNode.accept(FunctionNode.java:339)
	at jdk.nashorn.internal.codegen.CompilationPhase$7.transform(CompilationPhase.java:239)
	at jdk.nashorn.internal.codegen.CompilationPhase.apply(CompilationPhase.java:372)
	at jdk.nashorn.internal.codegen.Compiler.compile(Compiler.java:263)
	at jdk.nashorn.internal.runtime.Context.compile(Context.java:758)
	at jdk.nashorn.internal.runtime.Context.compileScript(Context.java:720)
	at jdk.nashorn.internal.runtime.Context.compileScript(Context.java:358)
	at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:463)
	at jdk.nashorn.api.scripting.NashornScriptEngine.compileImpl(NashornScriptEngine.java:451)
	at jdk.nashorn.api.scripting.NashornScriptEngine.evalImpl(NashornScriptEngine.java:379)
	at jdk.nashorn.api.scripting.NashornScriptEngine.eval(NashornScriptEngine.java:134)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:487)
	at org.apache.tools.ant.util.ReflectUtil.invoke(ReflectUtil.java:108)
	at org.apache.tools.ant.util.ReflectWrapper.invoke(ReflectWrapper.java:81)
	at org.apache.tools.ant.util.optional.JavaxScriptRunner.evaluateScript(JavaxScriptRunner.java:103)
	at org.apache.tools.ant.util.optional.JavaxScriptRunner.executeScript(JavaxScriptRunner.java:67)
	at org.apache.tools.ant.taskdefs.optional.Script.execute(Script.java:52)
	at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
	at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:487)
	at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
	at org.apache.tools.ant.Task.perform(Task.java:348)
	at org.apache.tools.ant.taskdefs.Sequential.execute(Sequential.java:68)
	at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
	at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:487)
	at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
	at org.apache.tools.ant.Task.perform(Task.java:348)
	at org.apache.tools.ant.taskdefs.MacroInstance.execute(MacroInstance.java:398)
	at org.apache.tools.ant.UnknownElement.execute(UnknownElement.java:291)
	at sun.reflect.GeneratedMethodAccessor74.invoke(Unknown Source)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:487)
	at org.apache.tools.ant.dispatch.DispatchUtils.execute(DispatchUtils.java:106)
	at org.apache.tools.ant.Task.perform(Task.java:348)
	at org.apache.tools.ant.Target.execute(Target.java:392)
	at org.apache.tools.ant.Target.performTasks(Target.java:413)
	at org.apache.tools.ant.Project.executeSortedTargets(Project.java:1399)
	at org.apache.tools.ant.Project.executeTarget(Project.java:1368)
	at org.apache.tools.ant.helper.DefaultExecutor.executeTargets(DefaultExecutor.java:41)
	at org.apache.tools.ant.Project.executeTargets(Project.java:1251)
	at org.apache.tools.ant.module.bridge.impl.BridgeImpl.run(BridgeImpl.java:283)
	at org.apache.tools.ant.module.run.TargetExecutor.run(TargetExecutor.java:541)
	at org.netbeans.core.execution.RunClassThread.run(RunClassThread.java:153)
Caused by: java.lang.ArrayIndexOutOfBoundsException: 0
	at jdk.internal.org.objectweb.asm.Frame.merge(Frame.java:1408)
	at jdk.internal.org.objectweb.asm.Frame.merge(Frame.java:1364)
	at jdk.internal.org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1382)
	at jdk.nashorn.internal.codegen.MethodEmitter.end(MethodEmitter.java:198)
	at jdk.nashorn.internal.codegen.CodeGenerator.leave(CodeGenerator.java:1000)
	... 50 more

The problem is that NetBeans uses the most recent JDK installed on your machine to run itself. And if you look in the About NetBeans menu entry, you will see that it uses the JDK 8 if it is installed, even if your JAVA_HOME points to your JDK 7 installation.

NB_JDK7

But there is a little workaround to get things working again: you can specify, in a configuration file of NetBeans, which JDK it should use. On OSX, show the package content of NetBeans 7.3.app and go to Content > Resources > NetBeans &gt etc and open the file netbeans.cnf. In this file, locate the line containing netbeans_jdkhome and uncomment it and specify the JDK home you want NetBeans to use. For example:

netbeans_jdkhome="/Library/Java/JavaVirtualMachines/Current/Contents/Home"

Then just restart NetBeans and go the About NetBeans menu entry. You should see that your JDK 7 installation instead of JDK 8.

NB_JDK8

Now if you try to launch your JavaFX application, everything is working again.

Set custom font in JavaFX 2

Maybe you would like to set custom fonts to your application for various reasons: make it touchy, be compliant with your corporation with corporate font, and so on. In JavaFX it’s pretty easy to change the font of a component. You can use the Labeled#setFont(Font f) method in your code, or define the -fx-font-family in your CSS. But what about custom fonts?

Load the font

The first thing you have to do is load the font. This is done like this:

Font.loadFont(SomeApp.class.getResource("/com/twasyl/someapp/font/MyFONT.TTF").toExternalForm(), 12);

This loads your font, which has a family, let’s say Thierry Font. This method makes the font available in your graphics environment and you just have to use it whenever you want. I like to place this code in my Application class, especially in the init method, so the I’m sure the font is loaded before any other treatment (especially before any labeled element is rendered). Let’s write this code:

public class SomeApp extends Application {

  @Override
  public void start(Stage stage) throws Exception {
    // Do some stuff
  }

  @Override
  public void init() throws Exception {
    super.init();

    Font.loadFont(SomeApp.class.getResource("/com/twasyl/someapp/font/MyFONT.TTF").toExternalForm(), 12);
  }

  public static void main(String[] args) {
      SomeApp.launch(args);
  }
}

Use your custom font

Punctual use

Either in your FXML or CSS code, you can now define the -fx-font-family with the value Thierry Font.

<Label style="-fx-font-family: 'Thierry Font'" />

This label will use the font, but what about the others elements? Do I really have to do this on ALL elements? Of course not …

General use

The interesting part is you can define your font for the whole application by default. Indeed in your CSS you just have to do this:

.root {
  -fx-font-family: 'Thierry Font';
  -fx-font-size: 15pt;
}

By default every labeled element will use your custom font. And of course you can change the font for a particular label again, using the style attribute for example.

DrawFX – the text tool

It hasn’t be an easy task to add a text tool, but I finally did it. The tool is actually a simple text area (with some customization for hiding the scroll bars) placed into a panel with some buttons (valid and cancel). The tool is not draggable and has the following options:
– Bold
– Italic
– Underline (a bit tricky to make that one work. A solution is proposed here but I used something else)
– Size for the text
– Change the font by using fonts on your system

It is also possible to resize the text area by simply drag the mouse anywhere. Below is a little demo.

DrawFX – this is JaaavaaaFX

DrawFX has made some good progress these days. A lot of new features/improvements have been implemented like:

  • Priority for tasks: tasks now have a priority which can be LOW, NORMAL and HIGH. The colour of each sticky accords the task’s priority: green for LOW, yellow for NORMAL and orange for HIGH ;
  • It is possible to have multiple layers
  • A “Pen” tool has been added. It draws a line (composed of squares) while the mouse is dragged. The thickness can be modified using a slider ;
  • A “Rectangle” tool has been added in order to draw rectangles. The stroke’s color is the primary color, the fill’s color the secondary one. The width of the stroke can be changed using a slider ;
  • An “Ellipse” tool has been added in order to draw ellipses. The stroke’s color is the primary color, the fill’s color the secondary one. The width of the stroke can be changed using a slider ;
  • A “Shape” tool has been added in order to draw polygons. One click with the primary mouse’s button in the drawing area draws a line between the current click’s location and the previous one, while a double click closes the polygon. The stroke’s color is the primary color, the fill’s color the secondary one. The width of the stroke can be changed using a slider ;
  • A “Move” tool has been added and allows to move a layer ;
  • The “Eraser” tool now have a width and height properties ;
  • The “Bucket” tool is now able to only fill an area delimited by a bound color. For example you can change the color of a polygon by using this tool ;
  • The “Brush” tool has been improved. It now draws shapes defined by a SVG path. By default, the SVG path is a square, but can be changed to any valid path. In my screencast I use the path of a Java logo. It is also to possible to specify the scale X and Y to resize the shape represented by the path.

I still have some nice features left in my mind.

DrawFX – What you draw is what you attach

Some have guessed what I’m developing: a kind of agile board in JavaFX. Well the thing is when I have a team meeting, where we discuss about functionalities, improvements, etc, sometimes I just want to draw something to explain what I understand, what could be done and so on. Sometimes a picture is better than thousand words… So I like to draw… For DrawFX I had this idea: why not give the possibility to the user to draw his ideas and then create a task and attach the content of the drawing board to the task? And that what I did.

I still have a lot of ideas, and here it’s just a first and basic implementation, but more is to come! Here are some screenshots and a screencast.
DrawFX_01

DrawFX02

DrawFX – early task board screencast

A screencast for an early version of a task board … So for now we have a basic task board and a basic drawing board … All done in JavaFX, and it’s not going to change … More to come …

DrawFX – early stage screencast

Here is a little screencast of the really early stage of DrawFX … Teasing …