问题
basically, I have a keylistener code (I am aware of keybindings thank you but I don't need that for my project), and it will re-size the window frame based on what you press. However, when you hold down w, it goes like this w [pause] wwwwwwww and it's noticeable whenever you re-size the window. Can someone help me successfully put timer in my code? I've excluded the import statements but they're all there.
public class KeyFrame extends JFrame implements KeyListener
{
public boolean t = true;
private final HashSet<Integer> pressed = new HashSet<Integer>();
private Timer timer;
public KeyFrame(String name) {
super(name);
}
public void keyTyped(KeyEvent e) {
return;
}
public void keyPressed(KeyEvent e) {
pressed.add(e.getKeyCode());
new Timer(10, new ActionListener(){public void actionPerformed(ActionEvent arg0){}}).start();
if (pressed.size() >= 1) {
for(int code : pressed) {
if(code == KeyEvent.VK_D){
this.setSize(getWidth()+5, getHeight());}
if(code == KeyEvent.VK_A)
this.setSize(getWidth()-5, getHeight());
if(code == KeyEvent.VK_S)
this.setSize(getWidth(), getHeight()+5);
if(code == KeyEvent.VK_W)
this.setSize(getWidth(), getHeight()-5);
}
}
}
public void keyReleased(KeyEvent e) {
pressed.remove(e.getKeyCode());
}
}
回答1:
However, when you hold down w, it goes like this w [pause] wwwwwwww
This is pretty standard operation under most OS's
Don't start the Timer
in KeyPressed
, have the Timer
running independently of the KeyListener
You might also like to put the check for the code into the ActionListener
instead of the keyPressed
method
public class KeyFrame extends JFrame implements KeyListener
{
public boolean t = true;
private final HashSet<Integer> pressed = new HashSet<Integer>();
private Timer timer;
public KeyFrame(String name) {
super(name);
new Timer(10, new ActionListener(){
public void actionPerformed(ActionEvent arg0){
if(pressed.contains(KeyEvent.VK_D)) {
setSize(getWidth()+5, getHeight());
} else if(pressed.contains(KeyEvent.VK_A)) {
setSize(getWidth()-5, getHeight());
} else if(pressed.contains(KeyEvent.VK_S)) {
setSize(getWidth(), getHeight()+5);
} else if(pressed.contains(KeyEvent.VK_W)) {
setSize(getWidth(), getHeight()-5);
}
}
}).start();
}
public void keyTyped(KeyEvent e) {
return;
}
public void keyPressed(KeyEvent e) {
pressed.add(e.getKeyCode());
}
public void keyReleased(KeyEvent e) {
pressed.remove(e.getKeyCode());
}
}
You will also find the Key Bindings will solve the focus related issues associated with KeyListener
which is why we typically recommend it
I am aware of keybindings thank you but I don't need that for my project
Then you should use them, there really isn't any excuse not to
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Delta xDelta;
private Delta yDelta;
public TestPane() {
xDelta = new Delta();
yDelta = new Delta();
bindKeyStrokeTo(WHEN_IN_FOCUSED_WINDOW, "delta.up.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), new DeltaAction(yDelta, -5));
bindKeyStrokeTo(WHEN_IN_FOCUSED_WINDOW, "delta.up.released", KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0, true), new DeltaAction(yDelta));
bindKeyStrokeTo(WHEN_IN_FOCUSED_WINDOW, "delta.down.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), new DeltaAction(yDelta, 5));
bindKeyStrokeTo(WHEN_IN_FOCUSED_WINDOW, "delta.down.released", KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0, true), new DeltaAction(yDelta));
bindKeyStrokeTo(WHEN_IN_FOCUSED_WINDOW, "delta.left.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), new DeltaAction(xDelta, -5));
bindKeyStrokeTo(WHEN_IN_FOCUSED_WINDOW, "delta.left.released", KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0, true), new DeltaAction(xDelta));
bindKeyStrokeTo(WHEN_IN_FOCUSED_WINDOW, "delta.right.pressed", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), new DeltaAction(xDelta, 5));
bindKeyStrokeTo(WHEN_IN_FOCUSED_WINDOW, "delta.right.released", KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0, true), new DeltaAction(xDelta));
Timer timer = new Timer(250, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Window window = SwingUtilities.getWindowAncestor(TestPane.this);
Dimension size = window.getSize();
size.width += xDelta.getValue();
size.height += yDelta.getValue();
window.setSize(size);
}
});
timer.start();
}
public void bindKeyStrokeTo(int condition, String name, KeyStroke keyStroke, Action action) {
InputMap im = getInputMap(condition);
ActionMap am = getActionMap();
im.put(keyStroke, name);
am.put(name, action);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
public class Delta {
private int value;
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
}
public class DeltaAction extends AbstractAction {
private Delta delta;
private int value;
public DeltaAction(Delta delta, int value) {
this.delta = delta;
this.value = value;
}
public DeltaAction(Delta delta) {
this(delta, 0);
}
@Override
public void actionPerformed(ActionEvent e) {
delta.setValue(value);
}
}
}
来源:https://stackoverflow.com/questions/30419775/not-sure-how-to-put-timer-into-my-keylistener-code