Added translate from tengwar to english.
This commit is contained in:
parent
b894c67900
commit
8a71899904
|
@ -17,6 +17,7 @@ import java.util.ArrayList;
|
||||||
|
|
||||||
public class Window {
|
public class Window {
|
||||||
|
|
||||||
|
//List of files that can be imported.
|
||||||
public static final List<String> OPEN_FILE_EXTENSIONS = new ArrayList<>();
|
public static final List<String> OPEN_FILE_EXTENSIONS = new ArrayList<>();
|
||||||
|
|
||||||
static {
|
static {
|
||||||
|
@ -39,18 +40,16 @@ public class Window {
|
||||||
|
|
||||||
private boolean isLive = false;
|
private boolean isLive = false;
|
||||||
|
|
||||||
public Window() {
|
Window() {
|
||||||
|
//Load the font into the system.
|
||||||
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||||
Font tengwar_annatar = null;
|
|
||||||
try {
|
try {
|
||||||
tengwar_annatar = Font.createFont(Font.TRUETYPE_FONT, this.getClass().getClassLoader().getResourceAsStream("resources/tngan.ttf"));
|
ge.registerFont(Font.createFont(Font.TRUETYPE_FONT, this.getClass().getClassLoader().getResourceAsStream("resources/tngan.ttf")));
|
||||||
} catch (FontFormatException e) {
|
} catch (FontFormatException e) {
|
||||||
e.printStackTrace();
|
System.err.println("Font format exception!");
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
e.printStackTrace();
|
System.err.println("IOException!");
|
||||||
}
|
}
|
||||||
ge.registerFont(tengwar_annatar);
|
|
||||||
|
|
||||||
//Explicit translation from english to tengwar.
|
//Explicit translation from english to tengwar.
|
||||||
toTengwarButton.addActionListener(new ActionListener() {
|
toTengwarButton.addActionListener(new ActionListener() {
|
||||||
|
@ -59,6 +58,7 @@ public class Window {
|
||||||
tengwarTextArea.setText(Translator.translateToTengwar(inputTextArea.getText()));
|
tengwarTextArea.setText(Translator.translateToTengwar(inputTextArea.getText()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Clear both text areas.
|
//Clear both text areas.
|
||||||
clearButton.addActionListener(new ActionListener() {
|
clearButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -67,10 +67,12 @@ public class Window {
|
||||||
inputTextArea.setText(null);
|
inputTextArea.setText(null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
//Translate tengwar to english.
|
//Translate tengwar to english.
|
||||||
toEnglishButton.addActionListener(new ActionListener() {
|
toEnglishButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
inputTextArea.setText(Translator.translateToEnglish(tengwarTextArea.getText()));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -101,20 +103,31 @@ public class Window {
|
||||||
this.inputTextArea.requestFocus();
|
this.inputTextArea.requestFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
public JPanel getMainPanel(){
|
JPanel getMainPanel(){
|
||||||
return this.mainPanel;
|
return this.mainPanel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the english text is changed, and live is selected, then update the tengwar text.
|
||||||
|
*/
|
||||||
private void onEnglishTextChanged(){
|
private void onEnglishTextChanged(){
|
||||||
if (isLive)
|
if (isLive && inputTextArea.hasFocus())
|
||||||
tengwarTextArea.setText(Translator.translateToTengwar(inputTextArea.getText()));
|
tengwarTextArea.setText(Translator.translateToTengwar(inputTextArea.getText()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If tengwar text is changed, and live is selected, then update the english text.
|
||||||
|
*/
|
||||||
|
private void onTengwarTextChanged(){
|
||||||
|
if (isLive && tengwarTextArea.hasFocus())
|
||||||
|
inputTextArea.setText(Translator.translateToEnglish(tengwarTextArea.getText()));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Toggle the live button and disable translate buttons if needed.
|
* Toggle the live button and disable translate buttons if needed.
|
||||||
* @param e event generated by the check box.
|
* @param e event generated by the check box.
|
||||||
*/
|
*/
|
||||||
public void onLiveToggled(ActionEvent e){
|
void onLiveToggled(ActionEvent e){
|
||||||
if (((JCheckBoxMenuItem) e.getSource()).getState()){
|
if (((JCheckBoxMenuItem) e.getSource()).getState()){
|
||||||
//Deactivate buttons, set live to true.
|
//Deactivate buttons, set live to true.
|
||||||
toTengwarButton.setEnabled(false);
|
toTengwarButton.setEnabled(false);
|
||||||
|
@ -131,7 +144,7 @@ public class Window {
|
||||||
/**
|
/**
|
||||||
* What to do if the user clicks the 'import' button.
|
* What to do if the user clicks the 'import' button.
|
||||||
*/
|
*/
|
||||||
public void onImportClicked(){
|
void onImportClicked(){
|
||||||
JFileChooser fileChooser = new JFileChooser(System.getProperty("user.documents"));
|
JFileChooser fileChooser = new JFileChooser(System.getProperty("user.documents"));
|
||||||
fileChooser.setFileFilter(new FileFilter() {
|
fileChooser.setFileFilter(new FileFilter() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -171,7 +184,7 @@ public class Window {
|
||||||
/**
|
/**
|
||||||
* What to do when the user wants to save their document.
|
* What to do when the user wants to save their document.
|
||||||
*/
|
*/
|
||||||
public void onSaveClicked(){
|
void onSaveClicked(){
|
||||||
JFileChooser fileChooser = new JFileChooser(System.getProperty("user.documents"));
|
JFileChooser fileChooser = new JFileChooser(System.getProperty("user.documents"));
|
||||||
int result = fileChooser.showSaveDialog(this.mainPanel);
|
int result = fileChooser.showSaveDialog(this.mainPanel);
|
||||||
if (result == JFileChooser.APPROVE_OPTION){
|
if (result == JFileChooser.APPROVE_OPTION){
|
||||||
|
@ -186,7 +199,7 @@ public class Window {
|
||||||
/**
|
/**
|
||||||
* Attempt to open the pdf in the browser.
|
* Attempt to open the pdf in the browser.
|
||||||
*/
|
*/
|
||||||
public void onEnglishModeAboutClicked(){
|
void onEnglishModeAboutClicked(){
|
||||||
if (Desktop.isDesktopSupported()){
|
if (Desktop.isDesktopSupported()){
|
||||||
try{
|
try{
|
||||||
Desktop.getDesktop().browse(new URI("https://github.com/andrewlalis/TengwarTranslator/blob/master/src/resources/EnglishOneToOneTengwarV2-1.pdf"));
|
Desktop.getDesktop().browse(new URI("https://github.com/andrewlalis/TengwarTranslator/blob/master/src/resources/EnglishOneToOneTengwarV2-1.pdf"));
|
||||||
|
@ -199,7 +212,7 @@ public class Window {
|
||||||
/**
|
/**
|
||||||
* Attempt to open Tengwar wikipedia page.
|
* Attempt to open Tengwar wikipedia page.
|
||||||
*/
|
*/
|
||||||
public void onTengwarAboutClicked(){
|
void onTengwarAboutClicked(){
|
||||||
if (Desktop.isDesktopSupported()){
|
if (Desktop.isDesktopSupported()){
|
||||||
try{
|
try{
|
||||||
Desktop.getDesktop().browse(new URI("https://en.wikipedia.org/wiki/Tengwar"));
|
Desktop.getDesktop().browse(new URI("https://en.wikipedia.org/wiki/Tengwar"));
|
||||||
|
@ -212,7 +225,7 @@ public class Window {
|
||||||
/**
|
/**
|
||||||
* Attempt to open my github page.
|
* Attempt to open my github page.
|
||||||
*/
|
*/
|
||||||
public void onAboutMeClicked(){
|
void onAboutMeClicked(){
|
||||||
if (Desktop.isDesktopSupported()){
|
if (Desktop.isDesktopSupported()){
|
||||||
try{
|
try{
|
||||||
Desktop.getDesktop().browse(new URI("https://github.com/andrewlalis"));
|
Desktop.getDesktop().browse(new URI("https://github.com/andrewlalis"));
|
||||||
|
|
|
@ -1,28 +1,12 @@
|
||||||
package net.agspace.translate;
|
package net.agspace.translate;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by Andrew's Computer on 23-Apr-17.
|
* Created by Andrew's Computer on 23-Apr-17.
|
||||||
*/
|
*/
|
||||||
public class Translator {
|
public class Translator {
|
||||||
|
|
||||||
private enum CHAR_TYPE {
|
|
||||||
CONSONANT,
|
|
||||||
COMPOUND,
|
|
||||||
ALTERNATE,
|
|
||||||
VOWEL,
|
|
||||||
NUMBER,
|
|
||||||
CARRIER,
|
|
||||||
PUNCTUATION,
|
|
||||||
BAR,
|
|
||||||
S_CURL,
|
|
||||||
UNKNOWN,
|
|
||||||
}
|
|
||||||
|
|
||||||
//Consonant variables.
|
//Consonant variables.
|
||||||
private static final char B = 'w';
|
private static final char B = 'w';
|
||||||
private static final char C = 'c';
|
private static final char C = 'c';
|
||||||
|
@ -184,7 +168,6 @@ public class Translator {
|
||||||
alternateChars.put('s', S_ALT);
|
alternateChars.put('s', S_ALT);
|
||||||
alternateChars.put('z', Z_ALT);
|
alternateChars.put('z', Z_ALT);
|
||||||
alternateChars.put('w', W_ALT);
|
alternateChars.put('w', W_ALT);
|
||||||
//alternateChars.put('r', R_ALT); R alt is used if followed by a vowel.
|
|
||||||
alternateChars.put('y', Y_ALT);
|
alternateChars.put('y', Y_ALT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,6 +355,92 @@ public class Translator {
|
||||||
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
|
return (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a tengwar character is a vowel.
|
||||||
|
* @param c tengwar char to check.
|
||||||
|
* @return true if vowel, false if not.
|
||||||
|
*/
|
||||||
|
private static boolean isVowelTengwar(char c){
|
||||||
|
for (Character[] ch : vowelChars.values()){
|
||||||
|
for (char cha : ch){
|
||||||
|
if (cha == c)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the english vowel representation of a tengwar vowel.
|
||||||
|
* @param tengwarVowel The tengwar vowel to decipher.
|
||||||
|
* @return english vowel char.
|
||||||
|
*/
|
||||||
|
private static char getEnglishVowel(char tengwarVowel){
|
||||||
|
if (!isVowelTengwar(tengwarVowel)){
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
for (Character[] ch : vowelChars.values()){
|
||||||
|
for (char cha : ch){
|
||||||
|
if (cha == tengwarVowel) {
|
||||||
|
return getKeyByValue(vowelChars, ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determines if a tengwar char is a silent E.
|
||||||
|
* @param tengwarChar the tengwar char to evaluate.
|
||||||
|
* @return True if it is a silent E, false otherwise.
|
||||||
|
*/
|
||||||
|
private static boolean isSilentE(char tengwarChar){
|
||||||
|
return tengwarChar == E_UNDER_1
|
||||||
|
|| tengwarChar == E_UNDER_2
|
||||||
|
|| tengwarChar == E_UNDER_3
|
||||||
|
|| tengwarChar == E_UNDER_4
|
||||||
|
|| tengwarChar == E_LAMBE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a character or string that is a literal translation from tengwar.
|
||||||
|
* @param tengwarChar the tengwar char to translate.
|
||||||
|
* @return english representation of the tengwar.
|
||||||
|
*/
|
||||||
|
private static String getEnglishLiteral(char tengwarChar){
|
||||||
|
if (consonantChars.containsValue(tengwarChar)){
|
||||||
|
return getKeyByValue(consonantChars, tengwarChar).toString();
|
||||||
|
} else if (compoundChars.containsValue(tengwarChar)){
|
||||||
|
return getKeyByValue(compoundChars, tengwarChar);
|
||||||
|
} else if (alternateChars.containsValue(tengwarChar)) {
|
||||||
|
return getKeyByValue(alternateChars, tengwarChar).toString();
|
||||||
|
} else if (tengwarChar == R_ALT){
|
||||||
|
return "r";
|
||||||
|
} else if (numberChars.containsValue(tengwarChar)){
|
||||||
|
return getKeyByValue(numberChars, tengwarChar).toString();
|
||||||
|
} else if (punctuationChars.containsValue(tengwarChar)){
|
||||||
|
return getKeyByValue(punctuationChars, tengwarChar).toString();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the key for a specified value in a 1 to 1 map.
|
||||||
|
* @param map The 1 to 1 map to use.
|
||||||
|
* @param value Value to return the key of.
|
||||||
|
* @param <T> Key type of the map.
|
||||||
|
* @param <E> Value type of the map.
|
||||||
|
* @return Key associated with value.
|
||||||
|
*/
|
||||||
|
private static <T, E> T getKeyByValue(Map<T, E> map, E value) {
|
||||||
|
for (Map.Entry<T, E> entry : map.entrySet()) {
|
||||||
|
if (Objects.equals(value, entry.getValue())) {
|
||||||
|
return entry.getKey();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Translate an english string to tengwar.
|
* Translate an english string to tengwar.
|
||||||
* @param englishString english string.
|
* @param englishString english string.
|
||||||
|
@ -380,19 +449,14 @@ public class Translator {
|
||||||
public static String translateToTengwar(String englishString){
|
public static String translateToTengwar(String englishString){
|
||||||
StringBuilder result = new StringBuilder(englishString.length());
|
StringBuilder result = new StringBuilder(englishString.length());
|
||||||
String input = englishString.toLowerCase().trim();
|
String input = englishString.toLowerCase().trim();
|
||||||
|
|
||||||
for (int i = 0; i < input.length(); i++){
|
for (int i = 0; i < input.length(); i++){
|
||||||
//Attempt to get previous, current, and next char.
|
//Attempt to get previous, current, and next char.
|
||||||
char currentChar = input.charAt(i);
|
char currentChar = input.charAt(i);
|
||||||
char previousChar = 0;
|
|
||||||
char nextChar = 0;
|
char nextChar = 0;
|
||||||
try{
|
|
||||||
previousChar = input.charAt(i-1);
|
|
||||||
} catch (IndexOutOfBoundsException e){
|
|
||||||
}
|
|
||||||
try{
|
try{
|
||||||
nextChar = input.charAt(i+1);
|
nextChar = input.charAt(i+1);
|
||||||
} catch (IndexOutOfBoundsException e){
|
} catch (IndexOutOfBoundsException e){
|
||||||
|
//Do nothing, since this may happen.
|
||||||
}
|
}
|
||||||
//Test if the current char is a vowel.
|
//Test if the current char is a vowel.
|
||||||
if (isVowel(currentChar)){
|
if (isVowel(currentChar)){
|
||||||
|
@ -429,6 +493,7 @@ public class Translator {
|
||||||
}
|
}
|
||||||
result.append(tengwarCharToBeAdded);
|
result.append(tengwarCharToBeAdded);
|
||||||
result.append(getAppropriateVowel(tengwarCharToBeAdded, currentChar));
|
result.append(getAppropriateVowel(tengwarCharToBeAdded, currentChar));
|
||||||
|
//Bar gets added after the vowel.
|
||||||
if (needsBar)
|
if (needsBar)
|
||||||
result.append(bars.get(barSizes.get(tengwarCharToBeAdded)));
|
result.append(bars.get(barSizes.get(tengwarCharToBeAdded)));
|
||||||
i++;
|
i++;
|
||||||
|
@ -483,4 +548,61 @@ public class Translator {
|
||||||
}
|
}
|
||||||
return result.toString();
|
return result.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Translates a tengwar string to english.
|
||||||
|
* @param tengwarString tengwar string.
|
||||||
|
* @return english string.
|
||||||
|
*/
|
||||||
|
public static String translateToEnglish(String tengwarString){
|
||||||
|
StringBuilder result = new StringBuilder(tengwarString.length()+tengwarString.length()/2);
|
||||||
|
for (int i = 0; i < tengwarString.length(); i++){
|
||||||
|
char currentChar = tengwarString.charAt(i);
|
||||||
|
char nextChar = 0;
|
||||||
|
char secondNextChar = 0;
|
||||||
|
try{
|
||||||
|
nextChar = tengwarString.charAt(i+1);
|
||||||
|
} catch (IndexOutOfBoundsException e){
|
||||||
|
//Do nothing, this is fine.
|
||||||
|
}
|
||||||
|
try{
|
||||||
|
secondNextChar = tengwarString.charAt(i+2);
|
||||||
|
} catch (IndexOutOfBoundsException e){
|
||||||
|
//Do nothing, this is fine.
|
||||||
|
}
|
||||||
|
String currentLiteral = getEnglishLiteral(currentChar);
|
||||||
|
System.out.println("At: "+i+" Literal: "+currentLiteral);
|
||||||
|
//Check if the current character is a literal translation.
|
||||||
|
if (currentLiteral != null){
|
||||||
|
//Check if the next character is a vowel that should be placed before a character.
|
||||||
|
if (isVowelTengwar(nextChar) && !isSilentE(nextChar)){
|
||||||
|
result.append(getEnglishVowel(nextChar));
|
||||||
|
result.append(currentLiteral);
|
||||||
|
i++;
|
||||||
|
//Check for a double-bar, and then add whatever the current char is.
|
||||||
|
if (bars.contains(secondNextChar)){
|
||||||
|
result.append(currentLiteral);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
} else if (bars.contains(nextChar)){
|
||||||
|
result.append(currentLiteral);
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
//Just append the current literal, no skipping.
|
||||||
|
result.append(currentLiteral);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
//Current character is not a literal translation, so it is an E_UNDER, or carrier.
|
||||||
|
if (carriers.contains(currentChar)){
|
||||||
|
//If carrier, append the following vowel.
|
||||||
|
result.append(getEnglishVowel(nextChar));
|
||||||
|
i++;
|
||||||
|
} else if (isSilentE(currentChar)) {
|
||||||
|
result.append('e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue