• 締切済み

JavaのLookAndFeelとメニューのイベントについて

誰か知ってる方教えてください(><) 環境は下記です。 OS :WinXP java:j2sdk1.4.2_08 ツール:eclips3.1.1 普通のJFrameを使って画面を作成し、メニューバー にメニューを追加して、メニューにてリターンキー のイベントを取得するプログラムを作成しております。 JMenuを継承したクラスを作成してイベント取得メソッドをオーバーライドしイベントを取得しようとしているのですが、Look and Feelの設定によってイベントが取れない場合があります。 手順を下記に記述します。 1.フレームを表示する。 2.F10キーを押してメニューにフォーカスを当てる。 3.リターンキーを押す。 4.JMenuを継承したクラスでイベントを受け付ける。   受け付けるメソッドはprocessKeyEvent(KeyEvent e, MenuElement path[],MenuSelectionManager manager) です。 現象的にはThe Microsoft Windows Look and Feelの場合に限り、一回目のリターン押下時のKEY_TYPEDおよびKEY_RELEASEDのイベントが取れないようです。 KEY_PRESSEDイベントのみ取得できます。 2回目以降はKEY_PRESSED,KEY_TYPED,KEY_RELEASEDともに取得できるようです。 【質問】 ・これはバグなのでしょうか? ・メニューにて一回目のリターンのKEY_RELEASEDイベントを取得するにはどうすればよいでしょうか。 長ったらしくてもうしわけありません。。。 次の投稿にサンプルのソースを記述します。

  • Java
  • 回答数3
  • ありがとう数1

みんなの回答

  • PecoPlus
  • ベストアンサー率76% (144/188)
回答No.3

>・F10キーを押したときに「LookAndFeel」にフォーカスがいくと思いますが、 >そのときプルダウンメニューは表示されるでしょうか。  私の環境でも、「The Microsoft Windows Look and Feel」の場合だけF10キーを押したときにはメニューにフォーカスが行くだけで、プルダウンメニューは表示されません。  しかし、一回目のEnter押下時のイベントは、 KEY_PRESSED keyText=Enter KEY_TYPED keyText=Unknown KEY_RELEASED keyText=Enter  となりました。  あとは、mayamさんと同じようです。

mayam
質問者

補足

