/* Author: Seren Thompson Created: Dec. 1999 Last modified: June 2001 You may redistribute this code freely provided that you do not charge for it and I am notified of any changes to the code or inclusion of it in other works. If you put this up on a web page, please let me know (I'd like to know where this gets to). Send bug reports via: http://www.seren.net/contact Revisions: June 12: Fixed problem when typing within blocks of text (the cursor would jump around). The problem is actually a bug in Netscape's implementation of java, but a modification of the code works around the problem. Removed the cursor position display. Added undo functionality to the Clear button. */ import java.applet.*; import java.awt.*; import java.awt.event.*; import java.util.*; import java.lang.*; public class KeystrokeConverter extends Applet implements ActionListener, KeyListener, MouseListener{ // Char arrays that list the keys that change between qwerty and dvorak private char qwertyKeys[] = { '-','=','\\', '_','+','|', 'q','w','e','r','t','y','u','i','o','p','[',']', 'Q','W','E','R','T','Y','U','I','O','P','{','}', 'a','s','d','f','g','h','j','k','l',';','\'', 'A','S','D','F','G','H','J','K','L',':','"', 'z','x','c','v','b','n','m',',','.','/', 'Z','X','C','V','B','N','M','<','>','?' }; private char dvorakKeys[] = { '[',']','\\', '{','}','|', '\'',',','.','p','y','f','g','c','r','l','/','=', '"','<','>','P','Y','F','G','C','R','L','?','+', 'a','o','e','u','i','d','h','t','n','s','-', 'A','O','E','U','I','D','H','T','N','S','_', ';','q','j','k','x','b','m','w','v','z', ':','Q','J','K','X','B','M','W','V','Z' }; private Hashtable KeyTable = new Hashtable(); /** GUI components */ TextArea typingArea = new TextArea( "Text in here is converted to dvorak\n\n Click here to start", 12, 70, 1); TextArea keyTypedArea = new TextArea("Text in here is qwerty", 1, 35, 3); Button clearButton = new Button("Clear"); Button undoButton = new Button("Undo"); /** Variables used when converting key strokes */ String keyUnconverted; String keyConverted; /** This is for erasing the instructions the text areas when the user first clicks */ boolean firstClick = true; /** This is for storing text that may be accidentally erased by the user */ String undoBuffer; public void init() { /* * Construct KeyTable. */ /** Check to make sure the character arrays are the same size */ if (qwertyKeys.length != dvorakKeys.length) { System.out.println( "Character maps are different lengths!"); System.exit(0); } /** Convert char arrays to Strings */ String qwertyKeysString = new String( qwertyKeys ); String dvorakKeysString = new String( dvorakKeys ); /* Build a hashtable of the character arrays, using * the qwerty characters as the hash keys. */ for (int i = 0; i < qwertyKeysString.length(); i++ ) { KeyTable.put( String.valueOf(qwertyKeysString.charAt(i)), String.valueOf(dvorakKeysString.charAt(i)) ); } /* * Set up the display area. */ setLayout( new BorderLayout() ); Panel bottom = new Panel(); bottom.setLayout( new BorderLayout() ); add(bottom, "South"); Panel bottomcenter = new Panel(); bottom.add(bottomcenter, "Center"); /** Add components to panels */ add(typingArea, "Center"); bottom.add(keyTypedArea, "West"); bottomcenter.add(undoButton); bottomcenter.add(clearButton); /** Set the typing area to be the only component to accept input */ typingArea.setEditable(true); keyTypedArea.setEditable(false); /** Add listeners to the typing area and buttons */ typingArea.addKeyListener(this); typingArea.addMouseListener(this); clearButton.addActionListener(this); undoButton.addActionListener(this); /** Set the button's action commands */ clearButton.setActionCommand("clear"); undoButton.setActionCommand("undo"); } public void keyTyped( KeyEvent k ) { /* This copies any selected text to the undo buffer in case they scew up * and hit the wrong control key (ex: Ctrl-I instead of Ctrl-C). */ if (k.isControlDown() == true) { undoBuffer = typingArea.getSelectedText(); } /** Replace the typed letter in the key buffer with it's Dvorak counterpart */ try { keyUnconverted = String.valueOf(k.getKeyChar()); // Get the type character as a string. /** Add the qwerty key to the keyTypedArea display */ keyTypedArea.append( String.valueOf(keyUnconverted) ); keyConverted = (String)KeyTable.get( keyUnconverted ); // Returns a one-char string from the hash table. k.setKeyChar( keyConverted.charAt(0) ); // Replace the typed character with the Dvorak one. } catch (Exception e) {} } public void mouseReleased( MouseEvent m ) { /** If they clicked in the typing area, update the location of the cursor */ if (m.getSource() == typingArea) { /** If it's the first click, erase the instructions */ if (firstClick == true) { clearFields(); firstClick = false; } } } public void actionPerformed( ActionEvent e ) { /** If the clear command's recieved, clear the fields */ if (e.getActionCommand().equals("clear")) { clearFields(); } /** If they hit the undo button, insert the undo buffer at the cursor */ if (e.getActionCommand().equals("undo")) { typingArea.insert( undoBuffer, typingArea.getCaretPosition()); } } /** Gotta include these since we implement the KeyListener and MouserListener interfaces */ public void keyPressed( KeyEvent k ) { } public void keyReleased( KeyEvent k ) { } public void mouseClicked( MouseEvent m ) { } public void mousePressed( MouseEvent m ) { } public void mouseEntered( MouseEvent m ) { } public void mouseExited( MouseEvent m ) { } /** This method clears the fields and resets the cursor position display */ private void clearFields() { undoBuffer = typingArea.getText(); //Copy text in case they want to undo typingArea.setText(""); keyTypedArea.setText(""); } }