Picture Filer: A free Java program for naming and sorting image files
I made this program to go along with my process for handling incoming digital pictures, but I hope you might find it useful also.
I copy files from my camera in to a working directory, and bulk rename them using my Nautilus script: rename-with-exif-date.sh. This gives me a bunch of files with a timestamp in YYMMDD_HHMMSS format, for example: 071125_090623.jpg.
Next I need to give them additional descriptive tags, and then sort them in to their permanent homes. I like to keep one big directory of originals for each year, and then a smaller subset sorted in to categories, which I might then crop and fix red-eye and etc. Let’s say the end result of a naming/sorting session results in these files:
~/pics/original/2007/
071125_090845 UFO Encounter- Saucer Landing.jpg
071125_090853 UFO Encounter- Saucer Landing.jpg
071125_091026 UFO Encounter- Colorful Lights.jpg
071125_091552 UFO Encounter- Little Green Man.jpg
071125_093410 Bedrock Bar- Fred.jpg
071125_093710 Bedrock Bar- Fred, Barney, Dino.jpg
071125_093928 Bedrock Bar- Wilma, Betty.jpg
~/pics/selected/2007/misc/
071125_090845 UFO Encounter- Saucer Landing.jpg
071125_091026 UFO Encounter- Colorful Lights.jpg
071125_091552 UFO Encounter- Little Green Man.jpg
~/pics/selected/2007/friends/
071125_093710 Bedrock Bar- Fred, Barney, Dino.jpg
071125_093928 Bedrock Bar- Wilma, Betty.jpg
(Yes: I use spaces in my picture names. Something I started in Windows. For other files I almost always use dashes instead of spaces now, but for pictures I’m not sure if I’ll convert.)
Maybe the second saucer landing picture and the Fred picture were good enough to keep, but didn’t warrant being included in the smaller subset. You should always try to protect your potential audience from picture proliferation.
How does the picture filer help us get to this organized end state?
Tags
You can define up to 15 “tags” which are represented by buttons on the left-hand side of the main window. Then you can quickly click or use keyboard shortcuts to add them to your filename. Upon renaming, trailing commas, dashes, and spaces are trimmed off. This is helpful for me, because most of my pictures are of my family, so the same names are used repeatedly. In the example, we could have had tags named “ Bedrock Bar-”, “ Fred,”, “ Barney,”, etc.
Sorting Dirs
You can define up to 10 directories for sorting files in to, represented in two rows of buttons across the top. These can be set up as copy or move directories, so that in my example, I’d click or use the keyboard shortcuts to first copy the renamed file to “misc” or “friends,” and then move the remaining working file in to the “2007” originals folder.
Let’s take a look at the interface:
Screenshots
That’s what it looks like for me in Ubuntu with the GTK “look and feel.” I think it looks better than the default Java cross-platform Metal UI look and feel.
You can also see what the main and config screens look like in Windows with the Windows XP look and feel.
Navigation/Keyboard Shortcuts/Configuration
I’ve tried to make it so that it’s easy to scroll back and forth, decide which pictures to keep or discard, and then name them and sort them. All of the navigation, tag, and directory buttons have keyboard shortcuts.
- Left Arrow: Previous picture
- Right Arrow: Next picture
- Backspace: Move focus to filename text field
- Enter: Rename file
- Delete: Delete file
- 0-9, A-F: Add associated tag to filename
- M-V: Copy or move file to associated dir
“Delete” isn’t really a delete. I wanted to make it so that deleted files would go to the trash (or recycle bin, or whatever), but unfortunately Java doesn’t provide a way to do this. I didn’t want to allow files to be easily deleted for good, and didn’t want to have an annoying prompt every time, so the program will attempt to create sub-directory under your current dir named “deleted” and put discarded files in there.
You set up your tags and directories in the config edit screen. After closing it, select “load” to load any new choices in to the main window. (This is kind of clumsy, I know. The config should be loaded as soon as you close the config window. More on that later.)
Configuration is saved in your home dir: ~/.mtf/config/pic-filer.conf. (mtf is for “moving to freedom”) For example: /home/scarpent/.mtf in GNU/Linux, or C:\Documents and Settings\scarpent\.mtf in Windows. The directory isn’t created until you select “ok” in the config screen, and can be safely removed at any time.
Development Notes
Your mileage may vary on the look and feel of the GUI. The program uses:
UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );
Which in my examples becomes:
com.sun.java.swing.plaf.gtk.GTKLookAndFeel //Ubuntu com.sun.java.swing.plaf.windows.WindowsLookAndFeel //Windows XP
I was happy with the way NetBeans worked for the user interface. The interface has many components, and it handled a lot of maneuvering of things without getting out of whack. It can be tricky, but it all seems to make sense. I really like how it manages things for you. I usually don’t care for code generators, but at least in this area of GUI design, I’m all for it. I’d hate to write all that code myself. And I think by following its “suggestions” for component placement, you can make a nice cross-platform GUI.
One area that I was limited in was the ability to work with control arrays. These are easy to do in Visual Basic and for a program like this with lots of controls, they can help make things simpler. But using the Matisse editor, I didn’t see a way to create and manage an array in design mode, so I had to place and name a lot of components. (I can see where it would be difficult to handle components that aren’t there at design time. The editor needs to know about all of them so it can create the necessary groups and relationships among items.) I found a suggestion to use an array to hold related components in order to address them with an index, and that worked out pretty well.
I’m a bit sketchy on how event handlers work. The designer made it easy to figure out how to add some to do what I needed, but I’m wondering if there is a more elegant way. I’ve got dozens of inner classes in the main form because of all the separate listeners I created. For example, I wanted every focusable control to listen for keypress events so that keyboard shortcuts would always work. Is there some more elegant way to do this than making every one of them have their own listener?
I made the config UI as a JFrame before realizing I couldn’t load one of those modally, and then couldn’t find or think of a way to make it update the main screen after selecting ok on it. I need to learn some things about JDialog, but didn’t want to spend my time on that right now. In the meantime, I have the config “load” button to work around this.
I’ve made some effort towards robustness, but as this is for my own use and I don’t expect an audience much larger than myself, I didn’t code for or test very many scenarios outside of my expected usage. If you do try it out and find problems, please let me know!
Downloads
Picture Filer is licensed with the GNU GPL, version 3 or later.
- Jar file: pic-filer.jar (178 KB) (Run with
java -jar pic-filer.jar) - Source *.java files: pic-filer-src.tgz (31 KB)
- NetBeans project (includes jar and src): pic-filer-nb-project.tgz (92 KB)
Requires the Java 6 JVM. There isn’t a completely free as in free software OpenJDK version yet for this, so I’m using Sun’s JDK in anticipation of independence day.
Related: Displaying a Scaled Image with Java Swing, an earlier version of the ImagePanel class used in Picture Filer.
Posted by Scott Carpenter on 26 November 2007 at 9:39 pm
filed under java, programming
No comments yet.
You can follow any responses to this entry through the
comments feed.

bookmark with del.icio.us
Richard Stallman:


