I can’t figure this out. After initializing a Canvas with new Canvas(), referencing it results in a NullPointerException. The doc tells me this can occur when the Canvas is not “enabled”, but I don’t know what it means to be enabled. I tried to debug it by including while(! cvs.isEnabled()); but the program just hung. What are the conditions that could result in a Canvas not being enabled, and how do I fix them?
Exception in thread "main" java.lang.NullPointerException
at matt.io.ConsoleCanvas.<init>(ConsoleCanvas.java:72)
at matt.io.ConsoleCanvas.<init>(ConsoleCanvas.java:51)
at matt.io.ConsoleCanvas.main(ConsoleCanvas.java:32)
public class ConsoleCanvas extends JFrame
{
private static final Font DEFAULT_FONT = new Font("Monospaced", Font.PLAIN, 12);
public static void main(String[] args)
{
ConsoleCanvas me = new ConsoleCanvas(); //ConsoleCanvas.java:32
//Program has crashed by this point, so rest of main removed to be concise
}
protected JTextField in;
private Canvas cvs;
private int row;
private int col;
public ConsoleCanvas()
{
this("Console Pane", 80, 10); //ConsoleCanvas.java:51
}
public ConsoleCanvas(String title, int rows, int cols)
{
in = new JTextField();
in.setEditable(true);
in.setFont(DEFAULT_FONT);
in.setColumns(cols);
cvs = new Canvas();
cvs.setSize(in.getWidth(), in.getHeight() * rows);
cvs.setFont(DEFAULT_FONT);
row = 0;
col = cvs.getGraphics().getFontMetrics().getHeight(); //ConsoleCanvas.java:72
//Program crashes at this line, so I'll leave out the rest for brevity again
//I've isolated the null to the Graphics returned by cvs.getGraphics()
}
}
I didn’t work with swing for quite some time, but try adding the canvas to a Panel before calling get graphics (the panel should also have some form of layout).
You can find an interesting tutorial here : http://docs.oracle.com/javase/tutorial/uiswing/
“To appear onscreen, every GUI component must be part of a containment hierarchy. A containment hierarchy is a tree of components that has a top-level container as its root. We’ll show you one in a bit.” So I think that instantiating the canvas class is not enough. The graphics object is assigned to your canvas object only after you add it to a top-level container.