我正在为家庭作业开发一个名为Namesurfer的Java程序。该程序包含五个类:'NameSurfer,NameSurferConstants,NameSurferDataBase,NameSurferEntry和NameSurferGraph。
代码已经完成(我认为),但是当我在NameSurfer控制台上输入名称并按Enter时,出现以下错误。当我单击“图形”时,它什么也没做。

我怀疑它与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) { }

}

最佳答案

您的“数据库”似乎为空。

请注意,您要么提供了不完整的NameSurfer源,要么需要重新编译您的应用程序-行号不可用,行58仅带有一个大括号。

07-24 21:07