net.nand.util.i18n.gui
Class PTEMain

java.lang.Object
  extended by java.awt.Component
      extended by java.awt.Container
          extended by java.awt.Window
              extended by java.awt.Frame
                  extended by javax.swing.JFrame
                      extended by net.nand.util.i18n.gui.PTEMain
All Implemented Interfaces:
java.awt.event.ActionListener, java.awt.event.WindowListener, java.awt.image.ImageObserver, java.awt.MenuContainer, java.io.Serializable, java.util.EventListener, javax.accessibility.Accessible, javax.swing.RootPaneContainer, javax.swing.WindowConstants

public class PTEMain
extends javax.swing.JFrame
implements java.awt.event.ActionListener, java.awt.event.WindowListener

Main startup for PropertiesTranslatorEditor. Gives buttons with choice of new, open, open backup, exit. Can browse to both dest + src files, or auto-pick src based on dest filename.

Work in progress. See PropertiesTranslatorEditor for current limitations.

Filename comparisons (source/destination, etc) are case-insensitive to avoid problems on Windows in case of a typo.

Author:
Jeremy D Monin <jeremy@nand.net>
See Also:
Serialized Form

Nested Class Summary
private  class PTEMain.NewDestSrcDialog
          Modal dialog to name a new destination locale file to create and edit, given a source.
private  class PTEMain.OpenDestSrcDialog
          Modal dialog to choose a pair of destination and source locale files to edit.
 
Nested classes/interfaces inherited from class javax.swing.JFrame
javax.swing.JFrame.AccessibleJFrame
 
Nested classes/interfaces inherited from class java.awt.Frame
java.awt.Frame.AccessibleAWTFrame
 
Nested classes/interfaces inherited from class java.awt.Window
java.awt.Window.AccessibleAWTWindow
 
Nested classes/interfaces inherited from class java.awt.Container
java.awt.Container.AccessibleAWTContainer
 
Nested classes/interfaces inherited from class java.awt.Component
java.awt.Component.AccessibleAWTComponent, java.awt.Component.BaselineResizeBehavior, java.awt.Component.BltBufferStrategy, java.awt.Component.FlipBufferStrategy
 
Field Summary
private  long askUnsavedAnsweredAt
          Most recent time when user answered a "Save before exiting?" dialog with Yes or No (not with Cancel exit), from System.currentTimeMillis(), or 0.
private  javax.swing.JButton bAbout
           
private  javax.swing.JButton bExit
           
private  javax.swing.JButton bNewDest
           
private  javax.swing.JButton bOpenDest
           
private  javax.swing.JButton bOpenDestSrc
           
private  javax.swing.JPanel btns
           
private static java.lang.String LAST_EDITED_DIR
          Preferences key in userPrefs for directory of the most recently edited properties file.
private  java.io.File lastEditedDir
          'Current' directory for open/save dialogs, from LAST_EDITED_DIR, or null.
private  java.util.ArrayList<PropertiesTranslatorEditor> ptes
          Editors we've opened; tracked here for unsaved changes before exit.
private static StringManager strings
          i18n text strings, taken from PropertiesTranslatorEditor.strings; if that's null, call PropertiesTranslatorEditor.initStringManager() to initialize.
private  java.util.prefs.Preferences userPrefs
          Persistently stored user preferences between runs, such as LAST_EDITED_DIR.
 
Fields inherited from class javax.swing.JFrame
accessibleContext, EXIT_ON_CLOSE, rootPane, rootPaneCheckingEnabled
 
Fields inherited from class java.awt.Frame
CROSSHAIR_CURSOR, DEFAULT_CURSOR, E_RESIZE_CURSOR, HAND_CURSOR, ICONIFIED, MAXIMIZED_BOTH, MAXIMIZED_HORIZ, MAXIMIZED_VERT, MOVE_CURSOR, N_RESIZE_CURSOR, NE_RESIZE_CURSOR, NORMAL, NW_RESIZE_CURSOR, S_RESIZE_CURSOR, SE_RESIZE_CURSOR, SW_RESIZE_CURSOR, TEXT_CURSOR, W_RESIZE_CURSOR, WAIT_CURSOR
 
Fields inherited from class java.awt.Component
BOTTOM_ALIGNMENT, CENTER_ALIGNMENT, LEFT_ALIGNMENT, RIGHT_ALIGNMENT, TOP_ALIGNMENT
 
