Referencing user input string from another class? - java

I'm trying to write a program that asks the user for input using the scanner class to name something. Then in a completely different class, reference that input.
For example:
class TeamInfo {
Scanner nScan = new Scanner(System.in);
public String GetName(){
String GetName = nScan.nextLine();
}
The issue I'm having is that the first time I reference the GetName method in the TeamInfo class, it works--At the right spot, it prompts for the team name.
However, it prompts for the team name every time after that. I can't seem to find anywhere online or in my Java Beginner's Guide how to make this input constant, so that I can reference the input. I'm also not entirely sure what it is I'm looking for, so that doesn't help.
In other words, what I want is to prompt the user one time, and then remember that answer and re-use it again and again.

You should make two methods: getName() and promptName() (or whatever names you like best)
One method would be for retrieving the name from the user, and the other would be for retrieving the value that you got from the user:
class TeamInfo {
private Scanner nScan = new Scanner(System.in);
private String name;
public void promptName() {
name = nScan.nextLine();
}
public String getName() {
return name;
}
}
When you want to get the name from the user, you'd call:
TeamInfo info = new TeamInfo();
info.promptName();
And when you wanted to retrieve the name for your uses:
String teamName = info.getName();

Save the result of the input to a field, then return that on request:
class TeamInfo {
private String name;
Scanner nScan = new Scanner(System.in);
public void promptForName() {
System.out.print("Name: ");
this.name = nScan.nextLine();
}
public String getName() {
return this.name;
}
}

You need to store the name you have read fro the Scanner in a class member, then return that class member when calling GetName (). Otherwise you will lose the name you have read, and will have to read it again (and thus prompt the user again for input).
For example:
class TeamInfo {
Scanner nScan = new Scanner(System.in);
String name = null;
public String GetName(){
if (name == null) {
name = nScan.nextLine();
}
return name;
}
On a different note, you should read on Java naming conventions. A method name should not start with a capital letter.

Related

Checking for errors from Scanner?

So I decided to make a program that makes Orc objects that each have a name.
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
for (int x = 0; x < 10; x++){
System.out.println("Input the name of your Orc here:");
String name = input.nextLine(); //THIS is where the inputed name is registerd.
Orcmaker Orc = new Orcmaker(name);
System.out.println(Orc);
input.close();
}
System.out.println("Fire");
//Find a way to run validation code while not obstructing the for loop to make multiple orc objects.
}
}
So I made that for loop to go through the code so that I can make a name for each orc until eventually I make 10 orcs. The problem is that I'm having issues now injecting input validation that won't make certain lines of code go blank because the loop swallowing up vital code.
Also I just don't know how to make it so that my if statement can see a number or special character to invalidate. Because these are NAMES I only want a String.
Just for completeness' sake here is my constructor. This is the only other class in this mini-project I have made myself.
public class Orcmaker {
private String name;
private int age;
private String weapon;
public Orcmaker(String OrcName){
this.name = OrcName;
}
#Override
public String toString() {
return String.valueOf(name);
}
}

Proper use of objects

I have this method addPerson (on the main) which is used to set the name of a person.
private static Person[] addPerson(Person _person[], int _minAge, int _id){
int personAge;
String personName;
Scanner scan = new Scanner(System.in);
System.out.println("What's his age?");
personAge = scan.nextInt();
if(personAge >= _minAge){
if(!_person[_id].getPerson().equals("")){
System.out.println("Person " + _person[_id].getPerson() + " already exists.");
}else{
System.out.println("Enter the name of the person");
Scanner addPerson = new Scanner(System.in);
personName = addPerson.next();
_person[_id].setPerson(personName);
}
}else{
System.out.println("Person is not old enough");
}
return _person;
}
And here is the method setPerson in my custom class which is used to set the name of the person.
public void setPerson(String name){
System.out.println("Person added");
personName = name;
}
I know I should be doing the checking on whether that person already exists inside my setPerson method, but I am sort of confused with this. As you see I am expecting the user to input an integer, so I guess that I should check that right away to not get an error in case he inputs a string.
So my question is which should be checked within the same method and which on the method on my custom class?
Your code (and your question) is a bit confusing, but from what I can understand you want to know if you should check whether a person exists in the array in setPerson() or not?
Well, from what I can gather from your code, you should not do it in setPerson(), because that's a method in the Person class. The Person class shouldn't need to know anything about your array of Person objects.
So the way you're doing it now is probably your best bet.
Some general hints about the code:
There's no need to create a new Scanner, you can just use the one you have. So this
Scanner addPerson = new Scanner(System.in);
personName = addPerson.next();
becomes this
personName = scan.next();
I would also suggest you use the name setName()instead of setPerson()for your method name, it doesn't make sense to have it named one way when what it's actually doing is something else.
I would do it this way. However I don't have java currently so I didn't test this snippet.
class Person {
private String name;
public void setName(String name) {
this.name = name;
}
}
class Main {
private static final int minAge = 22;
private static Map<Person> addPerson(Map<Person> people, int id) {
if(people.containsKey(id)) {
// print that person with this id exists
return people;
}
Scanner scanner = new Scanner(System.in);
int age = scanner.nextInt();
if(age < minAge) {
// print that given age is invalid
return people;
}
String name = scanner.next();
people.get(id).setName(name);
return people;
}
}

