changeset 1136:9d27da66582c

Use LocalizedString in public API where appropriate Reviewed-by: neugens Review-thread: http://icedtea.classpath.org/pipermail/thermostat/2013-May/006820.html
author Jon VanAlten <jon.vanalten@redhat.com>
date Mon, 27 May 2013 20:50:48 -0600
parents de36c4b57bb4
children 3a2501017e91
files client/core/src/main/java/com/redhat/thermostat/client/ui/ContextAction.java client/core/src/main/java/com/redhat/thermostat/client/ui/HostContextAction.java client/core/src/main/java/com/redhat/thermostat/client/ui/MenuAction.java client/core/src/main/java/com/redhat/thermostat/client/ui/VMContextAction.java client/living-vm-filter/core/src/main/java/com/redhat/thermostat/client/filter/vm/core/internal/LivingVMFilterMenuAction.java client/living-vm-filter/core/src/main/java/com/redhat/thermostat/client/filter/vm/core/internal/LocaleResources.java client/living-vm-filter/core/src/main/resources/com/redhat/thermostat/client/filter/vm/core/internal/strings.properties client/living-vm-filter/core/src/test/java/com/redhat/thermostat/client/filter/vm/core/internal/LocaleResourcesTest.java client/swing/src/main/java/com/redhat/thermostat/client/swing/MenuHelper.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButton.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionToggleButton.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/DescriptionField.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HeaderPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/LocalizedLabel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/OverlayPanel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SearchField.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java client/swing/src/main/java/com/redhat/thermostat/client/swing/components/StatusBar.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/LocaleResources.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainView.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/StatusBar.java client/swing/src/main/resources/com/redhat/thermostat/client/swing/internal/strings.properties client/swing/src/test/java/com/redhat/thermostat/client/swing/MenuHelperTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ActionButtonTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/HeaderPanelTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/SearchFieldTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/components/StatusBarTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/LocaleResourcesTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/StatusBarTest.java config/src/main/java/com/redhat/thermostat/shared/locale/LocalizedString.java killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/KillVMAction.java thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java vm-classstat/client-swing/src/main/java/com/redhat/thermostat/vm/classstat/client/swing/VmClassStatPanel.java vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/internal/VmCpuPanel.java vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/internal/VmGcPanel.java vm-gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramPanel.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapDumpListView.java vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/OverlayComponent.java vm-jmx/client-swing/src/main/java/com/redhat/thermostat/vm/jmx/client/swing/internal/JmxNotificationsSwingView.java vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/locale/LocaleResources.java vm-memory/client-core/src/main/resources/com/redhat/thermostat/vm/memory/client/locale/strings.properties vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/internal/VmOverviewPanel.java
diffstat 50 files changed, 743 insertions(+), 545 deletions(-) [+]
line wrap: on
line diff
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/ContextAction.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/ContextAction.java	Mon May 27 20:50:48 2013 -0600
@@ -36,6 +36,8 @@
 
 package com.redhat.thermostat.client.ui;
 
+import com.redhat.thermostat.shared.locale.LocalizedString;
+
 /**
  * Parent interface for all context-sensitive actions.
  * <p>
@@ -60,9 +62,9 @@
 public interface ContextAction {
     
     /** A user-visible name for this action */
-    String getName();
+    LocalizedString getName();
 
     /** A user-visible description for this action */
-    String getDescription();
+    LocalizedString getDescription();
 }
 
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/HostContextAction.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/HostContextAction.java	Mon May 27 20:50:48 2013 -0600
@@ -38,6 +38,7 @@
 
 import com.redhat.thermostat.annotations.ExtensionPoint;
 import com.redhat.thermostat.client.core.Filter;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.HostRef;
 
 /**
@@ -69,14 +70,14 @@
      * localized.
      */
     @Override
-    String getName();
+    LocalizedString getName();
 
     /**
      * A user-visible description for this {@code HostContextAction}. This
      * should be localized.
      */
     @Override
-    String getDescription();
+    LocalizedString getDescription();
 
     /**
      * Invoked when the user selects this {@code HostContextAction}.
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/MenuAction.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/MenuAction.java	Mon May 27 20:50:48 2013 -0600
@@ -36,6 +36,7 @@
 package com.redhat.thermostat.client.ui;
 
 import com.redhat.thermostat.annotations.ExtensionPoint;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 
 /**
  * {@code MenuAction}s are used to create top-level menu items in the main
@@ -65,11 +66,11 @@
 
     /** The user-visible text displayed as the menu item. */
     @Override
-    public String getName();
+    public LocalizedString getName();
 
     /** A user-visible description of what this {@code MenuAction} does. */
     @Override
-    public String getDescription();
+    public LocalizedString getDescription();
 
     /** Invoked when the user selects this menu item */
     void execute();
@@ -78,7 +79,7 @@
     Type getType();
 
     /** The path to the menu action. The last element must equal getName() */
-    String[] getPath();
+    LocalizedString[] getPath();
 
 }
 
--- a/client/core/src/main/java/com/redhat/thermostat/client/ui/VMContextAction.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/core/src/main/java/com/redhat/thermostat/client/ui/VMContextAction.java	Mon May 27 20:50:48 2013 -0600
@@ -38,6 +38,7 @@
 
 import com.redhat.thermostat.annotations.ExtensionPoint;
 import com.redhat.thermostat.client.core.Filter;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.VmRef;
 
 /**
@@ -70,14 +71,14 @@
      * localized.
      */
     @Override
-    public String getName();
+    public LocalizedString getName();
 
     /**
      * A user-visible description for {@code VMContextAction}. Should be
      * localized.
      */
     @Override
