質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

89.53%

keycodeとローマ字入力のエラー

受付中

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,123

lovekasutera

score 5

Javaで各アルファベットの毎のキー入力の時間の平均(押してから離すまで)を計測するアプリケーションをeclipseとSWINGデザイナーで作成しています。
TextFieldに文字を打ち込んでもらい、endキーを押すとそれまでの各キーの平均打鍵計測時間が表示される仕組みです。
半角のアルファベット入力での計測は問題なく出来たのですがカタカナ・ひらがな
ローマ字キーや半角/全角漢字キーを用いて日本語入力を行おうとすると下記のエラーが出てきてしまい計測秒数も明らかに巨大な数字が出てきてしまいます。
日本語入力でも問題なく計測したいのですがどのようにすればよろしいでしょうか?
ご回答お待ちしております。

package pack;

import java.awt.EventQueue;
import java.awt.Font;
import java.awt.TextComponent;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class TypingSample {

    private JFrame frmTypesample;
    long ptime;
    long rtime;
    long[] time = new long[99];
    long[] c = new long [99];
    String userstr;
    public TextComponent textField;
    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    TypingSample window = new TypingSample();
                    window.frmTypesample.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the application.
     */
    public TypingSample() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */

    private void initialize() {
        frmTypesample = new JFrame();
        frmTypesample.setTitle("TypingSample");
        frmTypesample.setBounds(100, 100, 567, 657);
        frmTypesample.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frmTypesample.getContentPane().setLayout(null);

        JLabel Label2 = new JLabel();
        Label2.setFont(new Font("MS UI Gothic", Font.PLAIN,40));
        Label2.setBounds(90, 504, 376, 33);
        frmTypesample.getContentPane().add(Label2);

        JTextField textField = new JTextField();
        textField.setFont(new Font("MS ゴシック", Font.PLAIN, 40));
        textField.setBounds(27, 291, 483, 203);
        frmTypesample.getContentPane().add(textField);
        textField.addKeyListener(new Keyboard_input());


        textField.addActionListener(
                new ActionListener(){
                  public void actionPerformed(ActionEvent e){
                     Label2.setText("");
                      userstr = textField.getText();
                     Label2.setText(userstr);
                     textField.setText("");
                    /* 処理したい内容をここに記述する */
                  }
                }
              );




    }

    class Keyboard_input implements KeyListener
    {
      public void keyPressed(KeyEvent event)
     {
          int KeyCode = event.getKeyCode();
          ptime = System.currentTimeMillis();
          if(KeyCode==35){
              for(int i=65;i<=90;i++){
                  System.out.println(i + ":" + time[i]);
              }
          }

     }


     public void keyReleased(KeyEvent event)
     {
    rtime = System.currentTimeMillis() - ptime;
    int KeyCode = event.getKeyCode();

    c[KeyCode]++;

    time[KeyCode] =(time[KeyCode]+rtime) / c[KeyCode];
      System.out.println("[" + KeyCode + "」Released.  Time:"+ rtime);
      System.out.println("AVTime:"+time[KeyCode]);
           }


     public void keyTyped(KeyEvent event)
     {
         }
     }

    }
`

###発生している問題・エラーメッセージ
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 240
    at pack.TypingSample$Keyboard_input.keyReleased(TypingSample.java:118)
    at java.awt.Component.processKeyEvent(Component.java:6494)
    at javax.swing.JComponent.processKeyEvent(JComponent.java:2832)
    at java.awt.Component.processEvent(Component.java:6310)
    at java.awt.Container.processEvent(Container.java:2236)
    at java.awt.Component.dispatchEventImpl(Component.java:4889)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1954)
    at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:806)
    at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:1074)
    at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:945)
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:771)
    at java.awt.Component.dispatchEventImpl(Component.java:4760)
    at java.awt.Container.dispatchEventImpl(Container.java:2294)
    at java.awt.Window.dispatchEventImpl(Window.java:2746)
    at java.awt.Component.dispatchEvent(Component.java:4711)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
    at java.awt.EventQueue.access$500(EventQueue.java:97)
    at java.awt.EventQueue$3.run(EventQueue.java:709)
    at java.awt.EventQueue$3.run(EventQueue.java:703)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue$4.run(EventQueue.java:731)
    at java.awt.EventQueue$4.run(EventQueue.java:729)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:76)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)
[65」Released.  Time:16127
AVTime:3235
[73」Released.  Time:16335
AVTime:2727
[85」Released.  Time:16607
AVTime:3330
[69」Released.  Time:16847
AVTime:3376
[79」Released.  Time:17248
AVTime:3458
[10」Released.  Time:17568
AVTime:8815
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

0

以下で配列を99個用意してますが、

// 定義の箇所
    long[] time = new long[99];
    long[] c = new long[99];

押されたキーのキーコードが要素番号を超えるとエラーになります。
ArrayIndexOutOfBoundsException
「^」だとキーコード514でエラーになりました。

配列の長さを大きくするか、HashMap<Integer, Integer>を使えば大丈夫だと思います。
KeyEvent#getKeyCodeが返す値の範囲が分かればよいのですが、調べてもわかりませんでした。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/12 17:37

    ありがとうございます。半角キーのkeycodeが三ケタの数字だった為おそらくエラーが出ていたのだと思います。
    少し調べた所、keyPressメソッドは全角の入力では呼び出されなく、keyTypedメソッドが呼び出されるとの事だったのですが、コードを変えてみた所入力時には呼び出されず、エンターで文字数が確定したとき、文字数分だけ呼び出されました。
    キーが押されたときに呼び出されるようにしたいのですがどのようにすれば良いかお判りでしょうか?

    キャンセル

  • 2016/09/12 17:51

    「keyPressメソッドは全角の入力では呼び出されなく」とのことですが、以下の検証をしました。

    Windows 10でEclipse Marsなのですが、
    配列の定義を以下にして「半角入力」->「あいうえお」->「Enterで確定」->「Enter」という操作をしました。

    ```
    long[] time = new long[245];
    long[] c = new long[245];
    ```

    以下がコンソールログです。

    ```
    [244」Released. Time:1473669699797
    AVTime:1473669699797
    [65」Released. Time:1473669700998
    AVTime:1473669700998
    [73」Released. Time:1473669702419
    AVTime:1473669702419
    [85」Released. Time:1473669703133
    AVTime:1473669703133
    [69」Released. Time:1473669703546
    AVTime:1473669703546
    [79」Released. Time:1473669703817
    AVTime:1473669703817
    [10」Released. Time:1473669704310
    AVTime:1473669704310
    [10」Released. Time:50
    AVTime:736834852180
    ```

    細かい部分はわからないのですが、上記出力は想定外なのでしょうか?

    全角入力でもキー入力ごとにkeyReleasedが呼び出されています。
    以下のページによるとキーに関係なく、KEY_PRESSED、KEY_TYPED、KEY_RELEASEDと記載があります。
    https://docs.oracle.com/javase/jp/8/docs/api/java/awt/event/KeyEvent.html

    キャンセル

  • 2016/09/12 19:01

    半角英数字の場合
    [65」Released. Time:95
    AVTime:95
    [73」Released. Time:96
    AVTime:96
    [85」Released. Time:96
    AVTime:96
    [69」Released. Time:64
    AVTime:64
    [79」Released. Time:80
    AVTime:80
    [10」Released. Time:48
    AVTime:48

    のような結果になるのでこれが本来取得したい値です。
    全角入力の場合、pressメソッドとtypedメソッドが呼び出されないkeyReleasedのみ呼び出されてしまい、単純に現在の時刻がミリ秒で表示されているだけになってしまっているみたいです。
    おとなしく半角文字で取得するようにしてみます。
    ありがとうございました!

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 89.53%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る