Generate non repeating numbers to add to customerNumber int variable

I'm creating a banking app and I need to generate a customer number starting from number 1, keeping track of the number so that it won't repeat itself each time I enter the loop and store it into an int variable that I can use to collect the value and pass it to the customerNumber variable outside the loop. I've tried a few things like arraylists and arrays, but I was getting troubles in passing the values to the variable I wanted. Thanks in advance and sorry for my terrible noobishness...I'm new in programming... Here's what I've got so far:
import java.util.ArrayList;
public class Bank{
public void addCustomer(String name, int telephone, String email, String profession) {
ArrayList customerList = new ArrayList();
Customer customer = new Customer();
customerList.add(customer);
}
}
public class Customer{
private String name;
private int telephone;
private String email;
private String profession;
private int customerNumber;
public Customer() {
}
}
public class Menu {
Scanner sc = new Scanner(System.in);
Bank bank = new Bank();
private void createCustomer() {
String name, email, profession;
int telephone, customerNumber;
System.out.println("Enter the customer's number: ");
name = sc.nextLine();
System.out.println("Enter the customer's telephone: ");
telephone = sc.nextInt();
System.out.println("Enter the customer's email: ");
email = sc.nextLine();
System.out.println("Enter the customer's profession: ");
profession = sc.nextLine();
bank.addCustomer(name, telephone, email, profession);
}
}
One thing you can do is create a singleton class, and request a number each time you need one. The singleton class keeps a list of the numbers that have been used already, and thus can return a number that has not been used before.
If you need also to generate new numbers after your application is restarted, then you can store all numbers in a file, and read that file whenever needed.
A singleton class, is a class that can have max 1 instance. You can achieve this by making the constructor private, and creating a public static method (usually called something like getInstance() ) to get an instance of this class. This getInstance() returns the ref to the only instance, and if no instance was created yet, it first creates one.
Then, this only instance knows all account numbers in use (inyour case), regardless how often an instance of this class is requested.
The responsibility of this class is to maintain the account nrs: create a nr, print them, save them, read them, ...
Example:
private AccoutnNr singleInstance;
private AccountNr(){
}
public AccountNr getInstance(){
if (singleInstance == null) {
singleInstance = new AccountNr();
}
return singleInstance;
}
public int getAccountNr{
// do whatever is needed to create an account nr
}
more methods if you need to do more than creating account numbers

How to read a text file into an array with private fields using mutators in Java

