2013-05-29 41 views
0

我正在爲一個家庭分配調用名爲「命名」的Java程序。該程序由五個類組成:NameSurfer,NameSurferConstants,NameSurferDataBase,NameSurferEntry和NameSurferGraph。 代碼是(我認爲)完成,但是當我將名稱放在NameSurfer控制檯上並按下Enter時,出現以下錯誤。當我點擊圖表時,它什麼都不做。Eclipse錯誤:線程「AWT-EventQueue-0」中的異常java.lang.NullPointerException

我懷疑它與NameSurferEntry類有關,但我一直在尋找幾個小時沒有成功。我真的是Java的新手,任何幫助將不勝感激。

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
at NameSurfer.actionPerformed(NameSurfer.java:58) 
at javax.swing.JTextField.fireActionPerformed(JTextField.java:492) 
at javax.swing.JTextField.postActionEvent(JTextField.java:705) 
at javax.swing.JTextField$NotifyAction.actionPerformed(JTextField.java:820) 
at javax.swing.SwingUtilities.notifyAction(SwingUtilities.java:1645) 
at javax.swing.JComponent.processKeyBinding(JComponent.java:2859) 
at javax.swing.JComponent.processKeyBindings(JComponent.java:2894) 
at javax.swing.JComponent.processKeyEvent(JComponent.java:2822) 
at java.awt.Component.processEvent(Component.java:6159) 
at java.awt.Container.processEvent(Container.java:2083) 
at java.awt.Component.dispatchEventImpl(Component.java:4744) 
at java.awt.Container.dispatchEventImpl(Container.java:2141) 
at java.awt.Component.dispatchEvent(Component.java:4572) 
at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1856) 
at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:722) 
at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1000) 
at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:865) 
at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:686) 
at java.awt.Component.dispatchEventImpl(Component.java:4616) 
at java.awt.Container.dispatchEventImpl(Container.java:2141) 
at java.awt.Window.dispatchEventImpl(Window.java:2489) 
at java.awt.Component.dispatchEvent(Component.java:4572) 
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:710) 
at java.awt.EventQueue.access$400(EventQueue.java:82) 
at java.awt.EventQueue$2.run(EventQueue.java:669) 
at java.awt.EventQueue$2.run(EventQueue.java:667) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87) 
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:98) 
at java.awt.EventQueue$3.run(EventQueue.java:683) 
at java.awt.EventQueue$3.run(EventQueue.java:681) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.security.AccessControlContext$1.doIntersectionPrivilege(AccessControlContext.java:87) 
at java.awt.EventQueue.dispatchEvent(EventQueue.java:680) 
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:296) 
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:211) 
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:201) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:196) 
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:188) 
at java.awt.EventDispatchThread.run(EventDispatchThread.java:122) 

以下是NameSurfer的代碼。

/* 
* File: NameSurfer.java 
* --------------------- 
* When it is finished, this program will implements the viewer for 
* the baby-name database described in the assignment handout. 
*/ 

import acm.program.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class NameSurfer extends Program implements NameSurferConstants { 

/* private instance variables*/ 
private JButton graphButton; 
private JButton clearButton; 
private JLabel nameLabel; 
private JTextField name; 
private NameSurferGraph graph; 
private NameSurferDataBase dataBase; 

/** 
* This method has the responsibility for reading in the data base 
* and initializing the interactors at the top of the window. 
*/ 
public void init() { 
    addActionListeners(); 
    graph = new NameSurferGraph(); 
    add(graph); 

    /* adds the control bar*/ 
    nameLabel = new JLabel ("Name"); 
    add(nameLabel, NORTH); 

    name = new JTextField(MAX_FONT_NAME); 
    name.addActionListener(this); 
    add(name, NORTH); 

    graphButton = new JButton ("Graph"); 
    add(graphButton, NORTH); 

    clearButton = new JButton ("Clear"); 
    add(clearButton, NORTH); 


} 

/** 
* This class is responsible for detecting when the buttons are 
* clicked, so you will have to define a method to respond to 
* button actions. 
*/ 
public void actionPerformed(ActionEvent e) { 

    if (e.getActionCommand().equals ("Clear")) { 
     graph.clear(); 
     graph.update(); 
    } else { 
     String inputName = name.getText(); 
     NameSurferEntry entry = dataBase.findEntry(inputName); 
     if (entry != null) { 
      graph.addEntry(entry); 
      graph.update(); 
     } 
    } 
} 
} 

這裏是NameSurferEntry的代碼。

/* 
* File: NameSurferEntry.java 
* -------------------------- 
* This class represents a single entry in the database. Each 
* NameSurferEntry contains a name and a list giving the popularity 
* of that name for each decade stretching back to 1900. 
*/ 

import acm.util.*; 
import java.util.*; 
import java.util.StringTokenizer; 

public class NameSurferEntry implements NameSurferConstants { 

/* private instance variables*/ 
private String name; 
private int[] ranks = new int [NDECADES]; 

/** 
* Creates a new NameSurferEntry from a data line as it appears 
* in the data file. Each line begins with the name, which is 
* followed by integers giving the rank of that name for each 
* decade. 
*/ 
public NameSurferEntry(String line) { 
    //gets the name 
    int nameEnd = line.indexOf(" "); 
    name = line.substring(0, nameEnd); 

    //gets the ranking and forms it into an array using StringTokenizer class 
    String rankingStart = line.substring(nameEnd + 1); 
    StringTokenizer tokenizer = new StringTokenizer(rankingStart); 
    for (int i = 0; tokenizer.hasMoreTokens(); i++) { 
      int yearRank = Integer.parseInt(tokenizer.nextToken()); 
      ranks[i] = yearRank; 
     } 

} 

/* Method: getName() */ 
/** 
* Returns the name associated with this entry. 
*/ 
public String getName() { 
    return name; 
} 

/* Method: getRank(decade) */ 
/** 
* Returns the rank associated with an entry for a particular 
* decade. The decade value is an integer indicating how many 
* decades have passed since the first year in the database, 
* which is given by the constant START_DECADE. If a name does 
* not appear in a decade, the rank value is 0. 
*/ 
public int getRank(int decade) { 
    if (decade <NDECADES) { 
    return ranks[decade]; 
    } 
    return 0; 
} 

/* Method: toString() */ 
/** 
* Returns a string that makes it easy to see the value of a 
* NameSurferEntry. 
*/ 
public String toString() { 
    String result = ""; 
    for (int i = 0; i < ranks.length; i++) { 
     result += getRank(i); 
    } 
    return ("\"" + name + "[" + result + "]\""); 
} 
} 

這裏是NameSurferGraph的代碼。

import acm.graphics.*; 
import java.awt.event.*; 
import java.util.*; 
import java.awt.*; 

