From: Kevin Lamonte Date: Sat, 19 Aug 2017 18:36:43 +0000 (-0400) Subject: Localize strings X-Git-Url: https://git.nikiroo.be/?a=commitdiff_plain;h=339652cc241d738d461670c3309eaf6fc85c992a;p=fanfix-jexer.git Localize strings --- diff --git a/build.xml b/build.xml index 93b79d8..807a6ea 100644 --- a/build.xml +++ b/build.xml @@ -61,8 +61,13 @@ + + + + + @@ -93,7 +98,7 @@ windowtitle="Jexer - Java Text User Interface - API docs"> - + diff --git a/docs/TODO.md b/docs/TODO.md index d717d4c..e0de8a2 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -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 diff --git a/src/jexer/TApplication.java b/src/jexer/TApplication.java index cedb631..57d6095 100644 --- a/src/jexer/TApplication.java +++ b/src/jexer/TApplication.java @@ -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 index 0000000..d43bc24 --- /dev/null +++ b/src/jexer/TApplication.properties @@ -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} diff --git a/src/jexer/TButton.java b/src/jexer/TButton.java index fc93c78..3b60cad 100644 --- a/src/jexer/TButton.java +++ b/src/jexer/TButton.java @@ -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(); } diff --git a/src/jexer/TEditColorThemeWindow.java b/src/jexer/TEditColorThemeWindow.java index a13bf14..b4f0dcf 100644 --- a/src/jexer/TEditColorThemeWindow.java +++ b/src/jexer/TEditColorThemeWindow.java @@ -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 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 index 0000000..f4c6220 --- /dev/null +++ b/src/jexer/TEditColorThemeWindow.properties @@ -0,0 +1,8 @@ +foregroundLabel=\ Foreground\ +backgroundLabel=\ Background\ +windowTitle=Colors +okButton=\ \ &OK\ \ +cancelButton=&Cancel +statusBar=Select Colors +colorName=Color Name +textTextText=Text Text Text diff --git a/src/jexer/TEditorWindow.java b/src/jexer/TEditorWindow.java index 5bf664d..d474db2 100644 --- a/src/jexer/TEditorWindow.java +++ b/src/jexer/TEditorWindow.java @@ -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 index 0000000..d18b078 --- /dev/null +++ b/src/jexer/TEditorWindow.properties @@ -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} diff --git a/src/jexer/TFileOpenBox.java b/src/jexer/TFileOpenBox.java index 0a69a97..05629cf 100644 --- a/src/jexer/TFileOpenBox.java +++ b/src/jexer/TFileOpenBox.java @@ -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 index 0000000..1dee738 --- /dev/null +++ b/src/jexer/TFileOpenBox.properties @@ -0,0 +1,5 @@ +openButton=\ &Open\ +openTitle=Open File... +saveButton=\ &Save\ +saveTitle=Save File... +cancelButton=&Cancel diff --git a/src/jexer/TMessageBox.java b/src/jexer/TMessageBox.java index 8ad5144..cd4a514 100644 --- a/src/jexer/TMessageBox.java +++ b/src/jexer/TMessageBox.java @@ -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 index 0000000..04e344a --- /dev/null +++ b/src/jexer/TMessageBox.properties @@ -0,0 +1,4 @@ +okButton=\ \ &OK\ \ +cancelButton=&Cancel +yesButton=&Yes +noButton=&No diff --git a/src/jexer/TTerminalWindow.java b/src/jexer/TTerminalWindow.java index d193653..3dc6a4c 100644 --- a/src/jexer/TTerminalWindow.java +++ b/src/jexer/TTerminalWindow.java @@ -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 index 0000000..ecfcf21 --- /dev/null +++ b/src/jexer/TTerminalWindow.properties @@ -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}. diff --git a/src/jexer/menu/TMenu.java b/src/jexer/menu/TMenu.java index a2f94b3..0e948ce 100644 --- a/src/jexer/menu/TMenu.java +++ b/src/jexer/menu/TMenu.java @@ -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 index 0000000..bf3b4f3 --- /dev/null +++ b/src/jexer/menu/TMenu.properties @@ -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...