I have Googled this for a couple of days without much luck. I am trying to read a text file and use that information to populate the private fields of an array for a class object. I am new to Java and pretty new to programming in general.
What I've come up with for reading into the array seems really clunky and I feel there must be a better way, but I cannot find a good example for this particular kind of case case.
Creating a bunch of string variables was the only way I could get this to work. Perhaps main is a bad place to do this; perhaps Scanner is a poor choice here?
What better ways are there to implement this situation?
My text file that contains Strings and integers separated by whitespace on lines is similar to this:
Joe 2541 555-1212 345 1542 Type
Bob 8543 555-4488 554 1982 Type
... etc.
Here's my majority of my code thus far which is within main:
Scanner in = new Scanner(new FileReader("accounts.txt")); //filename to import
Accounts [] account = new Accounts [10];
int i = 0;
while(in.hasNext())
{
account[i] = new Accounts();
String name = in.next();
String acct_num = in.next();
String ph_num = in.next();
String ss_num = in.next();
int open_bal = in.nextInt();
String type = in.next();
account[i].setName(name);
account[i].setAcctNum(acct_num);
account[i].setPhoneNum(ph_num);
account[i].setSSNum(ss_num);
account[i].setOpenBal(open_bal);
account[i].setType(type);
i++;
}
class Accounts
{
public Accounts()
{
}
public Accounts(String n, String a_num, String ph_num,
String s_num, int open_bal, String a_type, double close_bal)
{
name = n;
account_number = a_num;
phone_number = ph_num;
ssn = s_num;
open_balance = open_bal;
type = a_type;
close_balance = close_bal;
}
public String getName()
{
return name;
}
public void setName(String field)
{
name = field;
}
public String getAcctNum()
{
return account_number;
}
public void setAcctNum(String field)
{
account_number = field;
}
//And so forth for the rest of the mutators and accessors
//Private fields
private String name;
private String account_number;
private String phone_number;
private String ssn;
private int open_balance;
private String type;
private double close_balance;
}
I believe you need to split each line in order to get the data contained in each line. You can use the split() of the string class which will return a string[]. Then you can go through each index of the string array and pass them to the mutator methods of the account class.
Something like this maybe.
while(in.hasNext())
{
// will take each line in the file and split at the spaces.
String line = in.next();
String[] temp = line.split(" ");
account[i].setName(temp[0]);
account[i].setAcctNum(temp[1]);
account[i].setPhoneNum(temp[2] + "-" + temp[3]);
account[i].setSSNum(temp[4]);
account[i].setOpenBal((int)temp[5]);
account[i].setType(temp[6]);
// will account for blank line between accounts.
in.next();
i++;
}
The phone number gets split into two separate indices so you have to rejoin the phone number by accounting for the first 3 digits being in one index and the last 4 being in the next.
Replacing Accounts[] with Set<Accounts> would be more flexible solution as you can process either 10 lines or 10000 accounts without code changes. In general: Consider Collections vs arrays
Using Scanner seems to be reasonable in this particular case, however take a look at the others ways of processing text (performance vs convenience): Scanner vs. StringTokenizer vs. String.Split
Setting up account parameters with mutators or constructor might not be the best choice: Effective Java: Consider a builder when faced with many constructor parameters

One of my variables in one of my classes "cannot be resolved or is not a field"

Here's my class Person.java (simplified to remove text I think is unrelated to the problem):
public class Person {
int myIdNumber;
String myName;
String myBirthday;
String myType;
Person(String forTheName, int forTheId, String forTheBirthday, String forTheType){
this.myIdNumber = forTheId;
this.myName = forTheName;
this.myBirthday = forTheBirthday;
this.myType = forTheType;
}
}
And here's PersonAdd.java (likewise simplified):
import javax.swing.JOptionPane;
public class PersonAdd {
public static int numOfPeople = 0;
static String instruction = "Enter the person's ";
static String theName;
static String theBirthday;
static String theType;
static void entryText(){
numOfPeople++;
theName = JOptionPane.showInputDialog(null, instruction + "name.", "Add People", JOptionPane.QUESTION_MESSAGE);
theBirthday = JOptionPane.showInputDialog(null, instruction + "birthday.", "Add People", JOptionPane.QUESTION_MESSAGE);
theType = JOptionPane.showInputDialog(null, instruction + "type.", "Add People", JOptionPane.QUESTION_MESSAGE);
}
public static void main(String[] args) {
entryText();
Object person1 = new Person(theName, numOfPeople, theBirthday, theType);
entryText();
Object person2 = new Person(theName, numOfPeople, theBirthday, theType);
entryText();
Object person3 = new Person(theName, numOfPeople, theBirthday, theType);
String response = person1.myName;
JOptionPane.showMessageDialog(null, response);
}
}
The expected result is for the last dialog box to display the name given, but it's not working, although I believe it is storing the data entered correctly. The key problem is in the line
String response = person1.myName;
which cannot be resolved or is not a field. It also happens if I add a get method and use that instead of myName. Eclipse doesn't even seem to be able to see any of the objects of person1.
I'm sure this has to do with my failure to understand inheritance, or static/non-static, or something. (This class-and-object stuff is especially tricky for me to grasp; I think in "SQL mode" and want to be able to say something like "select-from-where".)
You've declared your variable as type Object which is the base type of every reference type, ie. it's the parent class of your Person class.
You can therefore only access fields and methods available through the Object type.
You'll need to declare your variable as type Person
Person person1 = new Person(...);
or cast the variable before you use it
String response = ((Person) person1).myName;
Also, be careful with your access modifiers.

Categories