4

ほとんどの人がキーリスナーで気付くように、keyPressedメソッドでは、Javaはキーの1回の押下を登録し、約0.5秒間一時停止してから、キーを押したときの安定したストリームを記録します。私の問題は、キーが押されるとすぐに、Javaが定常ストリームのkeyDownイベントをすぐに登録するようにしたいということです。私はこの問題に関する多くの記事を読みました、そしてそれらの多くは私がまた暗闇の中にいるスイングタイマーについて話します。次のコードをより見やすくするために、脂肪を取り除き、キーリスナーを別のクラスに配置しました。これに関するご意見をいただければ幸いです。

public class Keyer implements KeyListener
{

    Keyer(){}
    @Override
    public void keyPressed(KeyEvent ovent)
    {
        int keyCode = ovent.getKeyCode();
        System.out.println("You pressed: "+keyCode);
    }
    @Override
    public void keyReleased(KeyEvent ovent)
    {

    }
    @Override
    public void keyTyped(KeyEvent ovent)
    {

    }
}
4

2 に答える 2

6

これはJavaの問題ではなく、OSの問題だと思います。OSは、キーストロークのストリームを送信する前に、設定された期間、キーストロークの送信を遅らせます。解決策は、キーを押すとスイングタイマーを開始することです。また、KeyListenerではなくKeyBindingsを使用することをお勧めします。

また、Swing Timersについて「暗闇の中で」いると述べています。その場合は、この状況で他の人が行ったことを実行することをお勧めします。関連するチュートリアルを確認してください。グーグルはあなたがそれを非常に速く見つけるのを手伝います。また、このサイトを検索すると、Swing Timerでキーバインディングを使用する例を見つけるのに役立ちます。たとえば、こちらをご覧ください。

Edit
KeyListenerは低レベルの構成であり、一般に、副作用を引き起こしたり問題が発生したりすることなく、より安全で使いやすい高レベルの構成を使用することをお勧めします。たとえば、KeyListenerを使用すると、リッスンされているコンポーネントにフォーカスがある場合にのみ機能するため、フォーカスの問題の問題が発生しやすくなります。代わりにキーバインディングを使用した場合、これは簡単に回避できます。

于 2012-08-24T03:05:18.620 に答える
6

押されたキーがGUIを更新するトリガーである場合は、SwingTimersを組み込む必要があります。GUIの更新がトリガーされない場合は、通常のスレッドを使用できます。

記事が参照していると私が思うのは

  1. を使用して押されたキーを保存するKeyListener
  2. スイングタイマーを使用して、指定された間隔(たとえば100msごと)に押されたキーを確認します

これをどのようにあなたのに組み込むことができるかのサンプルがありますKeyListener

    public class Keyer implements KeyListener{

        /** Stores currently pressed keys */
        HashSet<Integer> pressedKeys = new HashSet<Integer>();

        public Keyer(){

            //Check every 100ms if there's keys pressed
            //(This is the Swing Timer they talk about)
            new Timer(100, new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    String keysString = "";
                    if(!pressedKeys.isEmpty()){
                        Iterator<Integer> i = pressedKeys.iterator();
                        while(i.hasNext()){
                            keysString += i.next() + ",";
                        }
                    } 
                    System.out.println(keysString);
                }
            }).start();
        }

        @Override
        public void keyPressed(KeyEvent ovent){
            //Add key to hashSet when pressed
            int keyCode = ovent.getKeyCode();
            pressedKeys.add(keyCode);
        }
        @Override
        public void keyReleased(KeyEvent ovent){
            //Remove key from hashset when released
            int keyCode = ovent.getKeyCode();
            pressedKeys.remove(keyCode);
        }
        @Override
        public void keyTyped(KeyEvent ovent){}
    }

これがすべてがまとめられたサンプルです-ラベルが更新され、どのキーが押されたかを正確に示します(キーコードによって)。

import java.awt.*;
import java.awt.event.*;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;

public class TempProject extends JPanel{
    /** Label to update with currently pressed keys */
    JLabel output = new JLabel();

    public TempProject(){
        super();
        setFocusable(true);
        add(output, BorderLayout.CENTER);
        requestFocus();
        addKeyListener(new Keyer());
    }

    public static void main(String args[])
    {
        EventQueue.invokeLater(new Runnable()
        {
            public void run()
            {
                JFrame frame = new JFrame();
                frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
                frame.setContentPane(new TempProject());    
                frame.pack();
                frame.setVisible(true);
                new TempProject();
            }
        });
    }

    public class Keyer implements KeyListener{

        /** Stores currently pressed keys */
        HashSet<Integer> pressedKeys = new HashSet<Integer>();

        public Keyer(){

            //Check every 100ms if there's keys pressed
            //(This is the Swing Timer they talk about)
            new Timer(100, new ActionListener(){
                @Override
                public void actionPerformed(ActionEvent arg0) {
                    String keysString = "";
                    if(!pressedKeys.isEmpty()){
                        Iterator<Integer> i = pressedKeys.iterator();
                        while(i.hasNext()){
                            keysString += i.next() + ",";
                        }
                    } 
                    output.setText(keysString);
                }
            }).start();
        }

        @Override
        public void keyPressed(KeyEvent ovent){
            //Add key to hashSet when pressed
            int keyCode = ovent.getKeyCode();
            pressedKeys.add(keyCode);
        }
        @Override
        public void keyReleased(KeyEvent ovent){
            //Remove key from hashset when released
            int keyCode = ovent.getKeyCode();
            pressedKeys.remove(keyCode);
        }
        @Override
        public void keyTyped(KeyEvent ovent){}
    }



}

編集

また、@HovercraftFullOfEelsによって投稿された警告を参照してくださいKeyListener。達成しようとしていることによっては、キーバインディングの使用を検討することをお勧めします(この投稿と同じ原則が適用されます)。ご覧になりたい場合は、キーバインディングに関する便利なチュートリアルをご覧ください。

于 2012-08-24T03:47:16.353 に答える