Fields inherited from interface javax.swing.WindowConstants
DISPOSE_ON_CLOSE, DO_NOTHING_ON_CLOSE, HIDE_ON_CLOSE
 
Fields inherited from interface java.awt.image.ImageObserver
ABORT, ALLBITS, ERROR, FRAMEBITS, HEIGHT, PROPERTIES, SOMEBITS, WIDTH
 
Constructor Summary
PTEMain()
          Initialize layout and fields.
 
Method Summary
 void actionPerformed(java.awt.event.ActionEvent e)
          Handle button clicks.
private static javax.swing.JButton addBtn(java.awt.Container btns, java.awt.event.ActionListener lsnr, java.lang.String label, int vkN)
          Add this button to the layout.
private static void addToGrid(java.awt.Container ct, java.awt.GridBagLayout gbl, java.awt.GridBagConstraints gbc, java.awt.Component cmp)
          Add this component to a container which uses GridBagLayout.
private  void askUnsaved(java.util.ArrayList<PropertiesTranslatorEditor> unsavedPTE)
          For any editors with unsaved changes, ask the user if they want to save, discard, or cancel exit.
private  java.util.ArrayList<PropertiesTranslatorEditor> checkUnsaved()
          Check all open editors' PropertiesTranslatorEditor.hasUnsavedChanges() and return any.
private  java.io.File chooseFile(boolean forNew, java.lang.String title)
          Choose a file to open or save.
private  void clickedNewDest()
          Handle a click on the "New Destination..." button.
private  void clickedOpenDestSrc()
          Handle a click on the "Open Destination + Source" button.
 void initAndShow()
          Pack and make visible.
static void main(java.lang.String[] args)
          If there's 1 or 2 properties files on the command line, try to open it.
 void openPropsEditor(java.io.File chooseFileSrc, java.io.File chooseFileDest, boolean isNew, java.util.List<java.lang.String> newDestComments)
          Open these file(s) in a PropertiesTranslatorEditor.
(package private) static void showAbout(javax.swing.JFrame parent)
          Show the PropertiesTranslatorEditor "About" dialog.
 boolean tryEditFromDestOnly(java.io.File dest, javax.swing.JFrame parent)
          Try to edit a destination file by finding its matching source file's name via the PropertiesTranslatorEditor(File) constructor.
private  void tryGetLastEditedDir()
          If possible, reads from persistent userPrefs and changes 'current' directory field (lastEditedDir) to that of the most recently edited destination properties file.
private  void trySetDirMostRecent()
          Store 'current' directory lastEditedDir to loaded userPrefs preferences.
 void windowActivated(java.awt.event.WindowEvent e)
           
 void windowClosed(java.awt.event.WindowEvent e)
           
 void windowClosing(java.awt.event.WindowEvent e)
          Check if any editor has unsaved changes.
 void windowDeactivated(java.awt.event.WindowEvent e)
           
 void windowDeiconified(java.awt.event.WindowEvent e)
           
 void windowIconified(java.awt.event.WindowEvent e)
           
 void windowOpened(java.awt.event.WindowEvent e)
           
 
Methods inherited from class javax.swing.JFrame
addImpl, createRootPane, frameInit, getAccessibleContext, getContentPane, getDefaultCloseOperation, getGlassPane, getGraphics, getJMenuBar, getLayeredPane, getRootPane, getTransferHandler, isDefaultLookAndFeelDecorated, isRootPaneCheckingEnabled, paramString, processWindowEvent, remove, repaint, setContentPane, setDefaultCloseOperation, setDefaultLookAndFeelDecorated, setGlassPane, setIconImage, setJMenuBar, setLayeredPane, setLayout, setRootPane, setRootPaneCheckingEnabled, setTransferHandler, update
 
Methods inherited from class java.awt.Frame
addNotify, getCursorType, getExtendedState, getFrames, getIconImage, getMaximizedBounds, getMenuBar, getState, getTitle, isResizable, isUndecorated, remove, removeNotify, setCursor, setExtendedState, setMaximizedBounds, setMenuBar, setResizable, setState, setTitle, setUndecorated
 
