In my program, I am trying to create a method that will Edit any property inside of a BaseContact. BaseContact is an abstract class that is extended within a PersonContact and BusinessContact classes. I want to create an edit method that asks the user what property they want to edit, shows them the old value, and then updates with the new value they want. I reuse a lot of code so I was thinking of trying to make another method that will help recycle code, but I'm unsure how that would work with the need of unique getters and setters.
public void editQuery() {
}
// Edit BaseContact
public void edit(int id) {
try {
contacts.contains(contacts.get(id - 1));
} catch (IndexOutOfBoundsException e) {
System.out.println("Contact does not exist\n--- EXIT ---");
return;
}
Boolean active = true;
// While Statement for Edit
while (active) {
System.out.println(
"What property would you like to edit?\n1. Name\n2. Phone Number\n3. Date of Birth\n4. Hobby\n5. Description"
+ "\n6. Website URL\n7. Hours of Operation\n8. Street\n9. City\n10. State\n11. Zip Code\n12. Location"
+ "\n13. Relatives" + "\n14. Photos\n15. Exit");
String choice = sc.nextLine();
switch (choice.toUpperCase()) {
case "1":
case "NAME":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
System.out.println("Contact Name: " + contact.getName() + "\n");
System.out.print("New Name: ");
String name = sc.nextLine();
contact.setName(name);
System.out.println("Contact Name Set To: " + contact.getName());
}
}
break;
case "3":
case "DATE OF BIRTH":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
if (contact.getType().equals("personContact")) {
PersonContact temp = (PersonContact) contact;
System.out.println("Contact Date of Birth (ex. January 01, 1999): " + temp.getDob() + "\n");
System.out.print("New Date of Birth: ");
String dob = sc.nextLine();
temp.setDob(dob);
System.out.println("Contact Date of Birth Set To: " + temp.getDob());
}
}
}
break;
case "10":
case "STATE":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
System.out.println("Contact State: " + contact.getLocation().getState());
System.out.print("New State: ");
String state = sc.nextLine();
contact.getLocation().setState(state);
System.out.println("Contact State Set To: " + contact.getLocation().getState());
}
}
break;
case "12":
case "LOCATION":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
// Location
Location location = createLocation();
contact.getLocation().setStreet(location.getStreet());
contact.getLocation().setCity(location.getCity());
contact.getLocation().setState(location.getState());
contact.getLocation().setZipCode(location.getZipCode());
System.out.println("Contact Location Set To: " + contact.getLocation());
}
}
break;
case "13":
case "RELATIVES":
for (BaseContact contact : contacts) {
if (contact.getId() == id) {
if (contact.getType().equals("personContact")) {
PersonContact temp = (PersonContact) contact;
System.out.println("List of Relatives");
System.out.print("Contact Relatives: ");
for (int i = 0; i < temp.getRelatives().size(); i++) {
System.out.println(temp.getRelatives().get(i).getName());
}
System.out.println("Would you like to 1. Add or 2. Remove relatives?");
String rChoice = sc.nextLine();
// Adding Relative
if (rChoice.equalsIgnoreCase("1") || rChoice.equalsIgnoreCase("ADD")) {
System.out.println("--- Add Relatives ---");
System.out.println("List of Available Contacts\n");
for (BaseContact rcontact : contacts) {
if (rcontact.getType().equals("personContact")) {
PersonContact rtemp = (PersonContact) rcontact;
System.out.print(rtemp.getName() + " | ");
}
}
System.out.println();
System.out.println("How many relatives would you like to add?");
int numOfRelatives = sc.nextInt();
sc.nextLine();
for (int i = 0; i < numOfRelatives; i++) {
System.out.println("--- Add Relative ---");
System.out.print("Relative Name: ");
String rname = sc.nextLine();
for (BaseContact r2contact : contacts) {
if (r2contact.getType().equals("personContact")) {
PersonContact r2temp = (PersonContact) r2contact;
if (rname.equalsIgnoreCase(r2temp.getName())) {
temp.getRelatives().add(r2temp);
}
}
}
}
// Removing Relative
} else if (rChoice.equals("2") || rChoice.equalsIgnoreCase("REMOVE")) {
System.out.println("--- Remove Relatives ---");
System.out.println("List of Relatives");
for (int i = 0; i < temp.getRelatives().size(); i++) {
System.out.println(temp.getRelatives().get(i).getName());
}
System.out.println();
System.out.println("How many relatives would you like to remove?");
int numOfRelatives = sc.nextInt();
sc.nextLine();
if (numOfRelatives > temp.getRelatives().size()
|| numOfRelatives == temp.getRelatives().size()) {
temp.getRelatives().clear();
System.out.println("All Relatives Removed");
} else {
for (int i = 0; i < numOfRelatives; i++) {
System.out.println("--- Remove Relative ---");
System.out.print("Relative Name: ");
String rName = sc.nextLine();
for (BaseContact r2contact : contacts) {
if (r2contact.getType().equals("personContact")) {
PersonContact r2temp = (PersonContact) r2contact;
if (rName.equalsIgnoreCase(r2temp.getName())) {
temp.getRelatives().remove(r2temp);
}
}
}
}
}
} else {
System.out.println("Invalid Option");
}
}
}
}
break;
Well ask and thou shall receive. I have looked mainly at the humongous switch statement you have going on. For a starter, that should be condensed. A more functional style of programming can help here.
I had to deduce a lot of the classes you have used based on the methods which were called in the code. Furthermore, I have picked a couple of switch expressions and converted them in something more dynamic. See this as a starting point to build on for the rest of your application.
Start of with creating an action class for the simple edits:
public class ActionHolder {
private final String actionText;
private final BiConsumer<String, PersonContact> action;
private final Function<PersonContact, String> originalValFunc;
public ActionHolder(String actionText, BiConsumer<String, PersonContact> action,
Function<PersonContact, String> originalValFunc) {
this.actionText = actionText;
this.action = action;
this.originalValFunc = originalValFunc;
}
public String getActionText() {
return actionText;
}
public BiConsumer<String, PersonContact> getAction() {
return action;
}
public Function<PersonContact, String> getOriginalValFunc() {
return originalValFunc;
}
}
The action class relies heavily on functional interfaces, make sure you read up on them thoroughly as they provide a powerful way of programming. (https://www.baeldung.com/java-8-functional-interfaces)
actionText: Is used to label the attribute which is edited.
action: A function which accepts two arguments and returns nothing.
In this case we will use this to set the respective value on the
PersonContact
originalValFunc: A function to retrieve the origional value from the
PersonContact, it is a function with one parameter (PersonContact)
and it returns a string.
The edit method can then be build up as follows:
class TestInputProgram {
public static void main(String[] args) {
TestInputProgram inputProgram = new TestInputProgram();
inputProgram.edit(1);
}
private final Scanner sc = new Scanner(System.in);
//Initialize with temp data
private final ArrayList<PersonContact> contacts = new ArrayList<PersonContact>() {{
add(new PersonContact(1));
}};
private static final Map<String, ActionHolder> actionMap = new HashMap<String, ActionHolder>() {{
put("1", new ActionHolder("Contact Name",
(input, contact) -> contact.setName(input), BaseContact::getName));
put("NAME", new ActionHolder("Contact Name",
(input, contact) -> contact.setName(input), BaseContact::getName));
put("3", new ActionHolder("Date of Birth",
(input, contact) -> contact.setDob(input), PersonContact::getDob));
put("DATE OF BIRTH", new ActionHolder("Date of Birth",
(input, contact) -> contact.setDob(input), PersonContact::getDob));
put("10", new ActionHolder("State",
(input, contact) -> contact.getLocation().setState(input),
(contact -> contact.getLocation().getState())));
put("STATE", new ActionHolder("State",
(input, contact) -> contact.getLocation().setState(input),
(contact -> contact.getLocation().getState())));
}};
// Edit BaseContact
public void edit(int id) {
while (true) {
System.out.println(
"What property would you like to edit?\n" +
"1. Name\n" +
"2. Phone Number\n" +
"3. Date of Birth\n" +
"15. Exit");
String choice = sc.nextLine();
if (Objects.equals(choice, "15")) {
break;
}
PersonContact pContact = contacts.stream()
.filter(contact -> contact.id == id)
.findFirst()
.orElseThrow(
() -> new IllegalArgumentException("Contact with id: " + id + " does not exist!")
);
Optional.ofNullable(actionMap.get(choice.toUpperCase())).ifPresent(actionHolder -> {
System.out.println(actionHolder.getActionText() + " current value: "
+ actionHolder.getOriginalValFunc().apply(pContact) + "\n");
System.out.println("Please provide the new value:");
String newValue = sc.nextLine();
actionHolder.getAction().accept(newValue, pContact);
System.out.println(actionHolder.getActionText() + " set to: "
+ actionHolder.getOriginalValFunc().apply(pContact));
System.out.println("############################# \n");
});
}
}
}
Some brief info about the variables and whats going on:
The actionMap holds all the possible edit options we currently provide. Notice the implementation of the action holder arguments. We implement the actions using both lamda's and static method references. Inside the edit method the map is queried and the actionHolder retrieved. The respective input action info is then printed to the user and asked for input. The input is processed using the (BiConsumer) from the actionHolder.
I hope this will provide some reference for future programming optimization.
Related
I'm working on this project and I'm in the process of creating the searchStore() method in User class but I can't think of any way to access the cost of the candies in a certain store.
When the user searches for a store, the program should print the stores that is nearby the landmarks, so if the user visits the lm 4 and lm1, Lolli's and Guccini's store would print. I need to access the cost of the candies in the store to check if the money of the user is enough to buy a candy. If the money is sufficient, then it should print that the user can buy a candy in the store, else it should prompt that the money is not enough to buy a candy.
I tried to create an instance inside the method but that's not correct because if I am to make a new instance, I'm not accessing the cost of the store that I want, but the cost of the instance that I created.
I also tried the getter method in the CandyStore class but it says that I should make the attribute cost static but that is not possible because the cost varies in different stores.
Can someone help me to implement the searchStore method in User class?
MAIN CLASS
package testing;
public class Main {
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello World");
User user1 = new User("Mylah", 1, 20f);
User user2 = new User("Meg", 2, 50f);
User user3 = new User("Marga", 3, 25f);
Landmark lm1 = new Landmark("Vista Mall", 1);
Landmark lm2 = new Landmark("Vista Residences", 2);
Landmark lm3 = new Landmark("Vista Park", 3);
Landmark lm4 = new Landmark("Crystal Mall", 4);
Landmark lm5 = new Landmark("Crystal Residences", 5);
Landmark lm6 = new Landmark("Crystal Park", 6);
CandyStore c1 = new CandyStore("Lolli's Store", 1, 15);
CandyStore c2 = new CandyStore("Mary's Store", 2, 25);
CandyStore c3 = new CandyStore("Guccini's Store", 3, 10);
c1.addLandmark(lm4);
c1.addLandmark(lm6);
c2.addLandmark(lm2);
c2.addLandmark(lm3);
c3.addLandmark(lm1);
c3.addLandmark(lm5);
user1.visits(lm4);
user1.visits(lm1);
user1.searchStore();
user1.viewState();
}
}
USER CLASS
package testing;
public class User {
String name;
int StudentId;
float money;
Landmark[] lm;
int lmCounter;
static int MAX_LM = 3;
User(String n, int id, float m) {
this.name = n;
this.StudentId = id;
this.money = m;
this.lm = new Landmark[User.MAX_LM];
}
void visits(Landmark l) {
if(this.lmCounter < MAX_LM) {
this.lm[this.lmCounter++] = l;
} else {
System.out.println("Please go home, you visited too many places already!\n");
}
}
void searchStore() {
//insert code here
}
void viewState() {
System.out.println("\n======== VIEW STATE ========");
System.out.println("Student ID: " + this.StudentId);
System.out.println("Student Name: " + this.name);
System.out.println("Student's Money: " + this.money);
if(this.lmCounter == 0) {
System.out.println(this.name + " is still in school!\n");
} else {
System.out.println(this.name + " visited :");
for (int i = 0; i < lmCounter; i++) {
Landmark L = lm[i];
int j = i+1;
System.out.println(j + ". " + L.name);
}
}
}
}
CANDYSTORE CLASS
package testing;
public class CandyStore {
String name;
int StoreId;
float cost; // cost of candies inside the store
int sales;
Landmark[] LM;
int lmCounter;
static int MAX_LM = 3;
CandyStore(String n, int id, float c) {
this.name = n;
this.StoreId = id;
this.cost = c;
this.sales = 0;
this.LM = new Landmark[CandyStore.MAX_LM];
}
void addLandmark(Landmark lm) {
if(this.lmCounter < MAX_LM) {
this.LM[this.lmCounter++] = lm;
} else {
System.out.println("Can't add landmark\n");
}
}
void ViewState() {
System.out.println("\n======== VIEW STATE ========");
System.out.println("Store ID: " + this.StoreId);
System.out.println("Store Name: " + this.name);
System.out.println("Store Sales: " + this.sales);
System.out.println("Landmark nearby");
if(lmCounter == 0) {
System.out.println("The store doesn't have any recognizable landmark\n");
} else {
for(int i = 0; i < lmCounter; i++) {
Landmark l = LM[i];
int j = i+1;
System.out.println(j + ". " + l.name);
}
}
}
}
LANDMARK CLASS
package testing;
public class Landmark {
int LMid; // landmark number
String name;
Landmark (String n, int id) {
this.name = n;
this.LMid = id;
}
void viewState() {
System.out.println("\n======== VIEW STATE ========");
System.out.println("Landmark Number: " + this.LMid);
System.out.println("Landmark Name: " + this.name);
}
}
PS. Please show me how to do the code correctly, thank you.
The problem is void searchStore() needs some help finding the stores from the class that created the CandyStores.
Your stores are created in the Main class so that's where we need code to find the nearby stores and pass them along to the searchStore() method, which I suggest renaming to searchStores().
Consider the following example. I added comments throughout the added code to explain what it does, and some tips to improve.
MAIN CLASS
public class Main {
//class variable so that we can access candyStore list in other methods
public static List<CandyStore> candyStores;
public static void main(String[] args) {
// TODO Auto-generated method stub
System.out.println("Hello World");
User user1 = new User("Mylah", 1, 20f);
User user2 = new User("Meg", 2, 50f);
User user3 = new User("Marga", 3, 25f);
Landmark lm1 = new Landmark("Vista Mall", 1);
Landmark lm2 = new Landmark("Vista Residences", 2);
Landmark lm3 = new Landmark("Vista Park", 3);
Landmark lm4 = new Landmark("Crystal Mall", 4);
Landmark lm5 = new Landmark("Crystal Residences", 5);
Landmark lm6 = new Landmark("Crystal Park", 6);
CandyStore c1 = new CandyStore("Lolli's Store", 1, 15);
CandyStore c2 = new CandyStore("Mary's Store", 2, 25);
CandyStore c3 = new CandyStore("Guccini's Store", 3, 10);
c1.addLandmark(lm4);
c1.addLandmark(lm6);
c2.addLandmark(lm2);
c2.addLandmark(lm3);
c3.addLandmark(lm1);
c3.addLandmark(lm5);
//Create a list of stores for easy lookup
candyStores = List.of(c1, c2, c3);
user1.visits(lm4);
user1.visits(lm1);
//Use the new method
List<CandyStore> nearbyStores = findNearbyStores(user1);
//Pass along the nearby stores
user1.searchStore(nearbyStores);
user1.viewState();
}
public static List<CandyStore> findNearbyStores(User user) { //Using a method to keep the program code organized
List<CandyStore> nearbyStores = new LinkedList<>(); //Make the candy store output list
Landmark userLandmark = user.lm[user.lmCounter]; //This was complicated, user should have a user.getLandmark() method instead.
for (CandyStore candyStore : candyStores) { //Look through the candystores
if (Arrays.asList(candyStore.LM).contains(userLandmark)) { //Have to convert LM array to list to use basic contains() method (better to just use lists instead of arrays to begin with unless you're building a very efficient server application
nearbyStores.add(candyStore); //Add the candy store to output list if its list of landmarks contains the user's current landmark.
}
}
return nearbyStores;
}
}
Finally, the searchStore() method in the User class can look like this:
void searchStore(List<CandyStore> nearbyStores) {
for (CandyStore candyStore : nearbyStores) { //Check each store
if (money >= candyStore.cost) { //Determine if they have enough money or not enough money
System.out.println("You have enough money to buy candy from " + candyStore.name);
} else {
System.out.println("You don't have enough money to buy candy from " + candyStore.name);
}
}
}
As you become a better Java programmer, you may come to realize that it's best to keep separate data classes, and the classes that manipulate and act upon the data. Data classes shouldn't be intelligent or have access to other data classes. And therefore if you are wanting to access an attribute in another class and can't, that code probably doesn't belong there.
This type of programming can prevent spaghetti code where a trail of code travels very deep throughout the program jumping from class to class rather than having all its cards laid out on the table in front of it.
Hereby a draft solution. However, for it to work, you need to modify existing code a bit (I marked new lines with ***):
LANDMARK
public class Landmark {
int LMid; // landmark number
String name;
// ***
CandyStore nearbyStore;
Landmark (String n, int id) {
this.name = n;
this.LMid = id;
}
void viewState() {
System.out.println("\n======== VIEW STATE ========");
System.out.println("Landmark Number: " + this.LMid);
System.out.println("Landmark Name: " + this.name);
}
// ***
CandyStore getNearbyStore() {
return nearbyStore;
}
// ***
void setNearbyStore(CandyStore candyStore) {
nearbyStore = candyStore;
}
}
CANDYSTORE
...
void addLandmark(Landmark lm) {
if(this.lmCounter < MAX_LM) {
this.LM[this.lmCounter++] = lm;
// ***
lm.setNearbyStore(this);
} else {
System.out.println("Can't add landmark\n");
}
}
...
// ***
float getCandyCost() {
return cost;
}
...
and finally the USER
...
void searchStore() {
// insert code here
System.out.println("Stores nearby visited landmarks:");
for (int i = 0; i < lmCounter; i++) {
Landmark visitedLandmark = lm[i];
CandyStore store = visitedLandmark.getNearbyStore();
store.ViewState();
if (store.getCandyCost() > money) {
System.out.println("The candies are too expensive here, bad luck :(");
} else {
System.out.println("Good news! You can buy a candy in this store!");
}
}
}
...
I apologize in advance for my rudimentary code--I started coding a couple months ago.
I'm trying to code a text-based baking game where there's a limited number of combos/recipes (16), and the user has to try to unlock all of the cake combos in order to finish the game. When I try to run the code, when asked for the topping the user wants, no matter what input I type in, the code doesn't run past this part. The expected result would be to take both the flavor and topping and add them together to become the new string of cake.
[A screenshot of the described problem][1]
[1]: https://i.stack.imgur.com/bphyO.png
Another problem I had, but can't check if I still have it because the code won't run past the "topping user input" section, is that when the code runs to the section where it checks if the cake combo has already been found or not, inside the terminal it prints out the combo the user first found infinitely.
I'd really appreciate any help, thank you so much.
The code:
import java.util.Arrays;
import java.util.Scanner;
import java.util.ArrayList;
public class Bakery
public ArrayList<String> aList = new ArrayList();
public static int achievements = 0;
static ArrayList<String> foundCakes = new <String>ArrayList();
public static String[] f = {"chocolate", "vanilla", "strawberry", "banana"};
public static String[] t = {"sprinkles", "fruit", "frosting", "nothing"};
public static void main (String[]args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
System.out.println("(To quit the game, type in 'quit')");
delay("Hi, what's your name?", 60L);
String playerName = sc.nextLine();
delay("Your name is: " + playerName, 60L);
delay("Welcome to this Bakery!", 40L);
delay("This Bakery has been without an owner for so long...",40L);
delay("Most of it's recipies have been lost.", 40L);
delay("It's up to you to collect all of the lost recipies!", 40L);
delay("These are the ingredients provided: ", 60L);
delay("Base flavors: " + Arrays.toString(f), 60L);
delay("Toppings: " + Arrays.toString(t), 60L);
while (achievements != 16){
System.out.println("Pick a flavor");
String flavor = sc.nextLine();
if (flavor.equalsIgnoreCase("quit")){
delay("Thanks for playing!", 40L);
System.exit(0);
}
String cuFlavor = flavor.toLowerCase();
boolean oo = false;
while (oo){
if(Arrays.asList(f).contains(cuFlavor)){
oo = true;
}
}
if (Arrays.asList(f).contains(cuFlavor) == false){
delay("Not an option, please pick again.", 40L);
flavor = sc.nextLine();
}
System.out.println("Pick a topping");
String topping = sc.nextLine();
if (topping.equalsIgnoreCase("quit")){
delay("Thanks for playing!", 40L);
System.exit(0);
}
String cuTopping = topping.toLowerCase();
boolean tt = false;
while (tt==false){
if(Arrays.asList(t).contains(cuTopping) == true){
tt = true;
}
}
if (Arrays.asList(t).contains(cuTopping) == false){
delay("Not an option, please pick again.", 40L);
topping = sc.nextLine();
}
String cake = cuFlavor+cuTopping;
boolean bb = false;
while (bb == false){
if(foundCakes.contains(cake)){
delay("Previously found recipe!", 40L);
delay(getRandomResponse(), 40L);
bb = true;
}
}
boolean nc = true;
while(nc == true){
if(foundCakes.contains(cake) == false){
delay("You found a new cake!", 40L);
delay("Unlocked: "+cake, 40L);
foundCakes.add(cake);
achievements++;
delay("Number of recipes found: " + achievements, 40L);
nc = false;
}
}
}
System.exit(0);
}
public int getAchievements(){
return achievements;
}
private static String getRandomResponse()
{
final int NUMBER_OF_RESPONSES = 4;
double r = Math.random();
int whichResponse = (int)(r * NUMBER_OF_RESPONSES);
String response = "";
if (whichResponse == 0)
{
response = "Don't worry! Still delicious.";
}
else if (whichResponse == 1)
{
response = "What a classic cake!";
}
else if (whichResponse == 2)
{
response = "Yummy :)";
}
else if (whichResponse == 3)
{
response = "Smells nice!";
}
return response;
}
public String toString(){
return "Flavors: "+Arrays.toString(f)+" Topping: "+Arrays.toString(t);
}
public static void delay(String s, long delay) throws InterruptedException {
for ( int i= 0; i < s.length(); i++) {
// for loop delays individual String characters
System.out.print(s.charAt(i));
Thread.sleep(delay); //time is in milliseconds
}
System.out.println(""); // this is the space in between lines
}
}
Take a look at your while loops. First:
boolean oo = false;
while (oo){
if (Arrays.asList(f).contains(cuFlavor)) {
oo = true;
}
}
This loop is never entered since oo == false.
Next:
boolean tt = false;
while (tt == false) {
if (Arrays.asList(t).contains(cuTopping) == true) {
tt = true;
}
}
This loop does execute, but what happens if t does not contain cuTopping? In that case, tt never get sets to true and the loop goes on forever.
The next two loops have the same issue.
You need to ensure the loops will end at some point. Example:
while (tt == false) {
if (Arrays.asList(t).contains(cuTopping) == true) {
tt = true;
}
else {
// Do something to change cuTopping
System.out.println("Pick a topping");
cuTopping = sc.nextLine();
// etc....
}
}
You can combine the loops with the gathering of the input:
String cuTopping = null;
do {
if (cuTopping != null) { // Only true after first iteration
System.out.println("That topping is not in the list!");
}
System.out.println("Pick a topping");
cuTopping = sc.nextLine().toLowerCase();
if (cuTopping.equalsIgnoreCase("quit")) {
delay("Thanks for playing!", 40L);
System.exit(0);
}
} while (!Arrays.asList(t).contains(cuTopping));
I'm trying create a program that use dialog boxes and stores elements in Object Goals(string, int, int). This is just a home project I've decided to do during Uni holidays.
So far it's working how I planned but there is one bug I can't figure out.
//asks user to input goals and stores them in an array list
public static void setup(){
int n = 0;
int i = 0;
boolean setupFinished = false;
boolean success = false;
List<Goals> setupList = new ArrayList<Goals>();
JOptionPane setupBox = new JOptionPane();
while(!setupFinished){
Goals goal = new Goals();
String str1 = JOptionPane.showInputDialog("A goal you wish to work on?");
if(str1 == null){
System.exit(0);
}
goal.setGoal(str1);
String goalPrefInput = JOptionPane.showInputDialog("What is the initial preference of this goal compare to the others?");
if(goalPrefInput == null){
System.exit(0);
} else if (goalPrefInput.equalsIgnoreCase("")){
n = Integer.parseInt("1");
} else {
while(!success){
try {
n = (Integer.parseInt(goalPrefInput));
success = true;
}
catch (Exception NumberFormatException){
JOptionPane.showMessageDialog(null, "You must enter a valid number");
}
}
}
goal.setGoalPref(n);
System.out.println(goal.getGoalPref());
success = false;
String goalFreqInput = JOptionPane.showInputDialog("What is the frequency rate you wish this preference to increase?");
if(goalFreqInput == null){
System.exit(0);
} else if (goalFreqInput.equalsIgnoreCase("")){
n = Integer.parseInt("1");
} else {
while(!success){
try {
n = (Integer.parseInt(goalFreqInput));
success = true;
}
catch (Exception NumberFormatException){
JOptionPane.showMessageDialog(null, "You must enter a valid number");
}
}
}
goal.setGoalPrefIncrease(n);
System.out.println(goal.getGoalPrefIncrease());
setupList.add(i, goal);
i++;
int f = JOptionPane.showConfirmDialog(null, "Have you finished setup?", "Setup Finished?", YES_NO_OPTION);
if(f == JOptionPane.YES_OPTION){
setupFinished = true;
}
}
System.out.print(setupList.toString());
String s = removeBrackets(setupList.toString());
JOptionPane.showMessageDialog(setupBox, "Here are your goals \n" + s);
}
}
It's not finished but what is happening that I don't understand is that the user will enter the first instance of goal the user will put in -
goal: a, goalPref: 1, goalFreq: 1.
Then the second instance they will put in
goal: b, goalPref: 2, goalFreq: 2.
However for the second instance the goalPref that is suppose to 2 will return 1 whilst goalFreq will return a 2 correctly. If the next instance is
goal: c, goalPref: 3 goalFreq: 3.
Then it will return c, 2, 3 as the previous goalPref was 2.
The thing that confuses me is the code for entering goalPref and goalFreq is identical so why is one working and one isn't?
Here is the Goals class code:
public class Goals {
private String goal;
private int goalPref;
private int goalPrefIncrease;
public String getGoal() {
return goal;
}
public void setGoal(String goal) {
this.goal = goal;
}
public int getGoalPref() {
return goalPref;
}
public void setGoalPref(int goalPref) {
this.goalPref = goalPref;
}
public int getGoalPrefIncrease() {
return goalPrefIncrease;
}
public void setGoalPrefIncrease(int goalPrefIncrease) {
this.goalPrefIncrease = goalPrefIncrease;
}
#Override
public String toString() {
String s = "Goal: " + this.getGoal() + ", Goal Preference: " + this.getGoalPref() + ", Goal Frequency Rate: " + this.getGoalPrefIncrease();
//String s = goal + ", Goal Preference: " + goalPref + ", Goal Frequency Rate: " + goalPrefIncrease;
return s;
}
}
You should have used a debugger to see what is the mistake in your code. The problem here is your success variable which holds a key in determining value of n for your inputs.
Currently at the end of your loop it is true so in next cycle its value is still true and after entering goal pref it is not going in your while(!success) loop to determine value of n so last value of n(which is last value of goal frequency you entered) is assigned to new goal pref.
In order to correct it you need to reset value of success to false at the start of every iteration.
while(!setupFinished){
success = false;
Goals goal = new Goals();
Hope this helps.
In my text-adventure game one of the commands is "take" which requires the user to enter both the letter 'T' and an item that is in the room they are in.
I have taken this input and split it into command and item, but I'm having trouble with the if statement. I have the first part that checks if the command section is equal to 'T', but I have to also check if this input has an "item" section to it. I tried using .isEmpty() and != null as well as using .contains().
Here is my code:
public Command getCommandFromResponse(String response) throws IllegalArgumentException{
String[] split = response.split(" ");
if (split.length < 1){
throw new IllegalArgumentException("Invalid command.");
}
Command command = new Command(split[0]);
if (split.length >= 2) {
command.setItem(split[1]);
}
return command;
}
This is the take method:
else if(userCommand.command.equalsIgnoreCase("T") && /*if userCommand contains an item*/){
//Split the input String into two parts, command and item
userCommand = getCommandFromResponse(userInput.nextLine());
if (locale.item != null) {
if (userCommand.item.equalsIgnoreCase(locale.item.itemName)) {
//add the item to the player's inventory
player1.inventory.add(locale.item);
System.out.println("\tA " + locale.item + " was added to your inventory");
System.out.println("\n\tYou can view your inventory by pressing 'I' or drop an item by pressing 'D'.");
if (locale.item.itemName.equals("map")) {
System.out.println("\n\tTo view the map press 'M'.");
}
//Add the item's worth to the score and set the items worth to zero to prevent double scoring
player1.score += locale.item.value;
System.out.println("\n\t" + locale.item.value + " points have been added to your score.");
System.out.println("\n\tThis is your current score: "+player1.score);
//remove the item from the current location
locale.item = null;
break;
} else {
System.out.println("\n\tThat item is not at this location.");
}
} else {
System.out.println("\n\tThere is no item to pick up here");
}
}//End of Take
This is my Command class:
public class Command {
String command;
String item;
public Command(String comm){
command = comm;
}
public Command(String comm, String item){
this.command = comm;
this.item = item;
}
public void setCommand(String command){
this.command = command;
}
public void setItem(String item){
this.item = item;
}
public String getCommand(){
return this.command;
}
public String getItem(){
return this.item;
}
public String toString(){
return this.command + ":" + this.item;
}
}
These are my items:
//Items {itemName, itemDes}
static Item[] items = {
new Item ("map","a layout of your house", 10 ),
new Item ("battery", "a double A battery", 5),
new Item ("flashlight", "a small silver flashlight", 10),
new Item ("key", "this unlocks some door in your house", 15),
};
I have more code if this is unclear.
My suggestion is to do it the following way:
change
if (userCommand.item.equalsIgnoreCase(locale.item.itemName)) {
to
if (userCommand.item!=null && userCommand.item.equalsIgnoreCase(locale.item.itemName)) {
This is the simplest way, which won't throw an exception if there was no item in the command.
(I'm sorry if this was not your question, but this is the problem what I think you mean.)
I am calling a method that passes in a variable. I want to be able to compare this variable to all the items in an ArrayList to see if there is a match.
This is my code...
private boolean input;
private ArrayList chcekItem = new ArrayList();
public void setAction(String action) {
input=true;
if (getChcekItem().isEmpty()) {
getChcekItem().add(action);
}
else {
Iterator iterators = getChcekItem().iterator();
while (iterators.hasNext()) {
if (iterators.next()==action) {
System.out.println(iterators.next()+"="+action);
input=false;
}
}
if (input) {
getChcekItem().add(action);
System.out.println("The item " + action + " is Successfully Added to array");
}
else{
System.out.println("The item " + action + " is Exist");
}
}
}
My code isn't working as I had expected. Could someone please help me fix the problem.
I take it that the checkItem variable is a List of Strings, thus it should be defined like this:
private List<String> checkItem = new ArrayList<String>();
When comparing an String you don't use string1==string2 but string1.equals(string2);
So
(iterators.next()==action)
should be:
(iterators.next().equals(action))
Remember to check the string for null values.
So the whole code could look like this:
private boolean input;
private List<String> chcekItem= new ArrayList<String>();
public void setAction(String action) {
input=true;
if (getChcekItem().isEmpty()) {
getChcekItem().add(action);
} else {
//Foreach loop instead of an iterator ;)
for(String item : chcekItem) {
if(item.equals(action)) {
System.out.println(item+"="+action);
input=false;
//We can jump out of the loop here since we already found a matching value
break;
}
}
if (input) {
getChcekItem().add(action);
System.out.println("The item " + action + " is Successfully Added to array");
}else{
System.out.println("The item " + action + " is Exist");
}
}
}
}