I have a query on handling error conditions with Java Swing.
I am using Netbeans to develop a simple Java Swing app. It is to load in a text file, then run calculation based on the numbers found in the text file. The main Swing class holds the JFrames and JPanels.
I have the file loading code as a separate class file. It returns the number of lines read and a List of numbers back to the main Swing app.
I realised that if the file reading fails (i.e. try -> catch (Exception ex)), the entire app will crash. What's the best way to handle errors resulting from my scenario above? That is to say, the file loading code crashes and I don't want the entire program to crash. I want the program to say the file is corrupted and wait for user to load new file.
Any thoughts?
Yakult
when you catch the exception, run:
JOptionPane.showMessageDialog("File is corrupted. Please select a new file.");
Then display the file dialog again.
It's probably best to do this as a loop that continues while the the file is not valid. If there is a corruption, then rather than throwing an exception, set a boolean flag and loop as long as the flag is set. That way, when a good file is found, the while loop will terminate.
Example:
public static void main(String[] args){
boolean goodFile = false;
while (!goodFile){
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog();
goodFile = processFile(chooser.getSelectedFile());
}
}
private boolean processFile(File file){
//do you stuff with the file
//return true if the processing works properly, and false otherwise
}
yeah
the problem is with your IO reading concept
the while loop is reading to the end of the file and so on..
to prevent that u can use a buffered reader
and use this code
String line = null
while((line = reader.readLine())!= null) {
// do stuf
}
if you are having this problem with processing the read line
all you need is to create a exception class of your own by extending Exception class and throw that exception in your catch block
after setting the message to your custom exception class you can set that message in to
JOptionPane.showMessageDialog(null,"message here"); //showMessageDialog is a static method
ok
You just catch the exception and put condition in the catch block. If the file contains other content that your application is intended to handle then you could call your method which will re-handle another file.
The main handling of your new process of the new file manipulation will start from your catch block. So in this way you are using java thrown exception to restart your application in a brand new way other than relaunching your app from the zero level.
Related
so I have an object, a Hotel, which implements Serializable. I am using an FX application that has many buttons. The FX application has a hotel object, as a field, which is the object that I want to read/write.
Is it read before write? or write before read? and should it be in the start method?
Do you have the read/write methods right next to each other on startup? Or should I have a button to close/save the application, and have it write the object to a file (and read it on startup)?
Here's what I have so far, and I believe it's writing successfully, but it is not reading.
#Override
public void start(Stage primaryStage) {
try {
ObjectOutputStream oosoos = new ObjectOutputStream(new FileOutputStream("hotelRooms.dat"));
oosoos.writeObject(hotel);
}catch (IOException e) {
System.out.println(e.getMessage());
}
// Hotel tempHotel;
try {
ObjectInputStream iisiis = new ObjectInputStream(new FileInputStream("hotelRooms.dat"));
hotel = (Hotel)iisiis.readObject();
} catch (IOException | ClassNotFoundException ffe ) {
System.out.println(ffe.getMessage());
}
I've never used FX before, but I think I might be able to help, by making some assumptions...
I assume that your start() method is a lifecycle method defined by some FX class and you need to load the Hotel object when the application starts. Presumably you then have some sort of finish() method where you want to save the latest version of the Hotel object for later..?
If so, you need to 'read()' the object in the start() method and 'write()' the Hotel in the finish() method.
The problem in your code snippet is that you are trying to do both in the start() method. This has all manner of potential issues, not least of which is that your write() method needs to flush the stream (causing the data to actually be written to the file) and you probably then need to close the output stream before the input stream will be allowed to read.
Probably.
It might just be that if you call
oosoos.close(); // this will flush the stream
...after
oosoos.writeObject(hotel);
then the intput stream will successfully read the object.
However, you really need to split this code up as I mentioned previously - the code that you have posted is pointless; you write the Hotel object to the file and then read it back... you could just use the object that you wrote to file, without ever reading it back in...
Hope this helps and apologies if I have misunderstood, due to lack of knowledge of FX.
What I did was split up the read/write. I have it so it reads/inputs on startup, and when they click a button to create a reservation, it writes the current hotel object to the file.
I've written a small method that is meant to tell me if another instance of the application is already running. I am aware that there are many ways to find out if another instance is running, but I chose this one. I am creating an empty file and keeping it locked for the duration of the application instance. If another instance is running, the tryLock() method is supposed to return null:
private static boolean alreadyRunning() throws IOException {
FileChannel fc = FileChannel.open(MYLOCKFILE,
StandardOpenOption.CREATE,
StandardOpenOption.WRITE,
StandardOpenOption.DELETE_ON_CLOSE);
return fc.tryLock() == null;
}
(MYLOCKFILE is a Path for a file in my temp directory.)
When testing this on Windows 7 Professional 64-bit, I found that it works as expected for the first instance and the second attempted instance. However, after the second instance exits (leaving just the first instance running), when a third instance is run, the tryLock() call throws java.nio.file.AccessDeniedException instead of returning null. Can you explain this behaviour? If this is considered normal behaviour, how can I differentiate between an existing instance having the file locked, and a real 'access denied' situation such as an idiot setting the TEMP directory to read-only?
I made a test project and tested the code the only problem because of which java.nio.file.AccessDeniedException is thrown is StandardOpenOption.DELETE_ON_CLOSE option used in the code.
I removed the option and it works fine now
FileChannel fc = FileChannel.open(MYLOCKFILE, StandardOpenOption.CREATE,
StandardOpenOption.WRITE);
Explanation that I can think because of which java.nio.file.AccessDeniedException is thrown is that as soon as your second instance terminates the option StandardOpenOption.DELETE_ON_CLOSE [More explaination] will attempt to delete the file on JVM exit and failing might have registered an event in kernel or OS to delete the file as and when possible. So if any other process tries to access, create or write the same file before deletion it throws java.nio.file.AccessDeniedException as a delete operation is already pending for that file.
EDIT
As per your new comment, you can add the following code in try finally block placed after checking alreadyRunning() code.
Snippet Example:
if(!alreadyRunning())
{
try
{
// YOUR CODE THAT RUNS
while(true)
{
//YOUR
Thread.sleep(35000);
}
}
finally
{
new File("f:\\test.lock").deleteOnExit();
}
}
I have a static method used to get the title from a PDF using the metadata via itext, which is used as a small part of a major Task.
I noticed an inexplicable path that I narrowed down to this section of code. Specifically, in the line where I instantiate a PdfReader, the process doesn't throw an exception or continue through to the print statement. In fact, it clears out all of my for loops up to the top level of my program and acts as if nothing has happened and my task completed.
try {
System.out.println("Entered method");
PdfReader myReader = new PdfReader(file.getAbsolutePath());
System.out.println("Reader instantiated"); //if no issues, prints to console
Map<String, String> info = myReader.getInfo();
System.out.println(info.get("Title"));
return info.get("Title");
} catch (IOException e) {
System.out.println("PdfReader throws exception"); //if issues, prints to console
e.printStackTrace();
}
Unless I'm mistaken, when this set of code is executed in my method, either "Reader Instantiated" or "PdfReader throws exception" is printed out to the console.
Neither happens. Instead, the process skips every if/for/while loop it is currently in and ends the task.
I'm wondering if someone can explain to me what is happening and how I should go about fixing it?
In the odd event this is searched for, yes, catching Throwable stops the thread from bailing out. I had never seen something like this before. The cause behind the problem was that a PDF was password-protected, so getInfo() failed.
I have a query on handling error conditions with Java Swing.
I am using Netbeans to develop a simple Java Swing app. It is to load in a text file, then run calculation based on the numbers found in the text file. The main Swing class holds the JFrames and JPanels.
I have the file loading code as a separate class file. It returns the number of lines read and a List of numbers back to the main Swing app.
I realised that if the file reading fails (i.e. try -> catch (Exception ex)), the entire app will crash. What's the best way to handle errors resulting from my scenario above? That is to say, the file loading code crashes and I don't want the entire program to crash. I want the program to say the file is corrupted and wait for user to load new file.
Any thoughts?
Yakult
when you catch the exception, run:
JOptionPane.showMessageDialog("File is corrupted. Please select a new file.");
Then display the file dialog again.
It's probably best to do this as a loop that continues while the the file is not valid. If there is a corruption, then rather than throwing an exception, set a boolean flag and loop as long as the flag is set. That way, when a good file is found, the while loop will terminate.
Example:
public static void main(String[] args){
boolean goodFile = false;
while (!goodFile){
JFileChooser chooser = new JFileChooser();
chooser.showOpenDialog();
goodFile = processFile(chooser.getSelectedFile());
}
}
private boolean processFile(File file){
//do you stuff with the file
//return true if the processing works properly, and false otherwise
}
yeah
the problem is with your IO reading concept
the while loop is reading to the end of the file and so on..
to prevent that u can use a buffered reader
and use this code
String line = null
while((line = reader.readLine())!= null) {
// do stuf
}
if you are having this problem with processing the read line
all you need is to create a exception class of your own by extending Exception class and throw that exception in your catch block
after setting the message to your custom exception class you can set that message in to
JOptionPane.showMessageDialog(null,"message here"); //showMessageDialog is a static method
ok
You just catch the exception and put condition in the catch block. If the file contains other content that your application is intended to handle then you could call your method which will re-handle another file.
The main handling of your new process of the new file manipulation will start from your catch block. So in this way you are using java thrown exception to restart your application in a brand new way other than relaunching your app from the zero level.
I am designing a program in JAVA that captures results in about 10 iterations. At the end of these iterations all the results must be written into a log file.
If any exception occurs then it should be written on my text file and secondly the program must not stop, it must go on till the last iteration is completed...
That is to say - if some error occur on any part of any iteration the program must not stop here. The error must be mentioned within my results by the name of error and it must go on and update my log file.
My code till now is bit lengthy...used try-catch, the try block is doing my calculations and writing my text file, but I need if incase some exception occurs my program must not stop and that exception must be updated in my log file.
You're looking for the try-catch block. See, for example, this tutorial.
OutputStream os = ....;
PrintStream ps = new PrintStream(os);
while(notDone) {
try {
doStuff();
}
catch(Throwable t) {
t.printStackTrace(ps);
}
ps.print(results);
}
the case is, in this kind of a question, you should better provide us a sample code, then only we can identify the problem without any issue.
If you just need to view the error, then "e.printStackTrace" will help you. The "e" is an instance of class "Exception".
However, if you need to LOG, then "Logger" class will help you, with Exception class.For an example,
try {
f = location.createNewFile();
} catch (IOException ex) {
Logger.getLogger(TestForm.class.getName()).log(Level.SEVERE, null, ex);
}
To do all of these, it is better to surround your code with try catch block