Methods inherited from class java.awt.Window
addPropertyChangeListener, addPropertyChangeListener, addWindowFocusListener, addWindowListener, addWindowStateListener, applyResourceBundle, applyResourceBundle, createBufferStrategy, createBufferStrategy, dispose, getBufferStrategy, getFocusableWindowState, getFocusCycleRootAncestor, getFocusOwner, getFocusTraversalKeys, getGraphicsConfiguration, getIconImages, getInputContext, getListeners, getLocale, getModalExclusionType, getMostRecentFocusOwner, getOwnedWindows, getOwner, getOwnerlessWindows, getToolkit, getWarningString, getWindowFocusListeners, getWindowListeners, getWindows, getWindowStateListeners, hide, isActive, isAlwaysOnTop, isAlwaysOnTopSupported, isFocusableWindow, isFocusCycleRoot, isFocused, isLocationByPlatform, isShowing, pack, paint, postEvent, processEvent, processWindowFocusEvent, processWindowStateEvent, removeWindowFocusListener, removeWindowListener, removeWindowStateListener, reshape, setAlwaysOnTop, setBounds, setBounds, setCursor, setFocusableWindowState, setFocusCycleRoot, setIconImages, setLocationByPlatform, setLocationRelativeTo, setMinimumSize, setModalExclusionType, setSize, setSize, setVisible, show, toBack, toFront
 
Methods inherited from class java.awt.Container
add, add, add, add, add, addContainerListener, applyComponentOrientation, areFocusTraversalKeysSet, countComponents, deliverEvent, doLayout, findComponentAt, findComponentAt, getAlignmentX, getAlignmentY, getComponent, getComponentAt, getComponentAt, getComponentCount, getComponents, getComponentZOrder, getContainerListeners, getFocusTraversalPolicy, getInsets, getLayout, getMaximumSize, getMinimumSize, getMousePosition, getPreferredSize, insets, invalidate, isAncestorOf, isFocusCycleRoot, isFocusTraversalPolicyProvider, isFocusTraversalPolicySet, layout, list, list, locate, minimumSize, paintComponents, preferredSize, print, printComponents, processContainerEvent, remove, removeAll, removeContainerListener, setComponentZOrder, setFocusTraversalKeys, setFocusTraversalPolicy, setFocusTraversalPolicyProvider, setFont, transferFocusBackward, transferFocusDownCycle, validate, validateTree
 
Methods inherited from class java.awt.Component
action, add, addComponentListener, addFocusListener, addHierarchyBoundsListener, addHierarchyListener, addInputMethodListener, addKeyListener, addMouseListener, addMouseMotionListener, addMouseWheelListener, bounds, checkImage, checkImage, coalesceEvents, contains, contains, createImage, createImage, createVolatileImage, createVolatileImage, disable, disableEvents, dispatchEvent, enable, enable, enableEvents, enableInputMethods, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, firePropertyChange, getBackground, getBaseline, getBaselineResizeBehavior, getBounds, getBounds, getColorModel, getComponentListeners, getComponentOrientation, getCursor, getDropTarget, getFocusListeners, getFocusTraversalKeysEnabled, getFont, getFontMetrics, getForeground, getHeight, getHierarchyBoundsListeners, getHierarchyListeners, getIgnoreRepaint, getInputMethodListeners, getInputMethodRequests, getKeyListeners, getLocation, getLocation, getLocationOnScreen, getMouseListeners, getMouseMotionListeners, getMousePosition, getMouseWheelListeners, getName, getParent, getPeer, getPropertyChangeListeners, getPropertyChangeListeners, getSize, getSize, getTreeLock, getWidth, getX, getY, gotFocus, handleEvent, hasFocus, imageUpdate, inside, isBackgroundSet, isCursorSet, isDisplayable, isDoubleBuffered, isEnabled, isFocusable, isFocusOwner, isFocusTraversable, isFontSet, isForegroundSet, isLightweight, isMaximumSizeSet, isMinimumSizeSet, isOpaque, isPreferredSizeSet, isValid, isVisible, keyDown, keyUp, list, list, list, location, lostFocus, mouseDown, mouseDrag, mouseEnter, mouseExit, mouseMove, mouseUp, move, nextFocus, paintAll, prepareImage, prepareImage, printAll, processComponentEvent, processFocusEvent, processHierarchyBoundsEvent, processHierarchyEvent, processInputMethodEvent, processKeyEvent, processMouseEvent, processMouseMotionEvent, processMouseWheelEvent, removeComponentListener, removeFocusListener, removeHierarchyBoundsListener, removeHierarchyListener, removeInputMethodListener, removeKeyListener, removeMouseListener, removeMouseMotionListener, removeMouseWheelListener, removePropertyChangeListener, removePropertyChangeListener, repaint, repaint, repaint, requestFocus, requestFocus, requestFocusInWindow, requestFocusInWindow, resize, resize, setBackground, setComponentOrientation, setDropTarget, setEnabled, setFocusable, setFocusTraversalKeysEnabled, setForeground, setIgnoreRepaint, setLocale, setLocation, setLocation, setMaximumSize, setName, setPreferredSize, show, size, toString, transferFocus, transferFocusUpCycle
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface java.awt.MenuContainer
getFont, postEvent
 

