Java Exception throw creates an infinite loop - exception

I have established a do-while loop to verify user input is valid. If a 0 or negative number is entered, the Exception is thrown and the catch prints out. However, if a string is entered (i.e., twenty instead of 20) it becomes an infinite loop constantly printing out "Invalid input!!", asking for user input, and printing out "Invalid input!!" again. Here's my code:
import java.util.Scanner;
public class Paint {
public static void main(String[] args) {
// Create object for the scanner class
Scanner scnr = new Scanner(System.in);
//Declare variables
double wallHeight = 0.0;
double wallWidth = 0.0;
double wallArea = 0.0;
double gallonsPaintNeeded = 0.0;
final double squareFeetPerGallons = 350.0;
//Implement a do-while loop to verify user provides valid input
do {
try {
//Prompt user for wall's height in feet
System.out.println("Enter wall height (feet): ");
wallHeight = scnr.nextDouble();
//Verify wallHeight is not less than or equal to zero
//If so, throw an exception
if(wallHeight <= 0) {
throw new Exception();
}
}
catch(Exception e) {
//Print invalid message
System.out.println("Invalid input!!");
}
}
while(wallHeight <= 0);
//Implement a do-while loop to verify user provides valid input
do {
try {
//Prompt user for wall's width in feet
System.out.println("Enter wall width (feet):");
wallWidth = scnr.nextDouble();
//Verify wallWidth is not less than or equal to zero
//If so, throw an exception
if(wallWidth <= 0) {
throw new Exception();
}
}
catch(Exception e) {
//Print invalid message
System.out.println("Invalid input");
}
}
while(wallWidth <= 0);
//Calculate wallArea
wallArea = wallHeight * wallWidth;
//Print wallArea
System.out.println("Wall area: " + wallArea + " square feet");
//Calculate gallonsPaintNeeded
gallonsPaintNeeded = wallArea / squareFeetPerGallons;
//Print paint needed
System.out.println("Paint needed: " + gallonsPaintNeeded + " gallons");
}
}

Related

Java Program doesn't continue and Exception Error still appears after it is caught

This is a homework assignment where we have to debug and handle exceptions. I setup a try-catch to handle any input that isn't a double and the exception that comes up is caught, but it still prints the error. Here is my code:
import java.util.Scanner;
import java.util.InputMismatchException;
public class Paint1 {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
double wallHeight = 0.0;
double wallWidth = 0.0;
double wallArea = 0.0;
double gallonsPaintNeeded = 0.0;
final double squareFeetPerGallons = 350.0;
do {
System.out.println("Enter wall height (feet): ");
try {
wallHeight = scnr.nextDouble();
throw new InputMismatchException();
} catch (InputMismatchException exc) {
System.out.println("Invalid input. Please try again.");
wallHeight = scnr.nextDouble();
}
} while (wallHeight <= 0);
...
...
}
}
and this is the output. Note: I used the number thirty spelled out to test the exception for the sake of the assignment.
Enter wall height (feet):
thirty
Invalid input. Please try again.
Exception in thread "main" java.util.InputMismatchException
at java.base/java.util.Scanner.throwFor(Scanner.java:939)
at java.base/java.util.Scanner.next(Scanner.java:1594)
at java.base/java.util.Scanner.nextDouble(Scanner.java:2564)
at Paint1.main(Paint1.java:24)
What am I missing or what do I have that I'm not supposed to?
When a scanner throws an InputMismatchException, the scanner will not pass the token that caused the exception, so that it may be retrieved or skipped via some other method.
You will have to pass this token by yourself, you can use the next() function to read and pass this token. Since the token was not passed your code was again reading the same token and that's why you were getting InputMismatchException again.
do {
System.out.println("Enter wall height (feet): ");
try {
wallHeight = scnr.nextDouble();
throw new InputMismatchException();
} catch (InputMismatchException exc) {
System.out.println("Invalid input " + scnr.next() + ".Please try again.");
wallHeight = scnr.nextDouble();
}
} while (wallHeight <= 0);
System.out.println("WallHeight: " + wallHeight);
Input:
aaa
10
Output:
Enter wall height (feet):
Invalid input aaa.Please try again.
WallHeight: 10.0
Still, this approach has an issue, What if the second value is invalid? Then it will throw the InputMismatchException, I would suggest to separate out the logic of reading input in a different function and that function should call itself when the input is wrong. Something like:
private Integer findValidIntValue(Integer numberOfChecks){
if(numberOfChecks > MAXIMUM_CHECKS_ALLOWED){
throw new InputMismatchException();
}
try {
wallHeight = scnr.nextDouble();
} catch (InputMismatchException exc) {
System.out.println("Invalid input " + scnr.next() + ".Please try again.");
return findValidIntValue(numberOfChecks + 1);
}
}

How to use try-catch in Java?

