- PR -

キーコードによる処理がうまく行かない原因は?

1
投稿者投稿内容
kathy2005
会議室デビュー日: 2005/03/01
投稿数: 3
投稿日時: 2005-03-01 18:20
下記のコードを実行しようとしています。マウスからのイベントについては、問題なく動くのですが、キーからのイベントを実行しようとしても、キーに反応してくれません。
考えられる原因を教えて下さい。 OS:Windows XP Java:SJ2 1.5.0_01

=========================================================================
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

/*
<applet code="Sample7.class" width=200 height=200></applet>
*/

public class Sample7 extends JApplet
{
private JLabel lb1, lb2;

public void init()
{

//コンテンツペインの取得
Container cnt = getContentPane();

//コンポーネントの作成
lb1 = new JLabel("矢印キーでお選び下さい。");
lb2 = new JLabel();

//コンテナへの追加
cnt.add(lb1, BorderLayout.NORTH);
cnt.add(lb2, BorderLayout.SOUTH);

addKeyListener( new SampleKeyListener());
}




class SampleKeyListener extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
String str;
//int k = e.getKeyCode();
switch(e.getKeyCode())
{
case KeyEvent.VK_UP:
str = "上"; //VK_UP 38
break;
case KeyEvent.VK_DOWN:
str = "下"; //VK_DOWN 40
break;
case KeyEvent.VK_LEFT:
str = "左"; //VK_LEFT 37
break;
case KeyEvent.VK_RIGHT:
str = "右"; //VK_RIGHT 39
break;
default :
str = "ほかのキー";
}
lb2.setText(str + "ですね。");
}
}
}

=========================================================================
takamaro
大ベテラン
会議室デビュー日: 2004/10/12
投稿数: 100
投稿日時: 2005-03-01 20:10
フォーカスが当ってないからでしょうね。
アプレットをクリックしてみてからキー操作するとどうなります?
希望通り動いたらフォーカスが原因だと言う事です。
対処法は、ComponentListenerでも組み込んでcomponentShown()
で「表示された」旨のイベントを拾ってrequestFocus()でもすれば
上手くいくんじゃないかと思います(他にも手はありそうですが)
kathy2005
会議室デビュー日: 2005/03/01
投稿数: 3
投稿日時: 2005-03-01 21:59
マウスでアプレットをクリックしてからキー操作すると、ちゃんと反応します。アプレットを最初にクリックしないと、動きません。
requestFocus()をつけてみましたが、同じでした。設定方法が違うのでしょうか?
もう一度、教えて下さい。

==============================================================================
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.Applet;

/*
<applet code="Sample7.class" width=200 height=200></applet>
*/

public class Sample7 extends JApplet
{
private JLabel lb1, lb2;

public void init()
{

//コンテンツペインの取得
Container cnt = getContentPane();

//コンポーネントの作成
lb1 = new JLabel("矢印キーでお選び下さい。");
lb2 = new JLabel();

//コンテナへの追加
cnt.add(lb1, BorderLayout.NORTH);
cnt.add(lb2, BorderLayout.SOUTH);

addKeyListener( new SampleKeyListener());
requestFocus();
}




class SampleKeyListener extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
String str;
//int k = e.getKeyCode();
switch(e.getKeyCode())
{
case KeyEvent.VK_UP:
str = "上"; //VK_UP 38
break;
case KeyEvent.VK_DOWN:
str = "下"; //VK_DOWN 40
break;
case KeyEvent.VK_LEFT:
str = "左"; //VK_LEFT 37
break;
case KeyEvent.VK_RIGHT:
str = "右"; //VK_RIGHT 39
break;
default :
str = "ほかのキー";
}
lb2.setText(str + "ですね。");
}
}
}

========================================================================


[ メッセージ編集済み 編集者: kathy2005 編集日時 2005-03-01 22:00 ]
takamaro
大ベテラン
会議室デビュー日: 2004/10/12
投稿数: 100
投稿日時: 2005-03-01 23:12
手順は一通り書いたつもりでしたが。

init()ででも

コード:

addComponentListener(new ComponentAdapter() {
    public void componentShown(ComponentEvent e) {
        this.requestFocus();
    }
});


