Going through a handler class object to read console - java

you may have seen my previous question, this builds on that with the implementation of a handler. however im finding it difficult to get it to work correctly.
i have three classes:
main.java
- simple method which requests to read console and then outputs the user input.
handler.java
- requests 'readconsole' from gui.java
gui.java
- displays gui
- reads console
feel like im missing something simple!
main.java
public class main {
static handler handler = new handler();
public static void main(String[] args) {
}
public static void menuSwitch(String input) {
System.out.println("entered menu switch with input " +input);
String s = handler.requestReadConsole();
System.out.println(s);
}
}
handler.java
public class handler {
static gui gui = new gui();
static String inputvariable= null;
public handler() {
requestAndSortReadConsole();
}
public String requestReadConsole() {
System.out.println("entered read console");
String s = gui.readConsole();
return s;
}
public String requestAndSortReadConsole() {
System.out.println("entered requestAndSortReadConsole");
sortInput(requestReadConsole());
System.out.println("sorted value = " + inputvariable);
return inputvariable;
}
public void sortInput(String input) {
System.out.println("entered sort input with input = " + input);
if (input.length() == 1) {
System.out.println("input length EQUALS 1");
main.menuSwitch(input);
}else {
inputvariable = input;
System.out.println(inputvariable);
}
System.out.println("return input");
}
}
gui.java
public class gui {
static Scanner in = new Scanner(System.in);
public gui() {
System.out.println("main menu called");
mainMenu();
}
public void mainMenu() {
System.out.println("press 1 for case 1");
System.out.println("press 2 for case 2");
System.out.println("press 3 for case 3");
}
public String readConsole () {
String input = null;
System.out.println("entered readconsole gui");
input = in.nextLine();
System.out.println("input = " + input);
in.close();
return input;
}
}
The method menuSwitch should print variable s but it doesnt print anything and continues to allow user to input to console!

Related

How do i get my java code to restart automatically all over again instead of the program ending? [duplicate]

