URL data printing trouble - java

I am reading from a URL = https://www.cia.gov/library/publications/the-world-factbook/rankorder/rawdata_2151.txt
I am trying to print out the top 3 countries but whenever I try it gives
me the total number of countries instead. Would a subString or Trim method work here? Just need a hint into the write direction. Thanks
class ButtonTotalListener implements ActionListener
{
public void actionPerformed(ActionEvent event)
{
if(event.getSource()==printButton){
String line = "";
try{
String address = "https://www.cia.gov/library/publications/the-world-factbook/rankorder/rawdata_2151.txt";
URL pageLocation = new URL(address);
Scanner in = new Scanner(pageLocation.openStream());
while(in.hasNextLine()){
line = in.nextLine();
String [] lineContent = line.split("\\s{2,}");
System.out.println(Arrays.toString(lineContent));
countries.setForeground(Color.YELLOW);
countries.setText(lineContent[2]);
}
}
catch (MalformedURLException ex) {
countries.setText("Country Not Found!");
}
catch (IOException ex) {}
}

You loop over all countries in in.hasNextLine()
You should introduce a counter variable and insert a break; after your limit was reached, or change the loop condition.
Additionally check which column you want to return. It seems you return the number from thrid column (which is [2]), but if you want to use the country name you need [1] for 2nd column (array index is 0-based).
As a third, what do you do with countries? You set the text, but for each loop iteration, you overwrite the former countries text (countries is the same variable, in each iteration)

Related

Move from string to array but after that select by the first character (Record Type 1, 2, 5)

I need your help, I am new in Java
I need to read a flat file with 5 different of records
the way to differentiate each record is the first characters, after that I have the idea to move to an 5 different array to play with with the data inside.
example
120220502Name Last Name1298843984 $1.50
120220501other client 8989899889 $23.89
2Toronto372 Yorkland drive 1 year Ontario
512345678Transfer Stove Pay
522457839Pending Microwave Interactive
any help will quite appreciated
Break the problem into chunks. The first problem is reading the file:
try (BufferedReader reader = new BufferedReader(new FileReader("path/to/file"))) {
parseData(reader); //method to do the work.
} catch (IOException e) {
e.printStackTrace();
}
Then you need to decide what kind of record it is:
public void parseData(BufferedReader input) throws IOException {
for (String line = input.readLine(); line != null; line = input.readLine()) {
if (line.startsWith("1")) {
parseType1(line);
} else if (line.startsWith("2")) {
parseType2(line);
} else if (line.startsWith("5")) {
parseType5(line);
} else {
throw new Exception("Unknown record type: " + line.charAt(0));
}
}
}
Then you'll need to create the various parseTypeX method to handle turning the text into usable chunks and then into classes.
public Type1Record parseType1(String data) {
//create a Type1Record
Type1Record record = new Type1Record();
//split the string something like
String [] fields = data.split("\\s+");
//Assign those chunks to the record
record.setId(fields[0]);
record.setFirstName(fields[1]);
record.setLastName(fields[2]);
record.setTotal(fields[3]); //if you want this to be a real number, you'll need to remove the $
}
Repeat the process with the other record types. You'll likely need to group records together, but that should be easy enough.

How to update txt file in java

I have JTable where I show data from text file:
Now, for deleting I have method like this:
private void delete(ActionEvent evt) {
DefaultTableModel model = (DefaultTableModel) tblRooms.getModel();
// get selected row index
try {
int SelectedRowIndex = tblRooms.getSelectedRow();
model.removeRow(SelectedRowIndex);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex);
}
}
And action listener:
btnDelete.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
delete(e);
}
});
It will delete row in JTable and thats okey, but my text file have 7 splits, where last spit is for logical deleting. So, if false - room isn't deleted.
13|family room|name apartman|4|true|true|true|false
14|superior room|super room|2|true|false|false|false
15|room|room for one|1|false|false|true|false
0|MisteryRoom|Mistery|0|true|true|free|false
How to delete certain room from JTable on correct way, and change from false to true?
For example if I click on super room, how to delete exactly that room.
This sort of thing is best handled using a database rather than a text file for a great number of reasons, never the less since you are utilizing a text file as your data storage I will demonstrate one way to replace a value (substring) in a specific data text file line.
Now, the following method can be used to modify any piece of field data on any file data line...even the room number so keep that in mind. You will need to ensure that you only modify when it's best to do so:
/**
* Updates the supplied Room Number data within a data text file. Even the
* Room Number can be modified.
*
* #param filePath (String) The full path and file name of the Data File.
*
* #param roomNumber (Integer - int) The room number to modify data for.
*
* #param fieldToModify (Integer - int) The field number in the data line to
* apply a new value to. The value supplied here is to be considered 0 based
* meaning that 0 actually means column 1 (room number) within the file data
* line. A value of 7 would be considered column 8 (the deleted flag).
*
* #param newFieldValue (String) Since the file is string based any new field
* value should be supplied as String. So to apply a boolean true you will need
* to supply "true" (in quotation marks) and to supply a new room number that
* room number must be supplied a String (ie: "666").
*
* #return (Boolean) True if successful and false if not.
*/
public boolean updateRoomDataInFile(String filePath, int roomNumber,
int fieldToModify, String newFieldValue) {
// Try with resources so as to auto close the BufferedReader.
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
// Add the data file contents to a List interface...
List<String> dataList = new ArrayList<>();
while ((line = reader.readLine()) != null) {
dataList.add(line);
}
for (int i = 0; i < dataList.size(); i++) {
line = dataList.get(i).trim(); // Trim off any leading or trailing whitespaces (if any).
// Skip Blank lines (if any) and skip Comment lines (if any).
// In this example file comment lines start with a semicolon.
if (line.equals("") || line.startsWith(";")) {
continue;
}
//Split each read line so as to collect the desired room number
// since everything will always be based from this unique ID number.
// Split is done baesed on the Pipe (|) character since this is
// what is implied with your data example.
String[] roomData = line.split("\\|");
// Get the current file data line room number.
// Make sure the first piece of data is indeed a valid integer room
// number. We use the String.matches() method for this along with a
// regular expression.
if (!roomData[0].trim().matches("\\d+")) {
// If not then inform User and move on.
JOptionPane.showMessageDialog(null, "Invalid room number detected on file line: "
+ (i + 1), "Invalid Room Number", JOptionPane.WARNING_MESSAGE);
continue;
}
// Convert the current data line room number to Integer
int roomNum = Integer.parseInt(roomData[0]);
// Does the current data line room number equal the supplied
// room number?
if (roomNum != roomNumber) {
// If not then move on...
continue;
}
// If we reach this point then we know that we are currently on
// the the data line we need and want to make changes to.
String strg = ""; // Use for building a modified data line.
// Iterate through the current data line fields
for (int j = 0; j < roomData.length; j++) {
// If we reach the supplied field number to modify
// then we apply that modification to the field.
if (j == fieldToModify) {
roomData[j] = newFieldValue;
}
// Build the new data line. We use a Ternary Operator, it is
// basicaly the same as using a IF/ELSE.
strg += strg.equals("") ? roomData[j] : "|" + roomData[j];
}
// Replace the current List element with the modified data.
dataList.set(i, strg);
}
// Rewrite the Data File.
// Try with resources so as to auto close the FileWriter.
try (FileWriter writer = new FileWriter(filePath)) {
// Iterate through the List and write it to the data file.
// This ultimately overwrites the data file.
for (int i = 0; i < dataList.size(); i++) {
writer.write(dataList.get(i) + System.lineSeparator());
}
}
// Since no exceptions have been caught at this point return true
// for success.
return true;
}
catch (FileNotFoundException ex) {
Logger.getLogger("updateFileRoomStatus()").log(Level.SEVERE, null, ex);
}
catch (IOException ex) {
Logger.getLogger("updateFileRoomStatus()").log(Level.SEVERE, null, ex);
}
// We must of hit an exception if we got
// here so return false for failure.
return false;
}
To use this method you might want to do it this way:
private void delete() {
DefaultTableModel model = (DefaultTableModel) tblRooms.getModel();
try {
// get selected row index
int SelectedRowIndex = tblRooms.getSelectedRow();
// Get out if nothing was selected but the button was.
if (SelectedRowIndex == -1) { return; }
int roomNumber = Integer.parseInt(model.getValueAt(SelectedRowIndex, 0).toString());
updateRoomDataInFile("HotelRoomsData.txt", roomNumber, 7, "true");
model.removeRow(SelectedRowIndex);
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex);
}
In the code above a data file name of "HotelRoomsData.txt" was supplied. This of course assumes the the data file contains that name and that is is located within the root folder (directory) of your particular project. If the file is named differently and it is located in some completely different location then you will need to change this to the full path and file name of the data file, for example:
"C:/Users/Documents/MyDataFile.txt"
The code really isn't that long, it's just that there are a lot of comments accompanying it so as to explain things. Of course these comments can be deleted from the code.