まぁ、副作用もあるのでこのままで良いかどうかは疑問ですが。。。
取り敢えず。
takamaro
大ベテラン
会議室デビュー日: 2004/10/12
投稿数: 100
投稿日時: 2005-03-01 23:30
引用:

takamaroさんの書き込み (2005-03-01 23:12) より:
手順は一通り書いたつもりでしたが。

init()ででも

コード:

addComponentListener(new ComponentAdapter() {
    public void componentShown(ComponentEvent e) {
        this.requestFocus();
    }
});


まぁ、副作用もあるのでこのままで良いかどうかは疑問ですが。。。
取り敢えず。



訂正です。this.requestFocus()はrequestFocus()かSample7.this.requestFocus()
ですね(汗。。脳内コンパイルはやっちゃ駄目ですね。。
それと、requestFocus()よりもrequestFocusInWindow()の方がベターなのかも。
詳しくは理解してませんが、リファレンス見る限りこちらの方が良さげですね。

失礼しました。ではでは。
kathy2005
会議室デビュー日: 2005/03/01
投稿数: 3
投稿日時: 2005-03-01 23:37
下記でちゃんと動く様になりました。ありがとうございます。

「requestForcus();」 に 「this.」をつけると、「シンボルを見つけられません」というコンパイルエラーになりました。「this.」をはずすと上手くいきました。
「this.」がついていても、ついていなくても同じではないかと思うのですが、理由は分かりません。

何度もありがとうございました。

==============================================================================
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.applet.Applet;

/*
<applet code="Sample7.class" width=200 height=200></applet>
*/

public class Sample7 extends JApplet
{
private JLabel lb1, lb2;

public void init()
{

//コンテンツペインの取得
Container cnt = getContentPane();

//コンポーネントの作成
lb1 = new JLabel("矢印キーでお選び下さい。");
lb2 = new JLabel();

//コンテナへの追加
cnt.add(lb1, BorderLayout.NORTH);
cnt.add(lb2, BorderLayout.SOUTH);

addKeyListener( new SampleKeyListener());

addComponentListener(new ComponentAdapter()
{
public void componentShown(ComponentEvent e)
{
requestFocus();
}
});
}




class SampleKeyListener extends KeyAdapter
{
public void keyPressed(KeyEvent e)
{
String str;
//int k = e.getKeyCode();
switch(e.getKeyCode())
{
case KeyEvent.VK_UP:
str = "上"; //VK_UP 38
break;
case KeyEvent.VK_DOWN:
str = "下"; //VK_DOWN 40
break;
case KeyEvent.VK_LEFT:
str = "左"; //VK_LEFT 37
break;
case KeyEvent.VK_RIGHT:
str = "右"; //VK_RIGHT 39
break;
default :
str = "ほかのキー";
}
lb2.setText(str + "ですね。");
}
}
}
==============================================================================
takamaro
大ベテラン
会議室デビュー日: 2004/10/12
投稿数: 100
投稿日時: 2005-03-02 00:33
引用:

kathy2005さんの書き込み (2005-03-01 23:37) より:

「requestForcus();」 に 「this.」をつけると、「シンボルを見つけられません」というコンパイルエラーになりました。「this.」をはずすと上手くいきました。
「this.」がついていても、ついていなくても同じではないかと思うのですが、理由は分かりません。


ここで言う「this」はあくまでComponentAdaperを継承した無名クラス自身のインスタンスという
ことです。例えば、、、
コード:

addComponentListener(new ComponentAdapter() {
    public void componentShown(ComponentEvene e) {
        requestFocusInWindow();
        removeComponentListener(this);
    }
});


上の例では「this」はComponentAdapter(implements ComponentListener)
を継承したクラス自身であるためremoveComponentListener()の引数である
ComponentListener参照として問題無くコンパイルが通ります(と思います・汗)
そして、この結果としてアプレットに登録されたComponentListenerは一度呼ばれ
た後は破棄され、ブラウザを非可視状態にしてから復帰表示させても、自動的にフォ
ーカスを得る事は無くなります(要するに、最初の表示の時だけ自動でフォーカスが
当てられ、以後はクリック等でフォーカスを与えない限りキーイベントを受けません)

*thisの説明と副作用の排除方法を合わせてみたつもりですが、かえって分かり辛い
内容になっちゃったかもしれませんね、、
1

スキルアップ/キャリアアップ(JOB@IT)