Field Detail

strings

private static StringManager strings
i18n text strings, taken from PropertiesTranslatorEditor.strings; if that's null, call PropertiesTranslatorEditor.initStringManager() to initialize.

Initialization is in PropertiesTranslatorEditor because the editor will always use that class but not always use PTEMain.


ptes

private final java.util.ArrayList<PropertiesTranslatorEditor> ptes
Editors we've opened; tracked here for unsaved changes before exit.


askUnsavedAnsweredAt

private long askUnsavedAnsweredAt
Most recent time when user answered a "Save before exiting?" dialog with Yes or No (not with Cancel exit), from System.currentTimeMillis(), or 0. Set in askUnsaved(ArrayList), checked in windowClosing(WindowEvent).


btns

private final javax.swing.JPanel btns

bNewDest

private javax.swing.JButton bNewDest

bOpenDest

private javax.swing.JButton bOpenDest

bOpenDestSrc

private javax.swing.JButton bOpenDestSrc

bAbout

private javax.swing.JButton bAbout

bExit

private javax.swing.JButton bExit

LAST_EDITED_DIR

private static final java.lang.String LAST_EDITED_DIR
Preferences key in userPrefs for directory of the most recently edited properties file.

See Also:
Constant Field Values

userPrefs

private java.util.prefs.Preferences userPrefs
Persistently stored user preferences between runs, such as LAST_EDITED_DIR. Windows stores these in the registry under HKCU, OSX/Unix under the home directory.


lastEditedDir

private java.io.File lastEditedDir
'Current' directory for open/save dialogs, from LAST_EDITED_DIR, or null. Tracked here because Java has no standard way to change the JVM's current directory. Used and set in chooseFile(boolean, String). Stored between runs within userPrefs.

Constructor Detail

PTEMain

public PTEMain()
Initialize layout and fields. Does not pack or make visible; call initAndShow() for that.

Method Detail

tryEditFromDestOnly

public boolean tryEditFromDestOnly(java.io.File dest,
                                   javax.swing.JFrame parent)
Try to edit a destination file by finding its matching source file's name via the PropertiesTranslatorEditor(File) constructor. If not found, or if it's a source file instead of a destination, displays an error message and returns false. Otherwise calls PropertiesTranslatorEditor.init() to show the pair for editing.

Parameters:
dest - Destination .properties file
parent - Parent for any MessageDialog shown, or null
Returns:
True if found and shown for editing, false if error message shown instead

main

public static void main(java.lang.String[] args)
If there's 1 or 2 properties files on the command line, try to open it. Otherwise, bring up the startup buttons.


showAbout

static void showAbout(javax.swing.JFrame parent)
Show the PropertiesTranslatorEditor "About" dialog. Static to allow calls from any class.

Parameters:
parent - Parent for the dialog, as in JOptionPane.showMessageDialog(java.awt.Component, Object)

initAndShow

public void initAndShow()
Pack and make visible.


openPropsEditor

public void openPropsEditor(java.io.File chooseFileSrc,
                            java.io.File chooseFileDest,
                            boolean isNew,
                            java.util.List<java.lang.String> newDestComments)
Open these file(s) in a PropertiesTranslatorEditor.

Parameters:
chooseFileSrc - Source properties file, or null to determine via the PropertiesTranslatorEditor(File) constructor. If null and not found, displays an error message.
chooseFileDest - Destination properties file; can't be null or returns immediately
isNew - True if chooseFileDest should be created on save. Assumes dest filename follows properties naming standards for language and country/region.
newDestComments - If isNew, any comment lines to use as the initial contents; same format as PropsFileParser.KeyPairLine#comment. Otherwise null.

