Search code examples
javaspecial-charactersawtrobot

Key pressing special characters using Robot class Java


I am writing a program that simply retypes the text from the data file. The program works until it hits its first special character. Here is an example:

data file

Hey what is up?

what i get

Hey what is up (throws illegal argument exception)

Here is my code:


 public static void KeyPresser() throws FileNotFoundException, AWTException {
        Robot robot = new Robot();
        Scanner file = new Scanner(new File("script.dat"));
        while(file.hasNext()) {
            String word = file.nextLine();
            for(int i = 0;i<word.length();i++) {
                char c = word.charAt(i);
                if (Character.isUpperCase(c)) {
                    robot.keyPress(KeyEvent.VK_SHIFT);
                }

                robot.keyPress(Character.toUpperCase(c));
                robot.keyRelease(Character.toUpperCase(c));

                if (Character.isUpperCase(c)) {
                    robot.keyRelease(KeyEvent.VK_SHIFT);
                }
               if(c=='?') {
                   robot.keyPress(KeyEvent.VK_SHIFT);
                   robot.keyPress(KeyEvent.VK_SLASH);
                   robot.keyRelease(KeyEvent.VK_SLASH);
                   robot.keyRelease(KeyEvent.VK_SHIFT);
               }

            }

    }

        }

It types up the letters, but not the special characters? Am I gonna have to use a long switch code? Or is there an easy fix to this? As you can tell I have tried using

                  if(c=='?') {
                   robot.keyPress(KeyEvent.VK_SHIFT);
                   robot.keyPress(KeyEvent.VK_SLASH);
                   robot.keyRelease(KeyEvent.VK_SLASH);
                   robot.keyRelease(KeyEvent.VK_SHIFT); 
}

But that doesnt work, what can i do?


Solution

  • I am writing a program that simply retypes the text from the data file

    Why are you using a Robot to retype the text? Why can't you just insert the text into a document of your text component.

    Am I gonna have to use a long switch code?

    You can use a HashMap to map a key that needs to be shifted with the regular key:

    import java.util.*;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class RobotString extends JPanel
    {
        private static HashMap<Character, Character> keyMap = new HashMap<>();
    
        private JTextField original;
        private JTextField copy;
    
    
        public RobotString()
        {
            setLayout( new BorderLayout() );
    
            original = new JTextField(10);
            add(original, BorderLayout.PAGE_START);
    
            JButton button = new JButton("Use Robot");
            add(button, BorderLayout.CENTER);
            button.addActionListener((e) -> invokeRobot() );
    
            copy = new JTextField(10);
            add(copy, BorderLayout.PAGE_END);
    
            //  Create mapping of keys
    
            keyMap.put('!', '1');
            keyMap.put('@', '2');
            keyMap.put('#', '3');
            keyMap.put(':', ';');
            keyMap.put('?', '/');
        }
    
        private void invokeRobot()
        {
            copy.requestFocusInWindow();
            copy.setText( "" );
    
            try
            {
                Robot robot = new Robot();
    
                char[] letters = original.getText().toCharArray();
    
                for(char letter: letters)
                {
                    boolean shiftRequired = false;
                    Character value = keyMap.get(letter);
    
                    if (value != null)
                    {
                        shiftRequired = true;
                        letter = value;
                    }
                    else if (Character.isUpperCase(letter))
                    {
                        shiftRequired = true;
                    }
    
                    int keyCode = KeyEvent.getExtendedKeyCodeForChar( letter );
    
                    if (shiftRequired)
                        robot.keyPress(java.awt.event.KeyEvent.VK_SHIFT);
    
                    robot.keyPress( keyCode );
                    robot.keyRelease( keyCode );
    
                    if (shiftRequired)
                        robot.keyRelease(java.awt.event.KeyEvent.VK_SHIFT);
                }
            }
            catch(Exception e) { e.printStackTrace(); }
        }
    
        private static void createAndShowGUI()
        {
            JFrame frame = new JFrame("SSCCE");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.add(new RobotString());
            frame.pack();
            frame.setLocationByPlatform( true );
            frame.setVisible( true );
        }
    
        public static void main(String[] args) throws Exception
        {
            java.awt.EventQueue.invokeLater( () -> createAndShowGUI() );
        }
    }
    

    Just type a text string in the top text field and click the button. Note it only supports a few special characters. But note this is not a reliable solution because the mapping depends on the keyboard.

    I know of now way to provide a generic solution for all keyboards.