We closed this forum 18 June 2010. It has served us well since 2005 as the ALPHA forum did before it from 2002 to 2005. New discussions are ongoing at the new URL http://forum.processing.org. You'll need to sign up and get a new user account. We're sorry about that inconvenience, but we think it's better in the long run. The content on this forum will remain online.
IndexProgramming Questions & HelpPrograms › A null PFont was passed to textFont()
Page Index Toggle Pages: 1
A null PFont was passed to textFont() (Read 1248 times)
A null PFont was passed to textFont()
Jan 16th, 2010, 2:17am
 
Can anyone tell me what is wrong with this program:
Code:

/*
Serial String Reader
Language: Processing

Reads in a string of characters from a serial port until
it gets a linefeed (ASCII 10). Then splits the string into
sections separated by commas. Then converts the sections to ints,
and prints them out.
*/

import processing.serial.*; // import the Processing serial library

int linefeed = 10; // Linefeed in ASCII
Serial myPort; // The serial port
int sensor = 0;
int startPos = 100;
int graphPos = startPos;
int lastPos = height-10;
int vals[];
boolean firstTime = true;
int dMode = 1;
int lastReading = 2;

PFont myFont;
PFont myFont2;
int fontSize = 20;
int fontSize2 = 50;

void setup() {
size(1000, 400);

// List all the available serial ports
println(Serial.list());

// I know that the first port in the serial list on my mac
// is always my Arduino module, so I open Serial.list()[0].
// Change the 0 to the appropriate number of the serial port
// that your microcontroller is attached to.
myPort = new Serial(this, Serial.list()[0], 9600);

// read bytes into a buffer until you get a linefeed (ASCII 10):
myPort.bufferUntil(linefeed);

vals = new int[width + 20];

PFont myFont = createFont(PFont.list()[2], fontSize);
textFont(myFont);

background(0);
stroke(255,255,255);
line(startPos-5, height, startPos-5, 49);

line(startPos-5, 49, startPos-10, 49);
text("5v", startPos-12-fontSize, 49+fontSize/2);

line(startPos-5, height-(816/3+10), startPos-10, height-(816/3+10));
text("4v", startPos-12-fontSize, (height-(816/3+10))-(fontSize/4));

line(startPos-5, height-(612/3+10), startPos-10, height-(612/3+10));
text("3v", startPos-12-fontSize, (height-(612/3+10))-(fontSize/4));

line(startPos-5, height-(408/3+10), startPos-10, height-(408/3+10));
text("2v", startPos-12-fontSize, (height-(408/3+10))-(fontSize/4));

line(startPos-5, height-(204/3+10), startPos-10, height-(204/3+10));
text("1v", startPos-12-fontSize, (height-(204/3+10))-(fontSize/4));

line(startPos-5, 390, startPos-10, 390);
text("0v", startPos-12-fontSize, 390-fontSize/4);
}

void draw() {
// twiddle your thumbs
}

// serialEvent method is run automatically by the Processing applet
// whenever the buffer reaches the byte value set in the bufferUntil()
// method in the setup():

void serialEvent(Serial myPort) {
// read the serial buffer:
String myString = myPort.readStringUntil(linefeed);

// if you got any bytes other than the linefeed:
if (myString != null) {

myString = trim(myString);

sensor = int(myString);
print(sensor*0.0048828125);
}
// add a linefeed after all the sensor values are printed:
println();
if(dMode == 1){
drawVom();
}else if(dMode == 2){
drawGraph();
}
}

