简体   繁体   中英

Scanner inside method dont ask for input

I ask user to insert an item name with extension ".txt" and if the item name is coresponding to the existing itemName.txt then user need to insert the location name with extension ".txt" where he want to "transfer" it. if everithing is ok then the content from itemName.txt will be writen into the locationName.txt

My Main looks like this:

package victor;

import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Scanner;

public class Main extends Item {
    public Main(String location, Integer length, Integer height, Integer depth) {
        super(location, length, height, depth);
    }

    public static void main(String[] args) throws IOException {
        List<Item> itemList = new ArrayList<>();
        List<Location> locationList = new ArrayList<>();
        System.out.println("Welcome to create new:");
        System.out.println("Please follow the steps:");
        HashMap<Integer, String> menu = new HashMap<>();
        menu.put(1, "Create Location");
        menu.put(2, "Create Item");
        menu.put(3, "Transfer to location");
        menu.forEach((key, value) -> System.out.println(key + "- " + value));
        int user_choice;
        Scanner userInputMenu = new Scanner(System.in);
        user_choice = userInputMenu.nextInt();
        switch (user_choice) {
            case 1:
                createLocationPlusFile(locationList);
            case 2:
                createItemPlusFile(itemList);
            case 3:
                transferItemToLocation(itemList, locationList);
        }
    }
}

When user input from menu - 3 , program is closing Process finished with exit code 0 .

Here is my Item Class with the method I wrote:

package victor;

import java.io.*;
import java.util.List;
import java.util.Scanner;

public class Item extends Location {
    private String itemName;
    private Integer kg;
    private Integer length;
    private Integer height;
    private Integer depth;

    public Item(String itemName, Integer kg, Integer length, Integer height, Integer depth) {
        super();
        this.itemName = itemName;
        this.kg = kg;
        this.length = length;
        this.height = height;
        this.depth = depth;
    }


    public Item() {

    }

    public Item(String location, Integer length, Integer height, Integer depth) {
        super();
    }

    public String getItemName() {
        return itemName;
    }

    public void setItemName(String itemName) {
        this.itemName = itemName;
    }

    public Integer getKg() {
        return kg;
    }

    public void setKg(Integer kg) {
        this.kg = kg;
    }

    public Integer getLength() {
        return length;
    }

    public void setLength(Integer length) {
        this.length = length;
    }

    public Integer getHeight() {
        return height;
    }

    public void setHeight(Integer height) {
        this.height = height;
    }

    public Integer getDepth() {
        return depth;
    }

    public void setDepth(Integer depth) {
        this.depth = depth;
    }

    @Override
    public String toString() {
        return "Item{" +
                "itemName='" + itemName + '\'' +
                ", kg=" + kg +
                ", length=" + length +
                ", height=" + height +
                ", depth=" + depth +
                '}';
    }

    public static void createItemPlusFile(List<Item> itemList) throws NullPointerException, IOException {
        int defaultLength = 80;
        int defaultHeight = 205;
        int defaultDepth = 120;
        int defaultKg = 3500;
        Scanner in1 = new Scanner(System.in);
        System.out.println("Enter Item Name: ");
        String itemName = in1.nextLine();
        System.out.println("New Item created successfully!" + "\n" + itemName);


        int inLength;
        Scanner in2 = new Scanner(System.in);
        System.out.println("Enter Item height: ");
        int itemLength = in2.nextInt();
        if (itemLength > defaultLength) {
            System.out.println("Height that you added is to big, please use a height of max  205");
            inLength = in2.nextInt();
        } else {
            System.out.println("Height inserted correctly! ");
        }


        int inHeight;
        Scanner in3 = new Scanner(System.in);
        System.out.println("Enter Item height: ");
        int itemHeight = in3.nextInt();
        if (itemHeight > defaultHeight) {
            System.out.println("Height that you added is to big, please use a height of max  205");
            inHeight = in3.nextInt();
        } else {
            System.out.println("Height inserted correctly! ");
        }
        int inDepth;
        Scanner in4 = new Scanner(System.in);
        System.out.println("Enter Item depth: ");
        int itemDepth = in4.nextInt();
        if (itemDepth > defaultDepth) {
            System.out.println("Depth that you added is to big, please use a depth of max  120");
            inDepth = in4.nextInt();
        } else {
            System.out.println("Depth inserted correctly! ");
        }
        int inKg;
        Scanner in5 = new Scanner(System.in);
        System.out.println("Enter Item kg: ");
        int itemKg = in4.nextInt();
        if (itemKg > defaultKg) {
            System.out.println("kg that you added is to big, please use a depth of max  3500");
            inDepth = in4.nextInt();
        } else {
            System.out.println("Kg inserted correctly! ");
        }
        Item item = new Item(itemName, itemKg, itemLength, itemHeight, itemDepth);
        File file = new File(item.getItemName() + "CUSCAS001GRY-uk.txt");
        if (!file.exists()) {
            file.createNewFile();
        }
        FileWriter fileWriter = new FileWriter(item.getItemName() + "CUSCAS001GRY-uk.txt", true);
        fileWriter.write(item + "\n");
        fileWriter.close();
    }
//this method I wrote, I expect to ask user to input the item and if item with this name exist then he insert the location where he want to "transfer" it .
       public static void transferItemToLocation(List<Item> itemList, List<Location> locationList) throws IOException {
    for (Item item : itemList) {
        for (Location location : locationList) {
            Scanner inputItemTransfer = new Scanner(System.in);
            System.out.println("Insert the item you want to transfer + .txt  extension!");
            inputItemTransfer.nextLine();
            if (inputItemTransfer.nextLine()
                    .equalsIgnoreCase(item + ".txt")) {
                Scanner inputTransferToLocation = new Scanner(System.in);
                System.out.println("Insert the location where you want to transfer the item");
                inputTransferToLocation.nextLine();
                if (inputTransferToLocation.nextLine()
                        .equalsIgnoreCase(String.valueOf(location))) {
                    BufferedReader bufferedReader = new BufferedReader(new FileReader(String.valueOf(inputItemTransfer)));
                    FileWriter fileWriter = new FileWriter(inputTransferToLocation + ".txt", true);
                    BufferedWriter outputStream = new BufferedWriter(fileWriter);
                    String str;
                    while ((str = bufferedReader.readLine()) != null) {
                        outputStream.write(str + "\n");
                    }
                    outputStream.close();
                }
            }
        }
    }
  }
}

I assume that I do something wrong with the scanner. Any help/critics are totaly appreciated

You don't need to create a Scanner object for every prompt where the User needs to input data. One Scanner object for the entire application will do just fine. Just declare the object as public static within the Main class, for example:

public class Main extends Item {
    
    // Declare a Scanner object that can potentially be used anywhere.
    public static Scanner userInput = new Scanner(System.in).useDelimiter("\\R");


    public Main(String location, Integer length, Integer height, Integer depth) {
        super(location, length, height, depth);
    }

    public static void main(String[] args) throws IOException {
        // ... main() method code here ...
    }
}

Then everywhere you have a prompt to the User and need to use a Scanner method to get input, use Main.userInput. instead, for example:

user_choice = Main.userInput.nextInt();

or:

String itemName = Main.userInput.nextLine();

When using Scanner#nextInt() (or any Scanner#nextXXX methods) and a Scanner#nextLine() prompt will directly follow then you will most likely need to consume the newline character from when the enter key is hit from the Scanner#nextInt() use. The nextInt() method does not consume the newline character like the nextline() method does and therefore the prompt using the nextLine() method appears to be skipped. In cases like this you would want to do:

user_choice = Main.userInput.nextInt();
Main.userInput.nextLine();

A good rule of thumb is:

If you use the Scanner#nextLine() method, then use it for everything otherwise, don't use it at all. Use the next() and nextXXX() methods instead.

If you create your Scanner as shown above (with the useDelimiter("\\R") method) then the Scanner#next() method will return that similar to what the Scanner#nextLine() method would return.


Currently, your transferItemToLocation() method is double prompting for each prompt within the method because of the way you are using the Scanner methods.

public static void transferItemToLocation(List<Item> itemList, List<Location> locationList) throws IOException {
    for (Item item : itemList) {
        for (Location location : locationList) {
            Scanner inputItemTransfer = new Scanner(System.in);
            System.out.println("Insert the item you want to transfer + .txt  extension!");
            inputItemTransfer.nextLine();
            if (inputItemTransfer.nextLine()
                    .equalsIgnoreCase(item + ".txt")) {
                Scanner inputTransferToLocation = new Scanner(System.in);
                System.out.println("Insert the location where you want to transfer the item");
                inputTransferToLocation.nextLine();
                if (inputTransferToLocation.nextLine()
                        .equalsIgnoreCase(String.valueOf(location))) {
                    BufferedReader bufferedReader = new BufferedReader(new FileReader(String.valueOf(inputItemTransfer)));
                    FileWriter fileWriter = new FileWriter(inputTransferToLocation + ".txt", true);
                    BufferedWriter outputStream = new BufferedWriter(fileWriter);
                    String str;
                    while ((str = bufferedReader.readLine()) != null) {
                        outputStream.write(str + "\n");
                    }
                    outputStream.close();
                }
            }
        }
    }
}

I can only assume why you are doing this because you have not provided all your code which is partially why I posted a lot of the drivel about Scanner above. What you've got here is not going to work the way you think it will. As mentioned earlier, get rid of all those Scanner objects and use something similar to what is declared within the Main class (similar to what is shown at the beginning of this post). Declare String variables named inputItemTransfer and inputTransferToLocation . Place the User input into those variables respectively for each prompt and use the data contained within those variables rather than the Scanner objects, for example:

public static void transferItemToLocation(List<Item> itemList, List<Location> locationList) throws IOException {
    String inputItemTransfer;
    String inputTransferToLocation;
    for (Item item : itemList) {
        for (Location location : locationList) {
            System.out.println("Insert the item you want to transfer + .txt  extension!");
            inputItemTransfer = Main.userInput.nextLine();
            if (inputItemTransfer.equalsIgnoreCase(item + ".txt")) {
                System.out.println("Insert the location where you want to transfer the item");
                inputTransferToLocation = Main.userInput.nextLine();
                if (inputTransferToLocation.equalsIgnoreCase(String.valueOf(location))) {
                    BufferedReader bufferedReader = new BufferedReader(new FileReader(String.valueOf(inputItemTransfer)));
                    FileWriter fileWriter = new FileWriter(inputTransferToLocation + ".txt", true);
                    BufferedWriter outputStream = new BufferedWriter(fileWriter);
                    String str;
                    while ((str = bufferedReader.readLine()) != null) {
                        outputStream.write(str + "\n");
                    }
                    outputStream.close();
                }
            }
        }
    }
}

Whether this method is now going to function properly is honestly beyond me. Without all the code or at least a minimal reproducible example it's hard to say. One step at a time I suppose.


On a side:

As mentioned in Comments, it does indeed appear that there is a lot of required data entry by a User to utilize your application which is sort of a downer and actually difficult for some. Perhaps consider a more menu based system to reduce entry requirements and make usage a more comfortable experience.


Good luck.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM