diff --git a/src/main/config/jpass.properties b/src/main/config/jpass.properties index 475a956d..702c7dbd 100644 --- a/src/main/config/jpass.properties +++ b/src/main/config/jpass.properties @@ -42,3 +42,6 @@ date.format=yyyy-MM-dd # Directory to be used for file chooser dialogs. (default: ./) # Leave that property empty to use the system default directory. file.chooser.directory=./ + +# Locale ID to set the program language +language.languageSetting=en-US \ No newline at end of file diff --git a/src/main/java/jpass/ui/EntryDetailsTable.java b/src/main/java/jpass/ui/EntryDetailsTable.java index 16bf1350..c52f1acc 100644 --- a/src/main/java/jpass/ui/EntryDetailsTable.java +++ b/src/main/java/jpass/ui/EntryDetailsTable.java @@ -45,6 +45,13 @@ import jpass.util.DateUtils; import jpass.xml.bind.Entry; +import static jpass.ui.JPassFrame.getLocalizedMessages; +import static jpass.util.Constants.VIEW_WINDOW_CREATED; +import static jpass.util.Constants.VIEW_WINDOW_MODIFIED; +import static jpass.util.Constants.VIEW_WINDOW_TITLE; +import static jpass.util.Constants.VIEW_WINDOW_URL; +import static jpass.util.Constants.VIEW_WINDOW_USER; + /** * Table to display entry details. */ @@ -54,11 +61,11 @@ public class EntryDetailsTable extends JTable { = DateUtils.createFormatter(Configuration.getInstance().get("date.format", "yyyy-MM-dd")); private enum DetailType { - TITLE("Title", Entry::getTitle), - URL("URL", Entry::getUrl), - USER("User", Entry::getUser), - MODIFIED("Modified", entry -> DateUtils.formatIsoDateTime(entry.getLastModification(), FORMATTER)), - CREATED("Created", entry -> DateUtils.formatIsoDateTime(entry.getCreationDate(), FORMATTER)); + TITLE(getLocalizedMessages().getString(VIEW_WINDOW_TITLE), Entry::getTitle), + URL(getLocalizedMessages().getString(VIEW_WINDOW_URL), Entry::getUrl), + USER(getLocalizedMessages().getString(VIEW_WINDOW_USER), Entry::getUser), + MODIFIED(getLocalizedMessages().getString(VIEW_WINDOW_MODIFIED), entry -> DateUtils.formatIsoDateTime(entry.getLastModification(), FORMATTER)), + CREATED(getLocalizedMessages().getString(VIEW_WINDOW_CREATED), entry -> DateUtils.formatIsoDateTime(entry.getCreationDate(), FORMATTER)); private final String description; private final Function valueMapper; @@ -78,7 +85,7 @@ public String getValue(Entry entry) { } private static final Map DETAILS_BY_NAME = Arrays.stream(DetailType.values()) - .collect(Collectors.toMap(detail -> detail.name(), Function.identity())); + .collect(Collectors.toMap(Enum::name, Function.identity())); private static final String[] DEFAULT_DETAILS = { DetailType.TITLE.name(), @@ -92,14 +99,14 @@ public EntryDetailsTable() { super(); detailsToDisplay = Arrays.stream(Configuration.getInstance().getArray("entry.details", DEFAULT_DETAILS)) - .map(name -> DETAILS_BY_NAME.get(name)) + .map(DETAILS_BY_NAME::get) .filter(Objects::nonNull) .distinct() .collect(Collectors.toList()); if (detailsToDisplay.isEmpty()) { Arrays.stream(DEFAULT_DETAILS) - .map(name -> DETAILS_BY_NAME.get(name)) + .map(DETAILS_BY_NAME::get) .forEach(detailsToDisplay::add); } diff --git a/src/main/java/jpass/ui/EntryDialog.java b/src/main/java/jpass/ui/EntryDialog.java index 5e7e60fb..c20ef204 100644 --- a/src/main/java/jpass/ui/EntryDialog.java +++ b/src/main/java/jpass/ui/EntryDialog.java @@ -54,7 +54,22 @@ import jpass.util.StringUtils; import jpass.xml.bind.Entry; +import static jpass.ui.JPassFrame.getLocalizedMessages; import static jpass.ui.helper.EntryHelper.copyEntryField; +import static jpass.util.Constants.BUTTON_MESSAGE_CANCEL; +import static jpass.util.Constants.BUTTON_MESSAGE_OK; +import static jpass.util.Constants.ENTRY_DIALOG_COPY_ENTRY; +import static jpass.util.Constants.ENTRY_DIALOG_FILL_TITLE_FIELD; +import static jpass.util.Constants.ENTRY_DIALOG_GENERATE_ENTRY; +import static jpass.util.Constants.ENTRY_DIALOG_SHOW_ENTRY; +import static jpass.util.Constants.ENTRY_DIALOG_TITLE_ALREADY_EXISTS; +import static jpass.util.Constants.PASSWORD_PASSWORDS_NOT_IDENTICAL; +import static jpass.util.Constants.VIEW_WINDOW_NOTES; +import static jpass.util.Constants.VIEW_WINDOW_PASSWORD; +import static jpass.util.Constants.VIEW_WINDOW_REPEAT; +import static jpass.util.Constants.VIEW_WINDOW_TITLE; +import static jpass.util.Constants.VIEW_WINDOW_URL; +import static jpass.util.Constants.VIEW_WINDOW_USER_NAME; /** * A dialog with the entry data. @@ -114,15 +129,15 @@ public EntryDialog(JPassFrame parent, String title, Entry entry, boolean newEntr this.originalEcho = this.passwordField.getEchoChar(); this.repeatField = TextComponentFactory.newPasswordField(true); - this.showButton = new JToggleButton("Show", MessageDialog.getIcon("show")); + this.showButton = new JToggleButton(getLocalizedMessages().getString(ENTRY_DIALOG_SHOW_ENTRY), MessageDialog.getIcon("show")); this.showButton.setActionCommand("show_button"); this.showButton.setMnemonic(KeyEvent.VK_S); this.showButton.addActionListener(this); - this.generateButton = new JButton("Generate", MessageDialog.getIcon("generate")); + this.generateButton = new JButton(getLocalizedMessages().getString(ENTRY_DIALOG_GENERATE_ENTRY), MessageDialog.getIcon("generate")); this.generateButton.setActionCommand("generate_button"); this.generateButton.setMnemonic(KeyEvent.VK_G); this.generateButton.addActionListener(this); - this.copyButton = new JButton("Copy", MessageDialog.getIcon("keyring")); + this.copyButton = new JButton(getLocalizedMessages().getString(ENTRY_DIALOG_COPY_ENTRY), MessageDialog.getIcon("keyring")); this.copyButton.setActionCommand("copy_button"); this.copyButton.setMnemonic(KeyEvent.VK_P); this.copyButton.addActionListener(this); @@ -137,15 +152,15 @@ public EntryDialog(JPassFrame parent, String title, Entry entry, boolean newEntr 5, 0); // xPad, yPad this.fieldPanel = new JPanel(new SpringLayout()); - this.fieldPanel.add(new JLabel("Title:")); + this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_TITLE)))); this.fieldPanel.add(this.titleField); - this.fieldPanel.add(new JLabel("URL:")); + this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_URL)))); this.fieldPanel.add(this.urlField); - this.fieldPanel.add(new JLabel("User name:")); + this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_USER_NAME)))); this.fieldPanel.add(this.userField); - this.fieldPanel.add(new JLabel("Password:")); + this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_PASSWORD)))); this.fieldPanel.add(this.passwordField); - this.fieldPanel.add(new JLabel("Repeat:")); + this.fieldPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_REPEAT)))); this.fieldPanel.add(this.repeatField); this.fieldPanel.add(new JLabel("")); this.fieldPanel.add(this.passwordButtonPanel); @@ -161,15 +176,15 @@ public EntryDialog(JPassFrame parent, String title, Entry entry, boolean newEntr this.notesPanel = new JPanel(new BorderLayout(5, 5)); this.notesPanel.setBorder(new EmptyBorder(0, 5, 0, 5)); - this.notesPanel.add(new JLabel("Notes:"), BorderLayout.NORTH); + this.notesPanel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_NOTES))), BorderLayout.NORTH); this.notesPanel.add(new JScrollPane(this.notesField), BorderLayout.CENTER); - this.okButton = new JButton("OK", MessageDialog.getIcon("accept")); + this.okButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_OK), MessageDialog.getIcon("accept")); this.okButton.setActionCommand("ok_button"); this.okButton.setMnemonic(KeyEvent.VK_O); this.okButton.addActionListener(this); - this.cancelButton = new JButton("Cancel", MessageDialog.getIcon("cancel")); + this.cancelButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_CANCEL), MessageDialog.getIcon("cancel")); this.cancelButton.setActionCommand("cancel_button"); this.cancelButton.setMnemonic(KeyEvent.VK_C); this.cancelButton.addActionListener(this); @@ -197,13 +212,13 @@ public void actionPerformed(ActionEvent e) { this.repeatField.setEchoChar(this.showButton.isSelected() ? NULL_ECHO : this.originalEcho); } else if ("ok_button".equals(command)) { if (this.titleField.getText().trim().isEmpty()) { - MessageDialog.showWarningMessage(this, "Please fill the title field."); + MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(ENTRY_DIALOG_FILL_TITLE_FIELD)); return; } else if (!checkEntryTitle()) { - MessageDialog.showWarningMessage(this, "Title is already exists,\nplease enter a different title."); + MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(ENTRY_DIALOG_TITLE_ALREADY_EXISTS)); return; } else if (!Arrays.equals(this.passwordField.getPassword(), this.repeatField.getPassword())) { - MessageDialog.showWarningMessage(this, "Password and repeated passwords are not identical."); + MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(PASSWORD_PASSWORDS_NOT_IDENTICAL)); return; } this.modifiedEntry = getEntryFromDialog(); diff --git a/src/main/java/jpass/ui/GeneratePasswordDialog.java b/src/main/java/jpass/ui/GeneratePasswordDialog.java index 328974af..1ee6d162 100644 --- a/src/main/java/jpass/ui/GeneratePasswordDialog.java +++ b/src/main/java/jpass/ui/GeneratePasswordDialog.java @@ -54,6 +54,22 @@ import jpass.util.CryptUtils; import jpass.util.SpringUtilities; +import static jpass.ui.JPassFrame.getLocalizedMessages; +import static jpass.util.Constants.BUTTON_MESSAGE_ACCEPT; +import static jpass.util.Constants.BUTTON_MESSAGE_CANCEL; +import static jpass.util.Constants.BUTTON_MESSAGE_CLOSE; +import static jpass.util.Constants.ENTRY_DIALOG_GENERATE_ENTRY; +import static jpass.util.Constants.PASSWORD_CAN_NOT_GENERATE_PASSWORD; +import static jpass.util.Constants.PASSWORD_GENERATED_PASSWORD; +import static jpass.util.Constants.PASSWORD_GENERATE_PASSWORD; +import static jpass.util.Constants.PASSWORD_GENERATE_PASSWORD_REQUEST; +import static jpass.util.Constants.PASSWORD_PASSWORD_LENGTH; +import static jpass.util.Constants.VIEW_WINDOW_CUSTOM_SYMBOLS; +import static jpass.util.Constants.VIEW_WINDOW_LOWER_CASE_LETTERS; +import static jpass.util.Constants.VIEW_WINDOW_NUMBERS; +import static jpass.util.Constants.VIEW_WINDOW_SETTINGS; +import static jpass.util.Constants.VIEW_WINDOW_UPPER_CASE_LETTERS; + /** * Dialog for generating random passwords. * @@ -71,9 +87,9 @@ public final class GeneratePasswordDialog extends JDialog implements ActionListe * Options for password generation. */ private static final String[][] PASSWORD_OPTIONS = { - {"Upper case letters (A-Z)", "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, - {"Lower case letters (a-z)", "abcdefghijklmnopqrstuvwxyz"}, - {"Numbers (0-9)", "0123456789"} + {getLocalizedMessages().getString(VIEW_WINDOW_UPPER_CASE_LETTERS), "ABCDEFGHIJKLMNOPQRSTUVWXYZ"}, + {getLocalizedMessages().getString(VIEW_WINDOW_LOWER_CASE_LETTERS), "abcdefghijklmnopqrstuvwxyz"}, + {getLocalizedMessages().getString(VIEW_WINDOW_NUMBERS), "0123456789"} }; private JCheckBox[] checkBoxes; @@ -128,12 +144,12 @@ public GeneratePasswordDialog(JDialog parent) { */ private void initDialog(final Component parent, final boolean showAcceptButton) { setModal(true); - setTitle("Generate Password"); + setTitle(getLocalizedMessages().getString(PASSWORD_GENERATE_PASSWORD)); setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); this.generatedPassword = null; this.lengthPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 5, 0)); - this.lengthLabel = new JLabel("Password length:"); + this.lengthLabel = new JLabel(String.format("%s:", getLocalizedMessages().getString(PASSWORD_PASSWORD_LENGTH))); this.lengthPanel.add(this.lengthLabel); int passwordGenerationLength = Configuration.getInstance().getInteger("default.password.generation.length", 14); @@ -148,14 +164,14 @@ private void initDialog(final Component parent, final boolean showAcceptButton) this.lengthPanel.add(this.lengthSpinner); this.charactersPanel = new JPanel(); - this.charactersPanel.setBorder(new TitledBorder("Settings")); + this.charactersPanel.setBorder(new TitledBorder(getLocalizedMessages().getString(VIEW_WINDOW_SETTINGS))); this.charactersPanel.add(this.lengthPanel); this.checkBoxes = new JCheckBox[PASSWORD_OPTIONS.length]; for (int i = 0; i < PASSWORD_OPTIONS.length; i++) { this.checkBoxes[i] = new JCheckBox(PASSWORD_OPTIONS[i][0], true); this.charactersPanel.add(this.checkBoxes[i]); } - this.customSymbolsCheck = new JCheckBox("Custom symbols"); + this.customSymbolsCheck = new JCheckBox(getLocalizedMessages().getString(VIEW_WINDOW_CUSTOM_SYMBOLS)); this.customSymbolsCheck.setActionCommand("custom_symbols_check"); this.customSymbolsCheck.addActionListener(this); this.charactersPanel.add(this.customSymbolsCheck); @@ -167,11 +183,11 @@ private void initDialog(final Component parent, final boolean showAcceptButton) SpringUtilities.makeCompactGrid(this.charactersPanel, 6, 1, 5, 5, 5, 5); this.passwordPanel = new JPanel(new BorderLayout()); - this.passwordPanel.setBorder(new TitledBorder("Generated password")); + this.passwordPanel.setBorder(new TitledBorder(getLocalizedMessages().getString(PASSWORD_GENERATED_PASSWORD))); this.passwordField = TextComponentFactory.newTextField(); this.passwordPanel.add(this.passwordField, BorderLayout.NORTH); - this.generateButton = new JButton("Generate", MessageDialog.getIcon("generate")); + this.generateButton = new JButton(getLocalizedMessages().getString(ENTRY_DIALOG_GENERATE_ENTRY), MessageDialog.getIcon("generate")); this.generateButton.setActionCommand("generate_button"); this.generateButton.addActionListener(this); this.generateButton.setMnemonic(KeyEvent.VK_G); @@ -182,15 +198,15 @@ private void initDialog(final Component parent, final boolean showAcceptButton) this.buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); if (showAcceptButton) { - this.acceptButton = new JButton("Accept", MessageDialog.getIcon("accept")); + this.acceptButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_ACCEPT), MessageDialog.getIcon("accept")); this.acceptButton.setActionCommand("accept_button"); this.acceptButton.setMnemonic(KeyEvent.VK_A); this.acceptButton.addActionListener(this); this.buttonPanel.add(this.acceptButton); - this.cancelButton = new JButton("Cancel", MessageDialog.getIcon("cancel")); + this.cancelButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_CANCEL), MessageDialog.getIcon("cancel")); } else { - this.cancelButton = new JButton("Close", MessageDialog.getIcon("close")); + this.cancelButton = new JButton(getLocalizedMessages().getString(BUTTON_MESSAGE_CLOSE), MessageDialog.getIcon("close")); } this.cancelButton.setActionCommand("cancel_button"); @@ -231,7 +247,7 @@ public void actionPerformed(ActionEvent e) { } if (characterSet.isEmpty()) { - MessageDialog.showWarningMessage(this, "Cannot generate password.\nPlease select a character set."); + MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(PASSWORD_CAN_NOT_GENERATE_PASSWORD)); return; } @@ -244,7 +260,7 @@ public void actionPerformed(ActionEvent e) { } else if ("accept_button".equals(command)) { this.generatedPassword = this.passwordField.getText(); if (this.generatedPassword.isEmpty()) { - MessageDialog.showWarningMessage(this, "Please generate a password."); + MessageDialog.showWarningMessage(this, getLocalizedMessages().getString(PASSWORD_GENERATE_PASSWORD_REQUEST)); return; } dispose(); diff --git a/src/main/java/jpass/ui/JPassFrame.java b/src/main/java/jpass/ui/JPassFrame.java index 69008f4b..88b12e07 100644 --- a/src/main/java/jpass/ui/JPassFrame.java +++ b/src/main/java/jpass/ui/JPassFrame.java @@ -43,6 +43,8 @@ import java.util.Collections; import java.util.Comparator; import java.util.List; +import java.util.Locale; +import java.util.ResourceBundle; import java.util.logging.Level; import java.util.logging.Logger; import java.util.stream.Collectors; @@ -63,6 +65,13 @@ import static jpass.ui.MessageDialog.YES_OPTION; import static jpass.ui.MessageDialog.getIcon; import static jpass.ui.MessageDialog.showQuestionMessage; +import static jpass.util.Constants.BOTTOM_MENU_ENTRIES_COUNT; +import static jpass.util.Constants.BOTTOM_MENU_ENTRIES_FOUND; +import static jpass.util.Constants.EDIT_MENU; +import static jpass.util.Constants.FILE_MENU; +import static jpass.util.Constants.HELP_MENU; +import static jpass.util.Constants.PANEL_SAVE_MODIFIED_QUESTION_MESSAGE; +import static jpass.util.Constants.TOOLS_MENU; /** * The main frame for JPass. @@ -72,6 +81,7 @@ */ public final class JPassFrame extends JFrame { + private static ResourceBundle localizedMessages; private static final Logger LOG = Logger.getLogger(JPassFrame.class.getName()); private static JPassFrame instance; @@ -95,7 +105,7 @@ public final class JPassFrame extends JFrame { private final StatusPanel statusPanel; private volatile boolean processing = false; - private JPassFrame(String fileName) { + private JPassFrame(String fileName, Locale locale) { try { setIconImages(Stream.of(16, 20, 32, 40, 64, 80, 128, 160) .map(size -> getIcon("jpass", size, size).getImage()) @@ -104,6 +114,8 @@ private JPassFrame(String fileName) { LOG.log(Level.CONFIG, "Could not set application icon.", e); } + localizedMessages = ResourceBundle.getBundle("resources.languages.languages", locale); + this.toolBar = new JToolBar(); this.toolBar.setFloatable(false); this.toolBar.add(MenuActionType.NEW_FILE.getAction()); @@ -135,7 +147,7 @@ private JPassFrame(String fileName) { this.jpassMenuBar = new JMenuBar(); - this.fileMenu = new JMenu("File"); + this.fileMenu = new JMenu(localizedMessages.getString(FILE_MENU)); this.fileMenu.setMnemonic(KeyEvent.VK_F); this.fileMenu.add(MenuActionType.NEW_FILE.getAction()); this.fileMenu.add(MenuActionType.OPEN_FILE.getAction()); @@ -150,7 +162,7 @@ private JPassFrame(String fileName) { this.fileMenu.add(MenuActionType.EXIT.getAction()); this.jpassMenuBar.add(this.fileMenu); - this.editMenu = new JMenu("Edit"); + this.editMenu = new JMenu(localizedMessages.getString(EDIT_MENU)); this.editMenu.setMnemonic(KeyEvent.VK_E); this.editMenu.add(MenuActionType.ADD_ENTRY.getAction()); this.editMenu.add(MenuActionType.EDIT_ENTRY.getAction()); @@ -164,13 +176,13 @@ private JPassFrame(String fileName) { this.editMenu.add(MenuActionType.FIND_ENTRY.getAction()); this.jpassMenuBar.add(this.editMenu); - this.toolsMenu = new JMenu("Tools"); + this.toolsMenu = new JMenu(localizedMessages.getString(TOOLS_MENU)); this.toolsMenu.setMnemonic(KeyEvent.VK_T); this.toolsMenu.add(MenuActionType.GENERATE_PASSWORD.getAction()); this.toolsMenu.add(MenuActionType.CLEAR_CLIPBOARD.getAction()); this.jpassMenuBar.add(this.toolsMenu); - this.helpMenu = new JMenu("Help"); + this.helpMenu = new JMenu(localizedMessages.getString(HELP_MENU)); this.helpMenu.setMnemonic(KeyEvent.VK_H); this.helpMenu.add(MenuActionType.LICENSE.getAction()); this.helpMenu.addSeparator(); @@ -220,7 +232,8 @@ public static JPassFrame getInstance() { public static synchronized JPassFrame getInstance(String fileName) { if (instance == null) { - instance = new JPassFrame(fileName); + String languageTag = Configuration.getInstance().get("language.languageSetting", "en-US"); + instance = new JPassFrame(fileName, Locale.forLanguageTag(languageTag)); } return instance; } @@ -286,9 +299,9 @@ public void refreshEntryTitleList(String selectTitle) { } if (searchCriteria.isEmpty()) { - this.statusPanel.setText("Entries count: " + entries.size()); + this.statusPanel.setText(String.format("%s: %d", localizedMessages.getString(BOTTOM_MENU_ENTRIES_COUNT), entries.size())); } else { - this.statusPanel.setText("Entries found: " + this.entryDetailsTable.getRowCount() + " / " + entries.size()); + this.statusPanel.setText(String.format("%s: %d / %d", localizedMessages.getString(BOTTOM_MENU_ENTRIES_FOUND), this.entryDetailsTable.getRowCount(), entries.size())); } } @@ -311,7 +324,7 @@ public void exitFrame() { return; } if (this.model.isModified()) { - int option = showQuestionMessage(this, FileHelper.SAVE_MODIFIED_QUESTION_MESSAGE, YES_NO_CANCEL_OPTION); + int option = showQuestionMessage(this, localizedMessages.getString(PANEL_SAVE_MODIFIED_QUESTION_MESSAGE), YES_NO_CANCEL_OPTION); if (option == YES_OPTION) { FileHelper.saveFile(this, false, () -> System.exit(0)); return; @@ -358,4 +371,12 @@ public boolean isProcessing() { public SearchPanel getSearchPanel() { return searchPanel; } + + /** + * Gets the resource bundle for localization + * @return resource bundle + */ + public static ResourceBundle getLocalizedMessages() { + return localizedMessages; + } } diff --git a/src/main/java/jpass/ui/MessageDialog.java b/src/main/java/jpass/ui/MessageDialog.java index 7a974aec..eb249028 100644 --- a/src/main/java/jpass/ui/MessageDialog.java +++ b/src/main/java/jpass/ui/MessageDialog.java @@ -61,6 +61,20 @@ import jpass.util.SpringUtilities; +import static jpass.ui.JPassFrame.getLocalizedMessages; +import static jpass.util.Constants.BUTTON_MESSAGE_CANCEL; +import static jpass.util.Constants.BUTTON_MESSAGE_NO; +import static jpass.util.Constants.BUTTON_MESSAGE_OK; +import static jpass.util.Constants.BUTTON_MESSAGE_YES; +import static jpass.util.Constants.PASSWORD_ENTER_PASSWORD_REQUEST; +import static jpass.util.Constants.PASSWORD_PASSWORDS_NOT_IDENTICAL; +import static jpass.util.Constants.SHOW_MESSAGE_CONFIRMATION; +import static jpass.util.Constants.SHOW_MESSAGE_ERROR; +import static jpass.util.Constants.SHOW_MESSAGE_INFORMATION; +import static jpass.util.Constants.SHOW_MESSAGE_WARNING; +import static jpass.util.Constants.VIEW_WINDOW_PASSWORD; +import static jpass.util.Constants.VIEW_WINDOW_REPEAT; + /** * Utility class for displaying message dialog. * @@ -104,23 +118,23 @@ private void initializeDialog(final Component parent, final Object message, fina JButton defaultButton; switch (optionType) { case YES_NO_OPTION: - defaultButton = createButton("Yes", YES_OPTION, getIcon("accept")); + defaultButton = createButton(getLocalizedMessages().getString(BUTTON_MESSAGE_YES), YES_OPTION, getIcon("accept")); buttonPanel.add(defaultButton); - buttonPanel.add(createButton("No", NO_OPTION, getIcon("close"))); + buttonPanel.add(createButton(getLocalizedMessages().getString(BUTTON_MESSAGE_NO), NO_OPTION, getIcon("close"))); break; case YES_NO_CANCEL_OPTION: - defaultButton = createButton("Yes", YES_OPTION, getIcon("accept")); + defaultButton = createButton(getLocalizedMessages().getString(BUTTON_MESSAGE_YES), YES_OPTION, getIcon("accept")); buttonPanel.add(defaultButton); - buttonPanel.add(createButton("No", NO_OPTION, getIcon("close"))); - buttonPanel.add(createButton("Cancel", CANCEL_OPTION, getIcon("cancel"))); + buttonPanel.add(createButton(getLocalizedMessages().getString(BUTTON_MESSAGE_NO), NO_OPTION, getIcon("close"))); + buttonPanel.add(createButton(getLocalizedMessages().getString(BUTTON_MESSAGE_CANCEL), CANCEL_OPTION, getIcon("cancel"))); break; case OK_CANCEL_OPTION: - defaultButton = createButton("OK", OK_OPTION, getIcon("accept")); + defaultButton = createButton(getLocalizedMessages().getString(BUTTON_MESSAGE_OK), OK_OPTION, getIcon("accept")); buttonPanel.add(defaultButton); - buttonPanel.add(createButton("Cancel", CANCEL_OPTION, getIcon("cancel"))); + buttonPanel.add(createButton(getLocalizedMessages().getString(BUTTON_MESSAGE_CANCEL), CANCEL_OPTION, getIcon("cancel"))); break; default: - defaultButton = createButton("OK", OK_OPTION, getIcon("accept")); + defaultButton = createButton(getLocalizedMessages().getString(BUTTON_MESSAGE_OK), OK_OPTION, getIcon("accept")); buttonPanel.add(defaultButton); break; } @@ -203,7 +217,7 @@ private static int showMessageDialog(final Component parent, final Object messag * @param message dialog message */ public static void showWarningMessage(final Component parent, final String message) { - showMessageDialog(parent, message, "Warning", getIcon("dialog_warning")); + showMessageDialog(parent, message, getLocalizedMessages().getString(SHOW_MESSAGE_WARNING), getIcon("dialog_warning")); } /** @@ -213,7 +227,7 @@ public static void showWarningMessage(final Component parent, final String messa * @param message dialog message */ public static void showErrorMessage(final Component parent, final String message) { - showMessageDialog(parent, message, "Error", getIcon("dialog_error")); + showMessageDialog(parent, message, getLocalizedMessages().getString(SHOW_MESSAGE_ERROR), getIcon("dialog_error")); } /** @@ -223,7 +237,7 @@ public static void showErrorMessage(final Component parent, final String message * @param message dialog message */ public static void showInformationMessage(final Component parent, final String message) { - showMessageDialog(parent, message, "Information", getIcon("dialog_info")); + showMessageDialog(parent, message, getLocalizedMessages().getString(SHOW_MESSAGE_INFORMATION), getIcon("dialog_info")); } /** @@ -235,7 +249,7 @@ public static void showInformationMessage(final Component parent, final String m * @return selected option */ public static int showQuestionMessage(final Component parent, final String message, final int optionType) { - return showMessageDialog(parent, message, "Confirmation", getIcon("dialog_question"), optionType); + return showMessageDialog(parent, message, getLocalizedMessages().getString(SHOW_MESSAGE_CONFIRMATION), getIcon("dialog_question"), optionType); } /** @@ -247,13 +261,13 @@ public static int showQuestionMessage(final Component parent, final String messa */ public static char[] showPasswordDialog(final Component parent, final boolean confirm) { JPanel panel = new JPanel(); - panel.add(new JLabel("Password:")); + panel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_PASSWORD)))); final JPasswordField password = TextComponentFactory.newPasswordField(); panel.add(password); JPasswordField repeat = null; if (confirm) { repeat = TextComponentFactory.newPasswordField(); - panel.add(new JLabel("Repeat:")); + panel.add(new JLabel(String.format("%s:", getLocalizedMessages().getString(VIEW_WINDOW_REPEAT)))); panel.add(repeat); } panel.setLayout(new SpringLayout()); @@ -261,12 +275,12 @@ public static char[] showPasswordDialog(final Component parent, final boolean co boolean incorrect = true; while (incorrect) { - int option = showMessageDialog(parent, panel, "Enter Password", getIcon("dialog_lock"), OK_CANCEL_OPTION); + int option = showMessageDialog(parent, panel, getLocalizedMessages().getString(PASSWORD_ENTER_PASSWORD_REQUEST), getIcon("dialog_lock"), OK_CANCEL_OPTION); if (option == OK_OPTION) { if (password.getPassword().length == 0) { - showWarningMessage(parent, "Please enter a password."); + showWarningMessage(parent, getLocalizedMessages().getString(PASSWORD_ENTER_PASSWORD_REQUEST)); } else if (confirm && !Arrays.equals(password.getPassword(), repeat.getPassword())) { - showWarningMessage(parent, "Password and repeated password are not identical."); + showWarningMessage(parent, getLocalizedMessages().getString(PASSWORD_PASSWORDS_NOT_IDENTICAL)); } else { incorrect = false; } diff --git a/src/main/java/jpass/ui/SearchPanel.java b/src/main/java/jpass/ui/SearchPanel.java index ca5a1ed0..ddd2e97b 100644 --- a/src/main/java/jpass/ui/SearchPanel.java +++ b/src/main/java/jpass/ui/SearchPanel.java @@ -46,6 +46,8 @@ import static javax.swing.KeyStroke.getKeyStroke; import static java.awt.event.KeyEvent.VK_ESCAPE; +import static jpass.ui.JPassFrame.getLocalizedMessages; +import static jpass.util.Constants.PANEL_FIND; /** * Class for representing search panel. Search panel is hidden by default. @@ -71,7 +73,7 @@ public SearchPanel(Consumer searchCallback) { super(new BorderLayout()); setBorder(new EmptyBorder(2, 2, 2, 2)); - this.label = new JLabel("Find: ", MessageDialog.getIcon("find"), SwingConstants.LEADING); + this.label = new JLabel(String.format("%s: ", getLocalizedMessages().getString(PANEL_FIND)), MessageDialog.getIcon("find"), SwingConstants.LEADING); this.criteriaField = TextComponentFactory.newTextField(); diff --git a/src/main/java/jpass/ui/StatusPanel.java b/src/main/java/jpass/ui/StatusPanel.java index 01d6c197..ebc88a5b 100644 --- a/src/main/java/jpass/ui/StatusPanel.java +++ b/src/main/java/jpass/ui/StatusPanel.java @@ -30,10 +30,13 @@ import java.awt.BorderLayout; -import javax.swing.JLabel; -import javax.swing.JPanel; import javax.swing.JProgressBar; import javax.swing.border.EmptyBorder; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import static jpass.ui.JPassFrame.getLocalizedMessages; +import static jpass.util.Constants.PANEL_PROCESSING; /** * Class for representing a status bar. @@ -67,6 +70,6 @@ public String getText() { public void setProcessing(boolean processing) { this.progressBar.setVisible(processing); this.progressBar.setIndeterminate(processing); - setText(processing ? "Processing..." : " "); + setText(processing ? getLocalizedMessages().getString(PANEL_PROCESSING) : " "); } } diff --git a/src/main/java/jpass/ui/action/MenuActionType.java b/src/main/java/jpass/ui/action/MenuActionType.java index 9a28a039..3792ddab 100644 --- a/src/main/java/jpass/ui/action/MenuActionType.java +++ b/src/main/java/jpass/ui/action/MenuActionType.java @@ -41,9 +41,12 @@ import jpass.ui.JPassFrame; import jpass.ui.MessageDialog; import jpass.ui.helper.EntryHelper; +import jpass.util.Constants; import jpass.xml.bind.Entry; import static javax.swing.KeyStroke.getKeyStroke; + +import static jpass.ui.JPassFrame.getLocalizedMessages; import static jpass.ui.helper.FileHelper.exportFile; import static jpass.ui.helper.FileHelper.importFile; import static jpass.ui.helper.FileHelper.openFile; @@ -53,6 +56,28 @@ import static java.awt.event.InputEvent.CTRL_DOWN_MASK; import static java.awt.event.InputEvent.ALT_DOWN_MASK; +import static jpass.util.Constants.PASSWORD_PASSWORD_NOT_MODIFIED; +import static jpass.util.Constants.PASSWORD_SUCCESSFULLY_MODIFIED; +import static jpass.util.Constants.EDIT_MENU_ADD_ENTRY; +import static jpass.util.Constants.EDIT_MENU_CLEAR_CLIPBOARD; +import static jpass.util.Constants.EDIT_MENU_COPY_PASSWORD; +import static jpass.util.Constants.EDIT_MENU_COPY_URL; +import static jpass.util.Constants.EDIT_MENU_COPY_USERNAME; +import static jpass.util.Constants.EDIT_MENU_DELETE_ENTRY; +import static jpass.util.Constants.EDIT_MENU_DUPLICATE_ENTRY; +import static jpass.util.Constants.EDIT_MENU_EDIT_ENTRY; +import static jpass.util.Constants.EDIT_MENU_FIND_ENTRY; +import static jpass.util.Constants.FILE_MENU_CHANGE_PASSWORD; +import static jpass.util.Constants.FILE_MENU_EXIT; +import static jpass.util.Constants.FILE_MENU_EXPORT_TO_XML; +import static jpass.util.Constants.FILE_MENU_IMPORT_FROM_XML; +import static jpass.util.Constants.FILE_MENU_NEW; +import static jpass.util.Constants.FILE_MENU_SAVE; +import static jpass.util.Constants.FILE_MENU_SAVE_AS; +import static jpass.util.Constants.HELP_MENU_ABOUT_JPASS; +import static jpass.util.Constants.HELP_MENU_LICENSE; +import static jpass.util.Constants.TOOLS_MENU_GENERATE_PASSWORD; + /** * Enumeration which holds menu actions and related data. * @@ -60,71 +85,71 @@ * */ public enum MenuActionType { - NEW_FILE(new AbstractMenuAction("New", getIcon("new"), getKeyStroke(KeyEvent.VK_N, CTRL_DOWN_MASK)) { + NEW_FILE(new AbstractMenuAction(getLocalizedMessages().getString(FILE_MENU_NEW), getIcon("new"), getKeyStroke(KeyEvent.VK_N, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { createNew(JPassFrame.getInstance()); } }), - OPEN_FILE(new AbstractMenuAction("Open File...", getIcon("open"), getKeyStroke(KeyEvent.VK_O, CTRL_DOWN_MASK)) { + OPEN_FILE(new AbstractMenuAction(getLocalizedMessages().getString(Constants.FILE_MENU_OPEN_FILE), getIcon("open"), getKeyStroke(KeyEvent.VK_O, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { openFile(JPassFrame.getInstance()); } }), - SAVE_FILE(new AbstractMenuAction("Save", getIcon("save"), getKeyStroke(KeyEvent.VK_S, CTRL_DOWN_MASK)) { + SAVE_FILE(new AbstractMenuAction(getLocalizedMessages().getString(FILE_MENU_SAVE), getIcon("save"), getKeyStroke(KeyEvent.VK_S, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { saveFile(JPassFrame.getInstance(), false); } }), - SAVE_AS_FILE(new AbstractMenuAction("Save As...", getIcon("save_as"), null) { + SAVE_AS_FILE(new AbstractMenuAction(getLocalizedMessages().getString(FILE_MENU_SAVE_AS), getIcon("save_as"), null) { @Override public void actionPerformed(ActionEvent ev) { saveFile(JPassFrame.getInstance(), true); } }), - EXPORT_XML(new AbstractMenuAction("Export to XML...", getIcon("export"), null) { + EXPORT_XML(new AbstractMenuAction(getLocalizedMessages().getString(FILE_MENU_EXPORT_TO_XML), getIcon("export"), null) { @Override public void actionPerformed(ActionEvent ev) { exportFile(JPassFrame.getInstance()); } }), - IMPORT_XML(new AbstractMenuAction("Import from XML...", getIcon("import"), null) { + IMPORT_XML(new AbstractMenuAction(getLocalizedMessages().getString(FILE_MENU_IMPORT_FROM_XML), getIcon("import"), null) { @Override public void actionPerformed(ActionEvent ev) { importFile(JPassFrame.getInstance()); } }), - CHANGE_PASSWORD(new AbstractMenuAction("Change Password...", getIcon("lock"), null) { + CHANGE_PASSWORD(new AbstractMenuAction(getLocalizedMessages().getString(FILE_MENU_CHANGE_PASSWORD), getIcon("lock"), null) { @Override public void actionPerformed(ActionEvent ev) { JPassFrame parent = JPassFrame.getInstance(); char[] password = MessageDialog.showPasswordDialog(parent, true); if (password == null) { - MessageDialog.showInformationMessage(parent, "Password has not been modified."); + MessageDialog.showInformationMessage(parent, getLocalizedMessages().getString(PASSWORD_PASSWORD_NOT_MODIFIED)); } else { parent.getModel().setPassword(password); parent.getModel().setModified(true); parent.refreshFrameTitle(); MessageDialog.showInformationMessage(parent, - "Password has been successfully modified.\n\nSave the file now in order to\nget the new password applied."); + getLocalizedMessages().getString(PASSWORD_SUCCESSFULLY_MODIFIED)); } } }), - GENERATE_PASSWORD(new AbstractMenuAction("Generate Password...", getIcon("generate"), getKeyStroke(KeyEvent.VK_Z, CTRL_DOWN_MASK)) { + GENERATE_PASSWORD(new AbstractMenuAction(getLocalizedMessages().getString(TOOLS_MENU_GENERATE_PASSWORD), getIcon("generate"), getKeyStroke(KeyEvent.VK_Z, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { new GeneratePasswordDialog(JPassFrame.getInstance()); } }), - EXIT(new AbstractMenuAction("Exit", getIcon("exit"), getKeyStroke(KeyEvent.VK_F4, ALT_DOWN_MASK)) { + EXIT(new AbstractMenuAction(getLocalizedMessages().getString(FILE_MENU_EXIT), getIcon("exit"), getKeyStroke(KeyEvent.VK_F4, ALT_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { JPassFrame.getInstance().exitFrame(); } }), - ABOUT(new AbstractMenuAction("About JPass...", getIcon("info"), getKeyStroke(KeyEvent.VK_F1, 0)) { + ABOUT(new AbstractMenuAction(getLocalizedMessages().getString(HELP_MENU_ABOUT_JPASS), getIcon("info"), getKeyStroke(KeyEvent.VK_F1, 0)) { @Override public void actionPerformed(ActionEvent ev) { StringBuilder sb = new StringBuilder(); @@ -137,37 +162,37 @@ public void actionPerformed(ActionEvent ev) { MessageDialog.showInformationMessage(JPassFrame.getInstance(), sb.toString()); } }), - LICENSE(new AbstractMenuAction("License", getIcon("license"), null) { + LICENSE(new AbstractMenuAction(getLocalizedMessages().getString(HELP_MENU_LICENSE), getIcon("license"), null) { @Override public void actionPerformed(ActionEvent ev) { - MessageDialog.showTextFile(JPassFrame.getInstance(), "License", "license.txt"); + MessageDialog.showTextFile(JPassFrame.getInstance(), getLocalizedMessages().getString(HELP_MENU_LICENSE), "license.txt"); } }), - ADD_ENTRY(new AbstractMenuAction("Add Entry...", getIcon("entry_new"), getKeyStroke(KeyEvent.VK_Y, CTRL_DOWN_MASK)) { + ADD_ENTRY(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_ADD_ENTRY), getIcon("entry_new"), getKeyStroke(KeyEvent.VK_Y, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { EntryHelper.addEntry(JPassFrame.getInstance()); } }), - EDIT_ENTRY(new AbstractMenuAction("Edit Entry...", getIcon("entry_edit"), getKeyStroke(KeyEvent.VK_E, CTRL_DOWN_MASK)) { + EDIT_ENTRY(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_EDIT_ENTRY), getIcon("entry_edit"), getKeyStroke(KeyEvent.VK_E, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { EntryHelper.editEntry(JPassFrame.getInstance()); } }), - DUPLICATE_ENTRY(new AbstractMenuAction("Duplicate Entry...", getIcon("entry_duplicate"), getKeyStroke(KeyEvent.VK_K, CTRL_DOWN_MASK)) { + DUPLICATE_ENTRY(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_DUPLICATE_ENTRY), getIcon("entry_duplicate"), getKeyStroke(KeyEvent.VK_K, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { EntryHelper.duplicateEntry(JPassFrame.getInstance()); } }), - DELETE_ENTRY(new AbstractMenuAction("Delete Entry...", getIcon("entry_delete"), getKeyStroke(KeyEvent.VK_D, CTRL_DOWN_MASK)) { + DELETE_ENTRY(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_DELETE_ENTRY), getIcon("entry_delete"), getKeyStroke(KeyEvent.VK_D, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { EntryHelper.deleteEntry(JPassFrame.getInstance()); } }), - COPY_URL(new AbstractMenuAction("Copy URL", getIcon("url"), getKeyStroke(KeyEvent.VK_U, CTRL_DOWN_MASK)) { + COPY_URL(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_COPY_URL), getIcon("url"), getKeyStroke(KeyEvent.VK_U, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { JPassFrame parent = JPassFrame.getInstance(); @@ -177,7 +202,7 @@ public void actionPerformed(ActionEvent ev) { } } }), - COPY_USER(new AbstractMenuAction("Copy User Name", getIcon("user"), getKeyStroke(KeyEvent.VK_B, CTRL_DOWN_MASK)) { + COPY_USER(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_COPY_USERNAME), getIcon("user"), getKeyStroke(KeyEvent.VK_B, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { JPassFrame parent = JPassFrame.getInstance(); @@ -187,7 +212,7 @@ public void actionPerformed(ActionEvent ev) { } } }), - COPY_PASSWORD(new AbstractMenuAction("Copy Password", getIcon("keyring"), getKeyStroke(KeyEvent.VK_C, CTRL_DOWN_MASK)) { + COPY_PASSWORD(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_COPY_PASSWORD), getIcon("keyring"), getKeyStroke(KeyEvent.VK_C, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { JPassFrame parent = JPassFrame.getInstance(); @@ -197,13 +222,13 @@ public void actionPerformed(ActionEvent ev) { } } }), - CLEAR_CLIPBOARD(new AbstractMenuAction("Clear Clipboard", getIcon("clear"), getKeyStroke(KeyEvent.VK_X, CTRL_DOWN_MASK)) { + CLEAR_CLIPBOARD(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_CLEAR_CLIPBOARD), getIcon("clear"), getKeyStroke(KeyEvent.VK_X, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { EntryHelper.copyEntryField(JPassFrame.getInstance(), null); } }), - FIND_ENTRY(new AbstractMenuAction("Find Entry", getIcon("find"), getKeyStroke(KeyEvent.VK_F, CTRL_DOWN_MASK)) { + FIND_ENTRY(new AbstractMenuAction(getLocalizedMessages().getString(EDIT_MENU_FIND_ENTRY), getIcon("find"), getKeyStroke(KeyEvent.VK_F, CTRL_DOWN_MASK)) { @Override public void actionPerformed(ActionEvent ev) { JPassFrame.getInstance().getSearchPanel().setVisible(true); diff --git a/src/main/java/jpass/ui/helper/EntryHelper.java b/src/main/java/jpass/ui/helper/EntryHelper.java index 84ec3095..dd2b9cca 100644 --- a/src/main/java/jpass/ui/helper/EntryHelper.java +++ b/src/main/java/jpass/ui/helper/EntryHelper.java @@ -33,11 +33,17 @@ import jpass.util.ClipboardUtils; import jpass.xml.bind.Entry; +import static jpass.ui.JPassFrame.getLocalizedMessages; import static jpass.ui.MessageDialog.showErrorMessage; import static jpass.ui.MessageDialog.showWarningMessage; import static jpass.ui.MessageDialog.showQuestionMessage; import static jpass.ui.MessageDialog.YES_NO_OPTION; import static jpass.ui.MessageDialog.YES_OPTION; +import static jpass.util.Constants.ENTRY_DIALOG_ADD_NEW_ENTRY; +import static jpass.util.Constants.ENTRY_DIALOG_DUPLICATE_ENTRY; +import static jpass.util.Constants.ENTRY_DIALOG_EDIT_ENTRY; +import static jpass.util.Constants.ENTRY_DIALOG_PLEASE_SELECT_ENTRY; +import static jpass.util.Constants.ENTRY_DIALOG_WANT_DELETE_ENTRY; /** * Helper class for entry operations. @@ -58,10 +64,10 @@ private EntryHelper() { */ public static void deleteEntry(JPassFrame parent) { if (parent.getEntryTitleTable().getSelectedRow() == -1) { - showWarningMessage(parent, "Please select an entry."); + showWarningMessage(parent, getLocalizedMessages().getString(ENTRY_DIALOG_PLEASE_SELECT_ENTRY)); return; } - int option = showQuestionMessage(parent, "Do you really want to delete this entry?", YES_NO_OPTION); + int option = showQuestionMessage(parent, getLocalizedMessages().getString(ENTRY_DIALOG_WANT_DELETE_ENTRY), YES_NO_OPTION); if (option == YES_OPTION) { String title = (String) parent.getEntryTitleTable().getValueAt(parent.getEntryTitleTable().getSelectedRow(), 0); parent.getModel().getEntries().getEntry().remove(parent.getModel().getEntryByTitle(title)); @@ -78,12 +84,12 @@ public static void deleteEntry(JPassFrame parent) { */ public static void duplicateEntry(JPassFrame parent) { if (parent.getEntryTitleTable().getSelectedRow() == -1) { - showWarningMessage(parent, "Please select an entry."); + showWarningMessage(parent, getLocalizedMessages().getString(ENTRY_DIALOG_PLEASE_SELECT_ENTRY)); return; } String title = (String) parent.getEntryTitleTable().getValueAt(parent.getEntryTitleTable().getSelectedRow(), 0); Entry originalEntry = parent.getModel().getEntryByTitle(title); - EntryDialog dialog = new EntryDialog(parent, "Duplicate Entry", originalEntry, true); + EntryDialog dialog = new EntryDialog(parent, getLocalizedMessages().getString(ENTRY_DIALOG_DUPLICATE_ENTRY), originalEntry, true); dialog.getModifiedEntry().ifPresent(entry -> { parent.getModel().getEntries().getEntry().add(entry); parent.getModel().setModified(true); @@ -99,12 +105,12 @@ public static void duplicateEntry(JPassFrame parent) { */ public static void editEntry(JPassFrame parent) { if (parent.getEntryTitleTable().getSelectedRow() == -1) { - showWarningMessage(parent, "Please select an entry."); + showWarningMessage(parent, getLocalizedMessages().getString(ENTRY_DIALOG_PLEASE_SELECT_ENTRY)); return; } String title = (String) parent.getEntryTitleTable().getValueAt(parent.getEntryTitleTable().getSelectedRow(), 0); Entry originalEntry = parent.getModel().getEntryByTitle(title); - EntryDialog dialog = new EntryDialog(parent, "Edit Entry", originalEntry, false); + EntryDialog dialog = new EntryDialog(parent, getLocalizedMessages().getString(ENTRY_DIALOG_EDIT_ENTRY), originalEntry, false); dialog.getModifiedEntry().ifPresent(entry -> { entry.setCreationDate(originalEntry.getCreationDate()); parent.getModel().getEntries().getEntry().remove(originalEntry); @@ -121,7 +127,7 @@ public static void editEntry(JPassFrame parent) { * @param parent parent component */ public static void addEntry(JPassFrame parent) { - EntryDialog dialog = new EntryDialog(parent, "Add New Entry", null, true); + EntryDialog dialog = new EntryDialog(parent, getLocalizedMessages().getString(ENTRY_DIALOG_ADD_NEW_ENTRY), null, true); dialog.getModifiedEntry().ifPresent(entry -> { parent.getModel().getEntries().getEntry().add(entry); parent.getModel().setModified(true); @@ -138,7 +144,7 @@ public static void addEntry(JPassFrame parent) { */ public static Entry getSelectedEntry(JPassFrame parent) { if (parent.getEntryTitleTable().getSelectedRow() == -1) { - showWarningMessage(parent, "Please select an entry."); + showWarningMessage(parent, getLocalizedMessages().getString(ENTRY_DIALOG_PLEASE_SELECT_ENTRY)); return null; } String title = (String) parent.getEntryTitleTable().getValueAt(parent.getEntryTitleTable().getSelectedRow(), 0); diff --git a/src/main/java/jpass/ui/helper/FileHelper.java b/src/main/java/jpass/ui/helper/FileHelper.java index 9a3f3ef6..9ef06da3 100644 --- a/src/main/java/jpass/ui/helper/FileHelper.java +++ b/src/main/java/jpass/ui/helper/FileHelper.java @@ -40,6 +40,7 @@ import jpass.ui.action.Worker; import jpass.util.Configuration; +import static jpass.ui.JPassFrame.getLocalizedMessages; import static jpass.ui.MessageDialog.showPasswordDialog; import static jpass.ui.MessageDialog.showWarningMessage; import static jpass.ui.MessageDialog.showQuestionMessage; @@ -47,6 +48,12 @@ import static jpass.ui.MessageDialog.YES_OPTION; import static jpass.ui.MessageDialog.YES_NO_CANCEL_OPTION; import static jpass.ui.MessageDialog.NO_OPTION; +import static jpass.util.Constants.PANEL_EXPORT; +import static jpass.util.Constants.PANEL_IMPORT; +import static jpass.util.Constants.PANEL_OPEN; +import static jpass.util.Constants.PANEL_SAVE; +import static jpass.util.Constants.PANEL_SAVE_MODIFIED_QUESTION_MESSAGE; +import static jpass.util.Constants.PANEL_UNENCRYPTED_DATA_WARNING_MESSAGE; import static jpass.util.StringUtils.stripString; import static java.lang.String.format; @@ -59,12 +66,6 @@ */ public final class FileHelper { - public static final String SAVE_MODIFIED_QUESTION_MESSAGE - = "The current file has been modified.\n" - + "Do you want to save the changes before closing?"; - private static final String UNENCRYPTED_DATA_WARNING_MESSAGE - = "Please note that all data will be stored unencrypted.\n" - + "Make sure you keep the exported file in a secure location."; private static final String OPEN_ERROR_CHECK_PASSWORD_ERROR_MESSAGE = "An error occured during the open operation.\nThe password might be incorrect.\n(Error: %s)"; private static final String CREATE_FILE_QUESTION_MESSAGE @@ -88,7 +89,7 @@ private FileHelper() { */ public static void createNew(final JPassFrame parent) { if (parent.getModel().isModified()) { - int option = showQuestionMessage(parent, SAVE_MODIFIED_QUESTION_MESSAGE, YES_NO_CANCEL_OPTION); + int option = showQuestionMessage(parent, getLocalizedMessages().getString(PANEL_SAVE_MODIFIED_QUESTION_MESSAGE), YES_NO_CANCEL_OPTION); if (option == YES_OPTION) { saveFile(parent, false, () -> { parent.clearModel(); @@ -111,8 +112,8 @@ public static void createNew(final JPassFrame parent) { * @param parent parent component */ public static void exportFile(final JPassFrame parent) { - showWarningMessage(parent, UNENCRYPTED_DATA_WARNING_MESSAGE); - File file = showFileChooser(parent, "Export", "xml", XML_FILES); + showWarningMessage(parent, getLocalizedMessages().getString(PANEL_UNENCRYPTED_DATA_WARNING_MESSAGE)); + File file = showFileChooser(parent, getLocalizedMessages().getString(PANEL_EXPORT), "xml", XML_FILES); if (file == null) { return; } @@ -140,13 +141,13 @@ protected Void doInBackground() throws Exception { * @param parent parent component */ public static void importFile(final JPassFrame parent) { - File file = showFileChooser(parent, "Import", "xml", XML_FILES); + File file = showFileChooser(parent, getLocalizedMessages().getString(PANEL_IMPORT), "xml", XML_FILES); if (file == null) { return; } final String fileName = file.getPath(); if (parent.getModel().isModified()) { - int option = showQuestionMessage(parent, SAVE_MODIFIED_QUESTION_MESSAGE, YES_NO_CANCEL_OPTION); + int option = showQuestionMessage(parent, getLocalizedMessages().getString(PANEL_SAVE_MODIFIED_QUESTION_MESSAGE), YES_NO_CANCEL_OPTION); if (option == YES_OPTION) { saveFile(parent, false, () -> importFileInBackground(fileName, parent)); return; @@ -205,7 +206,7 @@ public static void saveFile(final JPassFrame parent, final boolean saveAs) { public static void saveFile(final JPassFrame parent, final boolean saveAs, final Runnable successCallback) { final String fileName; if (saveAs || parent.getModel().getFileName() == null) { - File file = showFileChooser(parent, "Save", "jpass", JPASS_DATA_FILES); + File file = showFileChooser(parent, getLocalizedMessages().getString(PANEL_SAVE), "jpass", JPASS_DATA_FILES); if (file == null) { return; } @@ -264,12 +265,12 @@ protected void done() { * @param parent parent component */ public static void openFile(final JPassFrame parent) { - final File file = showFileChooser(parent, "Open", "jpass", JPASS_DATA_FILES); + final File file = showFileChooser(parent, getLocalizedMessages().getString(PANEL_OPEN), "jpass", JPASS_DATA_FILES); if (file == null) { return; } if (parent.getModel().isModified()) { - int option = showQuestionMessage(parent, SAVE_MODIFIED_QUESTION_MESSAGE, YES_NO_CANCEL_OPTION); + int option = showQuestionMessage(parent, getLocalizedMessages().getString(PANEL_SAVE_MODIFIED_QUESTION_MESSAGE), YES_NO_CANCEL_OPTION); if (option == YES_OPTION) { saveFile(parent, false, () -> openFileInBackground(file.getPath(), parent)); return; diff --git a/src/main/java/jpass/util/Constants.java b/src/main/java/jpass/util/Constants.java new file mode 100644 index 00000000..a150f6bb --- /dev/null +++ b/src/main/java/jpass/util/Constants.java @@ -0,0 +1,96 @@ +package jpass.util; + +public final class Constants { + private Constants() { + // not intended to be instantiated + } + + public static final String FILE_MENU = "menuBar.fileMenu"; + public static final String EDIT_MENU = "menuBar.editMenu"; + public static final String TOOLS_MENU = "menuBar.toolsMenu"; + public static final String HELP_MENU = "menuBar.helpMenu"; + + public static final String FILE_MENU_NEW = "fileMenu.new"; + public static final String FILE_MENU_OPEN_FILE = "fileMenu.openFile"; + public static final String FILE_MENU_SAVE = "fileMenu.save"; + public static final String FILE_MENU_SAVE_AS = "fileMenu.saveAs"; + public static final String FILE_MENU_EXPORT_TO_XML = "fileMenu.exportToXML"; + public static final String FILE_MENU_IMPORT_FROM_XML = "fileMenu.importFromXML"; + public static final String FILE_MENU_CHANGE_PASSWORD = "fileMenu.changePassword"; + public static final String FILE_MENU_EXIT = "fileMenu.exitMenu"; + + public static final String PASSWORD_ENTER_PASSWORD_REQUEST = "password.enterPasswordRequest"; + public static final String PASSWORD_GENERATE_PASSWORD_REQUEST = "password.generatePasswordRequest"; + public static final String PASSWORD_PASSWORD_NOT_MODIFIED = "password.passwordNotModified"; + public static final String PASSWORD_SUCCESSFULLY_MODIFIED = "password.successfullyModified"; + public static final String PASSWORD_PASSWORDS_NOT_IDENTICAL = "password.passwordsNotIdentical"; + public static final String PASSWORD_GENERATE_PASSWORD = "password.generatePassword"; + public static final String PASSWORD_PASSWORD_LENGTH = "password.passwordLength"; + public static final String PASSWORD_GENERATED_PASSWORD = "password.generatedPassword"; + public static final String PASSWORD_CAN_NOT_GENERATE_PASSWORD = "password.canNotGeneratePassword"; + + public static final String EDIT_MENU_ADD_ENTRY = "editMenu.addEntry"; + public static final String EDIT_MENU_EDIT_ENTRY = "editMenu.editEntry"; + public static final String EDIT_MENU_DUPLICATE_ENTRY = "editMenu.duplicateEntry"; + public static final String EDIT_MENU_DELETE_ENTRY = "editMenu.deleteEntry"; + public static final String EDIT_MENU_COPY_URL = "editMenu.copyURL"; + public static final String EDIT_MENU_COPY_USERNAME = "editMenu.copyUserName"; + public static final String EDIT_MENU_COPY_PASSWORD = "editMenu.copyPassword"; + public static final String EDIT_MENU_CLEAR_CLIPBOARD = "editMenu.clearClipboard"; + public static final String EDIT_MENU_FIND_ENTRY = "editMenu.findEntry"; + + public static final String TOOLS_MENU_GENERATE_PASSWORD = "toolsMenu.generatePassword"; + + public static final String HELP_MENU_LICENSE = "helpMenu.license"; + public static final String HELP_MENU_ABOUT_JPASS = "helpMenu.aboutJpass"; + + public static final String VIEW_WINDOW_TITLE = "viewWindow.title"; + public static final String VIEW_WINDOW_URL = "viewWindow.url"; + public static final String VIEW_WINDOW_USER = "viewWindow.user"; + public static final String VIEW_WINDOW_USER_NAME = "viewWindow.userName"; + public static final String VIEW_WINDOW_MODIFIED = "viewWindow.modified"; + public static final String VIEW_WINDOW_CREATED = "viewWindow.created"; + public static final String VIEW_WINDOW_PASSWORD = "viewWindow.password"; + public static final String VIEW_WINDOW_REPEAT = "viewWindow.repeat"; + public static final String VIEW_WINDOW_NOTES = "viewWindow.notes"; + public static final String VIEW_WINDOW_SETTINGS = "viewWindow.settings"; + public static final String VIEW_WINDOW_CUSTOM_SYMBOLS = "viewWindow.customSymbols"; + public static final String VIEW_WINDOW_UPPER_CASE_LETTERS = "viewWindow.upperCaseLetters"; + public static final String VIEW_WINDOW_LOWER_CASE_LETTERS = "viewWindow.lowerCaseLetters"; + public static final String VIEW_WINDOW_NUMBERS = "viewWindow.numbers"; + + public static final String SHOW_MESSAGE_INFORMATION = "showMessage.information"; + public static final String SHOW_MESSAGE_CONFIRMATION = "showMessage.confirmation"; + public static final String SHOW_MESSAGE_WARNING = "showMessage.warning"; + public static final String SHOW_MESSAGE_ERROR = "showMessage.error"; + + public static final String BUTTON_MESSAGE_YES = "buttonMessage.yes"; + public static final String BUTTON_MESSAGE_OK = "buttonMessage.ok"; + public static final String BUTTON_MESSAGE_ACCEPT = "buttonMessage.accept"; + public static final String BUTTON_MESSAGE_NO = "buttonMessage.no"; + public static final String BUTTON_MESSAGE_CANCEL = "buttonMessage.cancel"; + public static final String BUTTON_MESSAGE_CLOSE = "buttonMessage.close"; + + public static final String ENTRY_DIALOG_SHOW_ENTRY = "entryDialog.showEntry"; + public static final String ENTRY_DIALOG_GENERATE_ENTRY = "entryDialog.generateEntry"; + public static final String ENTRY_DIALOG_COPY_ENTRY = "entryDialog.copyEntry"; + public static final String ENTRY_DIALOG_FILL_TITLE_FIELD = "entryDialog.fillTitleField"; + public static final String ENTRY_DIALOG_TITLE_ALREADY_EXISTS = "entryDialog.titleAlreadyExists"; + public static final String ENTRY_DIALOG_PLEASE_SELECT_ENTRY = "entryDialog.pleaseSelectEntry"; + public static final String ENTRY_DIALOG_WANT_DELETE_ENTRY = "entryDialog.wantDeleteEntry"; + public static final String ENTRY_DIALOG_DUPLICATE_ENTRY = "entryDialog.duplicateEntry"; + public static final String ENTRY_DIALOG_EDIT_ENTRY = "entryDialog.editEntry"; + public static final String ENTRY_DIALOG_ADD_NEW_ENTRY = "entryDialog.addNewEntry"; + + public static final String BOTTOM_MENU_ENTRIES_COUNT = "bottomMenu.entriesCount"; + public static final String BOTTOM_MENU_ENTRIES_FOUND = "bottomMenu.entriesFound"; + + public static final String PANEL_PROCESSING = "panel.processing"; + public static final String PANEL_FIND = "panel.find"; + public static final String PANEL_EXPORT = "panel.export"; + public static final String PANEL_IMPORT = "panel.import"; + public static final String PANEL_SAVE = "panel.save"; + public static final String PANEL_OPEN = "panel.open"; + public static final String PANEL_SAVE_MODIFIED_QUESTION_MESSAGE = "panel.saveModifiedQuestionMessage"; + public static final String PANEL_UNENCRYPTED_DATA_WARNING_MESSAGE = "panel.unencryptedDataWarningMessage"; +} diff --git a/src/main/resources/resources/languages/languages_en_US.properties b/src/main/resources/resources/languages/languages_en_US.properties new file mode 100644 index 00000000..9dd7bca7 --- /dev/null +++ b/src/main/resources/resources/languages/languages_en_US.properties @@ -0,0 +1,89 @@ +#Strings for Menu Bar en_US locale +menuBar.fileMenu=File +menuBar.editMenu=Edit +menuBar.toolsMenu=Tools +menuBar.helpMenu=Help + +fileMenu.new=New +fileMenu.openFile=Open File... +fileMenu.save=Save +fileMenu.saveAs=Save As... +fileMenu.exportToXML=Export to XML... +fileMenu.importFromXML=Import from XML... +fileMenu.changePassword=Change Password... +fileMenu.exitMenu=Exit + +password.enterPasswordRequest=Please enter a password. +password.generatePasswordRequest=Please generate a password. +password.passwordNotModified=Password has not been modified. +password.successfullyModified=Password has been successfully modified.\n\nSave the file now in order to\nget the new password applied. +password.passwordsNotIdentical=Password and repeated password are not identical. +password.generatePassword=Generate Password +password.passwordLength=Password length +password.generatedPassword=Generated password +password.canNotGeneratePassword=Cannot generate password.\nPlease select a character set. + +editMenu.addEntry=Add Entry... +editMenu.editEntry=Edit Entry... +editMenu.duplicateEntry=Duplicate Entry... +editMenu.deleteEntry=Delete Entry... +editMenu.copyURL=Copy URL +editMenu.copyUserName=Copy Username +editMenu.copyPassword=Copy Password +editMenu.clearClipboard=Clear Clipboard +editMenu.findEntry=Find Entry + +toolsMenu.generatePassword=Generate Password... + +helpMenu.license=License +helpMenu.aboutJpass=About JPass... + +viewWindow.title=Title +viewWindow.url=URL +viewWindow.user=User +viewWindow.userName=User name +viewWindow.modified=Modified +viewWindow.created=Created +viewWindow.password=Password +viewWindow.repeat=Repeat +viewWindow.notes=Notes +viewWindow.settings=Settings +viewWindow.customSymbols=Custom symbols +viewWindow.upperCaseLetters=Upper case letters (A-Z) +viewWindow.lowerCaseLetters=Lower case letters (a-z) +viewWindow.numbers=Numbers (0-9) + +showMessage.information=Information +showMessage.confirmation=Confirmation +showMessage.warning=Warning +showMessage.error=Error + +buttonMessage.yes=Yes +buttonMessage.ok=Ok +buttonMessage.accept=Accept +buttonMessage.no=No +buttonMessage.cancel=Cancel +buttonMessage.close=Close + +entryDialog.showEntry=Show +entryDialog.generateEntry=Generate +entryDialog.copyEntry=Copy +entryDialog.fillTitleField=Please fill the title field. +entryDialog.titleAlreadyExists=Title already exists,\nPlease enter a different title. +entryDialog.pleaseSelectEntry=Please select an entry. +entryDialog.wantDeleteEntry=Do you really want to delete this entry? +entryDialog.duplicateEntry=Duplicate Entry +entryDialog.editEntry=Edit Entry +entryDialog.addNewEntry=Add New Entry + +bottomMenu.entriesCount=Entries count +bottomMenu.entriesFound=Entries found + +panel.processing=Processing... +panel.find=Find +panel.export=Export +panel.import=Import +panel.save=Save +panel.open=Open +panel.saveModifiedQuestionMessage=The current file has been modified.\nDo you want to save the changes before closing? +panel.unencryptedDataWarningMessage=Please note that all data will be stored unencrypted.\nMake sure you keep the exported file in a secure location. diff --git a/src/main/resources/resources/languages/languages_es_MX.properties b/src/main/resources/resources/languages/languages_es_MX.properties new file mode 100644 index 00000000..c2efa1ad --- /dev/null +++ b/src/main/resources/resources/languages/languages_es_MX.properties @@ -0,0 +1,88 @@ +#Strings for Menu Bar es_MX locale +menuBar.fileMenu=Archivo +menuBar.editMenu=Editar +menuBar.toolsMenu=Herramientas +menuBar.helpMenu=Ayuda + +fileMenu.new=Nuevo +fileMenu.openFile=Abrir Archivo... +fileMenu.save=Guardar +fileMenu.saveAs=Guardar Como... +fileMenu.exportToXML=Exportar a XML... +fileMenu.importFromXML=Importar desde XML... +fileMenu.changePassword=Cambiar Contraseña... +fileMenu.exitMenu=Salir + +password.enterPasswordRequest=Por favor, introduce una contraseña. +password.passwordNotModified=La contraseña no ha sido modificada. +password.successfullyModified=La contraseña ha sido modificada exitosamente.\n\nGuarda el archivo ahora para asegurarse que la nueva contraseña fue aplicada. +password.passwordsNotIdentical=La contraseña y contraseña de confirmación no son identicas. +password.generatePassword=Generar Contraseña +password.passwordLength=Tamaño de la contraseña +password.generatedPassword=Contraseña Generada +password.canNotGeneratePassword=No se puede generar la contraseña.\nSeleccione un conjunto de caracteres. + +editMenu.addEntry=Agregar Entrada... +editMenu.editEntry=Editar Entrada... +editMenu.duplicateEntry=Duplicar Entrada... +editMenu.deleteEntry=Remover Entrada... +editMenu.copyURL=Copiar URL +editMenu.copyUserName=Copiar Nombre de Usuario +editMenu.copyPassword=Copiar Contraseña +editMenu.clearClipboard=Limpiar Portapapeles +editMenu.findEntry=Buscar Entrada + +toolsMenu.generatePassword=Generar Contraseña... + +helpMenu.license=Licencia +helpMenu.aboutJpass=Acerca de JPass... + +viewWindow.title=Nombre +viewWindow.url=URL +viewWindow.user=Usuario +viewWindow.userName=Nombre de Usuario +viewWindow.modified=Modificado +viewWindow.created=Creado +viewWindow.password=Contraseña +viewWindow.repeat=Confirmar +viewWindow.notes=Notas +viewWindow.settings=Configuración +viewWindow.customSymbols=Caracteres pesonalizados +viewWindow.upperCaseLetters=Letras mayúsculas (A-Z) +viewWindow.lowerCaseLetters=Letras minúsculas (a-z) +viewWindow.numbers=Números (0-9) + +showMessage.information=Información +showMessage.confirmation=Confirmación +showMessage.warning=Advertencia +showMessage.error=Error + +buttonMessage.yes=Sí +buttonMessage.ok=Aceptar +buttonMessage.accept=Aceptar +buttonMessage.no=No +buttonMessage.cancel=Cancelar +buttonMessage.close=Cerrar + +entryDialog.showEntry=Mostrar +entryDialog.generateEntry=Generar +entryDialog.copyEntry=Copiar +entryDialog.fillTitleField=Please fill the title field. +entryDialog.titleAlreadyExists=El título ya existe,\nPor favor introduzca un título diferente. +entryDialog.pleaseSelectEntry=Por favor, selecciona una entrada. +entryDialog.wantDeleteEntry=¿Realmente quieres eliminar esta entrada? +entryDialog.duplicateEntry=Duplicar Entrada +entryDialog.editEntry=Editar Entrada +entryDialog.addNewEntry=Agregar Nueva Entrada + +bottomMenu.entriesCount=Numero de entradas +bottomMenu.entriesFound=Entradas encontradas + +panel.processing=Procesando... +panel.find=Encontrar +panel.export=Exportar +panel.import=Importar +panel.save=Guardar +panel.open=Abrir +panel.saveModifiedQuestionMessage=El archivo actual ha sido modificado.\n¿Deseas guardar los cambios antes de cerrar el programa? +panel.unencryptedDataWarningMessage=Note que toda la data se almancenará sin cifrar.\nAsegúrese de guardar el archivo exportado en un lugar seguro.