setting native desktop look and feel with java

March 30, 2014

This morning I woke up still thinking in Java and wondering why I have to live with the positively ancient and hideous Metal Look-and-Feel (LaF). Turns out I don’t have to. As you can see above, I’ve managed to turn on the Windows 8.1 LaF on my simple test framework, with just a few extra lines of code. And I’ve re-discovered it’s portable across all the environments I want to run this on (at least, the ones I care about), primarily Windows 7 and 8 and various Linux distributions and desktops. But first, the code. This is a modification to the source file, first seen in the prior post.

    private static void createGUI() {
        try {
            // Set system Java L&F (Windows for Windows, Gnome for Linux...)
        catch (UnsupportedLookAndFeelException |
                ClassNotFoundException |
                InstantiationException |
                IllegalAccessException exception) {
            // silently handle exception

        JTabbedPane tabbedPane = new JTabbedPane();
        ImageIcon icon = createImageIcon("images/image.gif");

        tabbedPane.addTab("Tab 1", icon, makeTable(), "Sample 1");
        tabbedPane.setTabComponentAt(0, new CloseTabControl(tabbedPane));
        tabbedPane.setMnemonicAt(0, KeyEvent.VK_1);

        tabbedPane.addTab("Tab 2", icon, makeTable(), "Sample 2");
        tabbedPane.setTabComponentAt(1, new CloseTabControl(tabbedPane));
        tabbedPane.setMnemonicAt(1, KeyEvent.VK_2);

        JFrame frame = new JFrame("Test tabs and tables");

        frame.setSize(800, 600);

Lines 2 through 13 are the new lines added. If you’re lazy and don’t care about defensive programming practices then you can toss the try/catch block and just copy lines 5 and 6 and be done with it. But I prefer to write a little more robustly if possible, so that try/catch block is a very small price to pay. I believe in quality code, especially in the final shipping product. In the process of adding this code block, I also removed a line of code; JFrame.setDefaultLookAndFeelDecorated(false);  . This line is no longer needed.

This code block also illustrates an interesting feature of NetBeans 8. The catch block (lines 8 through 13) is a multiple exception catch block that was introduced in Java 7. In earlier versions of Java you needed to write separate catch blocks for every exception, an onerous task, even if you had an IDE that would automatically assist you in creating them all. Once written you had all those individual catch blocks to maintain into the future. It’s no wonder that a lot of Java programmers eschewed writing try/catch unless it was absolutely necessary (as in, javac refused to compile the code). While this doesn’t remove all the pain, multiple exception catch makes it a lot easier to write, and in particular, easier to read in the future.

How does NetBeans 8 fit into this? I was given a recommendation by the NetBeans 8 IDE, and when I selected that from its dialog, it automatically reformatted the code for me. This is one key reason why a good IDE like NetBeans or IntelliJ IDE are at times vital to fast and accurate Java programming. Those tools support you in writing up-to-date compliant code, and teach you a few things along the way.

Here’s a few screen captures of the exact same code running on Linux. Both were running in VMware. The top screen capture is CentOS 6.5 (equivalent to RHEL 6.5) running Gnome 2, and the bottom is Linux Mint 15 running its Cinnamon desktop. Of note are the tabs. They don’t look quite right, and that’s because of the “hand-drawn” close button icon. I need to dig a little deeper and learn how to use a given LaF icon, using the “hand drawn” version when I can’t find it. That will make the tabs look a lot better. But for the time being, this is Good Enough.

NOTE: All my Linux installations (hardware and virtual) are now running Java 8. Even my little Raspberry Pi.