tryGetLastEditedDir

private void tryGetLastEditedDir()
If possible, reads from persistent userPrefs and changes 'current' directory field (lastEditedDir) to that of the most recently edited destination properties file.

See Also:
trySetDirMostRecent()

trySetDirMostRecent

private void trySetDirMostRecent()
Store 'current' directory lastEditedDir to loaded userPrefs preferences. Catches and ignores SecurityExceptions, because this field is stored only for convenience.

Note: Does not persist to disk; to do so, call userPrefs.flush().

See Also:
tryGetLastEditedDir()

addBtn

private static javax.swing.JButton addBtn(java.awt.Container btns,
                                          java.awt.event.ActionListener lsnr,
                                          java.lang.String label,
                                          int vkN)
Add this button to the layout.

Parameters:
btns - Add to this button panel
lsnr - Add this action listener to the button
label - Button's label
vkN - Shortcut mnemonic from KeyEvent
Returns:
the new button

addToGrid

private static final void addToGrid(java.awt.Container ct,
                                    java.awt.GridBagLayout gbl,
                                    java.awt.GridBagConstraints gbc,
                                    java.awt.Component cmp)
Add this component to a container which uses GridBagLayout.

Parameters:
ct - Container, with gbl as its layout manager
gbl - GridBagLayout used in ct
gbc - Constraints for gbl to be used with ct
cmp - Component to add to ct with constraints gbc

actionPerformed

public void actionPerformed(java.awt.event.ActionEvent e)
Handle button clicks.

Specified by:
actionPerformed in interface java.awt.event.ActionListener

clickedNewDest

private final void clickedNewDest()
Handle a click on the "New Destination..." button. Browse to the source file, then create and show the dialog to name the new destination file with a language + region.


clickedOpenDestSrc

private final void clickedOpenDestSrc()
Handle a click on the "Open Destination + Source" button. Browse to the destination file, then create and show the dialog to choose 2 property files.


chooseFile

private java.io.File chooseFile(boolean forNew,
                                java.lang.String title)
Choose a file to open or save. Uses and updates lastEditedDir. For visual feedback, uses Cursor.WAIT_CURSOR during the delay before the file chooser appears.

Parameters:
forNew - If true, use Save dialog, otherwise Open dialog
title - Optional dialog title, or null for default
Returns:
the chosen file, or null if nothing was chosen

checkUnsaved

private java.util.ArrayList<PropertiesTranslatorEditor> checkUnsaved()
Check all open editors' PropertiesTranslatorEditor.hasUnsavedChanges() and return any.

Returns:
Editors with unsaved changes to src or dest, or null if none
See Also:
askUnsaved(ArrayList)

askUnsaved

private void askUnsaved(java.util.ArrayList<PropertiesTranslatorEditor> unsavedPTE)
For any editors with unsaved changes, ask the user if they want to save, discard, or cancel exit. If not cancelled, sets askUnsavedAnsweredAt and calls windowClosing(null) to exit.

Parameters:
unsavedPTE - List of editors with unsaved changes, from checkUnsaved()

windowClosing

public void windowClosing(java.awt.event.WindowEvent e)
Check if any editor has unsaved changes. If any, call askUnsaved(ArrayList) instead of closing. Save userPrefs if possible, dispose of the main button window, and call System.exit(0).

Specified by:
windowClosing in interface java.awt.event.WindowListener
Parameters:
e - Event, ignored (null is okay)

windowActivated

public void windowActivated(java.awt.event.WindowEvent e)
Specified by:
windowActivated in interface java.awt.event.WindowListener

windowClosed

public void windowClosed(java.awt.event.WindowEvent e)
Specified by:
windowClosed in interface java.awt.event.WindowListener

windowDeactivated

public void windowDeactivated(java.awt.event.WindowEvent e)
Specified by:
windowDeactivated in interface java.awt.event.WindowListener

windowDeiconified

public void windowDeiconified(java.awt.event.WindowEvent e)
Specified by:
windowDeiconified in interface java.awt.event.WindowListener

windowIconified

public void windowIconified(java.awt.event.WindowEvent e)
Specified by:
windowIconified in interface java.awt.event.WindowListener

windowOpened

public void windowOpened(java.awt.event.WindowEvent e)
Specified by:
windowOpened in interface java.awt.event.WindowListener