Java help needed for Java beginner please

Hi,

I am trying to learn a bit of Java and have been following the W3 Schools tutorials. However, I have hit something of a brick wall.

I’m not sure if I am using the correct word in my following description - by “script” I mean one file that ends in .java and contains java code.

I want to have a script that seeks user input that can then be used/accessed by the main class in a different script.

If I create a file Locate.java thus:

import java.util.Scanner;  // Import the Scanner class

class Locat {
  public static void main(String[] args) {
    Scanner myObj = new Scanner(System.in);  // Create a Scanner object
    System.out.println("Enter username");

    String userName = myObj.nextLine();  // Read user input
    System.out.println("Username is: " + userName);  // Output user input
  }
}

I can then compile it and run it and it works - it prints to the screen “Enter Username” and when I type in some text (eg “Reginald”) it prints to the screen “Username is Reginald” - all as expected.

However, if I then create, in the same directory, main.java thus:

public class Main {
  public static void main(String[] args) {
    System.out.println("This is Main");
    System.out.println(Locat.userName);
  }
}

and try to compile it I get an error:

main.java:4: error: cannot find symbol
    System.out.println(Locat.userName);
                            ^
  symbol:   variable userName
  location: class Locat
1 error

I tried removing the word “static” from line 4 of Locat.java but this does not help.
I have some understanding of what classes, objects and methods and properties are.
I have tried for hours to find out what I am doing wrong. I wonder if it is something to do with scope?

Any help gratefully recieved.
Thank you.

You could make a User class, stick that into a package, and use that to manage the creation of new users. Here’s a quick example…

Create the following file structure:

myapp
├── Main.java
└── user
    └── User.java

In User.java:

package user;

public class User {
  private String name;

  public String getName() {
    return name;
  }

  public void setName(String newName) {
    this.name = newName;
  }
}

Compile the class by opening a terminal, navigating to myapp/user and executing javac User.java.

Then, you can import and use methods from the User class in Main.java:

import user.*;

public class Main {
  public static void main(String[] args) {
    User user = new User();
    System.out.println(user.getName());
    user.setName("Jim");
    System.out.println(user.getName());
    user.setName("wake689");
    System.out.println(user.getName());
  }
}

Now, from the project root, run the script with java Main.java and this should output:

null
Jim
wake689

I know this isn’t exactly what you asked, but hopefully it demonstrates a couple of useful concepts.

What exactly are you learning Java for, if I might ask?
Do I remember reading that you want to make an Android app or something?

If you are going to get far with Java, you will probably need to dive quite a bit deeper into OOP, classes and everything that comes with it.


Disclaimer: I know next to nothing about Java. I was just thinking about how I would solve this problem in a language I am more familiar with.

2 Likes

Thank you for your reply. I will have another read through of this and have a play around with it and see if it enables me to do what I need. I think I am missing some basic understanding of how one script accesses methods in another. I think you may have answered my question, but I won’t know until I have worked through it. Thank you for taking the time.

Yes, I am wanting to write a basic Android phone app that uses location data to measure how far I have walked. There are lots of apps available that do this but most of them upload the data to the provider of the app - I don’t want to tell anyone exactly where I am and when if I am just going for a walk. I found one app that doesn’t send the data back to the “mothership” but if I go indoors and the geolocation data becomes unreliable it adds eg a point a mile away to my walk and makes me seem like Superman! So I want to write an app that discards points that I could not have possibly walked to by walking at x mph.
Also, I thought it might be interesting to learn how to do this. I have set up Android studio and have created a “Hello World” app!

OK, I’ve worked through that and I see how it works.

But how would you obtain user input values?

I see that the Scanner class can be used for this, by creating a new Scanner object. I can do it in Main.java. But would it be better dealt with in a script of it’s own? That’s the bit I can’t seem to get right - how to obtain user input in a different script, to use in Main.java.

Well, you could stick the method on the User class and pass in an instance of user for it to work with.

User.java

package user;
import java.util.Scanner;

public class User {
  private String name;

  public String getName() {
    return name;
  }

  public void setName(String newName) {
    this.name = newName;
  }

  public void displayPrompt(User user) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Enter username:");

    String userName = scanner.nextLine();
    user.name = userName;
  }
}

Main.java

import user.*;

public class Main {
  public static void main(String[] args) {
    User user = new User();
    System.out.println("User name is: " + user.getName());
    user.displayPrompt(user);
    System.out.println("User name is: " + user.getName());
  }
}

This will do what you want:

User name is: null
Enter username
Jim 
User name is: Jim

But this is kinda messy and given the goals that you stated above, I’m not sure that this is the best way to approach things.

There are a ton of moving parts to an Android app. If I was you, I would look for a tutorial that gets you kind of close to what you want and follow along with that. Then, when you have a handle on how a simple Android app is built (and by simple, I mean something more than a Hello World app) see if you can adapt what you have to suit your own goals.

I spent a short while searching and came up with the following:

  • https://developer.android.com/guide — I would probably look at this one first (the App Basics and App Fundamentals parts), as it is the official “How to”. It will hopefully present a comprehensive high-level view of what pieces are involved and what goes where. It also has some good links to documentation and further learning (such as Google Codelabs, which claims to step you through the process of building a small app, or adding a new feature to an existing app).
  • Android Development for Beginners — This is a 15 hour course that shows you how to develop an Android app from scratch. It was released 2 years ago, so YMMV in terms of things being up-to-date, but it is from a recognized publisher (freeCodeCamp) and people still seem to be following it. I’d definitely do some more research before committing to this, but it might be worth a look.

Also, I’d think about your choice of stack. Google seems to be recommending Kotlin as the preferred language for Android app development. Also, it might be worth investigating if there is a way of writing the app in a more familiar language, such as JavaScript. AFAIK, Apache Cordova does this. This might get you to your goal much quicker.

And if you do decide to look into Kotlin, check out this tutorial that walks you through building a tip calculator.

2 Likes

Thank you again for your detailed reply.

Your approach does indeed do what I was trying to do. I will now go through it to try and understand fully what it is doing and why your method works and mine doesn’t.

Re Android Studio - I have bought an 800 page book about it. One of the chapters is called “The Anatomy of an Android App”. The book was published in Feb 2022 so hopefully will be as up to date as a book can be.

There is obviously a lot more to this than I thought!

Thank you.

1 Like

Thank you for your very helpful input. I have worked through it all and adapted and added to it so that I now have a working program consisting of three files. It asks the user for latitude and longitude of two points on Earth and using a routine I got from the Internet it calculates the distance (as the crow flies, of course) between these two points.

Could I have done this in a better way? Constructive criticism is very welcome.

The folder structure is:

myapp
├── Main.java
└── GFG4
   └── GFG.java
└── points
    └── ObtainPoints.java

The three pages (is that the correct term?) are:
Main.java:

import points.*;
import GFG4.*;

public class Main {
  public static void main(String[] args) {

    ObtainPoints point0 = new ObtainPoints();
    point0.displayPrompt(point0, "Enter start latitude: ");
    double lat1 = point0.getCoordinate();
    //System.out.println("Start latitude is " + lat1 + System.lineSeparator());

    ObtainPoints point1 = new ObtainPoints();
    point1.displayPrompt(point1, "Enter start longitude: ");
    double lon1 = point1.getCoordinate();
    //System.out.println("Start longitude is " + lon1 + System.lineSeparator());

    ObtainPoints point2 = new ObtainPoints();
    point2.displayPrompt(point2, "Enter end latitude: ");
    double lat2 = point2.getCoordinate();
    //System.out.println("End latitude is " + lat2 + System.lineSeparator());

    ObtainPoints point3 = new ObtainPoints();
    point3.displayPrompt(point3, "Enter end longitude: ");
    double lon2 = point3.getCoordinate();
    //System.out.println("Start longitude is " + lon2 + System.lineSeparator());

    //Print out the coordinates entered
    System.out.println("You have entered the following GPS coordinates:");
    System.out.println("Start latitude is " + lat1);
    System.out.println("Start longitude is " + lon1);
    System.out.println("End latitude is " + lat2);
    System.out.println("End longitude is " + lon2);

    //Convert latitude and longitude into miles
    double travelled = GFG.distance(lat1, lat2, lon1, lon2);

    //round the result to 2 decimal places and print result
    System.out.println("You have travelled " + (Math.round(travelled * 100.0) / 100.0) + "miles.");

  }
}

