Results 1 to 16 of 16
  1. #1
    kathmandu is offline Member
    Join Date
    May 2013
    Posts
    18
    Rep Power
    0

    Default Having Trouble Setting Position of Objects on Canvas

    I'm doing the Name Surfer Asssignment from the CS106a class. I finally worked out all the kinks from my code with one exception: the lines and labels on the graph aren't where they're supposed to be, or maybe I should say where I want them. The end points of the lines are correct in terms of their positions on the y-axis, but not the x-axis. They're all ending up along the top margin of the graph which is why you can't see them here:

    Having Trouble Setting Position of Objects on Canvas-namesurfer.jpg

    If I change the top variable to (GRAPH_MARGIN_SIZE + 100), this is what I get:

    Having Trouble Setting Position of Objects on Canvas-namesurfer2.jpg

    I'm sure I'm probably just overlooking something simple. Anyway, any help would be appreciated. Here's the code for this section:



    Java Code:
    public void update() {
    		removeAll();
    		createGrid();
    		double top = GRAPH_MARGIN_SIZE;
    		double bottom = getHeight() - GRAPH_MARGIN_SIZE;
    		int rank1 = 0;
    		int rank2 = 0;
    		double decadeSpacer = getWidth() / NDECADES;
    		if (namesInDisplay.size() > 0){
    			for( int i = 0; i < namesInDisplay.size(); i++){
    				Color color = colors[i];
    				NameSurferEntry entry = namesInDisplay.get(i);
    				//Adds the name and rank for each decade
    				for (int j = 1; j < NDECADES + 1; j++){
    					rank1 = (entry.getRank(j - 1));
    					double y1 = top + ((rank1/MAX_RANK) * (bottom - top));
    					double y2 = top + ((rank2/MAX_RANK) * (bottom - top));
    					GLabel name = new GLabel(entry.getName());
    					name.setLocation((j - 1) * decadeSpacer, y1 + name.getAscent());
    					GLabel rank = new GLabel(String.valueOf(rank1));
    					rank.setLocation((j - 1) * decadeSpacer, y2 + (2 * rank.getAscent()));
    					name.setColor(color);
    					rank.setColor(color);
    					add(name);
    					add(rank);		
    				}
    				//Draws the lines which represent the rank of the name for each decade
    				for( int j = 0; j < NDECADES - 1; j++){
    					rank1 = (entry.getRank(j));
    					rank2 = (entry.getRank(j + 1));
    					double y1 = top + ((rank1/MAX_RANK) * (bottom - top));
    					double y2 = top + ((rank2/MAX_RANK) * (bottom - top));
    					GLine line = new GLine((j * decadeSpacer), y1, ((j + 1) * decadeSpacer), y2);
    					line.setColor(color);
    					add(line);		
    				}
    				
    			}			
    		}
    	}

  2. #2
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,610
    Rep Power
    5

    Default Re: Having Trouble Setting Position of Objects on Canvas

    I am having a difficult time understanding this because you are using methods I am not familiar with. Also, I noticed that you are using Canvas. Is the instructor using Swing at all? Do you store you canvas in a Frame or JFrame?

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  3. #3
    kathmandu is offline Member
    Join Date
    May 2013
    Posts
    18
    Rep Power
    0

    Default Re: Having Trouble Setting Position of Objects on Canvas

    No Swing. Here's the entire code for the class:

    Java Code:
    /**
     * File: NameSurferGraph.java
     * ---------------------------
     * This class represents the canvas on which the graph of
     * names is drawn. This class is responsible for updating
     * (redrawing) the graphs whenever the list of entries changes or the window is resized.
     */
    
    import acm.graphics.*;
    import java.awt.event.*;
    import java.util.*;
    import java.awt.*;
    
    public class NameSurferGraph extends GCanvas
    	implements NameSurferConstants, ComponentListener {
    
    	/**
    	* Creates a new NameSurferGraph object that displays the data.
    	*/
    	public NameSurferGraph() {
    		addComponentListener(this);
    		update();
    	}
    	
    	private void createGrid(){
    		createVerticalLines();
    		createHorizontalLines();
    		createDecadeLabels();
    	}
    	
    	//Draws the vertical lines that separate decades
    	private void createVerticalLines(){
    		int width = getWidth();
    		int height = getHeight();
    		for (int i = 0; i < NDECADES; i++){
    			int x = i * (width / NDECADES);
    			int y1 = 0;
    			int y2 = height;
    			
    		GLine line = new GLine(x, y1, x, y2);
    		add(line);
    		}	
    	}
    	//Draws the horizontal lines that establish the boundaries of the graph
    	private void createHorizontalLines(){
    		double width = getWidth();
    		double height = getHeight();
    		double margin = GRAPH_MARGIN_SIZE;
    		GLine topLine = new GLine(0, margin, width, margin);
    		GLine bottomLine = new GLine (0, height - margin, width, height - margin);
    		add(topLine);
    		add(bottomLine);
    	}
    
    	//Draws the decade labels at the bottom of the graph
    	private void createDecadeLabels(){
    		double margin = GRAPH_MARGIN_SIZE;
    		double width = getWidth();
    		for (int i = 0; i < NDECADES; i++){
    			int decade = START_DECADE;
    			decade += i *10;
    			String label = Integer.toString(decade);
    			GLabel decadeMarker = new GLabel(label);
    			double x = i * (width / NDECADES);
    			double y = getHeight() - (margin/2) + (decadeMarker.getAscent()/2);
    			decadeMarker.setLocation(x, y);
    			add(decadeMarker);
    			}
    	
    }
    	
    	/**
    	* Clears the list of name surfer entries stored inside this class.
    	*/
    	public void clear() {
    		namesInDisplay.clear();
    		update();
    	}
    	
    	/** Method: addEntry(entry) */
    	/**
    	* 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) {
    		namesInDisplay.add(entry);
    		update();
    	}
    	
    	
    	
    	/**
    	* 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();
    		createGrid();
    		double top = GRAPH_MARGIN_SIZE;
    		double bottom = getHeight() - GRAPH_MARGIN_SIZE;
    		int rank1 = 0;
    		int rank2 = 0;
    		double decadeSpacer = getWidth() / NDECADES;
    		if (namesInDisplay.size() > 0){
    			for( int i = 0; i < namesInDisplay.size(); i++){
    				Color color = colors[i];
    				NameSurferEntry entry = namesInDisplay.get(i);
    				//Adds the name and rank for each decade
    				for (int j = 1; j < NDECADES + 1; j++){
    					String rankForLabel = "";
    					rank1 = (entry.getRank(j - 1));
    					double y1 = top + ((rank1/MAX_RANK) * (bottom - top));
    					double y2 = top + ((rank2/MAX_RANK) * (bottom - top));
    					GLabel name = new GLabel(entry.getName());
    					name.setLocation((j - 1) * decadeSpacer, y1 + name.getAscent());
    					if (rank1 != 0)rankForLabel = String.valueOf(rank1);
    					else rankForLabel = "*";
    					GLabel rank = new GLabel(rankForLabel);
    					rank.setLocation((j - 1) * decadeSpacer, y2 + (2 * rank.getAscent()));
    					name.setColor(color);
    					rank.setColor(color);
    					add(name);
    					add(rank);		
    				}
    				//Draws the lines which represent the rank of the name for each decade.
    				for( int j = 0; j < NDECADES - 1; j++){
    					rank1 = (entry.getRank(j));
    					rank2 = (entry.getRank(j + 1));
    					double y1 = top + ((rank1/MAX_RANK) * (bottom - top));
    					double y2 = top + ((rank2/MAX_RANK) * (bottom - top));
    					GLine line = new GLine((j * decadeSpacer), y1, ((j + 1) * decadeSpacer), y2);
    					line.setColor(color);
    					add(line);		
    				}
    				
    			}			
    		}
    	}
    	
    	
    	
    	
    	/** 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) { }
    	
    	/**Instance variables*/
    	private ArrayList<NameSurferEntry> namesInDisplay = new ArrayList<NameSurferEntry>();
    	private Color[] colors = {Color.black, Color.red, Color.blue, Color.orange, Color.green}; 
    	
    }
    Last edited by kathmandu; 07-15-2013 at 06:57 PM.

  4. #4
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,610
    Rep Power
    5

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Please edit you code and change your /* comments to /** comments. This is a problem with the formatter. It makes the code difficult to read.

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  5. #5
    kathmandu is offline Member
    Join Date
    May 2013
    Posts
    18
    Rep Power
    0

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Quote Originally Posted by jim829 View Post
    Please edit you code and change your /* comments to /** comments. This is a problem with the formatter. It makes the code difficult to read.

    Regards,
    Jim
    Done.

  6. #6
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,610
    Rep Power
    5

    Default Re: Having Trouble Setting Position of Objects on Canvas

    In your second loop in update(), try changing

    Java Code:
    for( int j = 0; j < NDECADES - 1; j++){
      // to
    for( int j = 0; j < NDECADES; j++){
    In general, you are inconsistent in how you construct your loops. In the first loop you iterate J from 1 to NDECADES + 1, and the subtract 1 from j when you use it. In the next loop, you do the opposite. It would help in debugging your code if you were more consistent (unless the code demands that you do it that way).

    Also, notice that

    Java Code:
    for (j = 1; j < NDECADES + 1; j++) 
       // is equivalent to
    for (j = 1; j <= NDECADES; j++)
    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  7. #7
    kathmandu is offline Member
    Join Date
    May 2013
    Posts
    18
    Rep Power
    0

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Noted. I made the change in the first loop. i left the second loop as is since I only want to draw ten lines.

  8. #8
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,610
    Rep Power
    5

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Did that solve your problem?

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  9. #9
    kathmandu is offline Member
    Join Date
    May 2013
    Posts
    18
    Rep Power
    0

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Quote Originally Posted by jim829 View Post
    Did that solve your problem?

    Regards,
    Jim
    It did not. I'm especially confused since there isn't any issue with the x coordinates.
    Last edited by kathmandu; 07-15-2013 at 08:15 PM.

  10. #10
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,610
    Rep Power
    5

    Default Re: Having Trouble Setting Position of Objects on Canvas

    What does the second loop do, draw horizontal or vertical lines (I thought horizontal). And what is the value of NDECADES?

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  11. #11
    kathmandu is offline Member
    Join Date
    May 2013
    Posts
    18
    Rep Power
    0

    Default Re: Having Trouble Setting Position of Objects on Canvas

    The second loop is supposed to draw the lines that graph the rank for each decade as shown here:

    Having Trouble Setting Position of Objects on Canvas-namesurfer3.jpg
    Last edited by kathmandu; 07-15-2013 at 08:28 PM. Reason: typo

  12. #12
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,610
    Rep Power
    5

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Quote Originally Posted by kathmandu View Post
    Noted. I made the change in the first loop. i left the second loop as is since I only want to draw ten lines.
    I just counted and you are drawing 10 lines. But you have 11 columns. Is that fact that you have 11 columns the problem?

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  13. #13
    kathmandu is offline Member
    Join Date
    May 2013
    Posts
    18
    Rep Power
    0

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Quote Originally Posted by jim829 View Post
    I just counted and you are drawing 10 lines. But you have 11 columns. Is that fact that you have 11 columns the problem?

    Regards,
    Jim
    I don't believe so. If I enter an if statement in the loop that changes the y coordinate for a specific iteration within the loop (e.g. if (j == 9) y2 = 200), the coordinate for the end point of that line displays correctly.

  14. #14
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,610
    Rep Power
    5

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Where are your Surfer constants and where do you read your data?

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

  15. #15
    kathmandu is offline Member
    Join Date
    May 2013
    Posts
    18
    Rep Power
    0

    Default Re: Having Trouble Setting Position of Objects on Canvas

    Quote Originally Posted by jim829 View Post
    Where are your Surfer constants and where do you read your data?

    Regards,
    Jim
    The constants are kept in a separate constants file (see below). The data is read in a separate database class (see below). Everything in the program is running properly with this one exception. If I add a console with a println statement showing the data I want to display, everything is correct. The labels showing the ranks for each decade are right, it's only the vertical position of the lines and labels on the graph.

    Having Trouble Setting Position of Objects on Canvas-namesurfer4.jpg

    I think this will just add undue confusion, but here's the code for the rest of the program:

    Main Class

    Java Code:
    /**
     * 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.graphics.GObject;
    import acm.graphics.GPoint;
    import acm.program.*;
    import java.awt.event.*;
    import java.util.HashMap;
    
    import javax.swing.*;
    
    public class NameSurfer extends ConsoleProgram implements NameSurferConstants {
    
    /** Method: init() */
    /**
     * This method has the responsibility for reading in the data base
     * and initializing the interactors at the bottom of the window.
     */
    	public void init() {
    		database = new NameSurferDataBase(NAMES_DATA_FILE);
    		
    		nameField = new JTextField(NAME_LENGTH);
    		nameField.addActionListener(this);
    		graphButton = new JButton("Graph");
    		clearButton = new JButton("Clear");
    		add (new JLabel ("Name"), SOUTH);
    		add (nameField, SOUTH);
    		add (graphButton, SOUTH);
    		add (clearButton, SOUTH);
    		addActionListeners();
    		
    		graph = new NameSurferGraph();
    		add(graph);
    		
    		
    	}
    
    /** Method: actionPerformed(e) */
    /**
     * 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) {
    		String name = nameField.getText();
    		Object source = e.getSource();
    		if (source == nameField || source == graphButton) {
    			NameSurferEntry entry = database.findEntry(name);
    			if (entry != null){
    			graph.addEntry(entry);
    			println(entry.toString());
    			}
    		}
    		else if (source == clearButton){
    			graph.clear();
    		}
    	}
    
    	
    	/*Static variables*/
    	private final int NAME_LENGTH = 25;
    	
    	/*	Instance variables*/
    	private JTextField nameField;	
    	private JButton graphButton;
    	private JButton clearButton;
    	private NameSurferGraph graph;
    	private NameSurferDataBase database;
    	
    }
    Name Surfer Database

    Java Code:
    /**
     * File: NameSurferDataBase.java
     * -----------------------------
     * This class keeps track of the complete database of names.
     * The constructor reads in the database from a file, and
     * the only public method makes it possible to look up a
     * name and get back the corresponding NameSurferEntry.
     * Names are matched independent of case, so that "Eric"
     * and "ERIC" are the same names.
     */
    
    import java.io.*;
    import java.util.*;
    import acm.util.*;
    
    public class NameSurferDataBase implements NameSurferConstants {
    	
    /** Constructor: NameSurferDataBase(filename) */
    /**
     * Creates a new NameSurferDataBase and initializes it using the
     * data in the specified file.  The constructor throws an error
     * exception if the requested file does not exist or if an error
     * occurs as the file is being read.
     */
    	public NameSurferDataBase(String filename) {
    		try{
    			BufferedReader rd = new BufferedReader( new FileReader(filename));
    			while (true){
    				String line = rd.readLine();
    				if (line == null) break;
    				NameSurferEntry entry = new NameSurferEntry(line);
    				database.put(entry.getName(), entry);	
    			}
    			rd.close();
    		} catch (IOException ex){
    			throw new Error(ex);
    		}	
    	}
    	
    /** Method: findEntry(name) */
    /**
     * Returns the NameSurferEntry associated with this name, if one
     * exists.  If the name does not appear in the database, this
     * method returns null.
     */
    	public NameSurferEntry findEntry(String name) {
    		char firstLetter = name.charAt(0);
    		if(Character.isLowerCase(firstLetter)){
    			firstLetter = Character.toUpperCase(firstLetter);
    		}
    		String restOfName = name.substring(1);
    		restOfName = restOfName.toLowerCase();
    		name = firstLetter + restOfName;
    		if(database.containsKey(name)){
    			return database.get(name);
    		}
    		else return null;
    	}
    	
    /*Instance variables*/
    	
    Map <String, NameSurferEntry> database = new HashMap <String, NameSurferEntry>();	
    	
    	
    }
    Name Surfer Entry

    Java Code:
    /**
     * 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 acm.program.*;
    
    public class NameSurferEntry implements NameSurferConstants {
    
    /** Constructor: NameSurferEntry(line) */
    /**
     * 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) {
    		
    		int endOfName = line.indexOf(" ");
    		firstName = line.substring(0, endOfName);
    		int indexStart = endOfName + 1;
    		for (int i = 0; i < NDECADES; i++){
    			int indexEnd = line.indexOf(" ", indexStart);
    			if (indexEnd != -1){
    				nameRankings[i] = Integer.parseInt(line.substring(indexStart, indexEnd));
    				indexStart = indexEnd + 1;
    			}
    			else nameRankings[i] = Integer.parseInt(line.substring(indexStart));
    		}
    	}
    	
    /** Method: getName() */
    /**
     * Returns the name associated with this entry.
     */
    	public String getName() {
    		return firstName;
    	}
    
    /** 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) {
    		// You need to turn this stub into a real implementation //
    		return nameRankings[decade];
    	}
    
    /** Method: toString() */
    /**
     * Returns a string that makes it easy to see the value of a
     * NameSurferEntry.
     */
    	public String toString() {
    		String nameString = "";
    		String decadeRankings = "";
    				for (int i = 0; i < NDECADES; i++){
    			decadeRankings += nameRankings[i] + " ";
    		}
    		nameString = firstName + "[ " + decadeRankings +  "]";
    		return nameString;
    	}
    	
    /*Instance variables*/
    	private String firstName;
    	private int[] nameRankings = new int[NDECADES];
    	
    }
    Name Surfer Constants

    Java Code:
    /**
     * File: NameSurferConstants.java
     * ------------------------------
     * This file declares several constants that are shared by the
     * different modules in the NameSurfer application.  Any class
     * that implements this interface can use these constants.
     */
    
    public interface NameSurferConstants {
    
    /** The width of the application window */
    	public static final int APPLICATION_WIDTH = 800;
    
    /** The height of the application window */
    	public static final int APPLICATION_HEIGHT = 600;
    
    /** The name of the file containing the data */
    	public static final String NAMES_DATA_FILE = "names-data.txt";
    
    /** The first decade in the database */
    	public static final int START_DECADE = 1900;
    
    /** The number of decades */
    	public static final int NDECADES = 11;
    
    /** The maximum rank in the database */
    	public static final int MAX_RANK = 1000;
    
    /** The number of pixels to reserve at the top and bottom */
    	public static final int GRAPH_MARGIN_SIZE = 20;
    
    }

  16. #16
    jim829 is offline Senior Member
    Join Date
    Jan 2013
    Location
    Northern Virginia, United States
    Posts
    3,610
    Rep Power
    5

    Default Re: Having Trouble Setting Position of Objects on Canvas

    The best I can offer at this point is that your indices are off somehow and coordinates are not being generated correctly. I suggest using ubiquitous print statements to try and discover the problem.

    Regards,
    Jim
    The Java™ Tutorial | SSCCE | Java Naming Conventions
    Poor planning our your part does not constitute an emergency on my part.

Similar Threads

  1. Setting position of JButton
    By badass708 in forum New To Java
    Replies: 1
    Last Post: 01-19-2013, 06:19 AM
  2. Setting different colors to objects
    By FOX427 in forum Java 2D
    Replies: 3
    Last Post: 04-13-2012, 07:52 AM
  3. Replies: 6
    Last Post: 01-14-2012, 05:14 PM
  4. Replies: 0
    Last Post: 12-14-2011, 02:30 PM
  5. need help setting up GUI objects
    By robertbob in forum New To Java
    Replies: 1
    Last Post: 05-07-2010, 03:03 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •