Not sure how to put timer into my keylistener code

落花浮王杯 提交于 2021-02-10 14:17:43

问题


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

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