-    public String getDescription();
+    public LocalizedString getDescription();
 
     /**
      * Invoked when the user selects this {@code VMContextAction}.
--- a/client/living-vm-filter/core/src/main/java/com/redhat/thermostat/client/filter/vm/core/internal/LivingVMFilterMenuAction.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/living-vm-filter/core/src/main/java/com/redhat/thermostat/client/filter/vm/core/internal/LivingVMFilterMenuAction.java	Mon May 27 20:50:48 2013 -0600
@@ -38,9 +38,12 @@
 
 import com.redhat.thermostat.client.filter.vm.core.LivingVMFilter;
 import com.redhat.thermostat.client.ui.MenuAction;
+import com.redhat.thermostat.shared.locale.LocalizedString;
+import com.redhat.thermostat.shared.locale.Translate;
 
 class LivingVMFilterMenuAction implements MenuAction {
 
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
     private LivingVMFilter filter;
     
     public LivingVMFilterMenuAction(LivingVMFilter filter) {
@@ -48,13 +51,13 @@
     }
     
     @Override
-    public String getName() {
-        return "Show Non Living VM";
+    public LocalizedString getName() {
+        return t.localize(LocaleResources.SHOW_DEAD_VM_NAME);
     }
 
     @Override
-    public String getDescription() {
-        return "Shows non living VM in the vm list";
+    public LocalizedString getDescription() {
+        return t.localize(LocaleResources.SHOW_DEAD_VM_DESC);
     }
 
     @Override
@@ -68,8 +71,8 @@
     }
 
     @Override
-    public String[] getPath() {
-        return new String[] { "Edit", getName() };
+    public LocalizedString[] getPath() {
+        return new LocalizedString[] { t.localize(LocaleResources.EDIT_MENU), getName() };
     }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/living-vm-filter/core/src/main/java/com/redhat/thermostat/client/filter/vm/core/internal/LocaleResources.java	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.filter.vm.core.internal;
+
+import com.redhat.thermostat.shared.locale.Translate;
+
+public enum LocaleResources {
+
+    SHOW_DEAD_VM_NAME,
+    SHOW_DEAD_VM_DESC,
+
+    EDIT_MENU,
+    ;
+
+    static final String RESOURCE_BUNDLE = "com.redhat.thermostat.client.filter.vm.core.internal.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/living-vm-filter/core/src/main/resources/com/redhat/thermostat/client/filter/vm/core/internal/strings.properties	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,3 @@
+SHOW_DEAD_VM_NAME = Show dead VM processes
+SHOW_DEAD_VM_DESC = Includes Java processes that are no longer running in the vm list
+EDIT_MENU = Edit
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/living-vm-filter/core/src/test/java/com/redhat/thermostat/client/filter/vm/core/internal/LocaleResourcesTest.java	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.filter.vm.core.internal;
+
+import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest;
+
+public class LocaleResourcesTest extends AbstractLocaleResourcesTest<LocaleResources> {
+
+    @Override
+    protected Class<LocaleResources> getEnumClass() {
+        return LocaleResources.class;
+    }
+
+    @Override
+    protected String getResourceBundle() {
+        return LocaleResources.RESOURCE_BUNDLE;
+    }
+
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/MenuHelper.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/MenuHelper.java	Mon May 27 20:50:48 2013 -0600
@@ -52,6 +52,7 @@
 import com.redhat.thermostat.client.ui.MenuAction;
 import com.redhat.thermostat.common.utils.LoggingUtils;
 import com.redhat.thermostat.common.utils.StringUtils;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 
 /**
  * Helps adding or removing {@link MenuAction} from {@link JMenuBar}s.
@@ -76,7 +77,7 @@
             new EdtHelper().callAndWait(new Runnable() {
                 @Override
                 public void run() {
-                    String[] path = action.getPath();
+                    LocalizedString[] path = action.getPath();
                     Menu parent = findMenuParent(menuBar, path, true);
                     JMenuItem menu = null;
                     switch (action.getType()) {
@@ -93,7 +94,7 @@
                         break;
                     }
 
-                    menu.setText(action.getName());
+                    menu.setText(action.getName().getContents());
                     menu.addActionListener(new java.awt.event.ActionListener() {
                         @Override
                         public void actionPerformed(ActionEvent e) {
@@ -130,9 +131,9 @@
             new EdtHelper().callAndWait(new Runnable() {
                 @Override
                 public void run() {
-                    String[] path = action.getPath();
+                    LocalizedString[] path = action.getPath();
                     Menu parent = findMenuParent(menuBar, path, false);
-                    parent.remove(path[path.length - 1]);
+                    parent.remove(path[path.length - 1].getContents());
                     menuBar.revalidate();
                 }
             });
@@ -149,23 +150,23 @@
 
     }
 
-    private static Menu findMenuParent(JMenuBar menuBar, String[] path, boolean createIfNotFound) {
+    private static Menu findMenuParent(JMenuBar menuBar, LocalizedString[] path, boolean createIfNotFound) {
         Menu parent = null;
         int mainMenuCount = menuBar.getMenuCount();
         for (int i = 0; i < mainMenuCount; i++) {
             JMenu menu = menuBar.getMenu(i);
-            if (menu.getText().equals(path[0])) {
+            if (menu.getText().equals(path[0].getContents())) {
                 parent = new Menu(menuBar.getMenu(i));
                 break;
             }
         }
         if (parent == null) {
             if (createIfNotFound) {
-                JMenu delegate = new JMenu(path[0]);
+                JMenu delegate = new JMenu(path[0].getContents());
                 parent = new Menu(delegate);
                 menuBar.add(delegate);
             } else {
-                throw new IllegalArgumentException("top-level " + path[0] + " not found (using path" + Arrays.toString(path) + ")");
+                throw new IllegalArgumentException("top-level " + path[0].getContents() + " not found (using path" + Arrays.toString(path) + ")");
             }
         }
 
@@ -174,14 +175,14 @@
             boolean found = false;
             for (int j = 0; j < children.length; j++) {
                 Menu menu = children[j];
-                if (menu.getText().equals(path[i])) {
+                if (menu.getText().equals(path[i].getContents())) {
                     parent = menu;
                     found = true;
                 }
             }
             if (!found) {
                 if (createIfNotFound) {
-                    Menu newMenu = new Menu(new JMenu(path[i]));
+                    Menu newMenu = new Menu(new JMenu(path[i].getContents()));
                     parent.add(newMenu);
                     parent = newMenu;
                 } else {
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButton.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionButton.java	Mon May 27 20:50:48 2013 -0600
@@ -93,7 +93,5 @@
             setText_noClient("");
         }
     }
-    
-
 }
 
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionToggleButton.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ActionToggleButton.java	Mon May 27 20:50:48 2013 -0600
@@ -36,16 +36,11 @@
 
 package com.redhat.thermostat.client.swing.components;
 
-import java.awt.Color;
-import java.awt.Component;
-import java.awt.Graphics;
-import java.lang.reflect.InvocationTargetException;
-
 import javax.swing.AbstractButton;
 import javax.swing.Icon;
-import javax.swing.JFrame;
 import javax.swing.JToggleButton;
-import javax.swing.SwingUtilities;
+
+import com.redhat.thermostat.shared.locale.LocalizedString;
 
 @SuppressWarnings("serial")
 public class ActionToggleButton extends JToggleButton implements ToolbarButton {
@@ -53,14 +48,14 @@
     private String lastText;
     private boolean showText;
     public ActionToggleButton(final Icon icon) {
-        this(icon, "");
+        this(icon, LocalizedString.EMPTY_STRING);
     }
     
-    public ActionToggleButton(final Icon icon, String text) {
+    public ActionToggleButton(final Icon icon, LocalizedString text) {
         super(icon);
                 
         showText = true;
-        setText(text);
+        setText(text.getContents());
         
         setUI(new ActionButtonUI());
         setOpaque(false);
@@ -93,47 +88,6 @@
         } else {
             setText_noClient("");
         }
-    }
-    
-    public static void main(String[] args) throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-            
-            @Override
-            public void run() {
-               JFrame frame = new JFrame();
-               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-               
-               HeaderPanel header = new HeaderPanel();
-               header.setHeader("Test");
-               
-               Icon icon = new Icon() {
-                   @Override
-                   public void paintIcon(Component c, Graphics g, int x, int y) {
-                       g.setColor(Color.CYAN);
-                       g.fillRect(x, y, 16, 16);
-                   }
-                
-                   @Override
-                   public int getIconWidth() {
-                       return 16;
-                   }
-                
-                   @Override
-                   public int getIconHeight() {
-                       return 16;
-                   }
-               }; 
-               
-               ActionToggleButton button = new ActionToggleButton(icon);
-               header.addToolBarButton(button);
-               
-               button.setText("fluff");
-               
-               frame.getContentPane().add(header);
-               frame.setSize(500, 500);
-               frame.setVisible(true);
-            }
-        });
-    }     
+    }    
 }
 
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/DescriptionField.java	Thu Jun 06 11:00:25 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,49 +0,0 @@
-/*
- * Copyright 2012, 2013 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.components;
-
-import javax.swing.JLabel;
-
-import com.redhat.thermostat.shared.locale.LocalizedString;
-
-public class DescriptionField extends JLabel {
-
-    public DescriptionField(LocalizedString text) {
-        super(text.getContents());
-    }
-
-}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HeaderPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/HeaderPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -46,7 +46,6 @@
 import java.awt.event.MouseEvent;
 import java.beans.PropertyChangeEvent;
 import java.beans.PropertyChangeListener;
-import java.lang.reflect.InvocationTargetException;
 import java.util.prefs.PreferenceChangeEvent;
 import java.util.prefs.PreferenceChangeListener;
 import java.util.prefs.Preferences;
@@ -54,13 +53,13 @@
 import javax.swing.AbstractButton;
 import javax.swing.BoxLayout;
 import javax.swing.JComponent;
-import javax.swing.JFrame;
 import javax.swing.JLabel;
 import javax.swing.JMenuItem;
 import javax.swing.JPanel;
-import javax.swing.JPopupMenu;
 import javax.swing.SwingUtilities;
 
+import com.redhat.thermostat.shared.locale.LocalizedString;
+
 /**
  * A component that host a panel with a nicely rendered header.
  */
@@ -71,7 +70,7 @@
     
     private boolean showText;
     
-    private String header;
+    private LocalizedString header;
     
     private JPanel contentPanel;
     private JLabel headerLabel;
@@ -83,14 +82,14 @@
     private Preferences prefs;
     
     public HeaderPanel() {
-        this("");
+        this(LocalizedString.EMPTY_STRING);
     }
     
-    public HeaderPanel(String header) {
+    public HeaderPanel(LocalizedString header) {
         this(Preferences.userRoot().node(HeaderPanel.class.getName()), header);
     }
     
-    public HeaderPanel(Preferences prefs, String header) {
+    public HeaderPanel(Preferences prefs, LocalizedString header) {
                 
         this.prefs = prefs;
         
@@ -150,13 +149,13 @@
         });
     }
     
-    public String getHeader() {
+    public LocalizedString getHeader() {
         return header;
     }
     
-    public void setHeader(String header) {
+    public void setHeader(LocalizedString header) {
         this.header = header;
-        headerLabel.setText(header);
+        headerLabel.setText(header.getContents());
     }
     
     public void setContent(JComponent content) {
@@ -218,22 +217,5 @@
             }
         }
     }
-    
-    public static void main(String[] args) throws InvocationTargetException, InterruptedException {
-        SwingUtilities.invokeAndWait(new Runnable() {
-            
-            @Override
-            public void run() {
-               JFrame frame = new JFrame();
-               frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-               
-               HeaderPanel header = new HeaderPanel();
-               header.setHeader("Test");
-               frame.getContentPane().add(header);
-               frame.setSize(500, 500);
-               frame.setVisible(true);
-            }
-        });
-    }
 }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/LocalizedLabel.java	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.components;
