/** SwingKeys version 1, prints information about keystrokes. Copyright (C) 2006 Doyle B. Myers This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA As a special exception, Doyle B. Myers gives permission to link this program with The Java platform and distribute the resulting executable, without including the source code for The Java platform in the source distribution. The phrase "The Java platform" specifically means the contents of all java.* packages as provided by Sun for either Commercial Use or under the Sun Community Source Code License. */ package javakeys; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class SwingKeys extends JApplet implements KeyListener, ActionListener, InputMethodListener { private boolean isStandalone = false; private JLabel mTypeHereLabel = new JLabel(); private JTextField mTextTarget = new JTextField(); private TextArea mLogArea = new TextArea(); // use AWT TextArea so we can easily copy from it. private JButton mClearLogButton = new JButton(); private JCheckBox mCheckShowPressed = new JCheckBox(); private JCheckBox mCheckShowTyped = new JCheckBox(); private JCheckBox mCheckShowReleased = new JCheckBox(); private JCheckBox mCheckShowIME = new JCheckBox(); private JLabel mLogLabel = new JLabel(); private JButton mAddMarkButton = new JButton(); private GridBagLayout gridBagLayout1 = new GridBagLayout(); private boolean mUnitTestFormat = true; /** * Get a parameter value. * * @param key Parameter name. * @param def Default value. * @return Value of parameter. May be null. */ public String getParameter( String key, String def ) { return isStandalone ? System.getProperty( key, def ) : ( getParameter( key ) != null ? getParameter( key ) : def ); } /** * Initialize the applet. */ public void init() { try { jbInit(); clearLog(); } catch( Exception e ) { e.printStackTrace(); } } /** * Component initialization. * * @throws Exception */ private void jbInit() throws Exception { mTypeHereLabel.setText( "Type here:" ); Container theContentPane = getContentPane(); theContentPane.setLayout( gridBagLayout1 ); mTextTarget.addKeyListener( this ); mLogArea.setEditable( false ); mClearLogButton.setText( "Clear Log" ); mClearLogButton.addActionListener( this ); mCheckShowPressed.setText( "Pressed" ); mCheckShowPressed.setSelected( true ); mCheckShowTyped.setText( "Typed" ); mCheckShowTyped.setSelected( true ); mCheckShowReleased.setText( "Released" ); mCheckShowReleased.setSelected( true ); mCheckShowIME.setText( "IME" ); mCheckShowIME.setSelected( false ); mCheckShowIME.addActionListener( this ); updateIME(); mLogLabel.setText( "Log:" ); mAddMarkButton.addActionListener( this ); mAddMarkButton.setText( "Mark Log" ); theContentPane.add( mTypeHereLabel, new GridBagConstraints( 0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 12, 12, 0, 0 ), 6, 11 ) ); theContentPane.add( mTextTarget, new GridBagConstraints( 1, 0, GridBagConstraints.REMAINDER, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets( 12, 6, 0, 12 ), 531, 9 ) ); theContentPane.add( mLogLabel, new GridBagConstraints( 0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets( 17, 12, 0, 0 ), 6, 5 ) ); theContentPane.add( mCheckShowPressed, new GridBagConstraints( 1, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 17, 7, 0, 0 ), 6, 2 ) ); theContentPane.add( mCheckShowTyped, new GridBagConstraints( 2, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 17, 10, 0, 0 ), 6, 2 ) ); theContentPane.add( mCheckShowReleased, new GridBagConstraints( 3, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 17, 9, 0, 0 ), 6, 2 ) ); theContentPane.add( mCheckShowIME, new GridBagConstraints( 4, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.NONE, new Insets( 17, 9, 0, 0 ), 6, 2 ) ); theContentPane.add( mAddMarkButton, new GridBagConstraints( 5, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 15, 9, 0, 0 ), 10, -2 ) ); theContentPane.add( mClearLogButton, new GridBagConstraints( 6, 1, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets( 15, 10, 0, 12 ), 10, -2 ) ); theContentPane.add( mLogArea, new GridBagConstraints( 0, 2, GridBagConstraints.REMAINDER, 1, 1.0, 1.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets( 15, 12, 15, 12 ), 592, 339 ) ); } /** * Start the applet. */ public void start() { mTextTarget.requestFocus(); } /** * Stop the applet. */ public void stop() { } /** * Destroy the applet. */ public void destroy() { } /** * Get Applet information. * * @return Applet information. */ public String getAppletInfo() { return "SwingKeys version 1."; } /** * Get applet parameter info. * * @return Null. We don't need no stinkin' parameters. */ public String[][] getParameterInfo() { return null; } /** * Produces a reduced version of KeyEvent.toString without the Component information. * Makes it easier to read the key event information in the log. * * @param e * @return Should be about the same as KeyEvent.toString without Component info. */ private String formatEvent( AWTEvent e ) { StringBuffer sb = new StringBuffer(); if( mUnitTestFormat ) { KeyEvent ke = (KeyEvent)e; sb.append( "generateKeyEvent( " ); // generateKeyEvent( int id, int modifiers, int keyCode, char keyChar, int keyLocation ) // generateKeyEvent( KeyEvent.KEY_PRESSED, 0, 65, 'a', KeyEvent.KEY_LOCATION_STANDARD ); sb.append( ke.getID() ); // PRESSED, etc. sb.append( "," ); sb.append( ke.getModifiers() ); // modifiers sb.append( "," ); sb.append( ke.getKeyCode() ); // key code sb.append( "," ); sb.append( (int)ke.getKeyChar() ); // key char sb.append( "," ); sb.append( ke.getKeyLocation() ); // key location (1.4+) sb.append( " );\t// " ); } // standard event formatting, like KeyEvent.toString sb.append( e.getClass().getName() ); sb.append( "[" ); sb.append( e.paramString() ); sb.append( "] on " ); sb.append( e.getSource().getClass().getName() ); sb.append( " " ); } else { sb.append( "off>" ); } sb.append( "\n" ); return sb.toString(); } /** * Key listener. Reports key pressed events. * * @param e Key event from VM. */ public void keyPressed( KeyEvent e ) { if( mCheckShowPressed.isSelected() ) { mLogArea.append( formatEvent( e ) ); } } /** * Key listener. Reports key typed events. * * @param e Key event from VM. */ public void keyTyped( KeyEvent e ) { if( mCheckShowTyped.isSelected() ) { mLogArea.append( formatEvent( e ) ); } } /** * Key listener. Reports key released events. * * @param e Key event from VM. */ public void keyReleased( KeyEvent e ) { if( mCheckShowReleased.isSelected() ) { mLogArea.append( formatEvent( e ) ); } } /** * Clear the log. */ private void clearLog() { if( mUnitTestFormat ) { StringBuffer sb = new StringBuffer( "// " ); sb.append( System.getProperty( "os.name" ) ); sb.append( " java " ); sb.append( System.getProperty( "java.version" ) ); sb.append( "\n" ); mLogArea.setText( sb.toString() ); } else { mLogArea.setText( "" ); } } /** * Mark the log. */ private void markLog() { mLogArea.append( "------------\n" ); } /** * Listens to mark and clear buttons. * * @param e */ public void actionPerformed( ActionEvent e ) { if( e.getSource() == mAddMarkButton ) { markLog(); } else if( e.getSource() == mClearLogButton ) { clearLog(); } else if( e.getSource() == mCheckShowIME ) { updateIME(); } } /** * IME listener. * * @param event */ public void inputMethodTextChanged( InputMethodEvent event ) { mLogArea.append( formatEvent( event ) ); } /** * IME listener. * * @param event */ public void caretPositionChanged( InputMethodEvent event ) { mLogArea.append( formatEvent( event ) ); } /** * Start or stop listening to IME events according to checkbox setting. * It is necessary to add or remove the IME listener because it changes * which events are delivered, so just not dumping the IME events is * not sufficient. */ private void updateIME() { if( mCheckShowIME.isSelected() ) { // listen to IME events mTextTarget.addInputMethodListener( this ); } else { // stop listening to IME events mTextTarget.removeInputMethodListener( this ); } } }