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

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

新規登録して質問してみよう
ただいま回答率
85.50%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

2回答

2875閲覧

MouseEventからの情報の取得 コンポーネントの種類を判別?

otftrough

総合スコア476

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

0クリップ

投稿2017/03/14 15:09

JLabelとJSliderにそれぞれ違う機能を持たせるつもりですが、両方ともMouseListenerを使いたいと思っています。
どのコンポーネントをクリックしたかはどうやって判断すればいいですか?
例えばActionListenerを使えばsetActionCommand()であらかじめコマンドを決めておいて、if(e.getActionCommand().equals("COMMAND1")){}というふうに判断できますが、MouseListenerでもできますか?
できなければ、JLabelとJSliderそれぞれを継承させたクラスを作って以下のようにするつもりです。
コンパイルエラーな気もしますが(試してない)
普通はこうするよって例があれば教えてください。

java

1private class MyLabel extends JLabel{ 2 3 public String command = null; 4} 5 6private class MySlider extends JSlider{ 7 8 public String command = null; 9} 10 11/****************************************************/ 12 13MyLabel lab = new MyLabel("abc"); 14lab.addMouseListener(this); 15lab.command = "label"; 16 17MySlider sli = new MySlider(); 18sli.addMouseListener(this); 19sli.command = "slider"; 20 21/****************************************************/ 22 23public void mouseClicked(MouseEvent e){ 24 25 String com = e.getSource().command; 26 27 if(com.equals("label")) // 28 else if(com.equals("slider")) // 29}

気になる質問をクリップする

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

自己解決

try文で、キャスト出来るかどうかによって判断しました。

java

1mouseClicked(MouseEvent e){ 2 3 String source = ""; 4 try{ 5 6 JSlider sl = (JSlider)e.getSource(); 7 source = "jslider"; 8 } catch(Exception ex){} 9 try{ 10 11 JLabel label = (JLabel)e.getSource(); 12 source = "jlabel"; 13 } catch(Exception ex){} 14 15 if(source.equals("jslider")){/****/} 16 else if(source.equals("jlabel")){/****/} 17}

投稿2017/03/15 10:20

otftrough

総合スコア476

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KSwordOfHaste

2017/03/15 12:16

try-catchを使うならisinstanceofの方が簡単ではないでしょうか? if (e.getSource() isinstanceof JSlider) { ... } else if (e.getSource() isinstanceof JLabel) { ... } のような雰囲気です。
otftrough

2017/03/16 00:08

そう!そういうのが欲しかったんです! 質問では、例として両方ともmouseClicked()内で処理しようとしていますが、僕が今作っているモノの中では、JSliderの場合mousePressed()のみ、JLabelではmouseClicked()のみで処理しようとしているので、どちらでもそんなに大きくちがいませんでした。 また次の機会にisinstanceofを使ってみようと思います、 ありがとうございました。
guest

0

ActionEventですとActionEvent#getSourceCommandにイベント発生元(AbstractActionなど)により決まるコマンド文字列が得られますね。これを利用して複数のイベント発生元のイベントターゲット(=ActionListener)を同一にしてgetSourceCommandの内容で実行内容を切り分けるなどといった例が見られます。

さてMouseEventにはgetSourceCommandメソッドは定義されてなく、getSource().commandなどとはできません。そもそもマウスイベントは「コマンドを発するイベント」としては設計されてませんので・・・

もちろんgetSourceを用いてイベント発生元は得られますのでそれがラベルなのかスライダーなのかといった区別はisinstanceofや==などを用いて切り分けることはできます。

java

1class MyFrame extends JFrame 2 implements MouseListener, MouseMotionListener { 3 4 MyLabel myLabel = ...; 5 MySlider mySlider = ...; 6 ... 7 MyFrame() { 8 myLabel.addMouseListener(this); 9 myLabel.addMouseMotionListener(this); 10 mySlider.addMouseListener(this); 11 mySlider.addMouseMotionListener(this); 12 ... 13 } 14 15 @Override public void mouseClicked(MouseEvent ev) { 16 if (ev.getSource() == myLabel) { 17 ... 18 } else if (eve.getSOurce() == mySlider) { 19 ... 20 } 21 } 22 ... 23}

しかしながら上記のような方法は「あまり合理的でない」と感じることも事実です。

ActionEventの場合、同一のアクションのイベント発生元がメニューやボタンなど複数個所に置くような設計もあるのでイベントの発生元ではなくコマンド文字列で「おこなうべき内容を決める」という考え方で設計するのは合理的と言えるでしょう。またActionListenerは単一のメソッドだけの単純なものなのであるコマンドに対するイベント発行元が一つしかないなら

java

1xxx.addActionListener(new ActionListner() { 2 @Override 3 public void actionPerformed(ActionEvent ev) { 4 ... 5 } 6}); 7あるいは 8xxx.addActionListener(ev -> { ... });

などのようにした方が分かりやすいという場合もあるでしょう。

さてマウスイベントについてはどうかというと、ラベルに対するマウスイベントの処理とスライダーに対するマウスイベントが同一のことを行うことを意味しないのであれば「異なる事象を意味するイベントを同一のターゲットでやること」は不自然な感じがします。

もし違うことをするなら別々のMouseListenerのインスタンスをターゲットにした方が自然に実装できる(=ハンドラーの中身が書きやすく理解もしやすくなる)のではないでしょうか。

最初に示した例のように、異なるコンポーネントのマウスイベントを単一のインスタンスで受けるようなコーディングをなぜしたくなるかといえば単にMouseListener, MouseMotionListnerが沢山のメソッドを持つインターフェースなのでそれを別々に定義するのがめんどくさいというような理由ではないかと思います。自分もそう感じたことはありますがMouseClickedのみしか処理がないといった単純なものならともかくMousePressed, MouseReleased, MouseDraggedなどを用いた処理をしようとするなら、かえってイベント発生元ごとに別のイベントターゲットを定義した方がわかりやすくなると思います。

投稿2017/03/14 17:09

KSwordOfHaste

総合スコア18392

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問