+
+import javax.swing.JLabel;
+
+import com.redhat.thermostat.shared.locale.LocalizedString;
+
+public class LocalizedLabel extends JLabel {
+
+    public LocalizedLabel(LocalizedString text) {
+        super(text.getContents());
+    }
+
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/OverlayPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/OverlayPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -54,6 +54,7 @@
 
 import com.redhat.thermostat.client.swing.GraphicsUtils;
 import com.redhat.thermostat.client.ui.Palette;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 
 /**
  * A panel meant to be stacked on top of existing components to display
@@ -81,7 +82,7 @@
     /**
      * Creates a new {@link OverlayPanel}, with an arrow facing upward.
      */
-    public OverlayPanel(String title) {
+    public OverlayPanel(LocalizedString title) {
         this(title, true);
     }
     
@@ -89,7 +90,7 @@
      * Creates a new {@link OverlayPanel}. The panel will display an up facing
      * arrow if {@code displayArrow} is {@code true}.
      */
-    public OverlayPanel(String title, boolean displayArrow) {
+    public OverlayPanel(LocalizedString title, boolean displayArrow) {
         
         this.displayArrow = displayArrow;
         
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SearchField.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/SearchField.java	Mon May 27 20:50:48 2013 -0600
@@ -58,6 +58,7 @@
 import com.redhat.thermostat.client.swing.IconResource;
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionNotifier;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.shared.locale.Translate;
 
 /**
@@ -82,7 +83,7 @@
     private final JTextField searchField = new JTextField();
 
     private final AtomicReference<String> searchText = new AtomicReference<String>("");
-    private final AtomicReference<String> label = new AtomicReference<>(translator.localize(LocaleResources.SEARCH_HINT).getContents());
+    private final AtomicReference<LocalizedString> label = new AtomicReference<>(translator.localize(LocaleResources.SEARCH_HINT));
     private final AtomicBoolean labelDisplayed = new AtomicBoolean(true);
 
     public SearchField() {
@@ -92,7 +93,7 @@
         JLabel searchIcon = new JLabel(IconResource.SEARCH.getIcon());
         searchIcon.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
 
-        searchField.setText(label.get());
+        searchField.setText(label.get().getContents());
         searchField.setName(VIEW_NAME);
         /* the insets are so we can place the actual icon inside the searchField */
         searchField.setMargin(new Insets(0, 0, 0, 30));
@@ -142,7 +143,7 @@
                 if (searchText.get().equals("")) {
                     labelDisplayed.set(true);
                     searchField.setForeground(Color.GRAY);
-                    searchField.setText(label.get());
+                    searchField.setText(label.get().getContents());
                 }
             }
 
@@ -180,15 +181,15 @@
         searchField.setText(text);
     }
 
-    public void setLabel(String label) {
+    public void setLabel(LocalizedString label) {
         this.label.set(label);
         if (labelDisplayed.get()) {
-            searchField.setText(this.label.get());
+            searchField.setText(this.label.get().getContents());
         }
     }
 
-    public void setTooltip(final String tooltip) {
-        searchField.setToolTipText(tooltip);
+    public void setTooltip(final LocalizedString tooltip) {
+        searchField.setToolTipText(tooltip.getContents());
     }
 
     public void addActionListener(ActionListener<SearchAction> listener) {
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/ShadowLabel.java	Mon May 27 20:50:48 2013 -0600
@@ -44,6 +44,7 @@
 import javax.swing.plaf.metal.MetalLabelUI;
 
 import com.redhat.thermostat.client.swing.GraphicsUtils;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 
 /**
  * A {@link JLabel} that has a shadow.
@@ -51,13 +52,13 @@
 @SuppressWarnings("serial")
 public class ShadowLabel extends JLabel {
 
-    public ShadowLabel(String text, Icon icon) {
-        super(text);
+    public ShadowLabel(LocalizedString text, Icon icon) {
+        super(text.getContents());
         this.setIcon(icon);
         setUI(new ShadowLabelUI());
     }
     
-    public ShadowLabel(String text) {
+    public ShadowLabel(LocalizedString text) {
         this(text, null);
     }
 
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/components/StatusBar.java	Thu Jun 06 11:00:25 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,130 +0,0 @@
-/*
- * Copyright 2012, 2013 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.components;
-
-import java.awt.BorderLayout;
-import java.awt.Dimension;
-import java.beans.Transient;
-
-import javax.swing.ImageIcon;
-import javax.swing.JFrame;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.SwingUtilities;
-
-/**
- * A status bar used to display relevant information and status.
- * <p>
- * A status bar is normally displayed at the bottom of the main window.
- * It may contain one or more areas displaying text and icons.
- */
-@SuppressWarnings("serial")
-public class StatusBar extends JPanel {
-
-    // some of this code is inspired by the book
-    // Swing Hacks: Tips & Tools for Building Killer GUIs
-    // By Joshua Marinacci, Chris Adamson
-    // ISBN: 0-596-00907-0
-    // website: http://www.oreilly.com/catalog/swinghks/
-
-    public static final String PRIMARY_STATUS_PROPERTY = "primaryStatus";
-    
-    private Dimension preferredSize;
-    
-    private String primaryStatus = "";
-    private JLabel primaryStatusLabel;
-    private JLabel iconLabel;
-    
-    public StatusBar() {
-        super();
-        setLayout(new BorderLayout(0, 0));
-        
-        primaryStatusLabel = new JLabel(primaryStatus);
-        primaryStatusLabel.setName("primaryStatusLabel");
-        primaryStatusLabel.setFont(getFont().deriveFont(10.0f));
-        primaryStatusLabel.setHorizontalAlignment(JLabel.LEADING);
-        primaryStatusLabel.setVerticalAlignment(JLabel.CENTER);
-
-        add(primaryStatusLabel, BorderLayout.WEST);
-        
-        iconLabel = new JLabel("");
-        ImageIcon grip = new ImageIcon(getClass().getResource("/icons/resize-grip.png"));
-        iconLabel.setIcon(grip);
-
-        iconLabel.setMinimumSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight()));
-        iconLabel.setPreferredSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight()));
-        iconLabel.setVerticalAlignment(JLabel.BOTTOM);
-
-        add(iconLabel, BorderLayout.EAST);
-        preferredSize = new Dimension(700, grip.getIconHeight() + 5);
-    }
-    
-    @Override
-    @Transient
-    public Dimension getMinimumSize() {
-        if (isMinimumSizeSet()) {
-            return super.getMinimumSize();
-        }
-        return preferredSize;
-    }
-    
-    @Override
-    @Transient
-    public Dimension getPreferredSize() {
-        if (isPreferredSizeSet()) {
-            return super.getPreferredSize();
-        }
-        return preferredSize;
-    }
-    
-    public void setPrimaryStatus(String primaryStatus) {
-        if (primaryStatus == null) throw new NullPointerException();
-        
-        String oldPrimaryStatus = this.primaryStatus;
-        this.primaryStatus = primaryStatus;
-        primaryStatusLabel.setText(" " + primaryStatus);
-        
-        firePropertyChange(PRIMARY_STATUS_PROPERTY, oldPrimaryStatus, this.primaryStatus);
-        repaint();
-    }
-
-    public String getPrimaryStatus() {
-        return primaryStatus;
-    }
-
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/LocaleResources.java	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal;
+
+import com.redhat.thermostat.shared.locale.Translate;
+
+public enum LocaleResources {
+
+    HOST_PRIMARY_STATUS,
+    VM_PRIMARY_STATUS,
+    ;
+
+    static final String RESOURCE_BUNDLE =
+            "com.redhat.thermostat.client.swing.internal.strings";
+
+    public static Translate<LocaleResources> createLocalizer() {
+        return new Translate<>(RESOURCE_BUNDLE, LocaleResources.class);
+    }
+}
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainView.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainView.java	Mon May 27 20:50:48 2013 -0600
@@ -48,6 +48,7 @@
 import com.redhat.thermostat.client.ui.MenuAction;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.HostsVMsLoader;
 import com.redhat.thermostat.storage.core.Ref;
@@ -87,7 +88,7 @@
 
     void setSubView(BasicView view);
 
-    void setStatusBarPrimaryStatus(String primaryStatus);
+    void setStatusBarPrimaryStatus(LocalizedString primaryStatus);
     
     /**
      * Adds a menu item to the window. Assumes the menu path is valid (has a
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindow.java	Mon May 27 20:50:48 2013 -0600
@@ -98,7 +98,6 @@
 import com.redhat.thermostat.client.swing.SwingComponent;
 import com.redhat.thermostat.client.swing.components.SearchField;
 import com.redhat.thermostat.client.swing.components.SearchField.SearchAction;
-import com.redhat.thermostat.client.swing.components.StatusBar;
 import com.redhat.thermostat.client.swing.components.ThermostatPopupMenu;
 import com.redhat.thermostat.client.swing.internal.components.DecoratedDefaultMutableTreeNode;
 import com.redhat.thermostat.client.ui.ContextAction;
@@ -110,6 +109,7 @@
 import com.redhat.thermostat.common.ActionListener;
 import com.redhat.thermostat.common.ActionNotifier;
 import com.redhat.thermostat.common.utils.StringUtils;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.HostsVMsLoader;
@@ -526,8 +526,8 @@
 
                 for (final ContextAction action: actions) {
                     JMenuItem contextAction = new JMenuItem();
-                    contextAction.setText(action.getName());
-                    contextAction.setToolTipText(action.getDescription());
+                    contextAction.setText(action.getName().getContents());
+                    contextAction.setToolTipText(action.getDescription().getContents());
 
                     contextAction.addActionListener(new java.awt.event.ActionListener() {
                         @Override
@@ -537,7 +537,7 @@
                     });
 
                     // the component name is for unit tests only
-                    contextAction.setName(action.getName());
+                    contextAction.setName(action.getName().getContents());
 
                     contextMenu.add(contextAction);
                 }
@@ -743,7 +743,7 @@
     }
 
     @Override
-    public void setStatusBarPrimaryStatus(final String primaryStatus) {
+    public void setStatusBarPrimaryStatus(final LocalizedString primaryStatus) {
         SwingUtilities.invokeLater(new Runnable() {
             @Override
             public void run() {
--- a/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImpl.java	Mon May 27 20:50:48 2013 -0600
@@ -88,6 +88,7 @@
 import com.redhat.thermostat.common.Timer.SchedulingType;
 import com.redhat.thermostat.common.config.ClientPreferences;
 import com.redhat.thermostat.common.utils.LoggingUtils;
+import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.storage.core.DefaultHostsVMsLoader;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.HostsVMsLoader;
@@ -103,6 +104,8 @@
 
     private static final Logger logger = LoggingUtils.getLogger(MainWindowControllerImpl.class);
 
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
     private final CopyOnWriteArrayList<Filter<HostRef>> hostFilters = new CopyOnWriteArrayList<>();
     private final CopyOnWriteArrayList<Filter<VmRef>> vmFilters = new CopyOnWriteArrayList<>();
 
@@ -557,14 +560,15 @@
             HostRef hostRef = (HostRef) ref;
             HostInformationController hostController = createHostInformationController(hostRef);
             view.setSubView(hostController.getView());
-            view.setStatusBarPrimaryStatus("host: " + hostRef.getHostName() + ", id: " + hostRef.getAgentId());
+            view.setStatusBarPrimaryStatus(t.localize(LocaleResources.HOST_PRIMARY_STATUS,
+                    hostRef.getHostName(), hostRef.getAgentId()));
         } else if (ref instanceof VmRef) {
             VmRef vmRef = (VmRef) ref;
             VmInformationController vmInformation =
                     vmInfoControllerProvider.getVmInfoController(vmRef);
             view.setSubView(vmInformation.getView());
-            view.setStatusBarPrimaryStatus("vm: " + vmRef.getName() + ", pid: " + vmRef.getStringID() +
-                                           ", host: " + vmRef.getAgent().getHostName());
+            view.setStatusBarPrimaryStatus(t.localize(LocaleResources.VM_PRIMARY_STATUS,
+                    vmRef.getName(), vmRef.getStringID(), vmRef.getAgent().getHostName()));
         } else {
             throw new IllegalArgumentException("unknown type of ref");
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/java/com/redhat/thermostat/client/swing/internal/StatusBar.java	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,130 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.beans.Transient;
+
+import javax.swing.ImageIcon;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import com.redhat.thermostat.shared.locale.LocalizedString;
+
+/**
+ * A status bar used to display relevant information and status.
+ * <p>
+ * A status bar is normally displayed at the bottom of the main window.
+ * It may contain one or more areas displaying text and icons.
+ */
+@SuppressWarnings("serial")
+public class StatusBar extends JPanel {
+
+    // some of this code is inspired by the book
+    // Swing Hacks: Tips & Tools for Building Killer GUIs
+    // By Joshua Marinacci, Chris Adamson
+    // ISBN: 0-596-00907-0
+    // website: http://www.oreilly.com/catalog/swinghks/
+
+    public static final String PRIMARY_STATUS_PROPERTY = "primaryStatus";
+    
+    private Dimension preferredSize;
+    
+    private LocalizedString primaryStatus = LocalizedString.EMPTY_STRING;
+    private JLabel primaryStatusLabel;
+    private JLabel iconLabel;
+    
+    public StatusBar() {
+        super();
+        setLayout(new BorderLayout(0, 0));
+        
+        primaryStatusLabel = new JLabel(primaryStatus.getContents());
+        primaryStatusLabel.setName("primaryStatusLabel");
+        primaryStatusLabel.setFont(getFont().deriveFont(10.0f));
+        primaryStatusLabel.setHorizontalAlignment(JLabel.LEADING);
+        primaryStatusLabel.setVerticalAlignment(JLabel.CENTER);
+
+        add(primaryStatusLabel, BorderLayout.WEST);
+        
+        iconLabel = new JLabel("");
+        ImageIcon grip = new ImageIcon(getClass().getResource("/icons/resize-grip.png"));
+        iconLabel.setIcon(grip);
+
+        iconLabel.setMinimumSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight()));
+        iconLabel.setPreferredSize(new Dimension(grip.getIconWidth() + 1, grip.getIconHeight()));
+        iconLabel.setVerticalAlignment(JLabel.BOTTOM);
+
+        add(iconLabel, BorderLayout.EAST);
+        preferredSize = new Dimension(700, grip.getIconHeight() + 5);
+    }
+    
+    @Override
+    @Transient
+    public Dimension getMinimumSize() {
+        if (isMinimumSizeSet()) {
+            return super.getMinimumSize();
+        }
+        return preferredSize;
+    }
+    
+    @Override
+    @Transient
+    public Dimension getPreferredSize() {
+        if (isPreferredSizeSet()) {
+            return super.getPreferredSize();
+        }
+        return preferredSize;
+    }
+    
+    void setPrimaryStatus(LocalizedString primaryStatus) {
+        if (primaryStatus == null) throw new NullPointerException();
+        
+        String oldPrimaryStatus = this.primaryStatus.getContents();
+        this.primaryStatus = primaryStatus;
+        primaryStatusLabel.setText(" " + primaryStatus.getContents());
+        
+        firePropertyChange(PRIMARY_STATUS_PROPERTY, oldPrimaryStatus, this.primaryStatus.getContents());
+        repaint();
+    }
+
+    LocalizedString getPrimaryStatus() {
+        return primaryStatus;
+    }
+
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/main/resources/com/redhat/thermostat/client/swing/internal/strings.properties	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,2 @@
+HOST_PRIMARY_STATUS = host: {0}, id: {1}
+VM_PRIMARY_STATUS = vm: {0}, pid: {1}, host: {2}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/MenuHelperTest.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/MenuHelperTest.java	Mon May 27 20:50:48 2013 -0600
@@ -64,6 +64,7 @@
 import org.junit.runner.RunWith;
 
 import com.redhat.thermostat.client.ui.MenuAction;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 
 @RunWith(CacioFESTRunner.class)
 public class MenuHelperTest {
@@ -106,11 +107,11 @@
     @Category(GUITest.class)
     @Test
     public void addRemoveWithNewTopLevelMenu() {
-        final String PARENT_NAME = "Test1";
-        final String MENU_NAME = "Test2";
+        final LocalizedString PARENT_NAME = new LocalizedString("Test1");
+        final LocalizedString MENU_NAME = new LocalizedString("Test2");
         MenuAction action = mock(MenuAction.class);
         when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
+        when(action.getPath()).thenReturn(new LocalizedString[] { PARENT_NAME, MENU_NAME });
         when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
 
         JMenuItemFixture menuItem;
@@ -119,13 +120,13 @@
 
         menu.addMenuAction(action);
 
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
         assertNotNull(menuItem);
 
         menu.removeMenuAction(action);
 
         try {
-            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+            menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
             // should not reach here
             assertTrue(false);
         } catch (ComponentLookupException cle) {
@@ -136,11 +137,11 @@
     @Category(GUITest.class)
     @Test
     public void addRemoveToExistingMenu() {
-        final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test2";
+        final LocalizedString PARENT_NAME = new LocalizedString("File");
+        final LocalizedString MENU_NAME = new LocalizedString("Test2");
         MenuAction action = mock(MenuAction.class);
         when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
+        when(action.getPath()).thenReturn(new LocalizedString[] { PARENT_NAME, MENU_NAME });
         when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
 
         JMenuItemFixture menuItem;
@@ -151,13 +152,13 @@
 
         menu.addMenuAction(action);
 
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
         assertNotNull(menuItem);
 
         menu.removeMenuAction(action);
 
         try {
-            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+            menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
             // should not reach here
             assertTrue(false);
         } catch (ComponentLookupException cle) {
@@ -168,7 +169,13 @@
     @Category(GUITest.class)
     @Test
     public void addRemoveHighlyNextedMenu() {
-        final String[] path = new String[] { "View", "Filter", "Virtual Machine", "Show Only Running" };
+        final LocalizedString[] path = new LocalizedString[] {
+                new LocalizedString("View"),
+                new LocalizedString("Filter"),
+                new LocalizedString("Virtual Machine"),
+                new LocalizedString("Show Only Running")
+                };
+        final String[] plainPath = fromLocalizedArray(path);
         MenuAction action = mock(MenuAction.class);
         when(action.getName()).thenReturn(path[path.length - 1]);
         when(action.getPath()).thenReturn(path);
@@ -180,13 +187,13 @@
 
         menu.addMenuAction(action);
 
-        menuItem = frameFixture.menuItemWithPath(path);
+        menuItem = frameFixture.menuItemWithPath(plainPath);
         assertNotNull(menuItem);
 
         menu.removeMenuAction(action);
 
         try {
-            menuItem = frameFixture.menuItemWithPath(path);
+            menuItem = frameFixture.menuItemWithPath(plainPath);
             // should not reach here
             assertTrue(false);
         } catch (ComponentLookupException cle) {
@@ -197,11 +204,11 @@
     @Category(GUITest.class)
     @Test
     public void addRadioMenu() {
-        final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test";
+        final LocalizedString PARENT_NAME = new LocalizedString("File");
+        final LocalizedString MENU_NAME = new LocalizedString("Test");
         MenuAction action = mock(MenuAction.class);
         when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
+        when(action.getPath()).thenReturn(new LocalizedString[] { PARENT_NAME, MENU_NAME });
         when(action.getType()).thenReturn(MenuAction.Type.RADIO);
 
         JMenuItemFixture menuItem;
@@ -210,7 +217,7 @@
 
         menu.addMenuAction(action);
 
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
         assertNotNull(menuItem);
 
         assertTrue(menuItem.target instanceof JRadioButtonMenuItem);
@@ -219,12 +226,12 @@
     @Category(GUITest.class)
     @Test
     public void addCheckBoxMenu() {
-        final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test";
+        final LocalizedString PARENT_NAME = new LocalizedString("File");
+        final LocalizedString MENU_NAME = new LocalizedString("Test");
         MenuAction action = mock(MenuAction.class);
         when(action.getName()).thenReturn(MENU_NAME);
         when(action.getType()).thenReturn(MenuAction.Type.CHECK);
-        when(action.getPath()).thenReturn(new String[] { PARENT_NAME, MENU_NAME });
+        when(action.getPath()).thenReturn(new LocalizedString[] { PARENT_NAME, MENU_NAME });
 
         JMenuItemFixture menuItem;
 
@@ -232,11 +239,18 @@
 
         menu.addMenuAction(action);
 
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
         assertNotNull(menuItem);
 
         assertTrue(menuItem.target instanceof JCheckBoxMenuItem);
     }
 
+    private String[] fromLocalizedArray(LocalizedString[] localized) {
+        String[] strings = new String[localized.length];
+        for (int i = 0; i < localized.length; i++) {
+            strings[i] = localized[i].getContents();
+        }
+        return strings;
+    }
 }
 
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ActionButtonTest.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/ActionButtonTest.java	Mon May 27 20:50:48 2013 -0600
@@ -96,8 +96,8 @@
                 JFrame frame = new JFrame();
                 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
-                HeaderPanel header = new HeaderPanel(prefs, "wrong");
-                header.setHeader("Test");
+                HeaderPanel header = new HeaderPanel(prefs, new LocalizedString("wrong"));
+                header.setHeader(new LocalizedString("Test"));
 
                 Icon icon = new Icon() {
 
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/HeaderPanelTest.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/HeaderPanelTest.java	Mon May 27 20:50:48 2013 -0600
@@ -93,7 +93,7 @@
             protected void executeInEDT() throws Throwable {
                 frame = new JFrame();
                 
-                header = new HeaderPanel(prefs, "Test Panel");
+                header = new HeaderPanel(prefs, new LocalizedString("Test Panel"));
                 header.setName("headerPanel");
                 
                 JPanel content = new JPanel();
@@ -111,7 +111,7 @@
                 ActionButton button2 = new ActionButton(someIcon2, new LocalizedString("button2"));
                 button2.setName("button2");
                 
-                ActionToggleButton toggle1 = new ActionToggleButton(someIcon3, "toggle1");
+                ActionToggleButton toggle1 = new ActionToggleButton(someIcon3, new LocalizedString("toggle1"));
                 toggle1.setName("toggle1");
 
                 header.addToolBarButton(button1);
@@ -144,35 +144,35 @@
     @Test
     public void testContentAdded() {
         frameFixture.show();
-        final String[] results = new String[2];
+        final LocalizedString[] results = new LocalizedString[2];
         
         GuiActionRunner.execute(new GuiTask() {
             @Override
             protected void executeInEDT() throws Throwable {
                 results[0] = header.getHeader();
-                header.setHeader("fluff");
+                header.setHeader(new LocalizedString("fluff"));
                 results[1] = header.getHeader();
             }
         });
         
-        assertEquals("Test Panel", results[0]);
-        assertEquals("fluff", results[1]);
+        assertEquals("Test Panel", results[0].getContents());
+        assertEquals("fluff", results[1].getContents());
         
         // do it again, with a new header
         GuiActionRunner.execute(new GuiTask() {
             @Override
             protected void executeInEDT() throws Throwable {
                 
-                HeaderPanel header = new HeaderPanel("Test");
+                HeaderPanel header = new HeaderPanel(new LocalizedString("Test"));
                 
                 results[0] = header.getHeader();
-                header.setHeader("fluff");
+                header.setHeader(new LocalizedString("fluff"));
                 results[1] = header.getHeader();
             }
         });
         
-        assertEquals("Test", results[0]);
-        assertEquals("fluff", results[1]);
+        assertEquals("Test", results[0].getContents());
+        assertEquals("fluff", results[1].getContents());
     }
     
     @Test
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/SearchFieldTest.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/SearchFieldTest.java	Mon May 27 20:50:48 2013 -0600
@@ -65,6 +65,7 @@
 import com.redhat.thermostat.client.swing.components.SearchField;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 
 @RunWith(CacioFESTRunner.class)
 public class SearchFieldTest {
@@ -117,7 +118,7 @@
     @GUITest
     @Test
     public void verifyLabelShownByDefault() {
-        final String LABEL = "search label to help users";
+        final LocalizedString LABEL = new LocalizedString("search label to help users");
         GuiActionRunner.execute(new GuiTask() {
             @Override
             protected void executeInEDT() throws Throwable {
@@ -126,14 +127,14 @@
 
         frameFixture.show();
         JTextComponentFixture textBox = frameFixture.textBox(SearchField.VIEW_NAME);
-        assertEquals(LABEL, textBox.text());
+        assertEquals(LABEL.getContents(), textBox.text());
     }
 
     @Category(GUITest.class)
     @GUITest
     @Test
     public void verifyLabelHiddenAndShownProperly() {
-        final String LABEL = "search label to help users";
+        final LocalizedString LABEL = new LocalizedString("search label to help users");
         final String USER_TEXT = "java";
 
         GuiActionRunner.execute(new GuiTask() {
@@ -146,7 +147,7 @@
 
         frameFixture.show();
         JTextComponentFixture textBox = frameFixture.textBox(SearchField.VIEW_NAME);
-        assertEquals(LABEL, textBox.text());
+        assertEquals(LABEL.getContents(), textBox.text());
 
         textBox.enterText(USER_TEXT);
 
@@ -155,7 +156,7 @@
         JButtonFixture button = frameFixture.button(OTHER_COMPONENT_NAME);
         button.focus();
 
-        assertEquals(LABEL, textBox.text());
+        assertEquals(LABEL.getContents(), textBox.text());
     }
 
     @Category(GUITest.class)
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/components/StatusBarTest.java	Thu Jun 06 11:00:25 2013 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,155 +0,0 @@
-/*
- * Copyright 2012, 2013 Red Hat, Inc.
- *
- * This file is part of Thermostat.
- *
- * Thermostat is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2, or (at your
- * option) any later version.
- *
- * Thermostat is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Thermostat; see the file COPYING.  If not see
- * <http://www.gnu.org/licenses/>.
- *
- * Linking this code with other modules is making a combined work
- * based on this code.  Thus, the terms and conditions of the GNU
- * General Public License cover the whole combination.
- *
- * As a special exception, the copyright holders of this code give
- * you permission to link this code with independent modules to
- * produce an executable, regardless of the license terms of these
- * independent modules, and to copy and distribute the resulting
- * executable under terms of your choice, provided that you also
- * meet, for each linked independent module, the terms and conditions
- * of the license of that module.  An independent module is a module
- * which is not derived from or based on this code.  If you modify
- * this code, you may extend this exception to your version of the
- * library, but you are not obligated to do so.  If you do not wish
- * to do so, delete this exception statement from your version.
- */
-
-package com.redhat.thermostat.client.swing.components;
-
-import static org.junit.Assert.*;
-
-import java.awt.BorderLayout;
-import java.beans.PropertyChangeEvent;
-import java.beans.PropertyChangeListener;
-import java.util.concurrent.Semaphore;
-
-import javax.swing.JFrame;
-
-import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
-
-import org.fest.swing.annotation.GUITest;
-import org.fest.swing.annotation.RunsInEDT;
-import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
-import org.fest.swing.edt.GuiActionRunner;
-import org.fest.swing.edt.GuiTask;
-import org.fest.swing.fixture.FrameFixture;
-import org.fest.swing.fixture.JLabelFixture;
-import org.junit.After;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-@RunWith(CacioFESTRunner.class)
-public class StatusBarTest {
-
-    private JFrame frame;
-    private FrameFixture frameFixture;
-    
-    private StatusBar statusBar;
-    
-    @BeforeClass
-    public static void setUpOnce() {
-        FailOnThreadViolationRepaintManager.install();
-    }
-    
-    @Before
-    public void setUp() {
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                frame = new JFrame();
-                frame.getContentPane().setLayout(new BorderLayout());
-                
-                statusBar = new StatusBar();
-                frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
-                
-                frame.setSize(500, 500);
-            }
-        });
-        frameFixture = new FrameFixture(frame);
-    }
-    
-    @After
-    public void tearDown() {
-        frameFixture.cleanUp();
-        frameFixture = null;
-    }
-    
-    @Test
-    @GUITest
-    @RunsInEDT
-    public void testSetPrimaryStatusLabel() throws InterruptedException {
-        frameFixture.show();
-        
-        JLabelFixture labelfixture = frameFixture.label("primaryStatusLabel");
-        labelfixture.requireText("");
-        
-        final Semaphore sem = new Semaphore(0);
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                statusBar.setPrimaryStatus("test");
-                sem.release();
-            }
-        });
-        sem.acquire();
-        
-        // the label has an extra space at the beginning
-        labelfixture.requireText(" test");
-    }
-    
-    @Test
-    @GUITest
-    @RunsInEDT
-    public void testSetPrimaryStatusLabelWithProperty() throws InterruptedException {
-        frameFixture.show();
-        
-        final String[] primaryStatus = new String[2];
-        
-        final Semaphore sem = new Semaphore(2);
-        statusBar.addPropertyChangeListener(StatusBar.PRIMARY_STATUS_PROPERTY,
-                                                      new PropertyChangeListener()
-        {
-            @Override
-            public void propertyChange(PropertyChangeEvent evt) {
-                primaryStatus[0] = (String) evt.getOldValue();
-                primaryStatus[1] = (String) evt.getNewValue();
-                sem.release();
-            }
-        });
-        
-        GuiActionRunner.execute(new GuiTask() {
-            @Override
-            protected void executeInEDT() throws Throwable {
-                statusBar.setPrimaryStatus("test");
-                sem.release();
-            }
-        });
-        sem.acquire(2);
-        
-        assertEquals("", primaryStatus[0]);
-        assertEquals("test", primaryStatus[1]);
-    }
-}
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/LocaleResourcesTest.java	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2013 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal;
+
+import com.redhat.thermostat.testutils.AbstractLocaleResourcesTest;
+
+public class LocaleResourcesTest extends AbstractLocaleResourcesTest<LocaleResources> {
+
+    @Override
+    protected Class<LocaleResources> getEnumClass() {
+        return LocaleResources.class;
+    }
+
+    @Override
+    protected String getResourceBundle() {
+        return LocaleResources.RESOURCE_BUNDLE;
+    }
+}
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowControllerImplTest.java	Mon May 27 20:50:48 2013 -0600
@@ -90,6 +90,7 @@
 import com.redhat.thermostat.common.Timer;
 import com.redhat.thermostat.common.Timer.SchedulingType;
 import com.redhat.thermostat.common.TimerFactory;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.HostsVMsLoader;
 import com.redhat.thermostat.storage.core.VmRef;
@@ -239,8 +240,8 @@
         Filter<HostRef> hostFilter1 = mock(Filter.class);
         when(hostFilter1.matches(isA(HostRef.class))).thenReturn(true);
 
-        when(hostContextAction1.getName()).thenReturn("action1");
-        when(hostContextAction1.getDescription()).thenReturn("action1desc");
+        when(hostContextAction1.getName()).thenReturn(new LocalizedString("action1"));
+        when(hostContextAction1.getDescription()).thenReturn(new LocalizedString("action1desc"));
         when(hostContextAction1.getFilter()).thenReturn(hostFilter1);
 
         context.registerService(HostContextAction.class, hostContextAction1, null);
@@ -251,8 +252,8 @@
         Filter action1Filter = mock(Filter.class);
         when(action1Filter.matches(isA(VmRef.class))).thenReturn(true);
 
-        when(vmContextAction1.getName()).thenReturn("action1");
-        when(vmContextAction1.getDescription()).thenReturn("action1desc");
+        when(vmContextAction1.getName()).thenReturn(new LocalizedString("action1"));
+        when(vmContextAction1.getDescription()).thenReturn(new LocalizedString("action1desc"));
         when(vmContextAction1.getFilter()).thenReturn(action1Filter);
         
         context.registerService(VMContextAction.class, vmContextAction1, null);
@@ -261,8 +262,8 @@
         Filter action2Filter = mock(Filter.class);
         when(action2Filter.matches(isA(VmRef.class))).thenReturn(false);
 
-        when(vmContextAction2.getName()).thenReturn("action2");
-        when(vmContextAction2.getDescription()).thenReturn("action2desc");
+        when(vmContextAction2.getName()).thenReturn(new LocalizedString("action2"));
+        when(vmContextAction2.getDescription()).thenReturn(new LocalizedString("action2desc"));
         when(vmContextAction2.getFilter()).thenReturn(action2Filter);
         
         context.registerService(VMContextAction.class, vmContextAction2, null);
@@ -617,7 +618,7 @@
         ActionListener<ThermostatExtensionRegistry.Action> menuListener = controller.getMenuListener();
 
         MenuAction action = mock(MenuAction.class);
-        when(action.getName()).thenReturn("Test1");
+        when(action.getName()).thenReturn(new LocalizedString("Test1"));
 
         ActionEvent<Action> addEvent = new ActionEvent<ThermostatExtensionRegistry.Action>(
         		menus, ThermostatExtensionRegistry.Action.SERVICE_ADDED);
--- a/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/MainWindowTest.java	Mon May 27 20:50:48 2013 -0600
@@ -84,6 +84,7 @@
 import com.redhat.thermostat.client.ui.MenuAction;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.storage.core.HostRef;
 import com.redhat.thermostat.storage.core.HostsVMsLoader;
 
@@ -260,11 +261,11 @@
     @Category(GUITest.class)
     @Test
     public void addRemoveMenu() {
-    	final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test2";
+        final LocalizedString PARENT_NAME = new LocalizedString("File");
+        final LocalizedString MENU_NAME = new LocalizedString("Test2");
         MenuAction action = mock(MenuAction.class);
         when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
+        when(action.getPath()).thenReturn(new LocalizedString[] {PARENT_NAME, MENU_NAME});
         when(action.getType()).thenReturn(MenuAction.Type.STANDARD);
 
         JMenuItemFixture menuItem;
@@ -273,7 +274,7 @@
 
         window.addMenu(action);
 
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
         assertNotNull(menuItem);
         menuItem.click();
 
@@ -282,7 +283,7 @@
         window.removeMenu(action);
 
         try {
-            menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+            menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
             // should not reach here
             assertTrue(false);
         } catch (ComponentLookupException cle) {
@@ -293,11 +294,11 @@
     @Category(GUITest.class)
     @Test
     public void addRadioMenu() {
-    	final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test";
+        final LocalizedString PARENT_NAME = new LocalizedString("File");
+        final LocalizedString MENU_NAME = new LocalizedString("Test");
         MenuAction action = mock(MenuAction.class);
         when(action.getName()).thenReturn(MENU_NAME);
-        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
+        when(action.getPath()).thenReturn(new LocalizedString[] {PARENT_NAME, MENU_NAME});
 
 
         when(action.getType()).thenReturn(MenuAction.Type.RADIO);
@@ -308,7 +309,7 @@
 
         window.addMenu(action);
 
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
         assertNotNull(menuItem);
 
         assertTrue(menuItem.target instanceof JRadioButtonMenuItem);
@@ -317,12 +318,12 @@
     @Category(GUITest.class)
     @Test
     public void addCheckBoxMenu() {
-    	final String PARENT_NAME = "File";
-        final String MENU_NAME = "Test";
+        final LocalizedString PARENT_NAME = new LocalizedString("File");
+        final LocalizedString MENU_NAME = new LocalizedString("Test");
         MenuAction action = mock(MenuAction.class);
         when(action.getName()).thenReturn(MENU_NAME);
         when(action.getType()).thenReturn(MenuAction.Type.CHECK);
-        when(action.getPath()).thenReturn(new String[] {PARENT_NAME, MENU_NAME});
+        when(action.getPath()).thenReturn(new LocalizedString[] {PARENT_NAME, MENU_NAME});
 
 
         JMenuItemFixture menuItem;
@@ -331,7 +332,7 @@
 
         window.addMenu(action);
 
-        menuItem = frameFixture.menuItemWithPath(PARENT_NAME, MENU_NAME);
+        menuItem = frameFixture.menuItemWithPath(PARENT_NAME.getContents(), MENU_NAME.getContents());
         assertNotNull(menuItem);
 
         assertTrue(menuItem.target instanceof JCheckBoxMenuItem);
@@ -363,7 +364,8 @@
         List<ContextAction> actions = new ArrayList<>();
 
         HostContextAction action = mock(HostContextAction.class);
-        when(action.getName()).thenReturn("action");
+        when(action.getName()).thenReturn(new LocalizedString("action"));
+        when(action.getDescription()).thenReturn(new LocalizedString("description of action"));
         Filter allMatchingFilter = mock(Filter.class);
         when(allMatchingFilter.matches(any(HostRef.class))).thenReturn(true);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/client/swing/src/test/java/com/redhat/thermostat/client/swing/internal/StatusBarTest.java	Mon May 27 20:50:48 2013 -0600
@@ -0,0 +1,157 @@
+/*
+ * Copyright 2012, 2013 Red Hat, Inc.
+ *
+ * This file is part of Thermostat.
+ *
+ * Thermostat is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published
+ * by the Free Software Foundation; either version 2, or (at your
+ * option) any later version.
+ *
+ * Thermostat is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Thermostat; see the file COPYING.  If not see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Linking this code with other modules is making a combined work
+ * based on this code.  Thus, the terms and conditions of the GNU
+ * General Public License cover the whole combination.
+ *
+ * As a special exception, the copyright holders of this code give
+ * you permission to link this code with independent modules to
+ * produce an executable, regardless of the license terms of these
+ * independent modules, and to copy and distribute the resulting
+ * executable under terms of your choice, provided that you also
+ * meet, for each linked independent module, the terms and conditions
+ * of the license of that module.  An independent module is a module
+ * which is not derived from or based on this code.  If you modify
+ * this code, you may extend this exception to your version of the
+ * library, but you are not obligated to do so.  If you do not wish
+ * to do so, delete this exception statement from your version.
+ */
+
+package com.redhat.thermostat.client.swing.internal;
+
+import static org.junit.Assert.*;
+
+import java.awt.BorderLayout;
+import java.beans.PropertyChangeEvent;
+import java.beans.PropertyChangeListener;
+import java.util.concurrent.Semaphore;
+
+import javax.swing.JFrame;
+
+import net.java.openjdk.cacio.ctc.junit.CacioFESTRunner;
+
+import org.fest.swing.annotation.GUITest;
+import org.fest.swing.annotation.RunsInEDT;
+import org.fest.swing.edt.FailOnThreadViolationRepaintManager;
+import org.fest.swing.edt.GuiActionRunner;
+import org.fest.swing.edt.GuiTask;
+import org.fest.swing.fixture.FrameFixture;
+import org.fest.swing.fixture.JLabelFixture;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import com.redhat.thermostat.shared.locale.LocalizedString;
+
+@RunWith(CacioFESTRunner.class)
+public class StatusBarTest {
+
+    private JFrame frame;
+    private FrameFixture frameFixture;
+    
+    private StatusBar statusBar;
+    
+    @BeforeClass
+    public static void setUpOnce() {
+        FailOnThreadViolationRepaintManager.install();
+    }
+    
+    @Before
+    public void setUp() {
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                frame = new JFrame();
+                frame.getContentPane().setLayout(new BorderLayout());
+                
+                statusBar = new StatusBar();
+                frame.getContentPane().add(statusBar, BorderLayout.SOUTH);
+                
+                frame.setSize(500, 500);
+            }
+        });
+        frameFixture = new FrameFixture(frame);
+    }
+    
+    @After
+    public void tearDown() {
+        frameFixture.cleanUp();
+        frameFixture = null;
+    }
+    
+    @Test
+    @GUITest
+    @RunsInEDT
+    public void testSetPrimaryStatusLabel() throws InterruptedException {
+        frameFixture.show();
+        
+        JLabelFixture labelfixture = frameFixture.label("primaryStatusLabel");
+        labelfixture.requireText("");
+        
+        final Semaphore sem = new Semaphore(0);
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                statusBar.setPrimaryStatus(new LocalizedString("test"));
+                sem.release();
+            }
+        });
+        sem.acquire();
+        
+        // the label has an extra space at the beginning
+        labelfixture.requireText(" test");
+    }
+    
+    @Test
+    @GUITest
+    @RunsInEDT
+    public void testSetPrimaryStatusLabelWithProperty() throws InterruptedException {
+        frameFixture.show();
+        
+        final String[] primaryStatus = new String[2];
+        
+        final Semaphore sem = new Semaphore(2);
+        statusBar.addPropertyChangeListener(StatusBar.PRIMARY_STATUS_PROPERTY,
+                                                      new PropertyChangeListener()
+        {
+            @Override
+            public void propertyChange(PropertyChangeEvent evt) {
+                primaryStatus[0] = (String) evt.getOldValue();
+                primaryStatus[1] = (String) evt.getNewValue();
+                sem.release();
+            }
+        });
+        
+        GuiActionRunner.execute(new GuiTask() {
+            @Override
+            protected void executeInEDT() throws Throwable {
+                statusBar.setPrimaryStatus(new LocalizedString("test"));
+                sem.release();
+            }
+        });
+        sem.acquire(2);
+        
+        assertEquals("", primaryStatus[0]);
+        assertEquals("test", primaryStatus[1]);
+    }
+}
+
--- a/config/src/main/java/com/redhat/thermostat/shared/locale/LocalizedString.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/config/src/main/java/com/redhat/thermostat/shared/locale/LocalizedString.java	Mon May 27 20:50:48 2013 -0600
@@ -38,6 +38,8 @@
 
 public final class LocalizedString {
 
+    public static final LocalizedString EMPTY_STRING = new LocalizedString("");
+
     private final String contents;
 
     /**
--- a/killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/KillVMAction.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/killvm/client-swing/src/main/java/com/redhat/thermostat/killvm/client/internal/KillVMAction.java	Mon May 27 20:50:48 2013 -0600
@@ -46,6 +46,7 @@
 import com.redhat.thermostat.common.command.Request.RequestType;
 import com.redhat.thermostat.common.command.RequestResponseListener;
 import com.redhat.thermostat.killvm.client.locale.LocaleResources;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.storage.core.VmRef;
 import com.redhat.thermostat.storage.dao.AgentInfoDAO;
@@ -76,13 +77,13 @@
     }
 
     @Override
-    public String getName() {
-        return t.localize(LocaleResources.ACTION_NAME).getContents();
+    public LocalizedString getName() {
+        return t.localize(LocaleResources.ACTION_NAME);
     }
 
     @Override
-    public String getDescription() {
-        return t.localize(LocaleResources.ACTION_DESCRIPTION).getContents();
+    public LocalizedString getDescription() {
+        return t.localize(LocaleResources.ACTION_DESCRIPTION);
     }
 
     @Override
--- a/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/thread/client-swing/src/main/java/com/redhat/thermostat/thread/client/swing/impl/ThreadMainPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -59,7 +59,7 @@
         setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
         
         HeaderPanel headerPanel = new HeaderPanel();
-        headerPanel.setHeader(t.localize(LocaleResources.THREAD_CONTROL_PANEL).getContents());
+        headerPanel.setHeader(t.localize(LocaleResources.THREAD_CONTROL_PANEL));
         
         JPanel content = new JPanel();
         headerPanel.setContent(content);
--- a/vm-classstat/client-swing/src/main/java/com/redhat/thermostat/vm/classstat/client/swing/VmClassStatPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-classstat/client-swing/src/main/java/com/redhat/thermostat/vm/classstat/client/swing/VmClassStatPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -81,7 +81,7 @@
         // any name works
         dataset.addSeries(new TimeSeries("class-stat"));
 
-        visiblePanel.setHeader(t.localize(LocaleResources.VM_LOADED_CLASSES).getContents());
+        visiblePanel.setHeader(t.localize(LocaleResources.VM_LOADED_CLASSES));
 
         JFreeChart chart = ChartFactory.createTimeSeriesChart(
                 null,
--- a/vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/internal/VmCpuPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-cpu/client-swing/src/main/java/com/redhat/thermostat/vm/cpu/client/swing/internal/VmCpuPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -106,7 +106,7 @@
 
     private void initializePanel() {
         visiblePanel = new HeaderPanel();
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_CPU_TITLE).getContents());
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_CPU_TITLE));
 
         JFreeChart chart = ChartFactory.createTimeSeriesChart(
                 null,
--- a/vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/internal/VmGcPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-gc/client-swing/src/main/java/com/redhat/thermostat/vm/gc/client/swing/internal/VmGcPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -129,7 +129,7 @@
 
     private void initializePanel() {
         visiblePanel.setContent(realPanel);
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_GC_TITLE).getContents());
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_GC_TITLE));
         realPanel.setLayout(new GridBagLayout());
     }
 
--- a/vm-gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-gc/remote-collector-client-swing/src/test/java/com/redhat/thermostat/gc/remote/client/swing/ToolbarGCButtonTest.java	Mon May 27 20:50:48 2013 -0600
@@ -60,6 +60,7 @@
 import org.junit.runner.RunWith;
 
 import com.redhat.thermostat.client.swing.components.HeaderPanel;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.gc.remote.client.common.RequestGCAction;
 
 @RunWith(CacioFESTRunner.class)
@@ -88,7 +89,7 @@
             protected void executeInEDT() throws Throwable {
                 frame = new JFrame();
                 
-                HeaderPanel header = new HeaderPanel(prefs, "Test Panel");
+                HeaderPanel header = new HeaderPanel(prefs, new LocalizedString("Test Panel"));
                 header.setName("headerPanel");
                 
                 JPanel content = new JPanel();
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HeapSwingView.java	Mon May 27 20:50:48 2013 -0600
@@ -110,12 +110,12 @@
         
         heapDetailPanel = new HeapPanel();
         
-        overview = new HeaderPanel(translator.localize(LocaleResources.HEAP_OVERVIEW_TITLE).getContents());
+        overview = new HeaderPanel(translator.localize(LocaleResources.HEAP_OVERVIEW_TITLE));
 
         stack = new JPanel();
         stack.setLayout(new OverlayLayout(stack));
         
-        overlay = new OverlayPanel(translator.localize(LocaleResources.DUMPS_LIST).getContents());
+        overlay = new OverlayPanel(translator.localize(LocaleResources.DUMPS_LIST));
         stack.add(overlay);
         stack.add(stats);
         stats.setOpaque(false);
@@ -139,7 +139,7 @@
         overview.addToolBarButton(takeDumpIconButton);
         
         Icon listDumpIcon = IconResource.HISTORY.getIcon();
-        showHeapListButton = new ActionToggleButton(listDumpIcon, translator.localize(LocaleResources.LIST_DUMPS_ACTION).getContents());
+        showHeapListButton = new ActionToggleButton(listDumpIcon, translator.localize(LocaleResources.LIST_DUMPS_ACTION));
         showHeapListButton.setToolTipText(translator.localize(LocaleResources.LIST_DUMPS_ACTION).getContents());
         showHeapListButton.setName("LIST_DUMPS_ACTION");
 
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/HistogramPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -70,7 +70,7 @@
         panel = new JPanel();
         panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
 
-        headerPanel = new HeaderPanel(translator.localize(LocaleResources.HEAP_DUMP_CLASS_USAGE).getContents());
+        headerPanel = new HeaderPanel(translator.localize(LocaleResources.HEAP_DUMP_CLASS_USAGE));
         panel.add(headerPanel);
     }
 
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/ObjectDetailsPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -125,7 +125,7 @@
         JLabel searchLabel = new JLabel(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_LABEL).getContents());
 
         searchField = new SearchField();
-        searchField.setTooltip(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_PATTERN_HELP).getContents());
+        searchField.setTooltip(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_PATTERN_HELP));
 
         JSplitPane splitPane = new JSplitPane();
         splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
@@ -185,7 +185,7 @@
                 }
             }
         });
-        searchField.setLabel(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_HINT).getContents());
+        searchField.setLabel(translator.localize(LocaleResources.HEAP_DUMP_OBJECT_BROWSE_SEARCH_HINT));
 
         java.awt.event.ActionListener treeToggleListener = new java.awt.event.ActionListener() {
             @Override
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapDumpListView.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/SwingHeapDumpListView.java	Mon May 27 20:50:48 2013 -0600
@@ -55,6 +55,7 @@
 import com.redhat.thermostat.client.swing.SwingComponent;
 import com.redhat.thermostat.client.swing.components.ShadowLabel;
 import com.redhat.thermostat.client.ui.Palette;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapDumpListView;
 import com.redhat.thermostat.vm.heap.analysis.common.HeapDump;
 
@@ -140,7 +141,7 @@
         public Component getListCellRendererComponent(JList<? extends HeapDump> list, HeapDump value, int index,
                                                       boolean isSelected, boolean cellHasFocus) {
             
-            ShadowLabel label = new ShadowLabel(value.toString());
+            ShadowLabel label = new ShadowLabel(new LocalizedString(value.toString()));
             label.setForeground(Palette.ROYAL_BLUE.getColor());
 
             if (!isSelected) {
--- a/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/OverlayComponent.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-heap-analysis/client-swing/src/main/java/com/redhat/thermostat/vm/heap/analysis/client/swing/internal/stats/OverlayComponent.java	Mon May 27 20:50:48 2013 -0600
@@ -42,6 +42,7 @@
 import com.redhat.thermostat.client.swing.components.ShadowLabel;
 import com.redhat.thermostat.client.swing.components.timeline.TimelineUtils;
 import com.redhat.thermostat.client.ui.Palette;
+import com.redhat.thermostat.shared.locale.LocalizedString;
 import com.redhat.thermostat.vm.heap.analysis.client.core.HeapIconResources;
 import com.redhat.thermostat.vm.heap.analysis.common.HeapDump;
 
@@ -60,8 +61,6 @@
 import java.util.Date;
 import java.util.Objects;
 
-import javax.swing.ButtonModel;
-
 @SuppressWarnings("serial")
 public class OverlayComponent extends ShadowLabel {
 
@@ -114,7 +113,7 @@
     
     public OverlayComponent(HeapDump dump) {
         
-        super("");
+        super(LocalizedString.EMPTY_STRING);
         
         setOpaque(false);
         
--- a/vm-jmx/client-swing/src/main/java/com/redhat/thermostat/vm/jmx/client/swing/internal/JmxNotificationsSwingView.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-jmx/client-swing/src/main/java/com/redhat/thermostat/vm/jmx/client/swing/internal/JmxNotificationsSwingView.java	Mon May 27 20:50:48 2013 -0600
@@ -57,7 +57,7 @@
 import com.redhat.thermostat.client.swing.IconResource;
 import com.redhat.thermostat.client.swing.SwingComponent;
 import com.redhat.thermostat.client.swing.components.ActionToggleButton;
-import com.redhat.thermostat.client.swing.components.DescriptionField;
+import com.redhat.thermostat.client.swing.components.LocalizedLabel;
 import com.redhat.thermostat.client.swing.components.HeaderPanel;
 import com.redhat.thermostat.common.ActionEvent;
 import com.redhat.thermostat.common.ActionListener;
@@ -78,7 +78,7 @@
 
     public JmxNotificationsSwingView() {
 
-        DescriptionField description = new DescriptionField(translate.localize(LocaleResources.NOTIFICATIONS_DESCRIPTION));
+        LocalizedLabel description = new LocalizedLabel(translate.localize(LocaleResources.NOTIFICATIONS_DESCRIPTION));
         description.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
         JList<String> issuesList = new JList<>(listModel);
 
@@ -110,7 +110,7 @@
             }
         });
 
-        toolbarButton = new ActionToggleButton(IconResource.SAMPLE.getIcon(), translate.localize(LocaleResources.NOTIFICATIONS_ENABLE).getContents());
+        toolbarButton = new ActionToggleButton(IconResource.SAMPLE.getIcon(), translate.localize(LocaleResources.NOTIFICATIONS_ENABLE));
         toolbarButton.setName("toggleNotifications");
         toolbarButton.setToolTipText(translate.localize(LocaleResources.NOTIFICATIONS_ENABLE_DESCRIPTION).getContents());
         toolbarButton.addActionListener(new java.awt.event.ActionListener() {
@@ -134,7 +134,7 @@
             }
         });
 
-        visiblePanel = new HeaderPanel(translate.localize(LocaleResources.NOTIFICATIONS_HEADER).getContents());
+        visiblePanel = new HeaderPanel(translate.localize(LocaleResources.NOTIFICATIONS_HEADER));
         visiblePanel.addToolBarButton(toolbarButton);
         visiblePanel.setContent(contents);
     }
--- a/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/locale/LocaleResources.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-memory/client-core/src/main/java/com/redhat/thermostat/vm/memory/client/locale/LocaleResources.java	Mon May 27 20:50:48 2013 -0600
@@ -42,6 +42,7 @@
 
     VM_INFO_TAB_MEMORY,
     ERROR_PERFORMING_GC,
+    MEMORY_REGIONS_HEADER,
 
     RESOURCE_MISSING;
     
--- a/vm-memory/client-core/src/main/resources/com/redhat/thermostat/vm/memory/client/locale/strings.properties	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-memory/client-core/src/main/resources/com/redhat/thermostat/vm/memory/client/locale/strings.properties	Mon May 27 20:50:48 2013 -0600
@@ -1,4 +1,5 @@
 RESOURCE_MISSING = Missing translation!
 VM_INFO_TAB_MEMORY = Memory
+MEMORY_REGIONS_HEADER = Memory Regions
 
 ERROR_PERFORMING_GC = Error performing Garbage Collection (agent: {0}, vm: {1})
\ No newline at end of file
--- a/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-memory/client-swing/src/main/java/com/redhat/thermostat/vm/memory/client/swing/internal/MemoryStatsViewImpl.java	Mon May 27 20:50:48 2013 -0600
@@ -57,11 +57,15 @@
 import com.redhat.thermostat.gc.remote.client.swing.ToolbarGCButton;
 import com.redhat.thermostat.gc.remote.common.command.GCCommand;
 import com.redhat.thermostat.shared.locale.LocalizedString;
+import com.redhat.thermostat.shared.locale.Translate;
 import com.redhat.thermostat.vm.memory.client.core.MemoryStatsView;
 import com.redhat.thermostat.vm.memory.client.core.Payload;
+import com.redhat.thermostat.vm.memory.client.locale.LocaleResources;
 
 public class MemoryStatsViewImpl extends MemoryStatsView implements SwingComponent {
 
+    private static final Translate<LocaleResources> t = LocaleResources.createLocalizer();
+
     private static final long REPAINT_DELAY = 500;
     private long lastRepaint;
     
@@ -82,7 +86,7 @@
  
         preferredSize = new Dimension(0, 0);
         
-        visiblePanel.setHeader("Memory Regions");
+        visiblePanel.setHeader(t.localize(LocaleResources.MEMORY_REGIONS_HEADER));
 
         visiblePanel.addHierarchyListener(new ComponentVisibleListener() {
             @Override
--- a/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/internal/VmOverviewPanel.java	Thu Jun 06 11:00:25 2013 -0400
+++ b/vm-overview/client-swing/src/main/java/com/redhat/thermostat/vm/overview/client/swing/internal/VmOverviewPanel.java	Mon May 27 20:50:48 2013 -0600
@@ -210,7 +210,7 @@
     private void initializePanel() {
         visiblePanel = new HeaderPanel();
 
-        visiblePanel.setHeader(translator.localize(LocaleResources.VM_INFO_TITLE).getContents());
+        visiblePanel.setHeader(translator.localize(LocaleResources.VM_INFO_TITLE));
 
         SectionHeader processSection = new SectionHeader(translator.localize(LocaleResources.VM_INFO_SECTION_PROCESS));
         LabelField pidLabel = new LabelField(translator.localize(LocaleResources.VM_INFO_PROCESS_ID));