0

Hello So I made a java program which display the keyEvent.getKeyCode() each time I press a key.

The purpose was to be able to make some kind of bot able to drive git/skyrim/fraps using the java robot class and some keyEvent.

However it seems that it cannot map AZERTY keyboard, as you can see some keyEvent code are the same.

azerty mapped

is there any other way of driving a keyboard?

Here is the program if you are wondering :

main class :

package keykeykey;
import java.awt.BorderLayout;

import javax.swing.JFrame;
import javax.swing.JTextField;

public class MainClass {
  public static void main(String args[]) throws Exception {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JTextField nameTextField = new JTextField();
    frame.add(nameTextField, BorderLayout.NORTH);

    JTextField codeTextField = new JTextField();
    frame.add(codeTextField, BorderLayout.SOUTH);

    MyKeyListener myKeyListener = new MyKeyListener(codeTextField, nameTextField);
    nameTextField.addKeyListener(myKeyListener);

    frame.setSize(250, 100);
    frame.setVisible(true);
  }
}

keyListener redefinition

package keykeykey;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JTextField;

public class MyKeyListener extends KeyAdapter implements KeyListener {

    public JTextField codeTextField;
    public JTextField writeTextField;

    public MyKeyListener(JTextField codeTextField, JTextField writeTextField) {
        this.codeTextField = codeTextField;
        this.writeTextField = writeTextField;
    }

    @Override
    public void keyPressed(KeyEvent keyEvent) {
    printIt("Pressed", keyEvent);
    codeTextField.setText("code = " + keyEvent.getKeyCode());
  }

  @Override
    public void keyReleased(KeyEvent keyEvent) {
    codeTextField.setText("");
    writeTextField.setText("");
  }

  @Override
    public void keyTyped(KeyEvent keyEvent) {
    //do nothing
  }

  private void printIt(String title, KeyEvent keyEvent) {
    int keyCode = keyEvent.getKeyCode();
    String keyText = KeyEvent.getKeyText(keyCode);
    System.out.println(title + " : " + keyText + " / " + keyEvent.getKeyChar() + " code = " + keyEvent.getKeyCode());
  }

}

Thanks.

Ps : yes I know about autoHotKey, however I need a strongly typed language and I love java.

EDIT

I must have not expressed myself correctly, I know that shift+VK1 makes "1" and the same goes for other keys.

My problem is that, as you can see in the first pictures, some key generate unrecognized key event (the one with red bars).

for example those 2 keys :

unknown key code

Community
  • 1
  • 1
Heetola
  • 5,791
  • 7
  • 30
  • 45
  • So, off the top of my head, shift, alt and CRTL combine together to generate extended key strokes. So shift+vk_1 will generate a key stroke that represents "&". Yu could take a look at [this example](http://stackoverflow.com/questions/14572270/how-can-i-perfectly-simulate-keyevents/14615814#14615814) which converts a String to a series of key strokes to be injected into either the event queue or via Robot – MadProgrammer Sep 03 '13 at 20:23
  • nope, shift+Vk1 generate "1", altGR+VK8 generate "\", this is a problem since there is no access to altGR. plus I absolutly need an acces to "²" which is apparently not possible – Heetola Sep 03 '13 at 21:35
  • That's because you only looking at the key codes. shift+vk_1 will generate the char "&". You need to take into consideration the extended state of the keystroke – MadProgrammer Sep 03 '13 at 22:21

1 Answers1

1

A virtual key can be changed based on the modifiers applied to. The actual result is depended on the keyboard driver itself, but for example...

Shift+1 will generate a KeyEvent whose keyCode is KeyEvent.VK_1, but whose keyChar is !

You are basically ignoring these modifiers...

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestKeyStrokes {

    public static void main(String[] args) {
        new TestKeyStrokes();
    }

    public TestKeyStrokes() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JList keyList;
        private DefaultListModel<String> model;

        public TestPane() {
            setLayout(new BorderLayout());
            model = new DefaultListModel<>();
            keyList = new JList(model);
            add(new JScrollPane(keyList));
            keyList.addKeyListener(new KeyListener() {

                @Override
                public void keyTyped(KeyEvent e) {
                }

                @Override
                public void keyPressed(KeyEvent e) {
                }

                @Override
                public void keyReleased(KeyEvent e) {
                    StringBuilder sb = new StringBuilder(64);
                    if (e.isShiftDown()) {
                        sb.append("[SHIFT]");
                    } else if (e.isAltDown()) {
                        sb.append("[ALT]");
                    } else if (e.isControlDown()) {
                        sb.append("[CTRL]");
                    } else if (e.isAltGraphDown()) {
                        sb.append("[ALT-GRPH]");
                    } else if (e.isMetaDown()) {
                        sb.append("[META]");
                    }
                    switch (e.getKeyCode()) {
                        case KeyEvent.VK_SHIFT:
                        case KeyEvent.VK_ALT:
                        case KeyEvent.VK_CONTROL:
                        case KeyEvent.VK_ALT_GRAPH:
                        case KeyEvent.VK_META:
                            break;
                        default:
                            sb.append("[").append(getVKText(e.getKeyCode())).append("/").append(e.getKeyChar()).append("]");
                            break;
                    }

                    model.addElement(sb.toString());
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(200, 200);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            g2d.dispose();
        }
    }

    private static VKCollection vKCollection;

    static VKCollection getVKCollection() {
        if (vKCollection == null) {
            vKCollection = new VKCollection();
        }
        return vKCollection;
    }

    static String getVKText(int keyCode) {
        VKCollection vkCollect = getVKCollection();
        Integer key = Integer.valueOf(keyCode);
        String name = vkCollect.findName(key);
        if (name != null) {
            return name.substring(3);
        }
        int expected_modifiers
                = (Modifier.PUBLIC | Modifier.STATIC | Modifier.FINAL);

        Field[] fields = KeyEvent.class.getDeclaredFields();
        for (int i = 0; i < fields.length; i++) {
            try {
                if (fields[i].getModifiers() == expected_modifiers
                        && fields[i].getType() == Integer.TYPE
                        && fields[i].getName().startsWith("VK_")
                        && fields[i].getInt(KeyEvent.class) == keyCode) {
                    name = fields[i].getName();
                    vkCollect.put(name, key);
                    return name.substring(3);
                }
            } catch (IllegalAccessException e) {
                assert (false);
            }
        }
        return "UNKNOWN";
    }

    static class VKCollection {

        Map code2name;
        Map name2code;

        public VKCollection() {
            code2name = new HashMap();
            name2code = new HashMap();
        }

        public synchronized void put(String name, Integer code) {
            assert ((name != null) && (code != null));
            assert (findName(code) == null);
            assert (findCode(name) == null);
            code2name.put(code, name);
            name2code.put(name, code);
        }

        public synchronized Integer findCode(String name) {
            assert (name != null);
            return (Integer) name2code.get(name);
        }

        public synchronized String findName(Integer code) {
            assert (code != null);
            return (String) code2name.get(code);
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366