I am trying to learn try and catch block but with below code something is missing, and my code is not giving my custom error given in catch block. What is the problem here?
Here is my code :
package com.example.java;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int num1;
int num2;
String operatorValue;
System.out.println("Please Enter First Number :");
Scanner firstInput = new Scanner(System.in);
num1 = firstInput.nextInt();
System.out.println("Please Enter Second Number :");
Scanner secondInput = new Scanner(System.in);
num2 = secondInput.nextInt();
System.out.println("Please Select operation + - * / % :");
Scanner operatorInput = new Scanner(System.in);
operatorValue = operatorInput.nextLine();
double results = 0;
try {
switch (operatorValue) {
case "+":
results = num1 + num2;
break;
case "-":
results = num1 - num2;
break;
case "*":
results = num1 * num2;
break;
case "/":
results = num1 / num2;
break;
case "%":
results = num1 % num2;
break;
default:
System.out.println("please Enter a valid operator value");
return;
}System.out.println("The Result is :"+ results);
} catch (Exception e) {
System.out.println("please enter a valid number "+ e.getMessage());
}
}
}
Your try...catch block doesn't include the input part. This is the part that is problematic so wrap it instead of the calculation:
int num1;
int num2;
String operatorValue;
try {
System.out.println("Please Enter First Number :");
Scanner firstInput = new Scanner(System.in);
num1 = firstInput.nextInt(); // can produce error
System.out.println("Please Enter Second Number :");
Scanner secondInput = new Scanner(System.in);
num2 = secondInput.nextInt(); // can produce error
System.out.println("Please Select operation + - * / % :");
Scanner operatorInput = new Scanner(System.in);
operatorValue = operatorInput.nextLine();
} catch (Exception e) {
System.out.println("please enter a valid number "+ e.getMessage());
}
// Rest of code

FFMPeg exception setDataSource failed: status = 0xFFFFFFFF

I have 175 mp4 files. When I process file from index 0 to index 65 (or 66), I get exception:
java.lang.IllegalArgumentException: setDataSource failed: status = 0xFFFFFFFF
at wseemann.media.FFmpegMediaMetadataRetriever.setDataSource(Native Method)
at com.jni.utils.Mp4ParserUsingFFMpeg.createThumbnail(Mp4ParserUsingFFMpeg.java:518)
at com.example.readmdtfile.activity.MainActivity$createMp4Async.createThumbnail(MainActivity.java:71)
at com.example.readmdtfile.activity.MainActivity$createMp4Async.doInBackground(MainActivity.java:55)
at com.example.readmdtfile.activity.MainActivity$createMp4Async.doInBackground(MainActivity.java:1)
at android.os.AsyncTask$2.call(AsyncTask.java:288)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:841)
If I run process from index 65 (or nearby), processing file 65 is successful. But it still get exception sometimes
Here is code which i'm using:
public static Bitmap createThumbnail (String videoPath) {
FFmpegMediaMetadataRetriever retriever = new FFmpegMediaMetadataRetriever();
Bitmap bitmap = null;
try {
retriever.setDataSource(videoPath); //file's path
String key;
String value;
for (int i = 0; i < MetadataKey.METADATA_KEYS.length; i++) {
key = MetadataKey.METADATA_KEYS[i];
value = retriever.extractMetadata(key);
if (value != null) {
// metadata.add(new Metadata(key, value));
Log.i(TAG, "Key: " + key + " Value: " + value);
}
}
bitmap = retriever.getFrameAtTime();
if (bitmap != null) {
Log.d(TAG, "Extracted frame");
Bitmap b2 = retriever.getFrameAtTime(4000000,
FFmpegMediaMetadataRetriever.OPTION_CLOSEST_SYNC);
if (b2 != null) {
bitmap = b2;
}
} else {
Log.d(TAG, "Failed to extract frame");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
retriever.release();
}
return bitmap;
}
https://github.com/wseemann/FFmpegMediaMetadataRetriever/issues/59
Please help me.
The error is simple, an IllegalArgumentException means the video URI is invalid, if this occurs an exception is thrown. Verify the URI is valid before attempting to use it with FFmpegMediaMetadataRetriever.
The error is simple, an RuntimeException means the video URI is invalid. Verify the valid Video URI with .mp4 format, before attempting to use it with FFmpegMediaMetadataRetriever.
ImageView thumbnail1 = (ImageView) findViewById(R.id.video1);
thumbnail1.setImageBitmap(retriveVideoFrameFromVideo("http://techslides.com/demos/sample-videos/small.mp4"));
public Bitmap retriveVideoFrameFromVideo(String videoPath) {
Bitmap bitmap = null;
MediaMetadataRetriever mediaMetadataRetriever = null;
try {
mediaMetadataRetriever = new MediaMetadataRetriever();
if (Build.VERSION.SDK_INT >= 14)
mediaMetadataRetriever.setDataSource(videoPath, new HashMap<String, String>());
else
mediaMetadataRetriever.setDataSource(videoPath);
// mediaMetadataRetriever.setDataSource(videoPath);
bitmap = mediaMetadataRetriever.getFrameAtTime(1, MediaMetadataRetriever.OPTION_CLOSEST);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_LONG).show();
} finally {
if (mediaMetadataRetriever != null) {
mediaMetadataRetriever.release();
}
}
return bitmap;
}
you just have to give setDataSource a String, save your path or url in a string like this:
String url;
mmr = new FFmpegMediaMetadataRetriever();
url = "http://www.stephaniequinn.com/Music/Commercial%20DEMO%20-%2009.mp3";
mmr.setDataSource(url, new HashMap<String, String>());
or:
mmr = new FFmpegMediaMetadataRetriever();
string s="path"
mmr.setDataSource(path);

