[SOLVED] I get a NullPointerException when switching from the default rendering technique to JavaFX 2D

Hi everyone,

I have a huge code of about 4000 lines, which works fine, except for the rendering speed. For this reason, I decided to switch from the default rendering technique to JavaFX 2D. I downloaded the library and imported it:
import processing.javafx.*;

Then modified the size() in the setup():

void setup() {
size(1820,660,FX2D); 
frameRate(100);
.
.
.
}

When I run my program, as usual, the following window appears, where I have to write my name, and then press ‘enter’.


However, when I press ‘enter’, I get a very long NullPointerException:

NullPointerException
NullPointerException
java.lang.NullPointerException: Cannot invoke "String.hashCode()" because "this.name" is null
	at processing.javafx.PGraphicsFX2D$FontCache$Key.hashCode(Unknown Source)
	at java.base/java.util.HashMap.hash(HashMap.java:338)
	at java.base/java.util.HashMap.getNode(HashMap.java:568)
	at java.base/java.util.LinkedHashMap.get(LinkedHashMap.java:441)
	at processing.javafx.PGraphicsFX2D$FontCache.get(Unknown Source)
	at processing.javafx.PGraphicsFX2D.handleTextFont(Unknown Source)
	at processing.javafx.PGraphicsFX2D.textFontImpl(Unknown Source)
	at processing.core.PGraphics.textFont(PGraphics.java:4385)
	at controlP5.ControlFont.adjust(Unknown Source)
	at controlP5.Label$SinglelineLabel.draw(Unknown Source)
	at controlP5.Label$SinglelineLabel.draw(Unknown Source)
	at controlP5.Label.draw(Unknown Source)
	at controlP5.Button$ButtonView.display(Unknown Source)
	at controlP5.Button$ButtonView.display(Unknown Source)
	at controlP5.Controller.draw(Unknown Source)
	at controlP5.ControllerGroup.drawControllers(Unknown Source)
	at controlP5.ControllerGroup.draw(Unknown Source)
	at controlP5.ControlWindow.draw(Unknown Source)
	at controlP5.ControlWindow.draw(Unknown Source)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:568)
	at processing.core.PApplet$RegisteredMethods.handle(PApplet.java:1309)
	at processing.core.PApplet.handleMethods(PApplet.java:1456)
	at processing.core.PApplet.handleDraw(PApplet.java:2106)
	at processing.javafx.PSurfaceFX$1.handle(Unknown Source)
	at processing.javafx.PSurfaceFX$1.handle(Unknown Source)
	at javafx.graphics/com.sun.scenario.animation.shared.TimelineClipCore.visitKeyFrame(TimelineClipCore.java:239)
	at javafx.graphics/com.sun.scenario.animation.shared.TimelineClipCore.playTo(TimelineClipCore.java:197)
	at javafx.graphics/javafx.animation.Timeline.doPlayTo(Timeline.java:172)
	at javafx.graphics/javafx.animation.AnimationAccessorImpl.playTo(AnimationAccessorImpl.java:39)
	at javafx.graphics/com.sun.scenario.animation.shared.InfiniteClipEnvelope.timePulse(InfiniteClipEnvelope.java:120)
	at javafx.graphics/javafx.animation.Animation.doTimePulse(Animation.java:1189)
	at javafx.graphics/javafx.animation.Animation$1.lambda$timePulse$0(Animation.java:207)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at javafx.graphics/javafx.animation.Animation$1.timePulse(Animation.java:206)
	at javafx.graphics/com.sun.scenario.animation.AbstractPrimaryTimer.timePulseImpl(AbstractPrimaryTimer.java:343)
	at javafx.graphics/com.sun.scenario.animation.AbstractPrimaryTimer$MainLoop.run(AbstractPrimaryTimer.java:266)
	at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:571)
	at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulse(QuantumToolkit.java:555)
	at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.pulseFromQueue(QuantumToolkit.java:548)
	at javafx.graphics/com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$11(QuantumToolkit.java:353)
	at javafx.graphics/com.sun.glass.ui.InvokeLaterDispatcher$Future.run(InvokeLaterDispatcher.java:96)
	at javafx.graphics/com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
	at javafx.graphics/com.sun.glass.ui.win.WinApplication.lambda$runLoop$3(WinApplication.java:184)
	at java.base/java.lang.Thread.run(Thread.java:833)
NullPointerException

When I go back to the default renderer by removing FX2D from size(), everything works again…

Does anyone have an idea of what the problem could be?

Thanks in advance!

Hello @MrImskiy,

You must add the JavaFX library with Processing 4.3:

Test with String.hashCode():

Important topic related to JavaFX:

:)

Thanks for your reply @glv !

I have no issue with adding and importing the library, and your test code works fine as well, so the problem is somewhere else… :confused:

Maybe…

You will sort it out!

:)

I have tried P2D, which made the rendering faster, but not as fast as needed. That’s why I wanted to test FX2D.

Focus on this:

java.lang.NullPointerException: Cannot invoke "String.hashCode()" because "this.name" is null

Lots of good stuff here including NullPointerException:

:)

Thanks @glv, I will give it a read :slight_smile:

I found the error. The problem lies with my cp5 initializations, which is done in the void keyPressed() section:

void keyPressed() {
  cp5 = new ControlP5(this);
  cp5.addButton("open");
  cp5.addButton("closePort");
  cp5.addButton("refresh");
  cp5.addScrollableList("comlist").close();
  String list[] = Serial.list();
  cp5.get(ScrollableList.class, "comlist").addItems(list);
    
  MyController = new ControlP5(this);
  MyController.addSlider("K_factor",0,30,1,slider_K_X,slider_K_Y,slider_W,slider_H); 
  MyController.addSlider("tau_I",0,10,0,slider_tau_I_X,slider_tau_I_Y,slider_W,slider_H);
  MyController.addSlider("tau_D",0,10,0,slider_tau_D_X,slider_tau_D_Y,slider_W,slider_H);
  MyController.addSlider("DB",0,1,0,slider_DB_X,slider_DB_Y,slider_W,slider_H);
}

This works perfectly when using the default renderer. But, when I use the JavaFX 2D renderer, that’s when I get the NPE.

So, when I put these initialization lines of code in comment (while JavaFX 2D is on), my program works again, and does not show a NPE.

Then I thought that, maybe if I initialize these cp5 objects in the setup() section instead of the keypressed() section it will work. But, when I do this, I get a NPE again…

[SOLUTION]

I found a solution for this problem on github:

In the case of using the FX2D renderer, controlP5’s BitFont can’t be rendered and by attempting to do so the above error message is caused. To work around this, set the font to a non-BitFont by calling cp5.setFont(createFont("Arial",10)); right after creating an instance of cp5.

1 Like