/* * [Esper.java] * * Summary: Translate Esperanto to English and back with word for word dictionary lookup. * * Copyright: (c) 2000-2017 Roedy Green, Canadian Mind Products, http://mindprod.com * * Licence: This software may be copied and used freely for any purpose but military. * http://mindprod.com/contact/nonmil.html * * Requires: JDK 1.8+ * * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/ * * Version History: * 1.1 2000-08-29 mini dictionary of short words. * 1.2 2000-08-30 colour to encode languages * 1.3 2000-08-31 automatic installers * 1.4 2000-09-05 various locals dictionaries, persistent cache, * persistent unknowns, no prefix/suffix analysis * however, nothing extra for English>Esperanto. * 1.5 2000-09-07 simplify. Combine local dictionaries. * added many rude words. * 1.6 2000-09-10 add Ergane dict Esperanto > English * reorganise logic using AllDicts and Vortaroj * to isolate multidictionary logic * failed attempt at displaying word by word as translation * is generated. * unknown for English>Esperanto * cache for English>Esperanto * 1.7 2000-09-28 added Ergane English>Esperanto dictionary * 1.8 2001-04-27 Web Start install, new InstallAnywhere Now * 1.9 2002-04-21 remove InstallAnywhere, put in package com.mindprod.esper * 2.0 2005-08-03 add about box, ANT builds. * 2.1 2006-03-05 reformat with IntelliJ, add Javadoc * 2.2 2008-04-06 add build to title, tidy code, fix spelling errors. * 2.3 2010-03-23 user selectable look and feel. * 2.4 2011-12-22 update JNLP. */ /* TODO: access more dictionaries access dictionaries in parallel peel off prefix suffix English and Esperanto cx convention at all interfaces give focus to input textbox */ package com.mindprod.esper; import com.mindprod.common18.Build; import com.mindprod.common18.CMPAboutJBox; import com.mindprod.common18.FontFactory; import com.mindprod.common18.HybridJ; import com.mindprod.common18.JEButton; import com.mindprod.common18.Laf; import com.mindprod.common18.VersionCheck; import javax.swing.JApplet; import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JScrollPane; import javax.swing.JTextArea; import java.awt.Color; import java.awt.Container; import java.awt.Font; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Insets; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.StringTokenizer; /** * Translate Esperanto to English and back with word for word dictionary lookup. * * @author Roedy Green, Canadian Mind Products * @version 2.4 2011-12-22 update JNLP. * @since 2000 */ public final class Esper extends JApplet { /** * height of Applet box in pixels. Does not include surrounding frame, includes menu bar. */ private static final int APPLET_HEIGHT = 800; /** * Width of Applet box in pixels. */ private static final int APPLET_WIDTH = 768; private static final int FIRST_COPYRIGHT_YEAR = 2000; /** * embedded copyright not displayed */ private static final String EMBEDDED_COPYRIGHT = "Copyright: (c) 2000-2017 Roedy Green, Canadian Mind Products, http://mindprod.com"; private static final String PUNCTUATION = " +=!@#$%^&*()_-?/|\\\"'<>,.;:`~[]{}\n"; private static final String RELEASE_DATE = "2011-12-22"; private static final String TITLE_STRING = "Esperanta Tradukilo Vortope"; private static final String VERSION_STRING = "2.4"; private static final Color BACKGROUND_FOR_APPLICATION = new Color( 0xffffcc ); private static final Color BACKGROUND_FOR_INPUT = Color.WHITE; private static final Color BACKGROUND_FOR_OUTPUT = new Color( 0xfffacd )/* lemon chiffon */; private static final Color FOREGROUND_FOR_INSTRUCTIONS = new Color( 0x008000 )/* dark green */; private static final Color FOREGROUND_FOR_TEXT = Color.BLACK; /** * for titles */ private static final Color FOREGROUND_FOR_TITLE = new Color( 0xdc143c ); /** * for for titles and About buttons */ private static final Font FONT_FOR_TITLE = FontFactory.build( "Dialog", Font.BOLD, 16 ); /** * for for title second line */ private static final Font FONT_FOR_TITLE2 = FontFactory.build( "Dialog", Font.PLAIN, 14 ); /** * clear screen */ private JButton clear; /** * request translation Esperanto to English */ private JButton toEnglish; /** * request translation English to Esperanto */ private JButton toEsperanto; /** * output translated text, pretty html */ private JEditorPane output; /** * instructions */ private JLabel instructions; /** * title */ private JLabel title; /** * title, second line */ private JLabel title2; /** * allows input text to scroll */ private JScrollPane inputScroll; /** * allows output text to scroll */ private JScrollPane outputScroll; /** * input text to translate */ private JTextArea input; /** * English to Esperanto */ private Lookup allDicts; /** * Esperanto to English */ private Lookup vortaroj; /** * allocate all components */ private void buildComponents() { title = new JLabel( TITLE_STRING + " " + VERSION_STRING, JLabel.CENTER ); title.setFont( FONT_FOR_TITLE ); title.setForeground( FOREGROUND_FOR_TITLE ); title2 = new JLabel( "released:" + RELEASE_DATE + " build:" + Build.BUILD_NUMBER ); title2.setFont( FONT_FOR_TITLE2 ); title2.setForeground( FOREGROUND_FOR_TITLE ); toEnglish = new JEButton( "To English" ); toEnglish.setToolTipText( "Translate Esperanto to English" ); clear = new JEButton( "Clear" ); clear.setToolTipText( "Clear everything" ); toEsperanto = new JEButton( "To Esperanto" ); toEsperanto.setToolTipText( "Translate English to Esperanto" ); input = new JTextArea( ""/* text */, 0/* rows */, 0/* cols */ ); input.setEditable( true ); input.setLineWrap( true ); input.setBackground( BACKGROUND_FOR_INPUT ); input.requestFocus();// does not seem to work // Serif has best chance of supporting Unicode. // So far only NT+Internet Explorer works input.setFont( FontFactory.build( "Serif", Font.PLAIN, 13 ) ); input.setForeground( FOREGROUND_FOR_TEXT ); inputScroll = new JScrollPane( input ); output = new JEditorPane(); output.setContentType( "text/html" ); output.setEditable( false ); // Serif has best chance of supporting Unicode. // So far only NT+Internet Explorer works output.setBackground( BACKGROUND_FOR_OUTPUT ); output.setFont( FontFactory.build( "Serif", Font.PLAIN, 13 ) ); output.setForeground( FOREGROUND_FOR_TEXT ); outputScroll = new JScrollPane( output ); instructions = new JLabel( "Enter simplified English or Esperanto in the top box.", JLabel.CENTER ); instructions.setFont( FontFactory.build( "Dialog", Font.PLAIN, 12 ) ); instructions.setForeground( FOREGROUND_FOR_INSTRUCTIONS ); } /** * build a menu with Look & Feel and About across the top */ private void buildMenu() { // turn on anti-alias System.setProperty( "swing.aatext", "true" ); final JMenuBar menubar = new JMenuBar(); setJMenuBar( menubar ); final JMenu lafMenu = Laf.buildLookAndFeelMenu(); if ( lafMenu != null ) { menubar.add( lafMenu ); } final JMenu menuHelp = new JMenu( "Help" ); menubar.add( menuHelp ); final JMenuItem aboutItem = new JMenuItem( "About" ); menuHelp.add( aboutItem ); aboutItem.addActionListener( new ActionListener() { public void actionPerformed( ActionEvent e ) { // open about frame new CMPAboutJBox( TITLE_STRING, VERSION_STRING, "Translates from English to Esperanto and,", "Esperanto to English in a crude word for word way.", "freeware", RELEASE_DATE, FIRST_COPYRIGHT_YEAR, "Roedy Green", "ESPER", "1.8" ); } } ); } /** * layout Components in a GridBag * * @param contentPane where to place the components */ private void layoutComponents( Container contentPane ) { // rough screen layout // 0------------1-----------2--- // 0 title title2---- ----- // 1 toEnglish Clear toEsperanto // 2 ------------input---------- // 3 ------------output--------- // 4 instructions--------------- // 0------------1-------2 // add // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title, new GridBagConstraints( 0, 0, 1, 1, 0.0, 10.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 10, 10, 5, 5 ), 5, 5 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( title2, new GridBagConstraints( 1, 0, 1, 1, 0.0, 10.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 10, 5, 5, 50 ), 5, 5 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( toEnglish, new GridBagConstraints( 0, 1, 1, 1, 10.0, 10.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 5, 10, 5, 5 ), 10, 10 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( clear, new GridBagConstraints( 1, 1, 1, 1, 10.0, 10.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 5, 5, 5, 5 ), 10, 10 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( toEsperanto, new GridBagConstraints( 2, 1, 1, 1, 10.0, 10.0, GridBagConstraints.EAST, GridBagConstraints.BOTH, new Insets( 5, 5, 5, 10 ), 10, 10 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( inputScroll, new GridBagConstraints( 0, 2, 3, 1, 90.0, 20.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 10, 5, 10 ), 100, 100 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( outputScroll, new GridBagConstraints( 0, 3, 3, 1, 100.0, 80.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 10, 5, 10 ), 300, 300 ) ); // x y w h wtx wty anchor fill T L B R padx pady contentPane.add( instructions, new GridBagConstraints( 0, 4, 3, 1, 90.0, 10.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 5, 10, 10, 10 ), 5, 10 ) ); } /** * translate Esperanto to English */ void translateToEnglish() { // break input up into words. final StringTokenizer t = new StringTokenizer( input.getText(), PUNCTUATION, true ); // StringBuilder to accumulate the translation. final StringBuilder result = new StringBuilder( 10000 ); // this is primitive, being rendered by AWT. result.append( "" ); result.append( "" ); while ( t.hasMoreTokens() ) { String word = t.nextToken(); if ( word.length() == 1 && PUNCTUATION.indexOf( word.charAt( 0 ) ) >= 0 ) { if ( word.charAt( 0 ) == '\n' ) { result.append( "
" ); } else { // we have punctuation, just copy it across. result.append( word ); } } else { // look it up it various dictionaries String translation = vortaroj.lookup( word ); // Later try peeling prefixes and suffixes on failure. if ( translation == null ) { // could not translate word, just copy it across // red indicates failure result.append( "" ); result.append( word ); result.append( "" ); } else { // could translate word. Show original Esperanto=[English] // use colour to separate English=blue and // Esperanto=saddlebrown result.append( "" ); result.append( word ); result.append( "" ); result.append( "=[" ); result.append( translation ); result.append( "]" ); } } // no point in displaying word by work since we are on the repaint // thread. } result.append( "" ); result.append( "" ); output.setText( result.toString() ); } // translateToEnglish /** * translate from English to Esperanto */ void translateToEsperanto() { // break input up into words. final StringTokenizer t = new StringTokenizer( input.getText(), PUNCTUATION, true ); // StringBuilder to accumulate the translation. final StringBuilder result = new StringBuilder( 10000 ); result.append( "" ); result.append( "" ); while ( t.hasMoreTokens() ) { final String word = t.nextToken(); if ( word.length() == 1 && PUNCTUATION.indexOf( word.charAt( 0 ) ) >= 0 ) { if ( word.charAt( 0 ) == '\n' ) { result.append( "
" ); } else { // we have punctuation, just copy it across. result.append( word ); } } else { // look it up it various dictionaries String translation = allDicts.lookup( word ); // Later try peeling prefixes and suffixes on failure, if ( translation == null ) { // could not translate word, just copy it across // red indicates failure result.append( "" ); result.append( word ); result.append( "" ); } else { // We could translate the word. Show original // English=Esperanto // use colour to separate English-blue and // Esperanto brown result.append( "" ); result.append( word ); result.append( "" ); result.append( "=[" ); result.append( translation ); result.append( "]" ); } } // no point in displaying word by word since we are on the repaint // thread. } result.append( "" ); result.append( "" ); output.setText( result.toString() ); } // translateToEsperanto /** * Allow this JApplet to run as as application as well. * * @param args command line arguments ignored. */ public static void main( String args[] ) { HybridJ.fireup( new Esper(), TITLE_STRING + " " + VERSION_STRING, APPLET_WIDTH, APPLET_HEIGHT ); } /** * Called by the browser or Applet viewer to inform * this Applet that it is being reclaimed and that it should destroy * any resources that it has allocated. */ public void destroy() { allDicts = null; clear = null; input = null; inputScroll = null; instructions = null; output = null; outputScroll = null; title = null; title2 = null; toEnglish = null; toEsperanto = null; vortaroj = null; } /** * Called by the browser or Applet viewer to inform * this Applet that it has been loaded into the system. */ @Override public void init() { Container contentPane = getContentPane(); // need 1.5 . if ( !VersionCheck.isJavaVersionOK( 1, 7, 0, contentPane ) ) { // effectively abort return; } buildMenu(); // also initial L&F contentPane.setLayout( new GridBagLayout() ); contentPane.setBackground( BACKGROUND_FOR_APPLICATION ); buildComponents(); layoutComponents( contentPane ); // hook up listener TheListener theListener = new TheListener(); toEnglish.addActionListener( theListener ); toEsperanto.addActionListener( theListener ); clear.addActionListener( theListener ); // get translation lookup objects allDicts = new AllDicts(); allDicts.open(); vortaroj = new Vortaroj(); vortaroj.open(); this.validate(); this.setVisible( true ); } // end init /** * shut down the Applet */ public void stop() { allDicts.close(); vortaroj.close(); } /** * Inner class to act as listener to respond to all end-user actions. */ private final class TheListener implements ActionListener { /** * @inheritDoc */ public void actionPerformed( ActionEvent event ) { final Object object = event.getSource(); if ( object == toEnglish ) { translateToEnglish(); } else if ( object == toEsperanto ) { translateToEsperanto(); } else if ( object == clear ) { input.setText( "" ); output.setText( "" ); } } // end actionPerformed } // end TheListener }