Getting the next value from a file when a test case fails

How can I retrieve the next value from text file when there is a failure in the test case?
Here is my code:
public void openFile(){
try{
x = new Scanner(new File("C:\\Project1\\ids.txt"));
public void readFile(){
}
}catch(Exception e){
System.out.println("not find file");
}
while(x.hasNext()){
String a = x.next();
driver.findElement(By.xpath("//*[#id=\"in_member_id\"]")).sendKeys(a);
}
}
If the value in line number 1 of file ids.text is wrong I want it to put the second value then the third and so on. If it's right I want it to continue to the last of the file.
One strategy you could try if your file isn't unreasonably large is to pre-fetch all the lines and store them in a list. Then loop over and break as the final statement which symbolizes the success that means you can stop trying. That could look something like this:
// Let's just assume the file is always found for example's sake
Scanner in = new Scanner(new File("C:\\Project1\\ids.txt"));
List<String> fileLines = new ArrayList<>();
// Pre fetch all the lines in the file
while (in.hasNextLine()) {
String line = in.nextLine();
if (!line.isEmpty()) {
fileLines.add(line);
}
}
// Try each id until one succeeds and the loop is broken
for (String aLine : fileLines) {
try {
driver.findElement(By.xpath("//*[#id=\"in_member_id\"]")).sendKeys(a);
// Here is where you would check for failures that don't throw an exception, if you need to...
// If this break is reached, then no failures were detected
break;
// If a failure happens that results in an exception
} catch (Exception e) {
System.out.println("An error happened, trying next line");
}
}

Return to previous spot in loop after try catch?

} else if (selectionKey == 2) {
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an invalid item name?");
}
That's my code atm. How do I return back to the if statement and continue the loop after it catches?
You could embed it in a loop like,
for (;;) { // <-- start an infinite loop
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
break; // <-- terminate the infinite loop.
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an "
+ "invalid item name?");
e.printStackTrace(); // <-- tell them what went wrong.
}
}
I think (if I understand your question and code correctly) that what you want is a loop containing the s.nextLine(). Note that I am assuming several things here:
s is a Scanner or something equivalent that reads input from the user
an exception is thrown if the user enters invalid input
you want to keep asking the user for input until they enter something valid
If this is the case, then you should create a loop like this:
while (true) {
System.out.println("Please enter the item name");
if (s.nextLine() != "") {
item = s.nextLine();
}
try {
ZybezChecker zb = new ZybezChecker(item);
zb.getAveragePrice();
System.out.println(zb.toString());
break;
} catch(Exception e) {
System.out.println("Something went wrong. Perhaps an invalid item name?");
}
}
Also, why are you calling nextLine() twice? When you call it the first time, it will read a line from the scanner. When you call it again, it will not return the same line; it will instead wait for a new line. This means the user has to enter some random string, then enter the actual value. Finally, you should NEVER use == or != on Strings. Since they are reference types, you are essentially checking if they occupy the same location in memory, rather than if they are equal. Use s.nextLine().equals("") instead.

Java reprompt for user input with try... catch

So if a user puts in a postfix value like say 453-* , my method EvalPostFix() does the work, but when the user inputs something invalid like 43*+ or any invalid string want the program to repromt the user for input dont know how to implement with try catch..
'
String in;
while(true){
System.out.println("Please enter the numbers first followed by the operators, make sure to have one less operator than of numbers");
try {
in = getString();
int result = EvalPostFix(in);
System.out.println(result);
} catch (IOException e) {
// TODO Auto-generated catch block
String s = "Not a valid postfix string";
e.toString();
in = getString();
}
}
'
Looking at your code I think you just need to get rid of the in = getString(); in the catch block and add an break at the end of the try block.
I don't recommend using a while(true) or an IOException for what you are doing though, but that should get your code working.
Use a flag:
boolean flag = false;
while(!flag)
{
//make the loop break, if no exception caught
flag = true;
try{
}
catch{
//make the loop repeat
flag = false;
}
}
this should repeat the prompt every time you catch an exception. you can also use this to validate input.
how the flag is oriented depends on your preference. I like to flag true when an error occured ;)
this will also break your while loop, as soon as you get a valid input.
Something like this is can be used to get an input of desired specifications
public static void userMove() {
System.out.println("Where would you like to move? (R, L, U, D)\n");
Scanner input = new Scanner(System.in) ;
while (true){
String userInput = input.next() ;
if(userInput.length()>1){
System.out.println("Please input a valid direction");
}else{
break ;
}
}
}

Categories

Resources