void drawGraph(){
int lineHeight = sensor/3 + 10;

//println(height-lineHeight);
if(firstTime){
firstTime = false;
vals[graphPos] = lineHeight;
}
else if(graphPos == startPos){
stroke(255,255,255);
line(startPos-5, height, startPos-5, 49);

line(startPos-5, 49, startPos-10, 49);
text("5v", startPos-12-fontSize, 49+fontSize/2);

line(startPos-5, height-(816/3+10), startPos-10, height-(816/3+10));
text("4v", startPos-12-fontSize, (height-(816/3+10))-(fontSize/4));

line(startPos-5, height-(612/3+10), startPos-10, height-(612/3+10));
text("3v", startPos-12-fontSize, (height-(612/3+10))-(fontSize/4));

line(startPos-5, height-(408/3+10), startPos-10, height-(408/3+10));
text("2v", startPos-12-fontSize, (height-(408/3+10))-(fontSize/4));

line(startPos-5, height-(204/3+10), startPos-10, height-(204/3+10));
text("1v", startPos-12-fontSize, (height-(204/3+10))-(fontSize/4));

line(startPos-5, 390, startPos-10, 390);
text("0v", startPos-12-fontSize, 390-fontSize/4);
vals[graphPos] = lastPos;
graphPos++;
}
vals[graphPos] = height-lineHeight;

stroke(255, 0, 0);

line(graphPos, vals[graphPos-1], graphPos, height-lineHeight);

if(graphPos >= width){
graphPos = startPos;
lastPos = height-lineHeight;
background(0);
}
else{
graphPos++;
}
}

void drawVom(){
if(lastReading != sensor){
background(0);
stroke(255,255,255);
PFont myFont2 = createFont(PFont.list()[2], fontSize2);
textFont(myFont2);
text(str(sensor*0.0048828125), width/2-fontSize2/2, height/2-fontSize2/2);
textFont(myFont);
}
}

when run it outputs:
Code:

error, disabling serialEvent() for /dev/ttyUSB0
java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at processing.serial.Serial.serialEvent(Serial.java:235)
at gnu.io.RXTXPort.sendEvent(RXTXPort.java:732)
at gnu.io.RXTXPort.eventLoop(Native Method)
at gnu.io.RXTXPort$MonitorThread.run(RXTXPort.java:1575)
Caused by: java.lang.RuntimeException: A null PFont was passed to textFont()
at processing.core.PGraphics.textFont(PGraphics.java:2476)
at processing.core.PApplet.textFont(PApplet.java:7346)
at processing_serial_input_graph_pde.drawVom(processing_serial_input_graph_pde.java:174)
at processing_serial_input_graph_pde.serialEvent(processing_serial_input_graph_pde.java:113)
... 8 more
Re: A null PFont was passed to textFont()
Reply #1 - Jan 16th, 2010, 3:42am
 
You should move the font2 creation to setup as well
just to test it write :
   PFont myFont = createFont("Arial", 12);
   PFont myFont2 = createFont("Arial", 12);

and see if it still throws an error
Re: A null PFont was passed to textFont()
Reply #2 - Jan 16th, 2010, 4:34am
 
When I tried this it gave the same error message

BTW: Sorry for the double post -- when I posted the first time it gave an error , I didn't know it had still posted it
Re: A null PFont was passed to textFont()
Reply #3 - Jan 16th, 2010, 4:51am
 
About the double-post: you can delete your extra message yourself. Apparently, that's a common glitch in the forum (even if I haven't experienced it myself).

About your fonts:
- First remark: you declare fonts at global level, but actually never use them! Not really a problem in this code, but it might bite you some day, so I prefer to warn. The PFont myFont2 = createFont(PFont.list()[2], fontSize2); line, for example, creates a new myFont2 variable, local to the current block (delimited by soft braces {}), hiding the global variable. It works because it only has to live the time to reach textFont() call... Smiley
- Second remark: I suggest you create a global font variable where you store PFont.list()[2] (assign it in setup()). I think PFont.list() is time consuming (particularly if you have lot of fonts on your system), so you better make it only once.

Ah, I finally found out your issue. It wasn't with textFont(myFont2), which is fine, as I wrote, but with textFont(myFont) just below. As explained above, myFont is there the global variable, that haven't been initialized, because it have been masked by the local variable in setup().

So, as Cedric advised, put the two font loading in setup(), except it should be:
Code:
String fontList = PFont.list();
myFont = createFont(fontList[2], fontSize);
myFont2 = createFont(fontList[2], fontSize2);

ie. without re-declaring the variables.
Re: A null PFont was passed to textFont()
Reply #4 - Jan 16th, 2010, 5:07am
 
Thanks
Page Index Toggle Pages: 1