public class NameSurferGraph extends GCanvas implements NameSurferConstants, ComponentListener { 

/*Private instance variables*/ 
private ArrayList <NameSurferEntry> dataDisplay; 

/** 
* Creates a new NameSurferGraph object that displays the data. 
*/ 
public NameSurferGraph() { 
    addComponentListener(this); 
    dataDisplay = new ArrayList<NameSurferEntry>(); 
} 

/** 
* Clears the list of name surfer entries stored inside this class. 
*/ 
public void clear() { 
    dataDisplay.clear(); 
    update(); 
} 

/** 
* Adds a new NameSurferEntry to the list of entries on the display. 
* Note that this method does not actually draw the graph, but 
* simply stores the entry; the graph is drawn by calling update. 
*/ 
public void addEntry(NameSurferEntry entry) { 
    dataDisplay.add(entry); 
} 


/** 
* Updates the display image by deleting all the graphical objects 
* from the canvas and then reassembling the display according to 
* the list of entries. Your application must call update after 
* calling either clear or addEntry; update is also called whenever 
* the size of the canvas changes. 
*/ 
public void update() { 
    removeAll(); 
    drawGraph(); 
    if (dataDisplay.size() >= 0) { 
     for (int i = 0; i < dataDisplay.size(); i++) { 
      NameSurferEntry entry = dataDisplay.get(i); 
      drawRankingGraph (entry, i); 
     } 
    } 
} 

/*draws the background grids and displays the years*/ 
private void drawGraph() { 
    drawMargins(); 
    drawVerticalLines(); 
    displayYears(); 
} 

/*Draws the horizontal lines at the top and the bottom of the window*/ 
private void drawMargins() { 
    double x1 = 0; 
    double x2 = getWidth(); 
    double y1 = GRAPH_MARGIN_SIZE; 
    double y2 = getHeight() - GRAPH_MARGIN_SIZE; 
    GLine topLine = new GLine (x1, y1, x2, y1); 
    GLine bottomLine = new GLine (x1, y2, x2, y2); 
    add(topLine); 
    add(bottomLine); 

} 

/*Draws the vertical lines*/ 
private void drawVerticalLines() { 
    double x = 0; 
    for (int i = 0; i < NDECADES; i++) { 
     GLine verticalLine = new GLine (x, 0, x, getHeight()); 
     x += getWidth()/NDECADES; 
     add(verticalLine); 
    } 
} 

/*Displays the years*/ 
private void displayYears() { 
    int decade = START_DECADE; 
    double x = 0; 
    for (int i = 0; i < NDECADES; i++) { 
     GLabel label = new GLabel ("" + decade); 
     add(label, x, getHeight() - GRAPH_MARGIN_SIZE/2 + (label.getAscent()/2)); 
     decade += NUMBER_OF_YEARS; 
     x += getWidth()/NDECADES; 
    } 
} 

/*Draws the ranking graph and the input name label*/ 
private void drawRankingGraph(NameSurferEntry entry, int n) { 
    int inputOrder = n; 
    for (int i = 0; i < NDECADES - 1; i++) { 
     int r1 = entry.getRank(i); 
     int r2 = entry.getRank(i + 1); 

     double x1 = i * (getWidth()/NDECADES); 
     double x2 = (i+1) * (getWidth()/NDECADES); 
     double y1 = 0; 
     double y2 = 0; 
     if (r1 == 0) { 
      y1 = getHeight() - GRAPH_MARGIN_SIZE; 
     } else { 
      y1 = GRAPH_MARGIN_SIZE + (getHeight() - GRAPH_MARGIN_SIZE*2) * r1/MAX_RANK; 
     } 
     if (r2 == 0) { 
      y2 = getHeight() - GRAPH_MARGIN_SIZE; 
     } else { 
      y2 = GRAPH_MARGIN_SIZE + (getHeight() - GRAPH_MARGIN_SIZE*2) * r2/MAX_RANK; 
     } 

     /*Sets the graph and the label on the window*/ 
     GLine rankingGraph = new GLine (x1, y1, x2, y2); 
     GLabel inputName = new GLabel(entry.getName() + " " + (entry.getRank(i) == 0 ? "*" : entry.getRank(i))); 

     /*Sets the color*/ 
     Color color = getColor(inputOrder%4); 
     rankingGraph.setColor(color); 
     inputName.setColor(color); 

     /*Displays the graph and the label*/ 
     add(rankingGraph); 
     add(inputName, x1, y2); 
    } 
} 

/*Gets the color of the rankingGraph and the inputName label*/ 
private Color getColor(int i) { 
    switch (i) { 
    case 0: return Color.black; 
    case 1: return Color.red; 
    case 2: return Color.blue; 
    } 
    return Color.magenta; 
} 


/* Implementation of the ComponentListener interface */ 
public void componentHidden(ComponentEvent e) { } 
public void componentMoved(ComponentEvent e) { } 
public void componentResized(ComponentEvent e) { update(); } 
public void componentShown(ComponentEvent e) { } 

} 
+2

tl; dr,其中「NameSurfer」類正好是第58行? – fge

回答

0

檢查「actionPerformed」方法的用法。你可能試圖在未設置的東西上使用它,因此「null」。

1

您的「數據庫」似乎爲空。

請注意,您要麼提供不完整的NameSurfer源代碼,要麼需要重新編譯應用程序 - 行號已關閉,第58行只有一個右大括號。

+0

我重新編譯了它。如果你能看一看就會很棒。謝謝! –

+0

'NameSurfer.java:58'line is'} else {'now - 它沒有任何意義。堆棧跟蹤與您發佈的源代碼仍然不同步。從代碼檢查,我沒有看到你在哪裏設置字段dataBase。實際的NPE是否可以從第60行開始('dataBase.findEntry(inputName);')? – Eugene

0

您正在對NameSurfer.java:58爲空的對象調用方法。找出那條線上什麼可以是空的,並找出爲什麼它是空的,即使你期望它不是。

與此無關,請閱讀Java命名約定。只有你的類型名稱應該以大寫字母開頭。

相關問題