This question already has an answer here:
Closing a Scanner throws java.util.NoSuchElementException
(1 answer)
Closed 4 years ago.
Currently im new to java, and im trying to get my code to restart from the top so essentially you can keep entering sentences until user cancels on purpose. Currently i keep getting an error.
import java.util.Scanner;
public class Reverser {
public static void main(String[] args) {
boolean run = true;
while(run) {
for(;;) {
Scanner scan = new Scanner(System.in);
System.out.println("Hello Welcome To The Sentence Reverser !");
System.out.println("Enter a sentence below to reverse.");
String str = scan.nextLine();
scan.close();
String reversedStr = new StringBuilder(str).reverse().toString();
System.out.println("Initial Sentence: " + str);
System.out.println("Reversed Sentence: " + reversedStr);
}
}
}
}
I once did something similar to this, this was for moderators to check specific user accounts. You basically re-call the search method after input handling. This way you can reset the program to a previous state.
/**
* #author Stan van der Bend
*/
public class Scanner {
private static final String CHARACTER_FILE_PATH = "data/characters";
private static ArrayDeque<String> matches = new ArrayDeque<>(200);
public static void main(final String... args) throws IOException {
search();
}
private static void search() throws IOException{
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter your desired keyword: ");
String keyword = reader.readLine();
System.out.println("Started scanning all files...");
long start = System.currentTimeMillis();
try {
Path path = Paths.get(CHARACTER_FILE_PATH);
Files.walkFileTree(path, new SimpleFileVisitor<>() {
#Override
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) throws IOException {
matches.addAll(Files
.readAllLines(path)
.stream()
.filter(line -> line.contains(keyword))
.collect(Collectors.toList())
);
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
e.printStackTrace();
System.out.println("Make sure this is in the same directory as "+CHARACTER_FILE_PATH);
}
long duration = System.currentTimeMillis() - start;
System.out.println("Found "+matches.size()+" matches for the keyword "+keyword);
matches.stream().sorted(Comparator.comparing(PlayerLogs::getDate)).forEach(System.out::println);
System.out.println("The scan toke " + duration + "ms to complete.");
System.out.print("For another scan type -r ");
matches.clear();
if(reader.readLine().equalsIgnoreCase("-r"))
search();
reader.close();
}
}

Test InputStream with Junit

I'm trying to test a function "DataFeatures" in my class "UserInput".
It doesn't matter what arguments I give in the test, It always pass.
Fields and constructor
public #Getter class UserInput {
FileType type;
FileOperation operation;
SynchronizationMethod method;
String path;
private static InputReader in = new InputReader();
public UserInput() {
// Dont need to do anything
}
Function to test
void getDataFeatures() {
System.out.println("For encryption press 1");
System.out.println("For decryption press 0");
operation = FileOperation.fromInt(in.nextInt());
System.out.println("For a file choose 1");
System.out.println("For an entire directory choose 0");
type = FileType.fromInt(in.nextInt());
if (type == FileType.DIR) {
System.out.println("For sync press 1");
System.out.println("For async press 0");
method = SynchronizationMethod.fromInt(in.nextInt());
}
}
My test
public class UserInputTest {
UserInput UI;
private final ByteArrayOutputStream outContent = new ByteArrayOutputStream();
private final ByteArrayOutputStream errContent = new ByteArrayOutputStream();
private final PrintStream oldStdOut = System.out;
private final PrintStream oldStdErr = System.err;
private final InputStream oldStdIn = System.in;
#Before
public void initlize(){
System.setOut(new PrintStream(outContent));
System.setErr(new PrintStream(errContent));
UI = new UserInput();
}
#Test
public void getDataFeaturesTest() {
String data = "0" + "\n0" + "\n0";
System.setIn(new ByteArrayInputStream(data.getBytes()));
UI.getDataFeatures();
System.out.println(UI.getOperation());
assertThat(UI.getOperation(), is(equalTo(FileOperation.decryption)));
assertThat(UI.getType(), is(equalTo(FileType.FILE)));
assertThat(UI.getMethod(), is(equalTo(SynchronizationMethod.SYNC)));
}
#After
public void cleanUpStreams() {
System.setOut(oldStdOut);
System.setErr(oldStdErr);
System.setIn(oldStdIn);
}
}
Note 1: FileOperation, FileType and SynchronizationMethod are all enums that get 1 or 0.
Example of SynchronizationMethod:
public enum SynchronizationMethod {
SYNC(1), ASYNC(0);
private int method;
private SynchronizationMethod(int meth) {
this.method = meth;
}
public static SynchronizationMethod fromInt(int meth) {
for (SynchronizationMethod SM : SynchronizationMethod.values()) {
if (SM.method == meth) {
return SM;
}
}
throw new IllegalArgumentException("No constant with method " + meth + " found");
}
public String toString(){
if (method == 1){
return "Sync";
}
else if(method == 0){
return "ASync";
}
else{
throw new IllegalArgumentException("No constant with method " + method + " found in toString");
}
}
}
Solution
The problem was in the class InputReader in the constructor function.
public InputReader() {
reader = new BufferedReader(new InputStreamReader(System.in));
tokenizer = null;
}
The reader in this function and the Input Stream in the Junit function were disconnenct as suggested in the comments
Guessing here - your UserInput class says:
private static InputReader in = new InputReader();
Whereas your testcase says:
String data = "0" + "\n0" + "\n0";
System.setIn(new ByteArrayInputStream(data.getBytes()));
In other words: there might be a disconnect. Depending on the implementation behind InputReader you might simply be reading from the wrong source.

NullPointerException on a static attribute

I am creating a simple login program in java. Here is the code i have so far.
import java.util.Scanner;
import java.io.*;
import java.util.Arrays;
public class PasswordProgram {
public static String user;
public String password;
public static boolean part1Finish = false;
public File file = new File("D:/file.txt");
public FileWriter UsernameWrite;
public char[] user1;
public void part1() {
System.out.println("Please create an account: ");
Scanner input = new Scanner(System. in );
System.out.println("Type in a username: ");
String user = input.next();
System.out.println("Type in a Password: ");
String password = input.next();
try {
UsernameWrite = new FileWriter(file);
UsernameWrite.write(user);
UsernameWrite.write(password);
System.out.println(user);
UsernameWrite.close();
part1Finish = true;
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void part2() {
Scanner scan = new Scanner(System. in );
System.out.println("Please confirm your username: ");
String usercheck = scan.next();
int PassAttempts = 5;
int UserAttempts = 5;
user1 = user.toCharArray();
user1 = password.toCharArray();
char[] usernamecheck = java.util.Arrays.copyOfRange(user1, 0, user.length());
System.out.println(usernamecheck);
do {
if (usercheck.equals(usernamecheck)) {
while (PassAttempts > 0) {
System.out.println("Please confirm your password: ");
String passcheck = scan.next();
if (passcheck.equals(password)) {
System.out.println("Thank You ");
} else if (passcheck != password && PassAttempts > 0) {
PassAttempts--;
System.out.println("That is incorrect. Please Try Again");
passcheck = scan.nextLine();
} else {
System.out.println("You have run out of Password Attempts");
break;
}
}
} else if (usercheck != user && UserAttempts > 0) {
UserAttempts--;
System.out.println("That is an incorrect username. Please Try Again");
usercheck = scan.nextLine();
} else {
System.out.println("You have run out of Username Attempts");
break;
}
} while (UserAttempts > 0);
}
public static void main(String[] args) {
// TODO Auto-generated method stub
PasswordProgram login = new PasswordProgram();
login.part1();
if (part1Finish == true) {
login.part2();
}
}
}
The problem i am getting is in the method part2. Here when I try to add the username that was saved under the variable user into a character array to use it as a range I get the error NullPointerException.
After investigating i see that when running part2 the value of user is null and therefore I get the error.
Is there a way I could do this through the FileReader method instead or how can i fix the current error I am getting ? Thank you.
Because the static field user is never assigned in part1, you get a NullPointerException when you try to use it in part2.
There are also other issues in the posted code:
why there is a file involved is unclear
you use != with String, for example in passcheck != password
you use equals between String and char[] in usercheck.equals(usernamecheck)
passcheck is assagned but never used
local variables (because of their names) are hiding some fields
UsernameWrite and UserAttempts have non conventional names (should be usernameWrite and userAttempts
You have two user variables declared, one which is static and has global scope, another which is local to part1(). When part2() is attempting to access user, it is using the static declaration, which is null. Your modifications to user in part1() are done to the local variable.
This is something called variable shadowing and should be avoided at all costs.
See the below example:
class Ideone
{
static String bla = "test1";
public static void myMethod() {
String bla = "test2";
System.out.println(bla);
}
public static void main (String[] args) throws java.lang.Exception
{
myMethod();
System.out.println(bla);
}
}
It outputs:
test2
test1

possible already open file error; halted

So, when I run this, I get no exceptions, but the execution halts. I entered a few lines of code to see where the hault is coming from. On initial execution, it creates a file in the path given in the Customer class. Once I do one of the actions, it doesn't let me go past the first debugging line. Ideas?
Heres the application:
package javaapplication18.pkg3;
import java.util.ArrayList;
import java.util.Scanner;
public class JavaApplication183 {
/**
* #param args the command line arguments
*/
static boolean keepGoing = true;
public static void main(String[] args) {
System.out.println("Welcome to the Customer Maintenance application");
//keepGoing = true;
Scanner sc = new Scanner(System.in);
while (keepGoing){
displayMenu();
String userChoice = getRequiredString("Enter a command: ", sc);
System.out.println("DEBUG LINE 1");
CustomerTextFile textFile = new CustomerTextFile();
System.out.println("DEBUG LINE 2");
performAction(userChoice, textFile);
System.out.println("DEBUG LINE 3");
}
// TODO code application logic here
}
public static void displayMenu() {
System.out.println();
System.out.println("COMMAND MENU");
System.out.println("list - List all customers");
System.out.println("add - Add a customer");
System.out.println("del - Delete a customer");
System.out.println("help - Show this menu");
System.out.println("exit - Exit this application");
System.out.println();
}
public static void performAction(String choice, CustomerTextFile textFile){
Scanner sc = new Scanner(System.in);
switch (choice.toLowerCase()) {
case "list":
//action
ArrayList<Customer> currentList = textFile.getCustomers();
for (Customer c : currentList) {
System.out.print(c.getEmail() + "\t");
System.out.print(c.getFirstName() + "\t");
System.out.println(c.getLastName());
}
break;
case "add":
String email = getRequiredString("Enter customer email address:", sc);
String firstName = getRequiredString("Enter first name:", sc);
String lastName = getRequiredString("Enter last name:", sc);
Customer c = new Customer(email, firstName, lastName);
textFile.addCustomer(c);
System.out.println(firstName + lastName + " was added to the database.");
break;
case "del":
String deleteUserByEmail = getRequiredString("Enter customer email to delete:", sc);
Customer delCustomer = textFile.getCustomer(deleteUserByEmail);
textFile.deleteCustomer(delCustomer);
break;
case "help":
//displayMenu();
break;
case "exit":
keepGoing = false;//exit();
break;
default:
System.out.println("You entereed something not in the list. Please try again.");
System.out.println();
}
}
public static boolean exit(){
System.out.println("Exit");
return false;
}
public static String getRequiredString(String prompt, Scanner sc) {
String s = "";
boolean isValid = false;
while (isValid == false) {
System.out.print(prompt);
s = sc.nextLine();
if (s.equals(""))
System.out.println("Error! This entry is required. Try again.");
else
isValid = true;
}
return s;
}
}
Here is the CustomerTextFile class:
package javaapplication18.pkg3;
import java.io.*;
import java.nio.file.*;
import java.util.ArrayList;
public class CustomerTextFile implements CustomerDAO{
private ArrayList<Customer> customers = null;
private Path customersPath = null;
private File customersFile = null;
public CustomerTextFile(){
customersPath = Paths.get("customers.txt");
customersFile = customersPath.toFile();
customers = this.getCustomers();
}
#Override
public Customer getCustomer(String emailAddress) {
for (Customer c : customers) {
if (c.getEmail().equals(emailAddress))
return c;
}
return null;
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public ArrayList<Customer> getCustomers() {
if (customers != null)
return customers;
customers = new ArrayList<>();
if (!Files.exists(customersPath)) {
try {
Files.createFile(customersPath);
}
catch (IOException e) {
return null;
}
}
if (Files.exists(customersPath)) {
try (BufferedReader in = new BufferedReader(new FileReader(customersFile))){
String line = in.readLine();
while(line != null) {
String[] columns = line.split("\t");
String email = columns[0];
String firstName = columns[1];
String lastName = columns[2];
Customer c = new Customer(email, firstName, lastName);
customers.add(c);
}
}
catch (IOException e) {
System.out.println(e);
return null;
}
}
return customers;
}
#Override
public boolean addCustomer(Customer c) {
customers.add(c);
return this.saveCustomers();
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public boolean updateCustomer(Customer c) {
Customer oldCustomer = this.getCustomer(c.getEmail());
int i = customers.indexOf(oldCustomer);
customers.remove(i);
customers.add(i, c);
return this.saveCustomers();
//throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
#Override
public boolean deleteCustomer(Customer c) {
customers.remove(c);
return this.saveCustomers();
}
private boolean saveCustomers() {
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(customersFile)))){
for (Customer customer : customers) {
out.print(customer.getEmail() + "\t");
out.print(customer.getFirstName() + "\t");
out.println(customer.getLastName());
}
out.close();
return true;
}
catch (IOException e) {
return false;
}
}
}
Im not certain if the problem is in the application or if it is in the textfile class
run:
Welcome to the Customer Maintenance application
COMMAND MENU
list - List all customers
add - Add a customer
del - Delete a customer
help - Show this menu
exit - Exit this application
list
DEBUG LINE 1
Above was an example of the console output.
Why are you declaring a string inside the loop?
try this instead:
Scanner sc = new Scanner(System.in);
String userChoice;
do {
displayMenu();
userChoice = sc.nextLine(); //takes in the entire lien you type in
System.out.println("DEBUG LINE 1");
CustomerTextFile textFile = new CustomerTextFile();
System.out.println("DEBUG LINE 2");
performAction(userChoice, textFile);
System.out.println("DEBUG LINE 3");
} while(keepGoing);
Hope this helps

New Method is not working

I'm getting an error that
"Illegal start of expression and error ';' expected"
I don't know if I'm doing the new method right, so please help me I need this for school work.
public class Testing{
public static void main(String args[])throws IOException{
String un, pw, login;
final String Username = "javajava";
final String Password = "testing";
BufferedReader inpt = new BufferedReader (new InputStreamReader(System.in));
public void Login(){
System.out.println("Please enter your Username & Password for you to be able to use the program");
System.out.println("Warning! Case Sensitive!");
for(int trial=3; trial>=1; trial--){
System.out.print("Username: ");
un = inpt.readLine();
System.out.print("Password: ");
pw = inpt.readLine();
System.out.println();
if(un.equals(Username) && pw.equals(Password)){
System.out.println("User has successfully logged in!");
break;
} else {
System.out.println("Sorry, you've entered an incorrect Username/Password - (" + (trial-1) + ") retries left");
}
if (trial==1){
System.out.println("It seems that you've reached the limit for the login attempts, please try again later");
}
}
}
You can't[1] have a method inside a method.
Move
public void Login(){
To outside
public static void main(String args[])throws IOException{.
I advise you to go through the tutorial Defining Methods.
[1] You can, indirectly, have a "method inside a method". It is possible to have a method that contains an inner class, and that class will contain a method. So.. you actually get a method inside a method ;)
try
import java.io.*;
public class Testing {
static String un, pw, login;
static final String Username = "javajava";
static final String Password = "testing";
public static void Login() throws IOException {
System.out
.println("Please enter your Username & Password for you to be able to use the program");
System.out.println("Warning! Case Sensitive!");
BufferedReader inpt = new BufferedReader(new InputStreamReader(
System.in));
for (int trial = 3; trial >= 1; trial--) {
System.out.print("Username: ");
un = inpt.readLine();
System.out.print("Password: ");
pw = inpt.readLine();
System.out.println();
if (un.equals(Username) && pw.equals(Password)) {
System.out.println("User has successfully logged in!");
break;
} else {
System.out
.println("Sorry, you've entered an incorrect Username/Password - ("
+ (trial - 1) + ") retries left");
}
if (trial == 1) {
System.out
.println("It seems that you've reached the limit for the login attempts, please try again later");
}
}
}
public static void main(String args[]) throws IOException {
Login();
}
}
You need to declare your method outside your main method:
public static void main(String[] args) {...}
public static void Login() {...}

Categories

Resources