回答ありがとうございます。 j2sdk1.5をダウンロードして試してみました。 問題なく一回目のKEY_TYPED,KEY_RELEASEDイベントを受け取ることができました。 どうやらj2sdk1.4では私のような現象が出るようです。 システム上j2sdk1.5に上げるのも厳しい気がします。 困りました・・・(´-`;)

  • PecoPlus
  • ベストアンサー率76% (144/188)
回答No.2

 こんばんは、サンプルを動かしてみました。 OS :WinXP java:j2sdk1.5.0_07  私の環境では、The Microsoft Windows Look and Feelだけが特別な動きをしているようでは、ありませんでした。  すべてのルックアンドフィールにおいて、  メニューの「LookAndFeel」でEnterを押したときには、 KEY_PRESSED keyText=Enter KEY_TYPED keyText=Unknown KEY_RELEASED keyText=Enter  メニュー項目のどれかでEnterを押して、プルダウンメニューが消えたときは、 KEY_PRESSED keyText=Enter  のみとなりました。  この動きは、バグというより仕様のように思われるのですが、mayamさんの環境では、やはり、違った動きになりますでしょうか?  あと、processKeyEventメソッドをオーバーライドしていますが、親のprocessKeyEventを呼んでおかないと、MenuKeyEventがうごかなくなるとおもいますが、どうでしょう? public void processKeyEvent(KeyEvent e, MenuElement path[],     MenuSelectionManager manager) {   super.processKeyEvent(e, path, manager);    ↑   これ   System.out.println("★EVENT = " + e.toString());   System.out.println("in JMenuItem.processKeyEvent/3 for " + getText()     + " " + KeyStroke.getKeyStrokeForEvent(e)); }

mayam
質問者

補足

おはようございます。 返答どうもありがとうございます。 私の環境では、The Microsoft Windows Look and Feelの場合に限り、F10キーを押して「LookAndFeel」にフォーカスを当てたときにメニューのプルダウンメニューが表示されません。そして一回目のEnter時にKEY_PPRESSEDのみを受け付け、プルダウンメニューが表示されます。2回目以降はプルダウンメニューが表示された状態となり、この状態でEnterを押すと、KEY_PRESSED,KEY_TYPED,KEY_PRESSEDイベントが受け取れるようです。この違いが関係あるのかしれませんね。。 【質問】 ・F10キーを押したときに「LookAndFeel」にフォーカスがいくと思いますが、そのときプルダウンメニューは表示されるでしょうか。 >メニュー項目のどれかでEnterを押して、プルダウンメニューが消えたときは、 > >KEY_PRESSED keyText=Enter > >のみとなりました。 これは同じです。 >この動きは、バグというより仕様のように思われるの>ですが、mayamさんの環境では、やはり、違った動きになりますでしょうか? やはり同じようにWindows Look and Feelのときのみ一回目のEnter時はKEY_PRESSEDイベントしかうけつけないようです。 > あと、processKeyEventメソッドをオーバーライドしていますが、親のprocessKeyEventを呼んでおかない>と、MenuKeyEventがうごかなくなるとおもいますが、>どうでしょう? おっしゃるとおりです。 最終的には、メニューでEnterを押された場合にマウスの左クリックイベントに差し替えてイベントを発生させることを試みる予定です。 まずはイベントが取れればなんとかなるかなぁと思って省略していました。Enter1回目のKEY_RELEASEDを受けとれればなんとかなるのですが・・・ jdkのバージョンを変えて試してみようかと思っております。 あと、1回目のKEY_RELEASEDを拾えるようにいろいろ検討してみます。 また何かお気づきの点がございましたら、どうぞよろしくお願いいたします。

  • PecoPlus
  • ベストアンサー率76% (144/188)
回答No.1

とりあえず、ここの補足にサンプルソースを投稿してみてください。

mayam
質問者

補足

2重に投稿できなくてこまってました。 ありがとうございます。 以下にサンプルを記述します。 800超えそうなのでぎゅうぎゅうでかいてます。 package demo; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import javax.swing.*; public class LookAndFeelTest extends JFrame { UIManager.LookAndFeelInfo[] lookAndFeelInfos; JLabel label = new JLabel("Demo"); JTextField textField; public LookAndFeelTest() { super("Look & Feel"); setDefaultCloseOperation(EXIT_ON_CLOSE); lookAndFeelInfos = UIManager.getInstalledLookAndFeels(); setJMenuBar(createMenu()); getContentPane().add(label, BorderLayout.NORTH); textField = new JTextField(UIManager.getLookAndFeel().getDescription()); getContentPane().add(textField, BorderLayout.CENTER); } public JMenuBar createMenu() { JMenuBar menuBar = new JMenuBar(); SampleMenu lafMenu = new SampleMenu("LookAndFeel"); for (int i = 0; i < lookAndFeelInfos.length; i++) { final String lafClassName = lookAndFeelInfos[i].getClassName(); lafMenu.add(new AbstractAction(lookAndFeelInfos[i].getName()) { public void actionPerformed(ActionEvent ev) { changeLookAndFeel(lafClassName); } }); } menuBar.add(lafMenu); return menuBar; } private void changeLookAndFeel(String lafClassName) { try { UIManager.setLookAndFeel(lafClassName); SwingUtilities.updateComponentTreeUI(this); textField.setText(UIManager.getLookAndFeel().getDescription()); this.pack(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) { JFrame window = new LookAndFeelTest(); window.pack(); window.setVisible(true); } } class SampleMenu extends JMenu { public SampleMenu(String s) { super(s); } public void processKeyEvent(KeyEvent e, MenuElement path[], MenuSelectionManager manager) { System.out.println("★EVENT = " + e.toString()); System.out.println("in JMenuItem.processKeyEvent/3 for " + getText() + " " + KeyStroke.getKeyStrokeForEvent(e)); } }

関連するQ&A

  • Java インスタンス作成のイベント取得方法

    インスタンス化したことをイベントで取得することはできますか? 例) public class MyClass{ private MyDialog dialog = null; public void action(){ dialog = new MyDialog(); //ダイアログの中身の処理・・・(1) dialog.show(); } public MyDialog getDialog(){ return dialog; } } public class MyDialog extends JDialog{ (省略) } 前提 クラスMyClassの中身は変更することができない。 やりたいことは、MyClass#action()が呼ばれるたびに MyDialogにはってあるオブジェクトに命令を行いたい。 MyDialogのインスタンス作成イベントを取得できれば 上記を実現できると考えています。 以上です。

    • ベストアンサー
    • Java
  • JavaのGUIプログラミング

    javaのGUIプログラミングでメニューを作成したのですが、どうしてわからないところがあります。 ルートペインにメニューを追加した後、各々の処理を記述しようとするときに、 ActionListenerを実装したクラスのactionPerformedメソッドでイベントが起きたものをif文で場合分けして、それぞれの処理を記述していますが、これがいい方法だとはどうしても思えません。 自分なり考えた結果、 ・各メニューごとにクラスを作成してそこに処理を書き込む ・匿名のインナークラスを使用する を思いついたのですが、初心者なのでこの場合に応用できません。 分かりにくい文章で申し訳ないのですが、なにかアドバイスをいただけないでしょうか? できれば、参考になるソースをのせてくれると勉強しやすいので助かります。 よろしくお願いします。

    • ベストアンサー
    • Java
  • モードレスダイアログのキー入力について

    VC++6.0で親ダイアログで作成した子ダイアログをモードレスで表示しています。(ShowWindowで表示した後、子ダイアログが終了するまでループ) 両方のダイアログに、OKボタンとキャンセルボタンしかない時には、リターンキー・ESCキーを押せば子ダイアログが終了していました。(親ダイアログにフォーカスがあるときには親ダイアログが終了) ところが、子ダイアログが表示されている間、親ダイアログ上でプログレスバーを表示・更新ようにしたら、とたんにリターンキー・ESCキーが効かなくなり、マウスのクリックでしか終了することができなくなりました。 WEBで調べてPreTranslateMessageを追加して、この関数にブレイクポイントを設定しましたが、呼ばれている様子がありません。 子ダイアログをマウスのボタンクリックで終了させた後は、親ダイアログのPreTranslateMessageでイベントが取得できます。 何をどうしたらリターンキー・ESCキーのイベントが取得できるようになるのでしょうか?

  • 技術的に可能かどうか教えてください

    C,VBプログラマで、最近JAVAの勉強を始めたJAVA初心者です。 JAVAではクラスの継承ができるとのことですが、下記の内容が実現できるかどうか教えてください。 ウィンドウを表示するクラスを作成します。ラベルやテキストボックスそしてボタンなどを表示するようにして イベントメソッドを作成して、名前を"ClassDispWindow"とでもします。 そして、"ClassDispWindow"を継承して"ClassDispOtherWindow"と言うクラスを作った後、新たなコントロールと イベントメソッドを追加して動作させたいと思っています。 この様な事は可能でしょうか? ご回答よろしくお願いします。

    • ベストアンサー
    • Java
  • richtextで入力文字列確定時にイベント

    VB6ですが、 RichTextBoxで文字列を入力し、変換終了後Returnキーにて、確定をした時のイベントを取得したい。 KeyPressイベントやkeydownイベントは変換確定時には、IMEに占有されていてイベントが起きないのです。 具体的にどんなソフトを作っているのかというと、 1.入力済みの文字列の一部(例えば「AB」)を反転して選択。 2.そして新しい文字列を入力(例えば「あいうえお」)。 3.Returnキーで確定時に反転していた文字列を新しく入力した文字列の「あいうえお」の「うえ」の間に挿入した文字列を入れたい。 4.結果は、「あいうABえお」と入力される。 というもの 入力時にイベントを起こせれば、自力で何とかなると思うのですが…… 文章下手で申し訳ありません。 よろしくお願いします。

  • マウス移動イベントでMessageBox終了

    Visual C++ 2010 Expressでプログラム開発している初心者です。 現在、オペレータに確認させるため、MessageBox::Show()によりメッセージを表示して OKボタン押下により、MessageBoxを終了しておりますが、ボタン押下する前に マウス移動イベントにより、MessageBoxを終了できないか、調査しております。 MessageBoxのメソッドには、このような機能はないようなので、自前で作成するしか ないかな、と考えております。 その場合には、まず (1)ウィンドウを作成し、マウスイベントを取得できるプログラムを登録 (2)ウィンドウ(メッセージ含む)表示 (3)マウスイベントを取得 (4)イベント解析 (5)ウィンドウ終了 上記のように動かすには、初心者の自分にはとても難しいので 他に方法はないでしょうか? こんな方法があるよ、とヒントでも構いませんので、是非ご教示ください。 よろしくお願い致します。

  • タスクバーのメニュー表示

    Visual C++ 6.0 MFCにて質問があります。 [環境] Visual C++ 6.0 MFC [タスクバーのアイコンの処理] リソースにMenuを作成して、以下のソースを作成いたしました。しかし、タスクバーのアイコンをクリックして、Menuが表示されるはずなのですが、途中でエラーが出てしまいます。CMenu* pMenu;がうまく処理されていないみたいなのですが、ソース的に問題ないように思うのですが.... 何か問題があるのでしょうか?? [ソース] CMenu MyMenu; CMenu* pMenu; POINT pt; // 現在のカーソル位置を取得 ::GetCursorPos(&pt); // フォーカスを当てる SetFocus(); // メニューのロード VERIFY(MyMenu.LoadMenu(IDR_MENU1)); // 0番目のメニューを取得 pMenu = MyMenu.GetSubMenu(0); ASSERT(pMenu != NULL); <-- ここでエラーがでる。 // メニューの表示 if(pMenu->TrackPopupMenu( TPM_LEFTALIGN| TPM_RIGHTBUTTON, pt.x, pt.y , this) == 0){ return FALSE; } // メッセージを送る PostMessage(WM_NULL); return TRUE;

  • iアプリ作成 画像を描画できない

    最初に4つのメニューを表示し、メニュー1を選ぶとある画像を表示し、メニュー2を選ぶとまた別の画像を表示する様なiアプリを作成しています。 その作り方が、メニュー1を選ぶと Manu1Canvas c = new Menu1Canvas(); Display.setCurrent(c); c.exe(); という感じでMenu1Canvasクラスのexe()の内容を実行し画像を描画しています。この時Menu1CanvasはCanvasを継承しておりpaint()メソッドを使い描画をしています。 メニュー2を選んだ場合も同じように、Canvasを継承したクラスで画像を描画しています。 このようにそれぞれのメニュー4つにクラスを作り、その4つのクラスにCanvasを継承させpaint()メソッドを使い画像を描画するという処理内容はおかしいのでしょうか?このようにやるとなぜか画面を切り替える時にDojaエミュレータが終了してしまいます。

    • ベストアンサー
    • Java
  • SocketのFileDescriptor取得

    Javaにて、SocketよりFileDescriptorを取得したいと考えております。 いろいろ検索して調べてみたものの、どのようにFileDescriptorを取得するのかがわかりません。 SocketImplのサブクラスを作成して取得などといったものはありますが、 具体的に何をどう継承してどのメソッドで実現するかが理解できていないです。 上記のSocketのFileDescriptorの取得について、ご教授お願いいたします。

  • java アプリケーションをjava アプレットに

    java超初学者です。詳しいかたご教授願います。 java アプリケーションをjava アプレットに書き換えたいのですが、具体的にはどう書き換えを行ったらいいのか修正をお願いします。 (文字制限があるので、14個あるクラスファイルの中で(内1つはhtmlファイル)、メインメソッドを持つ実行クラスだけのせています。) Appletを継承させる、属性をメインクラスとコンストラクタはpublic にする、 mainメソッドを削除し、initメソッドへ書き換える、サイズ指定は<applet>タグで指定する。等調べましたが 具体的にわかりません。特にコンストラクタとメインメソッドの部分のアプレットへの書き換えがわかりませんでした。 宜しくお願い致します。 //実行クラスです。 import java.awt.*; import java.awt.event.*; /** *ゲームクラス(ここから始まる)<p> *画面の作成 */ public class Game extends Frame { /** * メインクラス */ public static void main(String args[]) { //フレームの作成 new Game(); } /** * 引数なしのコンストラクタ */ Game() { //*** ウィンドウの初期化 //タイトル super("Shooting Game"); //クローズボタンによる終了処理の実装 addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { System.exit(0); } }); setSize(500, 500); //ウィンドウのサイズ //*** キャンバスの初期化 MyCanvas mc = new MyCanvas(); add(mc); //フレームにキャンバスを追加 setVisible(true); //ウィンドウの表示 //ゲームデータの初期化 mc.init(); //スレッドを作成 mc.initThread(); } }