I posted here a few weeks ago regarding a project I have for work. The project began as creating a simple little program that would take an incoming ACH file and read each line. The program would also ask a user for a "reason code" and "bank" which would affect the next step. The program would then reformat all the data in a certain way and save it to an external file. For those that don't know, an ACH is simply a text based file that is in a very concrete format. (Every character and space has a meaning.)
I have completed that task using a few GUI items (Jcombobox, JFileChooser, etc), string array lists, buffered reader/writer, and lots of if/else statements.
The task has now been expanded to a much more complicated and I don't know exactly how to begin, so I thought I would seek the communities advice.
When an ACH file comes in it will be in a format that looks something like this:
101 100000000000000000000000000000
522 00000202020382737327372732737237
6272288381237237123712837912738792178
6272392390123018230912830918203810
627232183712636283761231726382168
822233473498327497384798234724273487398
522 83398402830943240924332849832094
62723921380921380921382183092183
6273949384028309432083094820938409832
82283409384083209482094392830404829304
900000000000000000000000000000000
9999999999999999999999999999999999999
9999999999999999999999999999999999999
(I will refer to each line by " " number, for example "1 number" are the lines that begin with 1)
The end result is that the lines of data are maniuplated and put into "batches". The output file begins with the "1 number"
and then contains a batch with the format of
5
6
8
5
6
8
5
6
8
We continue using the same "5 number" until all sixes that were below it in the original file have been written, then we go to the next "5" and work with the "6" below it.
So, my project now is to create a full GUI. After the user inputs the file the GUI will have some type of drop down box or similar list of all the "6" numbers. For each number there should be another drop down box to choose the reason code (there are 7 reason codes).
Basically the ultimate objective is:
Display all the "6" numbers and give the user the ability to choose a reason code for each.
Allow the user to only select a certain amount of the "6" numbers if they wish.
Is it possible for me to do this using Buffered Reader/ Writer? I currently save the values into Array Lists using the following code:
while((sCurrentLine = br.readLine()) !=null)//<---------This loop will continue while there are still lines to be read.
{
if (sCurrentLine.startsWith("5")){//<------------------If the line starts with "5"..
listFive.add(sCurrentLine);//<-------------------------Add the line to the array list "listFive".
countFive++;//<---------------------------------------------Increase the counter "countFive" by one.
}else if (sCurrentLine.startsWith("6") && countFive==1){//<---------If the line starts with "6" and countFive is at a value of 1..
listSix.add(sCurrentLine);//<---------------------------------------Add the line to the array list "listSix".
}else if (sCurrentLine.startsWith("6") && countFive==2){//<-----------------If the line starts with "6" and countFive is at a value of 2..
listSixBatchTwo.add(sCurrentLine);//<--------------------------------------Add the line to the array list "listSixBatchTwo".
}else if (sCurrentLine.startsWith("6") && countFive==3){//<-----------------------If the line starts with "6" and countFive is at a value of 3..
listSixBatchThree.add(sCurrentLine);//<------------------------------------------Add the line to array list "listSixBatchThree".
}else if (sCurrentLine.startsWith("6") && countFive==4){//<------------------------------If the line starts with "6" and countFive is at a value of 4..
listSixBatchFour.add(sCurrentLine); //<--------------------------------------------------Add the line to array list "listSixBatchFour".
}else if (sCurrentLine.startsWith("8")){//<-----------------------------------------------------If the line starts with "8"..
listEight.add(sCurrentLine);//<----------------------------------------------------------------Add the line to array list "listEight".
}else if (sCurrentLine.startsWith("1")){//<-----------------------------------------------------------If the line starts with "1"..
one = sCurrentLine;//<-------------------------------------------------------------------------------Save the line to String "one".
}else if (sCurrentLine.startsWith("9") && count9 == 1){//<---------------------------------------------------If the line starts with "9" and count9 is at a value of 1..
nine = sCurrentLine;//<-------------------------------------------------------------------------------------Save the line to String "nine".
count9 = 0;//<--------------------------------------------------------------------------------------------------Set count9 to a value of 0.
}else if (sCurrentLine.startsWith("999") && count9 == 0){//<-----------------------------------------------------------If the line starts with "999" and count9 is at a value of 0..
listNine.add(sCurrentLine);//<---------------------------------------------------------------------------------------Add the line to array list "listNine".
}else{
}
}
If anyone can point me where I can get started I would be very grateful. If you need more information please let me know.
Update:
Here is an example of my JOptionPane with decision making.
String[] choices = {"Wells Fargo", "Bank of America", "CitiBank", "Wells Fargo Legacy", "JPMC"};
String input = (String) JOptionPane.showInputDialog(null, "Bank Selection", "Please choose a bank: ", JOptionPane.QUESTION_MESSAGE, null, choices, choices[0]);
if (input.equals("Wells Fargo"))
{
bank = "WELLS FARGO";
}else if (input.equals("Bank of America")){
bank = "BANK OF AMERICA";
}else if (input.equals("CitiBank")){
bank = "CITI BANK";
}else if (input.equals("Wells Fargo Legacy")){
bank = "WELLS FARGO LEGACY";
}else if (input.equals("JPMC")){
bank = "JPMC";
}
}else{
}
Let's assume I wanted to use the Buffered Writer to save all of the "6" numbers into a String array, then put them into a drop down box in the GUI. How could I accomplish this?
Can you use the input from Buffered Writer in a GUI..
Well, a BufferedWriter is not used to get input but rather to output information, but assuming that you meant a BufferedReader, then the answer is yes, definitely. Understand that a GUI and getting data with a BufferedReader are orthogonal concepts -- they both can work just fine independently of the other. The main issues involving reading in data with a Bufferedhaving a GUI
Say a JOptionPane for example.
I'm not sure what you mean here or how this relates.
If yes, then how could I go about doing that? In all the examples I have seen and tutorials about JOptionPane everything is done BEFORE the main method. What if I need if statements included in my JOptionPane input? How can I accomplish this?
I'm not sure what you mean by "everything is done before the main method", but it sounds like you may be getting ahead of yourself. Before worrying about nuts and bolts and specific location of code, think about what classes/objects your program will have, and how they'll interact -- i.e., what methods they will have.
I believe I just had an idea of how I need to proceed first. Can someone please verify? 1. Create static variables representing the lines that will be read. (Such as a static ArrayList.
No, don't think about static anything off the bat, since once you do that, you leave the OOP realm and go into procedural programming. The main data should be held in instance variables within a class or two.
Create the actual GUI, outside the main Method.
I'm not sure what you mean "outside the main method", but the GUI will consist of multiple classes, probably one main one, and an instance of the main class is not infrequently created in the main method, or in a method called by the main method, but queued onto the Swing event thread.
Create the Buffered Reader which will write to the variables mentioned in #1, inside the main method.
Again, I wouldn't do this. The main method should be short, very short, and its reason for existence is only to start your key objects and set them running, and that's it. Nothing critical (other than just what I stated) should be done in them. You're thinking small toy programs, and that's not what you're writing. The reader should be an instance variable inside of its own class. It might be started indirectly by the GUI via a control class which is a class that responds to GUI events. If you need the data prior to creation of the GUI, then you will have your main method create the class that reads in the data, ask it to get the data, and then create your GUI class, passing the data into it.
Related
So, before I start I just wanted to say that I'm very new to Java as a language and I've been reading a text book that was recommended to me.
One of the examples provided within the text book on for loops had the following code, which is meant to generate an infinite for loop until the user presses the character 'S' on their keyboard.
Here is the code:
class ForTest {
public static void main(String args[])
throws java.io.IOException {
int i;
System.out.println("Press S to stop.");
for (i = 0; (char) System.in.read() != 'S'; i++)
System.out.println("Pass #" + i);
}
}
I copied the code exactly as it was written within the book but when I run the program, to my surprise, it doesn't start printing out numbers onto the console. Additionally, whenever I press any keys on the keyboard it generates three numbers within the sequence. Example shown below:
I have also included a screenshot of the code from the book below:
I was wondering whether anyone knows why this is the case!
Any help would be greatly appreciated thanks.
The reason it's printing multiple times is because multiple characters are detected.
In your case, it's printing twice because you entered a value (Pass 1) and a new line (Pass 2)
The problem you have is not with System.in.read(), but because the console is usually using a buffered approach. Meaning that data is only transferred to the System.in.read() once you press enter.
So to get the example working, you would have to switch the console to an unbuffered mode, but there is no portable way to do this, because there are so much different types of consoles. Maybe have a look at what editor/console the book is using
This block of code looks like it was written by someone who was deliberately trying to make it obtuse and difficult to comprehend for a beginner.
The middle expression of a for statement is the criterion for taking the next step of the loop. It is evaluated before each step of the loop to determine whether the for loop is complete yet. In this case, it calls in.read() and checks if the input is S before each step of the loop.
in.read() waits for the next line of input it gets. When you enter a value and press Enter, that line gets read, so the loop takes a step. And a new line is also entered, so the loop takes a second step.
It will not print lines to the console unless you enter lines, because in.read() causes the program to block (wait) for the next input.
*EDIT - SOLVED: After instantiating the Scanner Object, I used a delimiter as follows:
scanner.useDelimiter("");
Prior to this, I did try a delimiter that looked something like this (the exact code is available on Stack Overflow):
scanner.useDelimiter("\\p{javaWhitespace}");
...but it didn't work very well.
Thank you, everyone. If you're having this very same issue, try the first delimiter. If it doesn't work, upgrade your JDK to 13 then try it again.
Ok, my goal is to have a user input a credit card number which I would then like to store in an ArrayList of Integers and subsequently pass this list to my functions which will perform the Luhn algorithm in order to validate the provided number. Once the user presses Enter, the processing begins. This is a console application, nothing fancy.
Everything works beautifully...except the user-input part. None of the user-input is being stored into the declared ArrayList. I've inserted a print message to give me the size of the list just after the pertinent while-loop and....yep, 0. I also pass this list into a custom lengthChecker(ArrayList<Integer> list){} function subsequent to the relevant while-loop and it's printing my custom error-message.
I have declared local int variables within the scope of the while-loop and that wasn't helping much. I have tried getting the user's input as Strings and storing them in an ArrayList<String> list; then parsing the input but that didn't work very well (especially as I need the Enter key to behave as a delimiter such that the next steps can take place)
Anyways, here is the code to the function in question. Am I missing something obvious or should I just quit programming?
public void userInput() {
Scanner scanner = new Scanner(System.in);
List<Integer> list = new ArrayList<Integer>();
System.out.println("Please input the card-number to be checked then press Enter: ");
while(scanner.hasNextInt()) {
list.add(scanner.nextInt());
}
System.out.println("Length of list: " + list.size());
listLengthChecker(list);
scanner.close();
}
Thank you in advance.
I don't have the full context on all the code you've written to be able to solve your problem, but I can guess at what's going on. If you want to run any user I/O (such as the scanner), it must occur within the main method. I can only assume that you run your userInput() function within the main method in your class. However, because your userInput() function doesn't have the static keyword in its definition, it can't be accessed without initialising an object of the class - but as far as I can tell from your code, there is no object that the method could refer to. Add the static keyword (i.e. initialise the method as public static void userInput()) to be able to run the function as you intend.
As for the while loop - there's a small chance that this is a difference in Java versions (I use Java 11), but while(scanner.hasNextInt()) won't stop being true at the end of your line or when you press enter - only when you insert something (such as a character) that cannot be interpreted as an integer.
This while loop untill you enter any non integer value.
You finished entering all the integer values and then your program will print your list elements.
I'm trying to make a tic-tac-toe game and I'm encountering a lot of copy-paste work for inputs. I'm trying to figure out what design pattern and implementation works for prompting the user, collecting their input, comparing it and then acting by assigning a value. Right now my code looks like this.
public void promptPlayerCount(BufferedReader in) throws IOException {
String input;
// initial prompt
System.out.println("How many players?");
input = "try again";
while (input.equals("try again")) {
input = in.readLine();
// extract data and check it
switch (Integer.parseInt(input)) {
case 1:
// assignment
playerCount = 1;
break;
case 2:
playerCount = 2;
break;
default:
input = "try again";
// clarified instructions
System.out.println("please enter 1 or 2");
}
}
}
There's a part of me that thinks I could make a function (maybe a factory?) that allows me to generate a function by passing the constructing function the details of the initial prompt, the extraction method, the assignment action and the clarification message.
Would this be best done with lambda functions?
Text input is hard, especially if you can't trust your user (like in a game). Your parseInt will throw a nasty exception right off if your value isn't an integer.
Also standard in is not friendly. I assume this is for an assignment so I won't fault you for using it, but in anything where you don't HAVE to use stdin, don't. The problem is that it's amazingly difficult to get Java to respond to anything less than an entire line with an enter at the end.
When dealing with user input I almost always trim it (Just because they love to insert random white spaces at the beginnings and end) and check to see if it's empty. This could probably be put into a function that also either shows an error or exits the program on "Empty" and otherwise returns a string.
If you often want int values, write a second function that calls the first. Have the second function return an int, but have it catch the exception if the text is invalid and prompt the user again. You could even have this function take a "Range" of integers as a parameter and provide a prompt. So what you have above could look like this:
playerCount = getUserInput("Please enter the number of users", 1, 2);
The rest is wrapped in simple non-redundant functions.
Won't write the code for you because A) it's probably a homework assignment and the fun part is actually coding it and B) someone else probably will provide a full solution with code before I'm done typing this :(
Good luck.
I am working on a program and I need to scan in a txt file. The txt file is guaranteed to follow a particular format in terms up where and when different types occur. I try to take advantage of this in my program and use a scanner to put the parts I know are ints into ints, along with doubles and strings. When I run my program It tells me I have a type mismatch exception, I know that due to the formatting of the txt file that all my types match up so how do I make the IDE think this is okay. Here's a block of the problematic code is that helps.
ArrayList<Student>studentList=new ArrayList<Student>();//makes a new Array list that we can fill with students.
FileInputStream in=new FileInputStream("studentList.txt");//inputs the text file we want into a File Input Stream
Scanner scnr=new Scanner(in);//Scanner using the Input Stream
for(int i=0;i<scnr.nextInt();i++)//we know the first number is the number of minor students so we read in a new minor that number of times
{
Undergrad j=new Undergrad();//make a new undergrad
j.setDegreeType("MINOR");//make the degree type minor because we know everyone in this loop is a minor.
j.setFirstName(scnr.next());//we know the next thing is the student's first name
j.setLastName(scnr.next());//we know the next thing is the student's last name
j.setID(scnr.nextInt());//we know the next thing is the student's ID
j.setGPA(scnr.nextDouble());//we know the next thing is the student's GPA
j.setCreditHours(scnr.nextDouble());//we know the next thing is the student's credit hours
studentList.add(j);//Finally, we add j to the arraylist, once it has all the elements it needs
}
Computer programs do exactly what you tell them to do.
If you create a program that expects certain input, and that program tells you "unexpected input"; then are exactly two logical explanations:
Your assumption about the layout of the input (that you put in your program) were wrong
The assumptions are correct, but unfortunately the input data doesn't care about that
Long story short: it is not the IDE that gets things wrong here.
Thus the "strategy" here is:
open your text file in an editor
open your source code in your IDE
Run a debugger; or "run your code manually"; meaning: walk through the instructions one by one; and for each scanner operation, check what the scanner should return; and what the file actually contains in that place
I need to get some input from user in my application, and then use it in Java. But, it is quite more complicated than get some value from GUI and assign it to variable. The value should be processed according some rules.
For example:
input from user is string "2 + 3", then he clicks "RUN" button, and when the button is clicked I need to assign "2" to one variable, "3" to next variable, and then make SUM of it.
I suggest you use http://www.beanshell.org/ This tool is used in a number of IDEs with the debugger to evaluate expressions.
Use the ScriptEngine. E.G. here.
=
If all you needed is to make some simple math calculation like these, I would use 2 Stacks to maintain the syntax. You can tokenise the input Strings and then use one Stack as the operators Stack and the other as the value Stack. And then you know that for every one pop from the operator Stack, the next pop from the value Stack must be an integer. If it isn't, you know the rules is broken and you can throw an error to your user.
Here is some code for a four-function calculator.