Facing issues while printing on Dot Matrix Printer

I am developing a desktop application in java swing; in which I need to take a bill print on dot matrix printer, the print will be having name, address and table which will be having item, qty, price…etc, which should be printed as per their x, y positions on paper, font stored in database .
But in print there is issue of overlapping/attaching letters if I use the following code:
class BillPrint implements ActionListener, Printable
{
PrintMngt PM=new PrintMngt();
public int print(Graphics gx, PageFormat pf, int page) throws PrinterException {
if (page>0){return NO_SUCH_PAGE;}
Graphics2D g = (Graphics2D)gx; //Cast to Graphics2D object
g.translate(pf.getImageableX(), pf.getImageableY());
Vector<Vector<Object>> data =PM.getvarientDetail(printID);
for (int i = 0; i <data.size(); i++) {
if(data.get(i).get(3).toString().equalsIgnoreCase("DYNAMIC"))
{
String bill_no=textField_Trans.getText();
int TblH,TblL;
Vector<String> Tbl_HL=PM.getTblHieghtNoLline(printID);
//PRINT_ID0, QUERY_STATIC1, OBJECT_NAME2, QUERY_TYPE3, X4, Y5, WIDTH6,
//ALIGN7, FONT8, F_SIZE9, F_STYLE10, SECTION11, LOOPES_NO12, OBJ_FORMAT13, VARIANT_ID14
TblH=Integer.parseInt(Tbl_HL.get(0).toString());
TblL=Integer.parseInt(Tbl_HL.get(1).toString());
int x=Integer.parseInt(data.get(i).get(4).toString());
int y=Integer.parseInt(data.get(i).get(5).toString());
String fName=data.get(i).get(8).toString();
int fSize=Integer.parseInt(data.get(i).get(9).toString());
String fStyle=data.get(i).get(10).toString();
Font font=null;
if(fStyle.equalsIgnoreCase("Plain"))
{
font = new Font(fName,Font.PLAIN, fSize);
}
else if(fStyle.equalsIgnoreCase("Bold"))
{
font = new Font(fName,Font.BOLD, fSize);
}
else if(fStyle.equalsIgnoreCase("Italic"))
{
font = new Font(fName,Font.ITALIC, fSize);
}
else if(fStyle.equalsIgnoreCase("Bold Italic"))
{
font = new Font(fName,Font.BOLD+ Font.ITALIC, fSize);
}
System.out.println("Myqry"+data.get(i).get(1).toString());
Vector<String> Query_Static=PM.getQuery_Static(data.get(i).get(1).toString(),bill_no);
for (int j = NoOfProd; j < Query_Static.size(); j++) {
g.drawString(Query_Static.get(j).toString(),x,y);
y=y+TblH/TblL;
g.setFont(font);
}
}
}
return PAGE_EXISTS; //Page exists (offsets start at zero!)
}
public void actionPerformed(ActionEvent e) {
PrinterJob job = PrinterJob.getPrinterJob();
job.setPrintable(this);
boolean ok = job.printDialog();
if (ok) {
try {
int ProductCnt= PM.getNoProduct(textField_Trans.getText().toString());//no. of products under given billno
int TableLine=PM.getTblNoLline(printID);//no. of lines to print
System.out.println("No of TableLines="+TableLine);
System.out.println("No of Product="+ProductCnt);
for (int i = 0; i <(TableLine/ProductCnt); i++)
{
job.print();
NoOfProd=NoOfProd+TableLine;
}
NoOfProd=0;
} catch (PrinterException ex) {
ex.printStackTrace();
}
}
}//end actionPerformed
}//end BillPrint
I have also tried with writing data to .txt file and then printing it. Here output is proper i.e letters are not overlapping , but here in this method I m not able to give proper positions for my data. Following method I used for this:
private void printData(){
File output = new File("E:\\PrintFile1.txt");
output.setWritable(true);
String billNo="B1000", patient = "ABC";
try
{
BufferedWriter out = new BufferedWriter(new FileWriter(output));
out.write(billNo + "\n");
out.write(patient + "\n" );
out.write("\n");
out.write("\n");
out.close();
}
catch (java.io.IOException e)
{
System.out.println("Failed to write Output");
}
FileInputStream textStream = null;
try
{
textStream = new FileInputStream("E:\\PrintFile1.txt");
}
catch (java.io.FileNotFoundException e)
{
System.out.println("Error trying to find the print file.");
}
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE;
Doc mydoc = new SimpleDoc(textStream, flavor, null);
PrintService printer = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob printJob = printer.createPrintJob();
try
{
printJob.print(mydoc, null);
}
catch (javax.print.PrintException e)
{
JOptionPane.showMessageDialog(this, "Error occured while attempting to print.", "Error!", JOptionPane.ERROR_MESSAGE);
}
}
Basically for the issue in the letters i just add one space for each character in the string
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;
import java.awt.print.PrinterException;
public class Print implements Printable {
/* Just add one space for all charaters */
String numero = "Numero Nro :";
String numeroreplace = numero.replaceAll(".(?=.)", "$0 ");
public Print() {
super();
}
/* The font for you string */
public int print(Graphics g,PageFormat pf, int page) throws PrinterException{
Font textFont = new Font(Font.SANS_SERIF,Font.PLAIN,8);
/* To set the position, you can use for or while if u need it. */
g.setFont(textFont);
g.drawString(numeroreplace,350,150);
}
}
Finally you need to copy all this code just add one space for all characters in code.
Note : you must be call from yor main program.

