[英]Why am I getting this NullPointerException?
我不知道這個。 使用新的Canvas()初始化Canvas之后,對其進行引用將導致NullPointerException。 該文檔告訴我,當“畫布”未“啟用”時會發生這種情況,但是我不知道啟用它意味着什么。 我試圖通過包括while(!cvs.isEnabled());來調試它。 但程序剛剛掛起。 哪些情況可能導致無法啟用Canvas,我該如何解決?
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()
}
}
我已經有一段時間沒有使用Swing了,但是嘗試在調用get圖形之前將畫布添加到Panel中(該面板也應該具有某種形式的布局)。 您可以在此處找到一個有趣的教程: http : //docs.oracle.com/javase/tutorial/uiswing/ “要在屏幕上顯示,每個GUI組件都必須是容器層次結構的一部分。容器層次結構是具有以下內容的組件樹以頂級容器為根。我們將向您展示一個。” 因此,我認為實例化canvas類是不夠的。 僅在將圖形對象添加到頂層容器后,才將其分配給您的畫布對象。
在組件無法顯示之前,其圖形將為空。 這是一個真正的麻煩,因為沒有沒有Graphics
訪問FontMetrics
簡便方法。
我知道幾種解決方案:
如果只需要線條高度,則Font.getLineMetrics()
就足夠了。
Toolkit.getDefaultToolkit().getFontMetrics(Font)
可以使用,但已棄用。
一個不建議使用但不必要的繞行解決方案是創建BufferedImage
並獲取其Graphics
。
編輯:
實際上,從1.5開始,您可以執行cvs.getFontMetrics(DEFAULT_FONT)
。 我不敢相信我以前從未注意到過!
您可能首先不應該使用Canvas。 這是一個舊的AWT類。 如果使用的是JFrame,則使用的是Swing。 如果要繪制某些東西:子類JComponent,請重寫paintComponent,然后可以在其中放置繪圖代碼。 我的猜測是getGraphics()返回null,因為它沒有附加到父級。 您可能必須等到以后才能訪問Graphics對象,就像顯示它一樣。
您不是應該先將Canvas添加到JFrame嗎?
cvs = new Canvas();
getContentPane().add(cvs);
someObject.getGraphics()在構造函數中的風險很高。 在這種情況下,可能由於尚未顯示。 我建議在col上使用惰性實例化。 只需編寫一個getter來檢查它是否已被分配:
public Graphics getCol() {
if (col == null) {
col = cvs.getGraphics();
}
return col;
}
這樣,您應該在第一次需要它時就獲得Graphics對象。 作為額外的保障,您可以檢查分配是否成功,如果為空(即快速失敗),則拋出未經檢查的異常。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.