GFG.java:

package GFG4;

// Java program to calculate distance between two points on Earth
import java.util.*;
import java.lang.*;


public class GFG {

    public static double distance(double lat1,
                     double lat2, double lon1,
                                  double lon2)
    {
        // The math module contains a function named toRadians which converts from degrees to radians.
        lon1 = Math.toRadians(lon1);
        lon2 = Math.toRadians(lon2);
        lat1 = Math.toRadians(lat1);
        lat2 = Math.toRadians(lat2);

        // Haversine formula to claculate distance from the GPS coordinates
        double dlon = lon2 - lon1;
        double dlat = lat2 - lat1;
        double a = Math.pow(Math.sin(dlat / 2), 2)
                 + Math.cos(lat1) * Math.cos(lat2)
                 * Math.pow(Math.sin(dlon / 2),2);

        double c = 2 * Math.asin(Math.sqrt(a));

        // Radius of earth in miles. Use 6371 for km
        double r = 3956;

// calculate the result
        return(c * r);
    }

  /*
    // driver code
    public static void main(String[] args)
    {
        double lat1 = 53.32055555555556;
        double lat2 = 53.31861111111111;
        double lon1 = -1.7297222222222221;
        double lon2 = -1.6997222222222223;
        System.out.println(distance(lat1, lat2,
                           lon1, lon2) + " K.M");
    }
*/
}


// This code is contributed by Prasad Kshirsagar

ObtainPoints.java:

package points;
import java.util.Scanner;

public class ObtainPoints {
  private double coordinate;

  public double getCoordinate() {
    return coordinate;
  }

  public void setCoordinate(double newCoordinate) {
    this.coordinate = newCoordinate;
  }

  public void displayPrompt(ObtainPoints points, String message) {
    Scanner scanner = new Scanner(System.in);
    System.out.println(message);

    double userCoordinate = scanner.nextDouble();
    points.coordinate = userCoordinate;
  }
}

I created this just to see if I could. I know that on its own it is not at all useful in and of itself!
Thank you again.

Hi,

Glad to hear you are progressing with your project.

So this is weird to me. You are building an Android app, but you are using System.in and System.out to obtain and display input. On a PC, this is a terminal. What does this look like on a phone? Shouldn’t you have a “proper” screen with input fields and a submit button (more like a web form).

Again the disclaimer that I am not very familiar with Java, so if anyone else wants to offer their advice, that would be welcome.

That said, you have an ObtainPoints class of which you create a new instance every time you want to obtain a single point of either longitude or latitude. Would it not be better to create a Points class which stores both longitude and latitude and only needs to be instantiated once?

1 Like

I just wanted to learn a little Java - I thought it might help me to understand things going forward with Android studio.

Duly noted :grinning:

That does seem to make better sense. I will have a bash at that.

Would I return the result from the class as an array?

Not sure what the most appropriate data structure would be in Java.

It seems there is a HashMap class, so I would look at something like that.

1 Like

Wow. That looks useful. Thank you. I appreciate all your input, even though you say thatJava is not your forte.

1 Like

Thank you for all your help with this. But I can’t quite get it to work. I have got it down to one error!

Same folder structure as above, namely:

myapp
├── Main.java
└── GFG4
   └── GFG.java
└── points
    └── ObtainPoints.java

Main.java:

import points.*;
import GFG4.*;

