Using JSON in Java Swing

After months of working with PHP and AJAX, I finally found time and a reason to go back to Java Swing. This simple application, made at a friend’s request, enables one to determine his/her Ghanaian name based on their date of birth. With all the time I have spent working with PHP and AJAX, I have come to love the JSON data exchange format and I simply could not pass up the opportunity to see how it performs and works with my latest Java Swing incarnation. The application also includes the new Swing Task Dialog component and makes use of the Joda Time API. 

Why Choose Java Swing?

During the initial planning for this application, I had to consider the various languages and platforms available that I could use for this application. The options included:

  • JavaFX: my preferred choice, unfortunately this needed to be a simple desktop application and the whole web based deployment would not work because we did not have a server to host this on. (Annoying!!! – Oracle take note)
  • Flash: I should have considered this, because it could do all that JavaFX could and can be run as a desktop application as well. (Oversight on my part – Oracle take note)
  • Java Swing: easy, simple and with the aid Netbeans a breeze to use. Allows for simple desktop deployment and there are a host of libraries to achieve anything.
  • PHP + AJAX: Awesome platform, but does not meet the desktop requirement.
  • .Net: haven’t coded anything in that environment before. Totally out of the question.

The Application

The application in it self is fairly simply, just a couple of combo boxes, a text field and a button and runs in simulated Full Screen Mode by disabling the title bar maximizing the application. See screen shots below

Where JSON Was Used

I needed to make the application a bit more fun to look at, so I decided to implement automatically changing background images. To do this, I needed to store the image path information somewhere and retrieve when the application run. Options for simple data store:

  • Key Value Pairs (Property Files): Useful, simple to implement, 100% success rate. Been there done that
  • CSV: tricky data store format, also I needed other properties aside the image data. Not gonna fly
  • JavaDB: useful, extensible, robust. I bit too much for a 49KB application
  • Mongo/Couch DB: never used it
  • XML: No way hose! To much parsing and stuff for just simple properties
  • JSON: Oh nice!!! Never tried that in a desktop application before. Let’s give it a shot

So I went with JSON.  I headed over to JSON.org and grabbed the Java implementation of the JSON parser and writer. Made a simple Netbeans Java Library project for the source code, made a few code polishes via the Netbeans code editor hints, compiled the library and was ready  to go.

The Data Store Format

Below is an example of the data store which is parsed on application start up to retrieve the images  and other properties.

/**
 * This file stores the information about the background images, and the time delay between loading the images
 **/
{
    "config": {
        "delay": 10, // in minutes
        "images": [
            "resources/bg.jpg",
            "resources/bg1.jpg",
            "resources/bg2.png"
        ]
    }
}

Note though, that although the Java style comments are supported by the Netbeans editor, when parsing the above code snippet, the JSON parse throws an error, since it does not automatically strip out the comments. So I had to do without them since I could not get a decent regex expression to run the replace on the code comments. Perhaps someone can help out with that.

The good thing here is that the “images” property is defined as an array, so I can just add as many images as possible and load them up as array in the actual application. The format itself is fairly simple and I even taught my friend (a non-programmer) how to edit the file to include his own images and further personalize the application.

I’m sure later, I will have to extract some the static text in the application and make them properties in this file as well, but until then, we’ll take it as it is.

Parsing the JSON Data

Below is the code used to parse the JSON data when the application starts up.

...
import org.json.JSONArray;
import org.json.JSONObject;
...

private javax.swing.Timer bgTimer;
private ArrayList bgImages;
private BufferedReader reader;
private JSONObject configObject;

public BackgroundSwitcher(final JComponent container) {

    // read the configuration information
    try {
        reader = new BufferedReader(new FileReader("resources/switcher.json"));

        StringBuilder jsonData = new StringBuilder();
        String data = "";
        while( (data = reader.readLine()) != null ) {
            jsonData.append(data);
        }

        configObject = new JSONObject( jsonData.toString() );
        System.out.println(configObject);
    } catch (Exception e) {
        showErrorMessage("Missing Configuration Information", e);
    }

    // get the switcher delay information from the configuration object
    double delay = 10; // default to 10 minutes if the config information is wrong
    try {
        delay = configObject.getJSONObject("config").getDouble("delay");
    } catch(Exception e) {
        showErrorMessage("Configuration Error: ", e);
    }

    // get the switcher images information from the configuration object
    bgImages = new ArrayList<String>();
    try {
        JSONArray array = configObject.getJSONObject("config").getJSONArray("images");
        for(int i = 0; i < array.length(); i++) {
            addImage( array.getString(i) );
        }

    } catch(Exception e) {
        showErrorMessage("Configuration Error", e);

        // add the default bg image if possible
        addImage("resources/bg.jpg");
    }

    // create the image switch timer control
    bgTimer = new javax.swing.Timer( (int)(1000 * 60 * delay), new ActionListener() {

        private int index = 0;

        @Override
        public void actionPerformed(ActionEvent e) {
            String imagePath = bgImages.get(0);

            if (imagePath != null) {
                container.setBorder(new BackgroundBorder(new File(bgImages.get(index))));
                System.out.println(imagePath);
            }

            index++;

            if (index >= bgImages.size()) {
                index = 0;
            }
        }
    });

    // set the initial delay to zero, so the images show up immediately
    bgTimer.setInitialDelay(0);
}

As can be seen from the above code snippet, the JSON source file is loaded and parsed with a BufferedReader and then resulting string is used to created JSONObject. The various properties and image reference information are then loaded saved to the respective variables.

The showErrorMessage() Function

This being a relatively new application, I just could not pass up the opportunity to make use of the all new Java Swing Task Dialog written by Eugene Ryzhikov. Below is the how the error message dialog was implemented:

private void showErrorMessage(String title, Exception e) {
    TaskDialog dialog = new TaskDialog(title);
        dialog.setText(e.getMessage());

        dialog.getDetails().setExpandableComponent(
                new JLabel("<html>" + Strings.stackStraceAsString(e).replaceAll("\n", "<br />") + "</html>"));

        dialog.show();
}

This basically takes the title of the error message as an argument and the error message it self and creates a general Task Dialog for all exception ins the application. Other areas of the application also make use of dedicated TaskDialog instances.

Other Libraries Used

In order to have a quick turn over and get the application out the door in the shortest possible time, I also made use of a few other Java Libraries, these include:

  • Joda-Time: the Java Date and Time API. Perhaps when Java 7 hits, I can rewrite this to use the official JSR. This was used to make simple three ComboBox DateSelection component
  • MigLayout: Java Layout Manager. Required by the TaskDialog component
  • BackgroundBorder: enables you to draw a background on any component, via the setBorder( ) method. Used for the background switching.

Conclusion

Although this was a simple application to implement, and I would have loved to use JavaFX instead of Java Swing for this so I could have benefited from a bit more animation in the UI than just the simple FadeIn and FadeOut implemented. But Sun/Oracle’s decision to make it strictly a web based RIA makes that an impossibility.

Personally, I hardly use Flash for anything except the occasional banner image on my website projects, so it stands to reason that I would neglect it as a viable option in the initial thought and planning process. But that said, I believe it is a superior platform to JavaFX at the moment, and implementing this application in Flash would have been much prettier and probably a lot faster to developer than Swing in some areas.

Lastly, if I chosen to extend the application to include an interface for dynamically loading and configuring the background image information, I believe that the JSON file format is an extremely excellent and easy choice for use as a data back store. It also makes it a lot more straight forward if I were to switch to either the new NoSQL data stores or an AJAX front end. Aside that, I think having the ability to process JSON in a Java Swing application opens a lot of possibilities in terms of RIA development, since it will be easy for example to communicate with a PHP backend and do a lot of stuff. However, there is no point in living in the past; if the new developments by Oracle towards JavaFX as the dominant Java UI development platform are the way forward, then I support it all the same. I only wish there was an easier way to implement JavaFX desktop applications, since Swing in itself if gradually loosing ground as a preferred choice for new desktop software development because of all the stagnated developments in the library.

About these ads