cannot implement actionPerformed(ActionEvent) in ActionListener

I am making a profile encryption program with 2 ciphers. I want to have a GUI with buttons for enciphering, deciphering and exiting.
My problem is with the actionPerformed method. It needs to throw the exception that the outputStream throws. This is the error I get when I try to complie it:
:53: error: actionPerformed(ActionEvent) in ProfileEncryption_2 cannot implement actionPerformed(ActionEvent) in ActionListener
public void actionPerformed (ActionEvent e) throws FileNotFoundException//When a button is clicked
I have though of multiple solutions, but am not sure how to implement them properly. I could catch the exception and do something with it, but I am not sure how and what. I could also check if the file exists, and if so, then output, but what I tried for that didn't work either.
public void actionPerformed (ActionEvent e) throws Exception //When a button is clicked
{
if (e.getSource() == encrBtn)
{
menu.setVisible(false);
createProfile();
menu.setVisible(true);
}
else
{
if (e.getSource() == decrBtn)
{
menu.setVisible(false);
viewProfile();
menu.setVisible(true);
}
else
{
if (e.getSource() == exitBtn)
{
JOptionPane.showMessageDialog(null, "Goodbye!");
System.exit(0);
}
}
}
}
//End of menu
//Start of create/view section
public static void createProfile() throws Exception //Create profile
{
String username = JOptionPane.showInputDialog("Enter your username.");
String password, confirmPass, strEncrType;
int intEncrType = 0, unlock = 0;
do
{
password = JOptionPane.showInputDialog("Enter your password.\nIt must be more than 7 characters long.");
confirmPass = JOptionPane.showInputDialog("Confirm password");
if (password.equals(confirmPass) && (password.length() >= 7))
{
JOptionPane.showMessageDialog(null, "Passwords match!");
unlock = 1;
}
else
{
if (!password.equals(confirmPass))
JOptionPane.showMessageDialog(null, "Passwords do not match!");
if (password.length() < 7)
JOptionPane.showMessageDialog(null, "Password is not long enough!");
}
}
while (unlock==0);
do
{
strEncrType = JOptionPane.showInputDialog("Choose which encryption type you would prefer:\n1. Vigenère\n2. Erénegiv mod 4");
if(!strEncrType.equals("1")&&!strEncrType.equals("2"))
JOptionPane.showMessageDialog(null, "Invalid response, try again.");
}
while (!strEncrType.equals("1")&&!strEncrType.equals("2"));
intEncrType = Integer.parseInt(strEncrType);
String name = JOptionPane.showInputDialog("Enter your real name.");
String phone = JOptionPane.showInputDialog("Enter your phone number.");
String email = JOptionPane.showInputDialog("Enter your email.");
String other = JOptionPane.showInputDialog("Enter notes/extra data you want stored.");
String data = password + "-" + username + "-tester-" + name + "-" + phone + "-" + email + "-" + other + "-" + strEncrType;
if (intEncrType ==1)
data = encrypt1(data);
else
data = encrypt2(data);
data = data + strEncrType;
OutputStream output = new FileOutputStream(username + ".txt");
byte buffer[] = data.getBytes();
output.write(buffer);
output.close();
}