public class Main {
  public static void main(String[] args) {

    ObtainPoints point0 = new ObtainPoints();
    point0.displayPrompt(point0);
    HashMap<String,Double> usersPoints = point0.getCoordinate();
    //System.out.println("Start latitude is " + lat1 + System.lineSeparator());

    System.out.println("Back in Main");
    // Print keys and values of HashMap object usersPoints
    for (String i : usersPoints.keySet()) {
    System.out.println("key: " + i + " value: " + usersPoints.get(i));
    }
  }
}

GFG.java:

package GFG4;

// Java program to calculate distance between two points on Earth
import java.util.*;
import java.lang.*;


public class GFG {

    public static double distance(double lat1,
                     double lat2, double lon1,
                                  double lon2)
    {
        // The math module contains a function named toRadians which converts from degrees to radians.
        lon1 = Math.toRadians(lon1);
        lon2 = Math.toRadians(lon2);
        lat1 = Math.toRadians(lat1);
        lat2 = Math.toRadians(lat2);

        // Haversine formula to claculate distance from the GPS coordinates
        double dlon = lon2 - lon1;
        double dlat = lat2 - lat1;
        double a = Math.pow(Math.sin(dlat / 2), 2)
                 + Math.cos(lat1) * Math.cos(lat2)
                 * Math.pow(Math.sin(dlon / 2),2);

        double c = 2 * Math.asin(Math.sqrt(a));

        // Radius of earth in miles. Use 6371 for km
        double r = 3956;

// calculate the result
        return(c * r);
    }

  /*
    // driver code
    public static void main(String[] args)
    {
        double lat1 = 53.32055555555556;
        double lat2 = 53.31861111111111;
        double lon1 = -1.7297222222222221;
        double lon2 = -1.6997222222222223;
        System.out.println(distance(lat1, lat2,
                           lon1, lon2) + " K.M");
    }
*/
}


// This code is contributed by Prasad Kshirsagar

ObtainPoints.java:

package points;

import java.util.Scanner;
import java.util.HashMap;

public class ObtainPoints {
  //create a HashMap object that will contain the coordinates entered by the user
  HashMap<String, Double> usersPoints = new HashMap<String, Double>();

  // I don't think this next line is applicable any longer
  //private double coordinate;

  public HashMap<String,Double>  getCoordinate() {
    return usersPoints; //usersPoints;
  }


  public void setCoordinate(HashMap<String,Double> newCoordinate) {
    this.usersPoints = newCoordinate;
  }



  public void displayPrompt(ObtainPoints points) {
    Scanner scanner = new Scanner(System.in);
    System.out.println("Enter start latitude:");
    //create a variable, lat1, with the value that was entered by the user
    double lat1 = scanner.nextDouble();

    // Add key and value to the HashMap object usersPoints
    usersPoints.put("lat1", lat1);


    Scanner scanner1 = new Scanner(System.in);
    System.out.println("Enter start longitude:");
    //create a variable, lat1, with the value that was entered by the user
    double lon1 = scanner1.nextDouble();

    // Add key and value to the HashMap object usersPoints
    usersPoints.put("lon1", lon1);

    //I'm not sure aboout this line - I think I may be doing something wrong here
    //points.usersPoints = coords;

    // Print keys and values of HashMap object usersPoints
    for (String i : usersPoints.keySet()) {
    System.out.println("key: " + i + " value: " + usersPoints.get(i));
    }
  }
}

I have only put routines to get the coordinates of the firt point, so far, to see if I can get the latitude and longitude for the first point.

ObtainPoints.java and GFG.java compile with no errors. But when compiling main.java I get the following error:

main.java:9: error: cannot find symbol
    HashMap<String,Double> usersPoints = point0.getCoordinate();
    ^
  symbol:   class HashMap
  location: class Main
1 error

I clearly do not have a deep enough understanding here of what I am doing. Am I making a simple error or am I doing it all wrong (just aiming to get a simple console based routine that asks the user for coordinates and calculates the distance between them.

You use HashMap in a file where you did not import java.util.HashMap

Ha! Of course, thank you so much. It now works!