سؤال

I have a class extending jframe with a key binding mapped to an invisible button that does stuff. When I press the key on the keyboard, it executes the command of the button. However, if the user holds the button down, it will execute the command like a hundred times per second, crashing the program. How do I prevent this so that the command only executes... let's say... once per second when the key is pressed down?

Code snippets are as follows:

JButton fire = new JButton("");
KeyStroke spaceBar = KeyStroke.getKeyStroke("SPACE");
FireCommand fc = new FireCommand();
this.fire.setAction(fc);
imap.put(SpaceBar,"space");
amap.put("space",fc);
هل كانت مفيدة؟

المحلول

The solution, on a Windows environment is to have two bindings. One for keyPressed which starts a Timer that continually fires at whatever interval you wish and another for a keyReleased which stops the Timer.

See the last example from Motion Using the Keyboard for a complete example.

I'm not sure if this approach still works on a Mac, because I believe the order of events on a Mac is pressed, released, pressed, released.... when you hold the key down. So the starting/stopping of the Timer may not work as expected.

نصائح أخرى

Add a variable that tracks the last time the button was pressed and add an if into your event handler that does nothing if not enough time has passed. E.g.:

// define last event time somewhere in your GUI
int lastClickTime = 0;

// min delay in milliseconds
static final int minClickDelay = 100;

// ...

// Add a check to the event handler
void onEvent(eventArgs)
{
    int now = System.currentTimeMillis();

    // do nothing, if not enough time has passed
    if (now - lastClickTime < minClickDelay) return;

    // do the real thing here
    doHardWork();
}

Take a look at KeyStroke#getKeyStroke(int, int, boolean), which will allow you to define a key stroke for a key release rather then key press. For example:

KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0, true);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top