Localize strings
authorKevin Lamonte <kevin.lamonte@gmail.com>
Sat, 19 Aug 2017 18:36:43 +0000 (14:36 -0400)
committerKevin Lamonte <kevin.lamonte@gmail.com>
Sat, 19 Aug 2017 18:36:43 +0000 (14:36 -0400)
17 files changed:
build.xml
docs/TODO.md
src/jexer/TApplication.java
src/jexer/TApplication.properties [new file with mode: 0644]
src/jexer/TButton.java
src/jexer/TEditColorThemeWindow.java
src/jexer/TEditColorThemeWindow.properties [new file with mode: 0644]
src/jexer/TEditorWindow.java
src/jexer/TEditorWindow.properties [new file with mode: 0644]
src/jexer/TFileOpenBox.java
src/jexer/TFileOpenBox.properties [new file with mode: 0644]
src/jexer/TMessageBox.java
src/jexer/TMessageBox.properties [new file with mode: 0644]
src/jexer/TTerminalWindow.java
src/jexer/TTerminalWindow.properties [new file with mode: 0644]
src/jexer/menu/TMenu.java
src/jexer/menu/TMenu.properties [new file with mode: 0644]

index 93b79d83df085d95d4064ee63da6acbaed292e65..807a6ea387faa24df2c3adfe0e801777e2a0771c 100644 (file)
--- a/build.xml
+++ b/build.xml
     <jar destfile="${jar.dir}/${ant.project.name}.jar"
          basedir="${classes.dir}">
       <fileset dir="${resources.dir}"/>
+
+      <!-- Include properties files. -->
+      <fileset dir="${src.dir}" includes="**/*.properties"/>
+
       <!-- Include source by default. -->
       <fileset dir="${src.dir}"/>
+
       <manifest>
         <attribute name="Main-Class" value="jexer.demos.Demo1"/>
         <attribute name="Implementation-Version" value="${version}"/>
@@ -93,7 +98,7 @@
         windowtitle="Jexer - Java Text User Interface - API docs">
 
       <fileset dir="${src.dir}" defaultexcludes="yes">
-        <include name="jexer/**"/>
+        <include name="jexer/**/*.java"/>
       </fileset>
 
       <doctitle>
index d717d4c6a915ac0e3f4c8c20ee160a3a82a55046..e0de8a2e0ac9425e186b2582d156274eca7fdb38 100644 (file)
@@ -7,14 +7,10 @@ Roadmap
 
 0.0.6
 
-#18 Rework TApplication run loop:
-    - Reduce thread spinlocks
-    - Eliminate unnecessary screen redraws
-    - No activity means no CPU usage
-
-- TSpinner
-- TComboBox
-- TCalendar
+- New widgets:
+  - TSpinner
+  - TComboBox
+  - TCalendar
 
 - TEditor
   - Horizontal scrollbar integration
index cedb631f77fa40188112ac5caa04e2dd67756733..57d60955e33a1f1d4b21a2069e8b930c922d0124 100644 (file)
@@ -34,6 +34,7 @@ import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.Reader;
 import java.io.UnsupportedEncodingException;
+import java.text.MessageFormat;
 import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
@@ -41,6 +42,7 @@ import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.ResourceBundle;
 
 import jexer.bits.CellAttributes;
 import jexer.bits.ColorTheme;
@@ -68,6 +70,11 @@ import static jexer.TKeypress.*;
  */
 public class TApplication implements Runnable {
 
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(TApplication.class.getName());
+
     // ------------------------------------------------------------------------
     // Public constants -------------------------------------------------------
     // ------------------------------------------------------------------------
@@ -537,8 +544,9 @@ public class TApplication implements Runnable {
      * Display the about dialog.
      */
     protected void showAboutDialog() {
-        messageBox("About", "Jexer Version " +
-            this.getClass().getPackage().getImplementationVersion(),
+        messageBox(i18n.getString("aboutDialogTitle"),
+            MessageFormat.format(i18n.getString("aboutDialogText"),
+                this.getClass().getPackage().getImplementationVersion()),
             TMessageBox.Type.OK);
     }
 
@@ -732,6 +740,8 @@ public class TApplication implements Runnable {
      * Draw everything.
      */
     private void drawAll() {
+        boolean menuIsActive = false;
+
         if (debugThreads) {
             System.err.printf("%d %s drawAll() enter\n",
                 System.currentTimeMillis(), Thread.currentThread());
@@ -799,6 +809,7 @@ public class TApplication implements Runnable {
             CellAttributes menuColor;
             CellAttributes menuMnemonicColor;
             if (menu.isActive()) {
+                menuIsActive = true;
                 menuColor = theme.getColor("tmenu.highlighted");
                 menuMnemonicColor = theme.getColor("tmenu.mnemonic.highlighted");
                 topLevel = menu;
@@ -851,22 +862,24 @@ public class TApplication implements Runnable {
         oldMouseY = mouseY;
 
         // Place the cursor if it is visible
-        TWidget activeWidget = null;
-        if (sorted.size() > 0) {
-            activeWidget = sorted.get(sorted.size() - 1).getActiveChild();
-            if (activeWidget.isCursorVisible()) {
-                if ((activeWidget.getCursorAbsoluteY() < desktopBottom)
-                    && (activeWidget.getCursorAbsoluteY() > desktopTop)
-                ) {
-                    getScreen().putCursor(true,
-                        activeWidget.getCursorAbsoluteX(),
-                        activeWidget.getCursorAbsoluteY());
-                    cursor = true;
-                } else {
-                    getScreen().putCursor(false,
-                        activeWidget.getCursorAbsoluteX(),
-                        activeWidget.getCursorAbsoluteY());
-                    cursor = false;
+        if (!menuIsActive) {
+            TWidget activeWidget = null;
+            if (sorted.size() > 0) {
+                activeWidget = sorted.get(sorted.size() - 1).getActiveChild();
+                if (activeWidget.isCursorVisible()) {
+                    if ((activeWidget.getCursorAbsoluteY() < desktopBottom)
+                        && (activeWidget.getCursorAbsoluteY() > desktopTop)
+                    ) {
+                        getScreen().putCursor(true,
+                            activeWidget.getCursorAbsoluteX(),
+                            activeWidget.getCursorAbsoluteY());
+                        cursor = true;
+                    } else {
+                        getScreen().putCursor(false,
+                            activeWidget.getCursorAbsoluteX(),
+                            activeWidget.getCursorAbsoluteY());
+                        cursor = false;
+                    }
                 }
             }
         }
@@ -2335,14 +2348,14 @@ public class TApplication implements Runnable {
      * @return the new menu
      */
     public final TMenu addFileMenu() {
-        TMenu fileMenu = addMenu("&File");
+        TMenu fileMenu = addMenu(i18n.getString("fileMenuTitle"));
         fileMenu.addDefaultItem(TMenu.MID_OPEN_FILE);
         fileMenu.addSeparator();
         fileMenu.addDefaultItem(TMenu.MID_SHELL);
         fileMenu.addDefaultItem(TMenu.MID_EXIT);
-        TStatusBar statusBar = fileMenu.newStatusBar("File-management " +
-            "commands (Open, Save, Print, etc.)");
-        statusBar.addShortcutKeypress(kbF1, cmHelp, "Help");
+        TStatusBar statusBar = fileMenu.newStatusBar(i18n.
+            getString("fileMenuStatus"));
+        statusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help"));
         return fileMenu;
     }
 
@@ -2352,14 +2365,14 @@ public class TApplication implements Runnable {
      * @return the new menu
      */
     public final TMenu addEditMenu() {
-        TMenu editMenu = addMenu("&Edit");
+        TMenu editMenu = addMenu(i18n.getString("editMenuTitle"));
         editMenu.addDefaultItem(TMenu.MID_CUT);
         editMenu.addDefaultItem(TMenu.MID_COPY);
         editMenu.addDefaultItem(TMenu.MID_PASTE);
         editMenu.addDefaultItem(TMenu.MID_CLEAR);
-        TStatusBar statusBar = editMenu.newStatusBar("Editor operations, " +
-            "undo, and Clipboard access");
-        statusBar.addShortcutKeypress(kbF1, cmHelp, "Help");
+        TStatusBar statusBar = editMenu.newStatusBar(i18n.
+            getString("editMenuStatus"));
+        statusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help"));
         return editMenu;
     }
 
@@ -2369,7 +2382,7 @@ public class TApplication implements Runnable {
      * @return the new menu
      */
     public final TMenu addWindowMenu() {
-        TMenu windowMenu = addMenu("&Window");
+        TMenu windowMenu = addMenu(i18n.getString("windowMenuTitle"));
         windowMenu.addDefaultItem(TMenu.MID_TILE);
         windowMenu.addDefaultItem(TMenu.MID_CASCADE);
         windowMenu.addDefaultItem(TMenu.MID_CLOSE_ALL);
@@ -2379,9 +2392,9 @@ public class TApplication implements Runnable {
         windowMenu.addDefaultItem(TMenu.MID_WINDOW_NEXT);
         windowMenu.addDefaultItem(TMenu.MID_WINDOW_PREVIOUS);
         windowMenu.addDefaultItem(TMenu.MID_WINDOW_CLOSE);
-        TStatusBar statusBar = windowMenu.newStatusBar("Open, arrange, and " +
-            "list windows");
-        statusBar.addShortcutKeypress(kbF1, cmHelp, "Help");
+        TStatusBar statusBar = windowMenu.newStatusBar(i18n.
+            getString("windowMenuStatus"));
+        statusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help"));
         return windowMenu;
     }
 
@@ -2391,7 +2404,7 @@ public class TApplication implements Runnable {
      * @return the new menu
      */
     public final TMenu addHelpMenu() {
-        TMenu helpMenu = addMenu("&Help");
+        TMenu helpMenu = addMenu(i18n.getString("helpMenuTitle"));
         helpMenu.addDefaultItem(TMenu.MID_HELP_CONTENTS);
         helpMenu.addDefaultItem(TMenu.MID_HELP_INDEX);
         helpMenu.addDefaultItem(TMenu.MID_HELP_SEARCH);
@@ -2400,8 +2413,9 @@ public class TApplication implements Runnable {
         helpMenu.addDefaultItem(TMenu.MID_HELP_ACTIVE_FILE);
         helpMenu.addSeparator();
         helpMenu.addDefaultItem(TMenu.MID_ABOUT);
-        TStatusBar statusBar = helpMenu.newStatusBar("Access online help");
-        statusBar.addShortcutKeypress(kbF1, cmHelp, "Help");
+        TStatusBar statusBar = helpMenu.newStatusBar(i18n.
+            getString("helpMenuStatus"));
+        statusBar.addShortcutKeypress(kbF1, cmHelp, i18n.getString("Help"));
         return helpMenu;
     }
 
@@ -2419,7 +2433,8 @@ public class TApplication implements Runnable {
     protected boolean onCommand(final TCommandEvent command) {
         // Default: handle cmExit
         if (command.equals(cmExit)) {
-            if (messageBox("Confirmation", "Exit application?",
+            if (messageBox(i18n.getString("exitDialogTitle"),
+                    i18n.getString("exitDialogText"),
                     TMessageBox.Type.YESNO).getResult() == TMessageBox.Result.YES) {
                 exit();
             }
@@ -2468,7 +2483,8 @@ public class TApplication implements Runnable {
 
         // Default: handle MID_EXIT
         if (menu.getId() == TMenu.MID_EXIT) {
-            if (messageBox("Confirmation", "Exit application?",
+            if (messageBox(i18n.getString("exitDialogTitle"),
+                    i18n.getString("exitDialogText"),
                     TMessageBox.Type.YESNO).getResult() == TMessageBox.Result.YES) {
                 exit();
             }
diff --git a/src/jexer/TApplication.properties b/src/jexer/TApplication.properties
new file mode 100644 (file)
index 0000000..d43bc24
--- /dev/null
@@ -0,0 +1,15 @@
+Help=Help
+fileMenuTitle=&File
+fileMenuStatus=File-management commands (Open, Save, Print, etc.)
+editMenuTitle=&Edit
+editMenuStatus=Editor operations, undo, and Clipboard access
+windowMenuTitle=&Window
+windowMenuStatus=Open, arrange, and list windows
+helpMenuTitle=&Help
+helpMenuStatus=Access online help
+
+exitDialogTitle=Confirmation
+exitDialogText=Exit application?
+
+aboutDialogTitle=About
+aboutDialogText=Jexer Version {0}
index fc93c782b5fda5c66ff01a9297fc23ee53588837..3b60cad037bba20c10d2f4d6520738a774ca2159 100644 (file)
@@ -73,11 +73,6 @@ public final class TButton extends TWidget {
      */
     private TAction action;
 
-    /**
-     * The time at which dispatch() was called.
-     */
-    private long dispatchTime;
-
     /**
      * How long to animate dispatch of the event in millis.
      */
@@ -89,11 +84,8 @@ public final class TButton extends TWidget {
      */
     public void dispatch() {
         if (action != null) {
-            long now = System.currentTimeMillis();
-            if (now - dispatchTime > DISPATCH_TIME) {
-                action.DO();
-                dispatchTime = now;
-            }
+            action.DO();
+            inButtonPress = false;
         }
     }
 
@@ -167,12 +159,6 @@ public final class TButton extends TWidget {
         shadowColor.setForeColor(Color.BLACK);
         shadowColor.setBold(false);
 
-        long now = System.currentTimeMillis();
-        boolean inDispatch = false;
-        if (now - dispatchTime < DISPATCH_TIME) {
-            inDispatch = true;
-        }
-
         if (!isEnabled()) {
             buttonColor = getTheme().getColor("tbutton.disabled");
             menuMnemonicColor = getTheme().getColor("tbutton.disabled");
@@ -184,7 +170,7 @@ public final class TButton extends TWidget {
             menuMnemonicColor = getTheme().getColor("tbutton.mnemonic");
         }
 
-        if (inButtonPress || inDispatch) {
+        if (inButtonPress) {
             getScreen().putCharXY(1, 0, ' ', buttonColor);
             getScreen().putStringXY(2, 0, mnemonic.getRawLabel(), buttonColor);
             getScreen().putCharXY(getWidth() - 1, 0, ' ', buttonColor);
@@ -199,7 +185,7 @@ public final class TButton extends TWidget {
                 GraphicsChars.CP437[0xDF], shadowColor);
         }
         if (mnemonic.getShortcutIdx() >= 0) {
-            if (inButtonPress || inDispatch) {
+            if (inButtonPress) {
                 getScreen().putCharXY(2 + mnemonic.getShortcutIdx(), 0,
                     mnemonic.getShortcut(), menuMnemonicColor);
             } else {
@@ -235,7 +221,6 @@ public final class TButton extends TWidget {
         this.mouse = mouse;
 
         if (inButtonPress && mouse.isMouse1()) {
-            inButtonPress = false;
             // Dispatch the event
             dispatch();
         }
index a13bf1444f439d6043a65c2cffaf5de69a61bd9f..b4f0dcf4a35cfcf3b7f5e6f54a506d7fad981aca 100644 (file)
@@ -29,6 +29,7 @@
 package jexer;
 
 import java.util.List;
+import java.util.ResourceBundle;
 
 import jexer.bits.Color;
 import jexer.bits.ColorTheme;
@@ -45,6 +46,11 @@ import static jexer.TKeypress.*;
  */
 public final class TEditColorThemeWindow extends TWindow {
 
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(TEditColorThemeWindow.class.getName());
+
     /**
      * The foreground color picker.
      */
@@ -197,7 +203,8 @@ public final class TEditColorThemeWindow extends TWindow {
                 attr.setForeColor(getTheme().getColor("tlabel").getForeColor());
                 attr.setBold(getTheme().getColor("tlabel").isBold());
             }
-            getScreen().putStringXY(1, 0, " Foreground ", attr);
+            getScreen().putStringXY(1, 0, i18n.getString("foregroundLabel"),
+                attr);
 
             // Have to draw the colors manually because the int value matches
             // SGR, not CGA.
@@ -470,7 +477,8 @@ public final class TEditColorThemeWindow extends TWindow {
                 attr.setForeColor(getTheme().getColor("tlabel").getForeColor());
                 attr.setBold(getTheme().getColor("tlabel").isBold());
             }
-            getScreen().putStringXY(1, 0, " Background ", attr);
+            getScreen().putStringXY(1, 0, i18n.getString("backgroundLabel"),
+                attr);
 
             // Have to draw the colors manually because the int value matches
             // SGR, not CGA.
@@ -650,7 +658,7 @@ public final class TEditColorThemeWindow extends TWindow {
     public TEditColorThemeWindow(final TApplication application) {
 
         // Register with the TApplication
-        super(application, "Colors", 0, 0, 60, 18, MODAL);
+        super(application, i18n.getString("windowTitle"), 0, 0, 60, 18, MODAL);
 
         // Initialize with the first color
         List<String> colors = getTheme().getColorNames();
@@ -681,7 +689,7 @@ public final class TEditColorThemeWindow extends TWindow {
         refreshFromTheme(colors.get(0));
         colorNames.setSelectedIndex(0);
 
-        addButton("  &OK  ", getWidth() - 37, getHeight() - 4,
+        addButton(i18n.getString("okButton"), getWidth() - 37, getHeight() - 4,
             new TAction() {
                 public void DO() {
                     ColorTheme global = getTheme();
@@ -696,7 +704,8 @@ public final class TEditColorThemeWindow extends TWindow {
             }
         );
 
-        addButton("&Cancel", getWidth() - 25, getHeight() - 4,
+        addButton(i18n.getString("cancelButton"), getWidth() - 25,
+            getHeight() - 4,
             new TAction() {
                 public void DO() {
                     getApplication().closeWindow(TEditColorThemeWindow.this);
@@ -708,7 +717,7 @@ public final class TEditColorThemeWindow extends TWindow {
         activate(colorNames);
 
         // Add shortcut text
-        newStatusBar("Select Colors");
+        newStatusBar(i18n.getString("statusBar"));
     }
 
     /**
@@ -725,7 +734,7 @@ public final class TEditColorThemeWindow extends TWindow {
             attr.setForeColor(getTheme().getColor("tlabel").getForeColor());
             attr.setBold(getTheme().getColor("tlabel").isBold());
         }
-        getScreen().putStringXY(3, 2, "Color Name", attr);
+        getScreen().putStringXY(3, 2, i18n.getString("colorName"), attr);
 
         // Draw the sample text box
         attr.reset();
@@ -733,9 +742,9 @@ public final class TEditColorThemeWindow extends TWindow {
         attr.setBold(foreground.bold);
         attr.setBackColor(background.color);
         getScreen().putStringXY(getWidth() - 17, getHeight() - 6,
-            "Text Text Text", attr);
+            i18n.getString("textTextText"), attr);
         getScreen().putStringXY(getWidth() - 17, getHeight() - 5,
-            "Text Text Text", attr);
+            i18n.getString("textTextText"), attr);
     }
 
     /**
diff --git a/src/jexer/TEditColorThemeWindow.properties b/src/jexer/TEditColorThemeWindow.properties
new file mode 100644 (file)
index 0000000..f4c6220
--- /dev/null
@@ -0,0 +1,8 @@
+foregroundLabel=\ Foreground\ 
+backgroundLabel=\ Background\ 
+windowTitle=Colors
+okButton=\ \ &OK\ \ 
+cancelButton=&Cancel
+statusBar=Select Colors
+colorName=Color Name
+textTextText=Text Text Text
index 5bf664d254e515f95d41418ef383ae01559dcdb4..d474db2fa3e623e155c90a93183ac898b0a4b530 100644 (file)
@@ -30,6 +30,8 @@ package jexer;
 
 import java.io.File;
 import java.io.IOException;
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
 import java.util.Scanner;
 
 import jexer.TApplication;
@@ -52,6 +54,11 @@ import static jexer.TKeypress.*;
  */
 public class TEditorWindow extends TScrollableWindow {
 
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(TEditorWindow.class.getName());
+
     /**
      * Hang onto my TEditor so I can resize it with the window.
      */
@@ -75,11 +82,15 @@ public class TEditorWindow extends TScrollableWindow {
         setLeftValue(1);
         setRightValue(editField.getMaximumColumnNumber());
 
-        statusBar = newStatusBar("Editor");
-        statusBar.addShortcutKeypress(kbF1, cmHelp, "Help");
-        statusBar.addShortcutKeypress(kbF2, cmSave, "Save");
-        statusBar.addShortcutKeypress(kbF3, cmOpen, "Open");
-        statusBar.addShortcutKeypress(kbF10, cmMenu, "Menu");
+        statusBar = newStatusBar(i18n.getString("statusBar"));
+        statusBar.addShortcutKeypress(kbF1, cmHelp,
+            i18n.getString("statusBarHelp"));
+        statusBar.addShortcutKeypress(kbF2, cmSave,
+            i18n.getString("statusBarSave"));
+        statusBar.addShortcutKeypress(kbF3, cmOpen,
+            i18n.getString("statusBarOpen"));
+        statusBar.addShortcutKeypress(kbF10, cmMenu,
+            i18n.getString("statusBarMenu"));
     }
 
     /**
@@ -140,7 +151,7 @@ public class TEditorWindow extends TScrollableWindow {
      * @param parent the main application
      */
     public TEditorWindow(final TApplication parent) {
-        this(parent, "New Text Document");
+        this(parent, i18n.getString("newTextDocument"));
     }
 
     /**
@@ -340,13 +351,15 @@ public class TEditorWindow extends TScrollableWindow {
                         String contents = readFileData(filename);
                         new TEditorWindow(getApplication(), filename, contents);
                     } catch (IOException e) {
-                        messageBox("Error", "Error reading file: " +
-                            e.getMessage());
+                        messageBox(i18n.getString("errorDialogTitle"),
+                            MessageFormat.format(i18n.
+                                getString("errorReadingFile"), e.getMessage()));
                     }
                 }
             } catch (IOException e) {
-                messageBox("Error", "Error opening file dialog: " +
-                    e.getMessage());
+                messageBox(i18n.getString("errorDialogTitle"),
+                    MessageFormat.format(i18n.
+                        getString("errorOpeningFileDialog"), e.getMessage()));
             }
             return;
         }
@@ -356,7 +369,9 @@ public class TEditorWindow extends TScrollableWindow {
                 try {
                     editField.saveToFilename(filename);
                 } catch (IOException e) {
-                    messageBox("Error", "Error saving file: " + e.getMessage());
+                messageBox(i18n.getString("errorDialogTitle"),
+                    MessageFormat.format(i18n.
+                        getString("errorSavingFile"), e.getMessage()));
                 }
             }
             return;
diff --git a/src/jexer/TEditorWindow.properties b/src/jexer/TEditorWindow.properties
new file mode 100644 (file)
index 0000000..d18b078
--- /dev/null
@@ -0,0 +1,10 @@
+statusBar=Editor
+statusBarHelp=Help
+statusBarSave=Save
+statusBarOpen=Open
+statusBarMenu=Menu
+newTextDocument=New Text Document
+errorDialogTitle=Error
+errorReadingFile=Error reading file: {0}
+errorOpeningFileDialog=Error opening file dialog: {0}
+errorSavingFile=Error saving file: {0}
index 0a69a972674fbc7f0b62d09c0239d356d8fea090..05629cf8e3d3cecf4a10a7a222a247ce6cbf22e4 100644 (file)
@@ -30,6 +30,7 @@ package jexer;
 
 import java.io.File;
 import java.io.IOException;
+import java.util.ResourceBundle;
 
 import jexer.bits.GraphicsChars;
 import jexer.event.TKeypressEvent;
@@ -53,6 +54,11 @@ import static jexer.TKeypress.*;
  */
 public final class TFileOpenBox extends TWindow {
 
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(TFileOpenBox.class.getName());
+
     /**
      * TFileOpenBox can be called for either Open or Save actions.
      */
@@ -199,12 +205,12 @@ public final class TFileOpenBox extends TWindow {
         String openLabel = "";
         switch (type) {
         case OPEN:
-            openLabel = " &Open ";
-            setTitle("Open File...");
+            openLabel = i18n.getString("openButton");
+            setTitle(i18n.getString("openTitle"));
             break;
         case SAVE:
-            openLabel = " &Save ";
-            setTitle("Save File...");
+            openLabel = i18n.getString("saveButton");
+            setTitle(i18n.getString("saveTitle"));
             break;
         default:
             throw new IllegalArgumentException("Invalid type: " + type);
@@ -224,7 +230,7 @@ public final class TFileOpenBox extends TWindow {
         );
         openButton.setEnabled(false);
 
-        addButton("&Cancel", getWidth() - 12, 5,
+        addButton(i18n.getString("cancelButton"), getWidth() - 12, 5,
             new TAction() {
                 public void DO() {
                     filename = null;
diff --git a/src/jexer/TFileOpenBox.properties b/src/jexer/TFileOpenBox.properties
new file mode 100644 (file)
index 0000000..1dee738
--- /dev/null
@@ -0,0 +1,5 @@
+openButton=\ &Open\ 
+openTitle=Open File...
+saveButton=\ &Save\ 
+saveTitle=Save File...
+cancelButton=&Cancel
index 8ad51446893b85593161abb17585ebc688ba7f69..cd4a514ea912aa92b5f353f2545e293639ef7ae6 100644 (file)
@@ -30,6 +30,7 @@ package jexer;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.ResourceBundle;
 
 import jexer.event.TKeypressEvent;
 import static jexer.TKeypress.*;
@@ -53,6 +54,11 @@ import static jexer.TKeypress.*;
  */
 public class TMessageBox extends TWindow {
 
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(TMessageBox.class.getName());
+
     /**
      * Message boxes have these supported types.
      */
@@ -215,7 +221,7 @@ public class TMessageBox extends TWindow {
                 setWidth(15);
             }
             buttonX = (getWidth() - 11) / 2;
-            buttons.add(addButton("  &OK  ", buttonX, lineI,
+            buttons.add(addButton(i18n.getString("okButton"), buttonX, lineI,
                     new TAction() {
                         public void DO() {
                             result = Result.OK;
@@ -232,7 +238,7 @@ public class TMessageBox extends TWindow {
                 setWidth(26);
             }
             buttonX = (getWidth() - 22) / 2;
-            buttons.add(addButton("  &OK  ", buttonX, lineI,
+            buttons.add(addButton(i18n.getString("okButton"), buttonX, lineI,
                     new TAction() {
                         public void DO() {
                             result = Result.OK;
@@ -242,7 +248,7 @@ public class TMessageBox extends TWindow {
                 )
             );
             buttonX += 8 + 4;
-            buttons.add(addButton("&Cancel", buttonX, lineI,
+            buttons.add(addButton(i18n.getString("cancelButton"), buttonX, lineI,
                     new TAction() {
                         public void DO() {
                             result = Result.CANCEL;
@@ -259,7 +265,7 @@ public class TMessageBox extends TWindow {
                 setWidth(20);
             }
             buttonX = (getWidth() - 16) / 2;
-            buttons.add(addButton("&Yes", buttonX, lineI,
+            buttons.add(addButton(i18n.getString("yesButton"), buttonX, lineI,
                     new TAction() {
                         public void DO() {
                             result = Result.YES;
@@ -269,7 +275,7 @@ public class TMessageBox extends TWindow {
                 )
             );
             buttonX += 5 + 4;
-            buttons.add(addButton("&No", buttonX, lineI,
+            buttons.add(addButton(i18n.getString("noButton"), buttonX, lineI,
                     new TAction() {
                         public void DO() {
                             result = Result.NO;
@@ -286,7 +292,7 @@ public class TMessageBox extends TWindow {
                 setWidth(31);
             }
             buttonX = (getWidth() - 27) / 2;
-            buttons.add(addButton("&Yes", buttonX, lineI,
+            buttons.add(addButton(i18n.getString("yesButton"), buttonX, lineI,
                     new TAction() {
                         public void DO() {
                             result = Result.YES;
@@ -296,7 +302,7 @@ public class TMessageBox extends TWindow {
                 )
             );
             buttonX += 5 + 4;
-            buttons.add(addButton("&No", buttonX, lineI,
+            buttons.add(addButton(i18n.getString("noButton"), buttonX, lineI,
                     new TAction() {
                         public void DO() {
                             result = Result.NO;
@@ -306,7 +312,8 @@ public class TMessageBox extends TWindow {
                 )
             );
             buttonX += 4 + 4;
-            buttons.add(addButton("&Cancel", buttonX, lineI,
+            buttons.add(addButton(i18n.getString("cancelButton"), buttonX,
+                    lineI,
                     new TAction() {
                         public void DO() {
                             result = Result.CANCEL;
diff --git a/src/jexer/TMessageBox.properties b/src/jexer/TMessageBox.properties
new file mode 100644 (file)
index 0000000..04e344a
--- /dev/null
@@ -0,0 +1,4 @@
+okButton=\ \ &OK\ \ 
+cancelButton=&Cancel
+yesButton=&Yes
+noButton=&No
index d1936535c63e5a41bc0a1a06eede35a20e7c5a4c..3dc6a4c19e11322f22d4d20126721cb01f4b7209 100644 (file)
@@ -30,9 +30,11 @@ package jexer;
 
 import java.io.IOException;
 import java.lang.reflect.Field;
+import java.text.MessageFormat;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.ResourceBundle;
 
 import jexer.bits.Cell;
 import jexer.bits.CellAttributes;
@@ -50,6 +52,12 @@ import static jexer.TKeypress.*;
 public class TTerminalWindow extends TScrollableWindow
                              implements DisplayListener {
 
+
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(TTerminalWindow.class.getName());
+
     /**
      * The emulator.
      */
@@ -148,7 +156,8 @@ public class TTerminalWindow extends TScrollableWindow
     public TTerminalWindow(final TApplication application, final int x,
         final int y, final int flags) {
 
-        super(application, "Terminal", x, y, 80 + 2, 24 + 2, flags);
+        super(application, i18n.getString("windowTitle"), x, y,
+            80 + 2, 24 + 2, flags);
 
         vScroller = new TVScroller(this, getWidth() - 2, 0, getHeight() - 2);
         setBottomValue(0);
@@ -204,7 +213,9 @@ public class TTerminalWindow extends TScrollableWindow
             emulator = new ECMA48(deviceType, shell.getInputStream(),
                 shell.getOutputStream(), this);
         } catch (IOException e) {
-            messageBox("Error", "Error launching shell: " + e.getMessage());
+            messageBox(i18n.getString("errorLaunchingShellTitle"),
+                MessageFormat.format(i18n.getString("errorLaunchingShellText"),
+                    e.getMessage()));
         }
 
         // Setup the scroll bars
@@ -215,7 +226,7 @@ public class TTerminalWindow extends TScrollableWindow
         addShortcutKeys();
 
         // Add shortcut text
-        newStatusBar("Terminal session executing...");
+        newStatusBar(i18n.getString("statusBarRunning"));
     }
 
     /**
@@ -417,13 +428,13 @@ public class TTerminalWindow extends TScrollableWindow
                 try {
                     int rc = shell.exitValue();
                     // The emulator exited on its own, all is fine
-                    setTitle(String.format("%s [Completed - %d]",
-                            getTitle(), rc));
+                    setTitle(MessageFormat.format(i18n.
+                            getString("windowTitleCompleted"), getTitle(), rc));
                     shell = null;
                     emulator.close();
                     clearShortcutKeypresses();
-                    statusBar.setText("Terminal session completed, exit " +
-                        "code " + rc + ".");
+                    statusBar.setText(MessageFormat.format(i18n.
+                            getString("statusBarCompleted"), rc));
                 } catch (IllegalThreadStateException e) {
                     // The emulator thread has exited, but the shell Process
                     // hasn't figured that out yet.  Do nothing, we will see
@@ -434,13 +445,13 @@ public class TTerminalWindow extends TScrollableWindow
                 try {
                     int rc = shell.exitValue();
                     // If we got here, the shell died.
-                    setTitle(String.format("%s [Completed - %d]",
-                            getTitle(), rc));
+                    setTitle(MessageFormat.format(i18n.
+                            getString("windowTitleCompleted"), getTitle(), rc));
                     shell = null;
                     emulator.close();
                     clearShortcutKeypresses();
-                    statusBar.setText("Terminal session completed, exit " +
-                        "code " + rc + ".");
+                    statusBar.setText(MessageFormat.format(i18n.
+                            getString("statusBarCompleted"), rc));
                 } catch (IllegalThreadStateException e) {
                     // The shell is still running, do nothing.
                 }
diff --git a/src/jexer/TTerminalWindow.properties b/src/jexer/TTerminalWindow.properties
new file mode 100644 (file)
index 0000000..ecfcf21
--- /dev/null
@@ -0,0 +1,6 @@
+windowTitle=Terminal
+errorLaunchingShellTitle=Error
+errorLaunchingShellText=Error launching shell: {0}
+statusBarRunning=Terminal session executing...
+windowTitleCompleted={0} [Completed - {1}]
+statusBarCompleted=Terminal session completed, exit code {0}.
index a2f94b37a86c765773ba352cbb8dc05bf21ecc7c..0e948cee0df2fbb7845a53bcf76e6a64074da37e 100644 (file)
@@ -28,6 +28,8 @@
  */
 package jexer.menu;
 
+import java.util.ResourceBundle;
+
 import jexer.TApplication;
 import jexer.TKeypress;
 import jexer.TWidget;
@@ -44,6 +46,11 @@ import static jexer.TKeypress.*;
  */
 public final class TMenu extends TWindow {
 
+    /**
+     * Translated strings.
+     */
+    private static final ResourceBundle i18n = ResourceBundle.getBundle(TMenu.class.getName());
+
     /**
      * If true, this is a sub-menu.  Note package private access.
      */
@@ -385,89 +392,89 @@ public final class TMenu extends TWindow {
         switch (id) {
 
         case MID_EXIT:
-            label = "E&xit";
+            label = i18n.getString("menuExit");
             key = kbAltX;
             break;
 
         case MID_SHELL:
-            label = "O&S Shell";
+            label = i18n.getString("menuShell");
             break;
 
         case MID_OPEN_FILE:
-            label = "&Open";
+            label = i18n.getString("menuOpen");
             key = kbAltO;
             break;
 
         case MID_CUT:
-            label = "Cu&t";
+            label = i18n.getString("menuCut");
             key = kbCtrlX;
             break;
         case MID_COPY:
-            label = "&Copy";
+            label = i18n.getString("menuCopy");
             key = kbCtrlC;
             break;
         case MID_PASTE:
-            label = "&Paste";
+            label = i18n.getString("menuPaste");
             key = kbCtrlV;
             break;
         case MID_CLEAR:
-            label = "C&lear";
+            label = i18n.getString("menuClear");
             // key = kbDel;
             break;
 
         case MID_TILE:
-            label = "&Tile";
+            label = i18n.getString("menuWindowTile");
             break;
         case MID_CASCADE:
-            label = "C&ascade";
+            label = i18n.getString("menuWindowCascade");
             break;
         case MID_CLOSE_ALL:
-            label = "Cl&ose All";
+            label = i18n.getString("menuWindowCloseAll");
             break;
         case MID_WINDOW_MOVE:
-            label = "&Size/Move";
+            label = i18n.getString("menuWindowMove");
             key = kbCtrlF5;
             break;
         case MID_WINDOW_ZOOM:
-            label = "&Zoom";
+            label = i18n.getString("menuWindowZoom");
             key = kbF5;
             break;
         case MID_WINDOW_NEXT:
-            label = "&Next";
+            label = i18n.getString("menuWindowNext");
             key = kbF6;
             break;
         case MID_WINDOW_PREVIOUS:
-            label = "&Previous";
+            label = i18n.getString("menuWindowPrevious");
             key = kbShiftF6;
             break;
         case MID_WINDOW_CLOSE:
-            label = "&Close";
+            label = i18n.getString("menuWindowClose");
             key = kbCtrlW;
             break;
 
         case MID_HELP_CONTENTS:
-            label = "&Contents";
+            label = i18n.getString("menuHelpContents");
             break;
         case MID_HELP_INDEX:
-            label = "&Index";
+            label = i18n.getString("menuHelpIndex");
             key = kbShiftF1;
             break;
         case MID_HELP_SEARCH:
-            label = "&Topic search";
+            label = i18n.getString("menuHelpSearch");
             key = kbCtrlF1;
             break;
         case MID_HELP_PREVIOUS:
-            label = "&Previous topic";
+            label = i18n.getString("menuHelpPrevious");
             key = kbAltF1;
             break;
         case MID_HELP_HELP:
-            label = "&Help on help";
+            label = i18n.getString("menuHelpHelp");
             break;
         case MID_HELP_ACTIVE_FILE:
-            label = "Active &file...";
+            label = i18n.getString("menuHelpActive");
             break;
         case MID_ABOUT:
-            label = "&About...";
+            label = i18n.getString("menuHelpAbout");
             break;
 
         default:
diff --git a/src/jexer/menu/TMenu.properties b/src/jexer/menu/TMenu.properties
new file mode 100644 (file)
index 0000000..bf3b4f3
--- /dev/null
@@ -0,0 +1,22 @@
+menuExit=E&xit
+menuShell=O&S Shell
+menuOpen=&Open
+menuCut=Cu&t
+menuCopy=&Copy
+menuPaste=&Paste
+menuClear=C&lear
+menuWindowTile=&Tile
+menuWindowCascade=C&ascade
+menuWindowCloseAll=Cl&ose All
+menuWindowMove=&Size/Move
+menuWindowZoom=&Zoom
+menuWindowNext=&Next
+menuWindowPrevious=&Previous
+menuWindowClose=&Close
+menuHelpContents=&Contents
+menuHelpIndex=&Index
+menuHelpSearch=&Topic search
+menuHelpPrevious=&Previous topic
+menuHelpHelp=&Help on help
+menuHelpActive=Active &file...
+menuHelpAbout=&About...