FramePanel
Use local variables instead of instance variables if they're only used in one method.
I wouldn't implement ActionListener but instead add each action with a new ActionListener, either as an anonymous inner class, or if they get complex, a separate class.
Look at MVC examples like GUI Classes and ListenersGUI Classes and Listeners to see ways of separating this functionality.
Error Handling
There are a few things to keep in mind when adding error handling to a program:
- Log debugging information for the developer.
Consider using a logger instead of printStackTrace()
, and log extra
information on what the program was doing along with the exception.
This can be sent to a file which can be accessed afterwards. Error
output will usually be lost when a user runs a Swing program because they're
not running in a console.
Clean up resources.
try { writer = new BufferedWriter(new FileWriter(file.getAbsolutePath())); writer.write(""); // to clear out text writer.append(text); } catch (Exception e) { e.printStackTrace(); } finally { try { writer.flush(); writer.close(); } catch (Exception e) { e.printStackTrace(); } }
Closing the writer in the finally block is good, but you should check for null because the writer might not be set after an exception has occurred. The finally block is repetitive enough to put in a util method. Try-with-resource or alternative library methods take care of a lot of this boilerplate.
- Display feedback for the user.
If there's an error saving the file, no feedback is displayed to the user. The user only finds out later when they try to open the file, after they've lost their work.
Resume execution from a consistent state.
String fileName = util.openFile(edit, dialog.getSelectedFile()); openFile = dialog.getSelectedFile(); window.setName(fileName);
After an error, the previous file contents are still displayed, but the open file has changed to the new one. This is an inconsistent state, and accidently saving here can overwrite the contents of the new file with the old one.
So the util methods can't deal with the exception by themselves because the ActionListeners have their own error handling to do. The util methods should either return a error status, or throw the exception to let the caller know there's been an error.