23 thoughts on “Using JSON in Java Swing

    1. Francis Adu-Gyamfi Post author

      Thanks Eugene for giving many of us Swing Developers a reason to come back to Java, since the framework is so mature that it hurts when its own owners do so little to make it a viable platform. C/C++ is much older than Java, yet it is finding so many ways to re-invent itself and stay fresh.

      Also thanks for the use case information. I will certainly update the source code internally and perhaps on this post for the benefit of others as well.

      Reply
    2. Francis Adu-Gyamfi Post author

      After reviewing the awesome short cuts provided by the TaskDialogs class, I think I will stick with the custom implementation for the exception handling, since I usually prefer to also edit the Dialog Title as well when showing error messages.

      From my experience, some users usually read that first before reading the actual error message, and I prefer to take that opportunity to start driving home the message.

      I think the TaskDialogs methods however, could benefit from the addition of the title parameter. But with that, we will be slowly drawing closer to an API which is syntactically similar the JOptionPane API, lol! That would have its pros and cons, but I think one advantage would be similarity or familiarity for Java developers who will be making the API transition to TaskDialog.

      Reply
    1. Francis Adu-Gyamfi Post author

      Good to know. Will add that to my arsenal of great Java tools and will most likely make use of it in my next project.

      Reply
  1. PhiLho

    JavaFX can run on the desktop, no need for a Web server to run such application. Just distribute the JNLP file along with the jar file.
    But alas, it will still reach Internet to get the JavaFX runtime… :-(

    Reply
    1. Francis Adu-Gyamfi Post author

      Okay assuming you already have the JavaFX runtime pre-loaded, do you have an example of how the JNLP would be constructed? I would be glad to have an example, perhaps I might just re-write this in JavaFX if deployment would be easy.

      Reply
    1. Francis Adu-Gyamfi Post author

      Thanks for the compliment, but I’m not using anything extra ordinary. Everything here aside the external libraries explicitly mentioned can be found in the Java Swing and AWT packages.

      Firstly, I used the Netbeans GUI Designer for laying out the content using the Free Design Layout. Secondly, the rounded rectangle was achieved by overriding the paintComponent(Graphics g) method of the central JPanel component, and using Custom Java2D painting to draw the rectangle and its stroke using an Alpha Composite of 50% with anti-aliasing turned on.

      The rest is are just normal JLabels, ComboBoxes ans Button properly aligned (to pixel perfect quality as much as possible). The fonts needed to be big because the software might be projected on screen, so I just increased the default Windows font to about 18px (for the JLabels, buttons and boxes) and 24px+ for the other labels. The images at the back are simple JPEG images, some found on Google and others created using an image editor.

      If there is anything you don’t understand let me know, and I might try to explain further or point you to the necessary resources for the relevant reading, source code examples or downloads.

      Reply
      1. G

        Thank you for the info. Sure, if you have reading, source code examples or downloads I’ll be happy to learn that stuff!

      2. Muchachon

        Francis you have good skills for UI with Swing, It would be cool if you could post a tutorial in how you created this nice UI so it will be very handy to learn from you. The images you created them with a tool?.

        I think if there is more tutorials and tricks on how to use Swing it could get again the steam cause seeing your program I see Swing have a lot of potential. As you said JavaFX have a lot of problems and also the license ruins it. I prefer Java and Swing but I would like to learn to do better UI’s with it.

        Best regards.

      3. Francis Adu-Gyamfi Post author

        Thanks Muchachon. I’ve been thinking the same thing myself, i.e. about the tutorials and also finding a way to make Swing gain some traction again. See my reply to “G” above for a summary on how this was created.

        Truthfully, making UI in JavaFX is 5 times easier than Swing but personally I also prefer Swing for it robustness and power. I’m praying I get the wisdom and time to post more UI related articles. Perhaps I could take over from where Romain Guy and Chet Haase left off. Who knows?

  2. Pingback: Blog bookmarks 05/20/2010 « My Diigo bookmarks

  3. Pingback: JSON In Java. Where Should It Go? « ICED IN CODE

  4. Pingback: 2010 in review « ICED IN CODE

  5. sonnykwe

    Hey, im working with swingx library to render JSON. I would like to include an embedded db for my desktop app, but there aren’t many options to store JSON… What is your opinion about embedded JSON databases? Grettings

    Reply
    1. Francis Adu-Gyamfi Post author

      Could you not simply use a TEXT field to store the JSON data. I also have not personally used a JSON database in an embedded application, but I believe the performance will be comparable to an SQL database.

      Reply
  6. evanxg852000

    “Java Swing: easy, simple and with the aid Netbeans a breeze to use. Allows for simple desktop deployment and there are a host of libraries to achieve anything.”

    Don’t agree man ! I am struggling currently to embed flash in my swing application but have not found any good library . also the Java media framework is null . I turned to jfx for swing but does not work. I have to develop my own JNI

    Reply
  7. Pasindu

    If we use Json for database connectivity (online db) will the App freeze or crashed? I used direct JDBC connection for Online DB conectivity for Java Swing, but it is very slow.

    Reply
    1. Francis Adu-Gyamfi Post author

      JSON is only a data exchange format, so it cannot cause your application to crash. If the application is crashing then you have issues with how you handle multi-threading, connection management to your external resources or potential resource locking due to race conditions.

      I advise you try to profile your application to determine what goes on just before the application crashes, because JSON itself is not the cause.

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s