Using Java's Robot to hold a key down

十年热恋 提交于 2019-11-29 12:27:40

If I understand your problem, you can't get key repeats to occur when using Robot and keyPress.

In this case, you may need to produce a "psudo" "long" key press.

Basically, I tried something like this:

Robot bot = new Robot();
bot.setAutoDelay(1);

int duration = 3000;
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < duration) {
    bot.keyPress(KeyEvent.VK_R);
    bot.keyRelease(KeyEvent.VK_R);
}

Which, rapidly pressed and releases the key over a period of time...

And I used this to test it...

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.Robot;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingWorker;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestRobot {

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

    public TestRobot() {
        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 JTextArea ta;

        public TestPane() {

            setLayout(new BorderLayout());
            ta = new JTextArea(20, 20);
            ta.setWrapStyleWord(true);
            ta.setLineWrap(true);
            add(new JScrollPane(ta));

            JButton btn = new JButton("Start");
            btn.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    ta.requestFocusInWindow();
                    ta.append("Start\n");
                    SwingWorker worker = new SwingWorker<Object, Object>() {
                        @Override
                        protected Object doInBackground() throws Exception {

                            Robot bot = new Robot();
                            bot.setAutoDelay(1);

                            int duration = 3000;
                            long start = System.currentTimeMillis();
                            while (System.currentTimeMillis() - start < duration) {
                                bot.keyPress(KeyEvent.VK_R);
                                bot.keyRelease(KeyEvent.VK_R);
                            }
                            return null;

                        }

                        @Override
                        protected void done() {
                            ta.append("\nDone");
                        }
                    };
                    worker.execute();
                }
            });
            add(btn, BorderLayout.SOUTH);

        }
    }
}

Updated

With a little testing, I was able to get this to work...

Robot bot = new Robot();
bot.setAutoDelay(50);

int duration = 3000;
long start = System.currentTimeMillis();
while (System.currentTimeMillis() - start < duration) {
    bot.keyPress(KeyEvent.VK_R);
}
bot.keyRelease(KeyEvent.VK_R);

Now, if you play around with the autoDelay property, you can adjust the time (in milliseconds) between each event, which may produce a more desirable effect...

Why not use a for loop?

for (int i = 0; i < 10; i++)
    rob.keyPress(whatever);

Or, to emulate the hold down effect you want:

rob.keyPress(whatever);
Thread.sleep(500);
for (int i = 0; i < 10; i++) {
    rob.keyPress(whatever);
    Thread.sleep(10);
}

If you want more "organic" behaviour, just randomize the number of iterations.

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!