title: JAVA: Constructing a graph with DrawingPanel.java (provided); difficulty parsing input and correctly passing variables?
body: <p>Here is where the DrawingPanel class is located, for compilation purposes, if necessary.
  <a href="http://www.buildingjavaprograms.com/DrawingPanel.java" rel="nofollow">DrawingPanel.java</a></p>
  
  <p>I am writing a program where I am supposed to graph a data set, which is stored in the following <a href="http://courses.cs.washington.edu/courses/cse142/14au/homework/names.txt" rel="nofollow">file</a>, called "names.txt", using the class DrawingPanel.</p>
  
  <p>This java file allows you to create a panel of a given size, and draw shapes and lines in this panel. The problems I am encountering with my program are unrelated to the specifications and understandings of the class methods.</p>
  
  <p>The data set that I am supposed to graph using this java file is configured in the following way:</p>
  
  <p>[name] [gender] [ranking] [ranking] [ranking] [ranking]....etc for a total of 14 rankings. </p>
  
  <p>Example:</p>
  
  <p>Jane F 56 400 336 102 17 33 187 292 275 969 73 53 24 2 </p>
  
  <p>The user is supposed to input the name and gender they would like to see graphed. The data is then graphed, rankings representing the y axis and time representing the x axis. </p>
  
  <p>I have encountered a number of problems, such as correctly parsing and comparing the user input with the file.<br>
  My main problem is drawing the lines that compose the graph. The lines of these graphs are drawn with the method:</p>
  
  <p>g.drawLine(x1, y1, x2, y2)</p>
  
  <p>with g representing a Graphics object. Two points are necessary as two endpoints are necessary to create a line. </p>
  
  <p>From the way that my program is currently configured, I have a while loop:</p>
  
  <pre><code>    while (file.hasNextLine() &amp;&amp; (fileContains = false)) {
          String inputLine = file.nextLine().toUpperCase();
          if ((inputLine.contains(name) &amp;&amp; (inputLine.contains(gender)))){
              String toBeRemoved = name.toUpperCase() + " " + gender.toUpperCase();
              inputLine = inputLine.replace(toBeRemoved, " ");
              Scanner numberSplit = new Scanner(inputLine);
              rank = Integer.parseInt(numberSplit.next());
              rank2 = Integer.parseInt(numberSplit.next());
              fileContains = true;
              drawGraph(name, gender, rank, rank2);
  
          } 
      }
  </code></pre>
  
  <p>This while loop passes through the file and searches for lines that match user input. The reason why two variables for rankings, rank and rank2, respectively, exist is because two points are necessary to draw a line. </p>
  
  <p>The drawGraph method:</p>
  
  <pre><code>public static void drawGraph(String name, String gender, int rank, int rank2) {
      int yearIncrease = 0;
      DrawingPanel panel = new DrawingPanel(DECADES * SECTION_WIDTH, 550);
      Graphics g = panel.getGraphics();
      g.setColor(Color.BLACK);
      for (int i = DECADES * SECTION_WIDTH; i &gt;= 0; i -= SECTION_WIDTH){
          //horizontal line 1st
          //these lines need to be drawn in black. however they are drawn in red.
          g.drawLine(i, 0, i, 550);
          //line between points
          //how do you pass new ranks to g.drawLine? by the while loop configuration, 
          //only two values of rank are passed to the method. however, g.drawLine is
          //dependent on drawGraph to construct it.
          g.drawLine(i, (rank/2) + 25, i + SECTION_WIDTH, (rank2/2) + 25);
          String decadeInterval = String.valueOf(STARTING_YEAR + yearIncrease);
          String intervalLabel = name + " " + gender + " " + String.valueOf(rank);
          String intervalLabel2 = name + " " + gender + " " + String.valueOf(rank2);
          yearIncrease += 10;
          g.drawString(decadeInterval, i, 550);
          //draw String at first point
          g.drawString(intervalLabel, rank, (rank/2 + 25));
          g.drawString(intervalLabel2, rank2, (rank2/2 + 25));
          drawLabels(g, rank, gender, name, i);
  
      }
      g.drawLine(0, 525, DECADES * SECTION_WIDTH, 525);
      g.drawLine(0, 25, DECADES * SECTION_WIDTH, 25);
  }
  </code></pre>
  
  <p>is responsible for graphing the ranks that are listed in the input file. However, the while loop only passes the rank variables once, so it ends up graphing the same points, rather than graphing all of the points.</p>
  
  <p>To use the example: </p>
  
  <p>Jane F 56 400 336 102 17 33 187 292 275 969 73 53 24 2 </p>
  
  <p>The rankings after 400 are never passed into the drawGraph method for it to use in its graph. Instead, it graphs as though the line of input were:</p>
  
  <p>Jane F 56 400 56 400 56 400 56 400 56 400 56 400 56 400</p>
  
  <p>I am not sure how to fix this. I cannot move the drawLine method out of drawGraph, as it is dependent on the Graphics g object that is created in the method, and on for loop variables for proper placement. The DrawingPanel object cannot be constructed outside of the drawGraph method, for a DrawingPanel should only be constructed if the while loop successfully found the user input in its file. </p>
  
  <p>There are a number of other problems in this program, such as the labels for the graphs not being correctly printed in the right amount or color, but the problem that I have described is the one that I am most concerned about, and the one that I have absolutely no idea how to fix. </p>
  
  <p>If you need any other details, please feel free to comment.</p>
  
  <p>For more specific requirements that may constrain what is possible to do, if necessary, please see this. <a href="http://courses.cs.washington.edu/courses/cse142/14au/handouts/12.html" rel="nofollow">Specification</a></p>
  
  <p>CODE FOR COMPILATION PURPOSES:</p>
  
  <pre><code>import java.util.*;
  import java.awt.*;
  import java.io.*;
  public class Names {
  public static final int STARTING_YEAR = 1880;
  public static final int DECADES = 14;
  public static final int SECTION_WIDTH = 70;
  public static void main(String [] args) throws FileNotFoundException{
      Scanner input = new Scanner(System.in);
      File inputFile = new File("names2.txt");
      if(inputFile.exists()){
          System.out.println("File exists.");
      } else {
          System.out.println("File does not exist. Do something about it.");
      }
      Scanner fileScanner = new Scanner(inputFile);
      introduction();
      String userInput = introQuery(input);
      fileNameScanner(fileScanner, userInput);
  } 
  public static void introduction() {
      System.out.println("This program allows you to search trhough the");
      System.out.println("data from the Social Security Administration");
      System.out.println("to see how popular a particular name has been");
      System.out.println("since " + STARTING_YEAR +".");
  }
  public static String introQuery(Scanner input) {
      String params = "";
      System.out.print("name? ");
      params += input.next() + " ";
      System.out.print("gender (M or F)? ");
      params += input.next();
      System.out.println(params);
      // is this necessary? This complicates the parsing of the input string later with
      // multiple scanners.
      return params;      
  }
  public static void fileNameScanner(Scanner file, String params) {
      boolean fileContains = false;
      System.out.println("fileNameScanner ran");
      int rank = 0;
      int rank2 = 0;
      //investigate whether or not a delimiter is truly necessary. doesn't Scanner
      //already parse by whitespace?
      Scanner split = new Scanner(params).useDelimiter(" ");
      String name = split.next().toUpperCase();
      String gender = split.next().toUpperCase();
  
      while (file.hasNextLine() /* &amp;&amp; (fileContains = false)*/) {
          String inputLine = file.nextLine().toUpperCase();
          if ((inputLine.contains(name) &amp;&amp; (inputLine.contains(gender)))){
              //this removal of the first part of the inputLine does not work all this time.
              //How do I fix this? this does not work because Tommie, for example,
              //includes an M in its name.
              String toBeRemoved = name.toUpperCase() + " " + gender.toUpperCase();
              inputLine = inputLine.replace(toBeRemoved, " ");
              //TOMMIE M 
              //01234567
              //if M is 7, new string includes everything after M.
              Scanner numberSplit = new Scanner(inputLine);
              rank = Integer.parseInt(numberSplit.next());
              rank2 = Integer.parseInt(numberSplit.next());
              fileContains = true;
              drawGraph(name, gender, rank, rank2);
  
          }
      }
      if (fileContains = false) {
          System.out.println("name/gender combination not found");
      }
  
  }
  public static void drawGraph(String name, String gender, int rank, int rank2) {
      int yearIncrease = 0;
      DrawingPanel panel = new DrawingPanel(DECADES * SECTION_WIDTH, 550);
      Graphics g = panel.getGraphics();
      g.setColor(Color.BLACK);
      for (int i = DECADES * SECTION_WIDTH; i &gt;= 0; i -= SECTION_WIDTH){
          //horizontal line 1st
          //these lines need to be drawn in black. however they are drawn in red.
          g.drawLine(i, 0, i, 550);
          //line between points
          //how do you pass new ranks to g.drawLine? by the while loop configuration, 
          //only two values of rank are passed to the method. however, g.drawLine is
          //dependent on drawGraph to construct it.
          g.drawLine(i, (rank/2) + 25, i + SECTION_WIDTH, (rank2/2) + 25);
          String decadeInterval = String.valueOf(STARTING_YEAR + yearIncrease);
          String intervalLabel = name + " " + gender + " " + String.valueOf(rank);
          String intervalLabel2 = name + " " + gender + " " + String.valueOf(rank2);
          yearIncrease += 10;
          g.drawString(decadeInterval, i, 550);
          //draw String at first point
          g.drawString(intervalLabel, rank, (rank/2 + 25));
          g.drawString(intervalLabel2, rank2, (rank2/2 + 25));
          drawLabels(g, rank, gender, name, i);
  
      }
      g.drawLine(0, 525, DECADES * SECTION_WIDTH, 525);
      g.drawLine(0, 25, DECADES * SECTION_WIDTH, 25);
  }
  public static void drawLabels(Graphics g, int rank1, String gender, String name, int x) {
      g.setColor(Color.RED);
      String intervalLabel = name + " " + gender + " " + String.valueOf(rank1);
      //draw String at first point
      g.drawString(intervalLabel, rank1, (rank1/2 + 25));
  }
  </code></pre>
  
  <p>}</p>