java 按下某个键响应,Java Swing:在按下键时执行某些操作

Im using a KeyAdpater to get the events and the method addKeyListener and works fine. The problem is that when a press the key, the action ocurrs only once and not while its being pressed, after 3-4 secs holding down the key the action occurs all the time which is what I want.

I'd want to know if there is good way to do the action all the time the key is being pressed from the very begining, not after 3-4 seconds holding down.

I thought on the next solution, but maybe there is already an implemented way to do it:

public abstract class MyKeyAdapter extends KeyAdapter{

private boolean isPressed = false;

private int pressedKey = 0;

Thread t = new Thread(new Runnable() {

@Override

public void run() {

while(isPressed)

keyPressedAction(pressedKey);

}

});

@Override

public void keyPressed(KeyEvent e) {

if(!isPressed){

pressedKey = e.getKeyCode();

t.start();

}

}

@Override

public void keyReleased(KeyEvent e) {

if(isPressed && e.getKeyCode()==pressedKey)}

isPressed = false;

}

public abstract void keyPressedAction(int key);

}

解决方案

I've had good success with this by using Key Bindings, not a KeyListener, and start a Swing Timer on key press, and then stopping the Timer on Swing release. You can differentiate between the key press and release by passing the correct KeyStroke object into the bound component's InputMap using the KeyStroke.getKeyStroke(int keyCode, int modifiers, boolean onKeyRelease) method found here: KeyStroke API. If the boolean parameter is false, the input will respond to key press, and the converse if the parameter is true.

For a quick and inelegant example:

import java.awt.Color;

import java.awt.Dimension;

import java.awt.Font;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.awt.event.KeyEvent;

import javax.swing.*;

@SuppressWarnings("serial")

public class KeyBindingEg extends JPanel {

private static final String UP_KEY_PRESSED = "up key pressed";

private static final String UP_KEY_RELEASED = "up key released";

private static final int UP_TIMER_DELAY = 200;

private static final Color FLASH_COLOR = Color.red;

private Timer upTimer;

private JLabel label = new JLabel();

public KeyBindingEg() {

label.setFont(label.getFont().deriveFont(Font.BOLD, 32));

label.setOpaque(true);

add(label);

setPreferredSize(new Dimension(400, 300));

int condition = WHEN_IN_FOCUSED_WINDOW;

InputMap inputMap = getInputMap(condition);

ActionMap actionMap = getActionMap();

KeyStroke upKeyPressed = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, false);

KeyStroke upKeyReleased = KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true);

inputMap.put(upKeyPressed, UP_KEY_PRESSED);

inputMap.put(upKeyReleased, UP_KEY_RELEASED);

actionMap.put(UP_KEY_PRESSED, new UpAction(false));

actionMap.put(UP_KEY_RELEASED, new UpAction(true));

}

private class UpAction extends AbstractAction {

private boolean onKeyRelease;

public UpAction(boolean onKeyRelease) {

this.onKeyRelease = onKeyRelease;

}

@Override

public void actionPerformed(ActionEvent evt) {

if (!onKeyRelease) {

if (upTimer != null && upTimer.isRunning()) {

return;

}

System.out.println("key pressed");

label.setText(UP_KEY_PRESSED);

upTimer = new Timer(UP_TIMER_DELAY, new ActionListener() {

@Override

public void actionPerformed(ActionEvent e) {

Color c = label.getBackground();

if (FLASH_COLOR.equals(c)) {

label.setBackground(null);

label.setForeground(Color.black);

} else {

label.setBackground(FLASH_COLOR);

label.setForeground(Color.white);

}

}

});

upTimer.start();

} else {

System.out.println("Key released");

if (upTimer != null && upTimer.isRunning()) {

upTimer.stop();

upTimer = null;

}

label.setText("");

}

}

}

private static void createAndShowGui() {

KeyBindingEg mainPanel = new KeyBindingEg();

JFrame frame = new JFrame("KeyBindingEg");

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

frame.getContentPane().add(mainPanel);

frame.pack();

frame.setLocationByPlatform(true);

frame.setVisible(true);

}

public static void main(String[] args) {

SwingUtilities.invokeLater(new Runnable() {

public void run() {

createAndShowGui();

}

});

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值