Archive for the ‘Java’ Category.

Writing UTF-8 CSV Files for Excel

Yesterday a coworker complained that Excel wasn’t displaying a CSV (comma separated values) file correctly. Our application allows the user to send a report via email. The application provides the report as a CSV file. Because the report can contain multilingual text, we’ve decided to encode it in UTF-8. Unfortunately, when users click on the file to display it, usually in Excel, all of the multi-byte encoded characters display incorrectly.

The problem was immediately clear to me…Excel was opening the UTF-8 encoded files, but it was incorrectly identifying them as Latin-1 encoded files. In the absence of any charset identification, Excel must guess about a file’s content encoding. In our environment, many host PCs use en_US locales with Latin-1 as the typical charset. Excel uses that default to read and display CSV files.

My solution to the problem was to use the byte-order marker (BOM) to identify the CSV file as a Unicode file. I instructed my colleague to prepend the FEFF character to the file. The Java application that writes the file uses a FileWriter that encodes to UTF-8 to create the CSV file. It was simple to just output the BOM as the first character in the file.

Now when our customers double-click on these files, Excel opens the file, notices the BOM, and automatically selects UTF-8 as the file’s charset encoding. Now Excel displays the previously mangled characters correctly. And I was able to help resolve a problem with an easy solution.

Maybe you can give your applications a hint about plain text files as well. Writing the BOM to your file can help Unicode-enabled applications know how to decode your Unicode files.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

International Enhancements in Java SE 6

One important strength of the Java Platform, Standard Edition (Java SE) has always been its internationalization and localization support. The platform continues to evolve, and Java SE 6 provides developers even more control over how they access and use locale-sensitive resources in their applications. Java SE 6 provides the following major enhancements to its internationalization support:

  • Resource control and access
  • Locale-sensitive service
  • Text normalization
  • International domain names
  • Japanese calendars
  • New supported locales

Read more about this in the article:

International Enhancements in Java SE 6

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

Understanding Locale in the Java Platform

Language and geographic environment are two important influences on our culture. They create the system in which we interpret other people and events in our life. They also affect, even define, proper form for presenting ourselves and our thoughts to others. To communicate
effectively with another person, we must consider and use that person’s culture, language, and environment.

Similarly, a software system should respect its users’ language and geographic region to be effective. Language and region form a locale, which represents the target setting and context for localized software. The Java platform uses java.util.Locale objects to represent locales. This article describes the Locale object and its implications for programs written for the Java platform.

Have a look. It’s an older article, but still perfectly valid and useful: Understanding Locale in the Java Platform.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

UTF-8 charset encoding update

The UTF-8 encoding is easy to abuse in some ways. Or rather, sometimes people use it in unexpected ways.

Recently the Java platform received an update to reject one malformed UTF-8 encoding sequence called “non-shortest form.” You can learn more about this fix and its implications for you in the article Overhauling the Java UTF-8 Charset.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

Discovering resource bundles at runtime

hellodlg

Yesterday a friend asked me a question about Java resource bundles: how can I get my application to discover resource bundles dynamically?

It seemed like a simple question. I answered in my typical fashon: Well, everytime you need a new bundle, just add that bundle’s jar or directory to your classpath and run the application. Or if it’s just a single properties file, add that file to your existing classpath, maybe drop it into the same directory as your other properties files.

My friend wasn’t content with that. He had done some homework before asking me. He said, “My application is in a jar file. I launch it on the command line like this, java -jar MyApp.jar. When I wanted to add new resource bundle jar files, I tried this: java -cp Hello_ja.jar -jar MyApp.jar. It didn’t work. The app doesn’t see the additional Hello_ja.jar file.”

I explained that when you use java -jar MyApp.jar, the jar’s own classpath settings defined by its manifest file will override anything on the command line that is defined by the cp option. The cp option is worthless for setting a classpath in this situation.

Of course, he still needed a solution. Hmmm…how could I help him?

It turns out that you actually can add classes to your classpath dynamically at runtime. Your application can discover new jar files and use the functionality it finds in them. The ClassLoader class can help you. The ClassLoader class can add class directories, jar files, and even lists of jar files to a classpath. Then when you need a class from that directory or jar file, you can use ClassLoader to load the class.

Let’s look at how this might work for loading resource bundles. In my examples, I’m going to create an application that displays three greetings in a panel. I’ll package the application as a jar file. The application will load its resource bundles from jar files that I’ll place into a “plugins” subdirectory directly under the application jar. The big deal about this is that the application will discover the jar files that are in the plugins subdirectory each time it launches. So, if you want to add another localized set of bundles, just drop the new jar into the plugins directory.

First, let’s start with the Greetings application. It’s simple just to demonstrate the point. It loads resources from a standard resource bundle and puts the resource strings in a dialog. Although the ResourceBundle for messages is just a standard bundle, notice that I’ve provided a class loader. The class loader has been instructed to add jar files to the classpath, specifically the jars found in the plugins subdirectory. I’ll show you the ResourceLoader class later. For now, here’s part of the basic dialog-based app:

package com.joconner.hello;

import com.joconner.resplugin.ResourceLoader;
import java.util.Locale;
import java.util.ResourceBundle;

/**
 *
 * @author JOConner
 */
public class GreetingDialog extends javax.swing.JDialog {
    /** A return status code - returned if Cancel button has been pressed */
    public static final int RET_CANCEL = 0;
    /** A return status code - returned if OK button has been pressed */
    public static final int RET_OK = 1;

    private ResourceBundle res = null;

    /** Creates new form GreetingDialog */
    public GreetingDialog(java.awt.Frame parent, boolean modal) {
        super(parent, modal);
        ClassLoader resourceLoader = ResourceLoader.createForDirectory("plugins/");
        res = ResourceBundle.getBundle("com.joconner.hello.resources.messages",
                Locale.getDefault(), resourceLoader);
        initComponents();
    }

    /** @return the return status of this dialog - one of RET_OK or RET_CANCEL */
    public int getReturnStatus() {
        return returnStatus;
    }

    private void initComponents() {
        tfMorning = new javax.swing.JTextField();
        tfAfternoon = new javax.swing.JTextField();
        tfEvening = new javax.swing.JTextField();
        addWindowListener(new java.awt.event.WindowAdapter() {
            public void windowClosing(java.awt.event.WindowEvent evt) {
                closeDialog(evt);
            }
        });
        tfMorning.setText(res.getString("greeting.morning"));
        tfAfternoon.setText(res.getString("greeting.afternoon"));
        tfEvening.setText(res.getString("greeting.evening"));

As you can see, the above dialog doesn’t do anything surprising with the bundles; it retrieves a bundle, pulls strings from it, and uses those strings in 3 text fields. However, notice that I’ve instructed the ResourceBundle class to use a special class loader. The class loader code is here:

public class ResourceLoader {

    private ResourceLoader() {}
    private ResourceLoader(File dir) {
        this.directory = dir;

    }

    /**
     * Create a ResourceLoader for a specific file system location.
     * All JAR files and subdirectories in the location will be added
     * to the classpath
     */
    public static ClassLoader createForDirectory(File dir) {
        ResourceLoader loader = null;
        if (dir.isDirectory()) {
            loader = new ResourceLoader(dir);
        }
        loader.addJarsToPath();
        return loader.getClassLoader();
    }

    public static ClassLoader createForDirectory(String dir) {
        File f = new File(dir);
        return createForDirectory(f);
    }

    private File[] addJarsToPath() {
        File[] jarFiles = directory.listFiles();

        List urlList = new ArrayList();
        for(File f: jarFiles) {
            try {
                urlList.add(f.toURI().toURL());
            } catch (MalformedURLException ex) {
                Logger.getLogger(ResourceLoader.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        ClassLoader parentLoader = Thread.currentThread().getContextClassLoader();
        URL[] urls = new URL[urlList.size()];
        urls = urlList.toArray(urls);
        URLClassLoader classLoader = new URLClassLoader(urls, parentLoader);
        this.loader = classLoader;

        return jarFiles;
    }

    public ClassLoader getClassLoader() {
        return this.loader;
    }

    private File directory;
    private ClassLoader loader;
}

This ClassLoader puts all jar files that are in my application-defined “plugins” subdirectory onto the classpath. See the addJarsToPath method for the exact wa to do this. Of course, this particular implementation isn’t robust. If you were doing this in an important application, you might want to confirm that a jar file really was a resource jar file….maybe your jar has a particular manifest file entry to provide very basic assurance that it is what you think it is.

Finally, just create your ResourceBundles as you normally would. Create jar files for each set of localized bundles for a specific language. Then drop them into a “plugins” directory immediately under your application’s main directory…the place your applications sits on the file system.

Now you can add new localized bundles to your application without having to recompile or jar your primary application. You don’t even have to change its classpath since new “plugins” jar files will automatically be added to the classpath for resource bundle creation.

There you go. Enjoy.

VN:F [1.9.3_1094]
Rating: 5.0/5 (1 vote cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

Is the Swing Application Framework necessary now?

Although resurrecting the Swing Application Framework (SAF) is a noble and respectable goal, is that even necessary now with JavaFX? If Sun does finalize and fix any remaining rough spots in SAF, is any significant number of developers going to benefit?

Even though I mean no harm or disrespect, someone is bound to view my question as an attack. It’s not. I thought the Swing Application Framework was a great idea. I even spent time writing about and promoting it. But I’m thinking differently these days. I think JavaFX confuses the issue for me.

SAF really is all about making it easier to write Swing application GUIs. The newbie benefits tremendously. Even a veteran benefits because some of the basic boilerplate setup and application structure is already defined. That doesn’t change at all. SAF still fills the void there if you’re going to write Swing applications. For newbies, it’ll get you started in the right direction. For veterans, it might save you some time.

However, most existing applications won’t need SAF. Any of the basic problems that the simple SAF resolves have already been fixed in any existing, big application. The effort to retrofit an existing application to SAF is…well, maybe it isn’t worth it.

More importantly, don’t you really get the feeling that the near and mid-term future of GUIs is JavaFX? Don’t you think the vast majority of Sun resources has been going to JavaFX? I really do. So…any newbie in the world of Java GUIs would probably do best to learn JavaFX, not Swing. Considering Sun’s efforts to push and promote JavaFX for rich GUI apps, JavaFX is really the right place to put your energy right now — especially on new development.

Maybe you don’t buy into JavaFX just yet because of its short history. In that case, go ahead with Swing and the SAF. But…I think any effort put into SAF is for a short-term benefit at this point.

Enough already. I’ve said it. The Swing Application Framework was a good thing, but it didn’t really get the support it needed in the time frame that would have helped its adoption. Resurrecting it now may be a noble goal, but I personally think the people and projects that need SAF the most are now looking at JavaFX.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

JSR 310, is it time for a new Date concept in Java

JSR 310: A New Java Date/Time API by Jesse Farnham — Java SE’s Date and Calendar classes leave much to be desired. Will the third time be the charm? JSR 310, tracking for inclusion in Java SE 7, once again tries to offer a comprehensive date and time API, borrowing much of its design from the popular Joda Time API. In this article, Jesse Farnham takes a look at JSR 310′s concepts and how they may yet bring sense to dates and times in Java.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

Understanding locale in the Java platform

traveling dukeLanguage and geographic environment are two important influences on our culture. They create the system in which we interpret other people and events in our life. They also affect, even define, proper form for presenting ourselves and our thoughts to others. To communicate effectively with another person, we must consider and use that person’s culture, language, and environment.

Read Understanding Locale in the Java Platform for more details about how to use locale in your Java applications.

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

Managing resources in the Swing Application Framework (JSR 296)

Instead of loading and working with ResourceBundle files directly, you will use the ResourceManager and ResourceMap framework classes to manage resources. A ResourceMap contains the resources defined in a specific ResourceBundle implementation. A map also contains links to its parent chain of ResoureMap objects. The parent chain for any class includes the ResourceMap for that specific class, the application subclass to which the class belongs, and all superclasses of your application up to the base Application class.

Continue reading ‘Managing resources in the Swing Application Framework (JSR 296)’ »

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)

International Domain Names

The Java SE 6 release provides an interesting new class: java.net.IDN. It’s small, simple…very focused on a single task. That task has two parts:

  1. to convert domain names from practically any Unicode character to an ASCII Compatible Encoding or ACE.
  2. to convert ACE names back into their full Unicode UTF-16 encoding

Continue reading ‘International Domain Names’ »

VN:F [1.9.3_1094]
Rating: 0.0/5 (0 votes cast)
VN:F [1.9.3_1094]
Rating: 0 (from 0 votes)