Draw2Dでのイベント検知

このQ&Aのポイント
  • SWT + GEF(Draw2D)を使用してGUIアプリケーションを作成しています。
  • FigureCanvasにPanelを張り、その上にFigureを追加し、マウスドラッグによるFigureの移動機能を実装しようと試行錯誤しています。
  • LabelにMouseListenerを登録して移動するラベルを検知し、MouseMotionListenerをPanelに登録してドラッグを実現させましたが、カーソルがLabel上にある時にイベントを検知できず、カクカクした動きになっています。
回答を見る
  • ベストアンサー

Draw2Dでのイベント検知

SWT + GEF(Draw2D) でGUIアプリケーションを作成しています。 FigureCanvasにPanelを張り、その上にFigure(例えばLabel)を追加し、マウスドラッグによるFigureの移動機能を追加しよう試行錯誤しています。 最初はLabelにMouseMotionListenerを登録してmouseDraggedを実装する方法をとっていたのですが、カーソルを早く動かしてLabelの外にカーソルが出てしまうと移動が止まってしまうという減少に陥りました。 そこで、LabelにMouseListenerを登録して移動するラベルを検知し、MouseMotionListenerをPanelに登録して検知したLabelのドラッグを実現させました。 ところが今度は、カーソルがLabel上にあるときにPanelに登録したリスナでイベントを検知できず、Labelの外にカーソルが移動してPanel領域に触れたときに初めてイベントを検知して移動ができるという現象に陥っています。(←つまり動きがカクカクする) SwingだとJPanel上にある部品の上にカーソルがある場合も、JPanelに登録したリスナでイベントを検知してくれるようなのですが、どう対処すればよいでしょうか。

  • asock
  • お礼率71% (25/35)
  • Java
  • 回答数1
  • ありがとう数1

質問者が選んだベストアンサー

  • ベストアンサー
  • kacchann
  • ベストアンサー率58% (347/594)
回答No.1

実験してないので自信なし。 (SWT環境もってないので) --- mousePressed(MouseEvent e)ハンドラ内部で「e.consume()」してあげると、 あとは"普通に"、 (図形のドラッグ)処理を書けばいいみたい。 http://www13.plala.or.jp/observe/draw2d/draw2d_event.html --- 自信ないのですが、 ソースコードをなんとなく読んだ限りでは、 mousePressed(MouseEvent e)ハンドラ内部で「e.consume()」してあげると 『そのpressされた図形をキャプチャ(※以後のドラッグ操作を追跡監視)する』 みたいです。 (※追跡対象になった図形は、そのドラッグ中(追跡中)に、 たとえマウスがその図形の領域を外れても、マウスイベントは 相変わらずその図形に対し発生する…といったところかな?) この「マウスpress時の明示的キャプチャ」をプログラマがやらない場合、 マウスを動かした際に、 「その瞬間に、マウスカーソルに最も近い図形が その都度キャプチャされる」 みたいです。 (Java swingの場合は、何もやらなくても、 マウス押下された図形が自動的に「ドラッグ追跡(監視)対象」になるっぽい) --- 参考資料: ・ここ http://www13.plala.or.jp/observe/draw2d/draw2d_overview.html の「LightweightSystem」の説明。 ・LightweightSystem.java ・SWTEventDispatcher.java

asock
質問者

お礼

詳しいご解説&URLが大変参考になりました。 consume()はそのような役割があったのですね。 おかげさまで無事解決することが出来ました。 ありがとうございます。

関連するQ&A

  • マウスイベントに合わせた動作を行いたい。

    いつもお世話になってます。 再びお願いします。 枠上か否かの判別はできるようになったのですが 動作が不安定というか意図し動作にならず困っております。 悩み疲れてよく分からなくなってきました(汗) 枠上だと判定した場合にはボーダーサイズを変更して、 枠の内部と判定した場合にはボーダーを含んだパネルを ドラッグの動きに合わせて移動したいのです。 どなたかどこを直せば良いのか分かりますでしょうか。 宜しくお願いいたします。 public class SampleButtonSize extends JFrame { private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JPanel jPanel = null; private Border jBdrPower = null; private JButton jButton = null; private JButton jButton1 = null; public Point pMus; private JPanel getJPanel() { if (jPanel == null) { jPanel = new JPanel(); jPanel.setLayout(null); jPanel.setBounds(new Rectangle(30, 25, 205, 98)); jPanel.setBorder(new TitledBorder( new EtchedBorder(), "Power" )); jPanel.add(getJButton(), null); jPanel.add(getJButton1(), null); jPanel.addMouseMotionListener(new java.awt.event.MouseMotionListener() { public void mouseDragged(java.awt.event.MouseEvent e) { MusX = e.getX(); MusY = e.getY(); inner = jBdrPower.getBorderInsets(jPanel); Dimension PnlSize = jPanel.getSize(); pMus = jPanel.getLocation(); if( MusX< inner.left || MusX> PnlSize.width - inner.right || MusY< inner.top || MusY> PnlSize.height - inner.bottom ) { // border の内側線よりも外:サイズ変更 jPanel.setSize(MusX, MusY); } else { // border の内側線よりも内:移動 jPanel.setLocation( pMus.x + MusX, pMus.y + MusY ); } } public void mouseMoved(java.awt.event.MouseEvent e) { } }); } return jPanel; } private JButton getJButton() { if (jButton == null) { jButton = new JButton(); jButton.setBounds(new Rectangle(16, 25, 82, 58)); } return jButton; } private JButton getJButton1() { if (jButton1 == null) { jButton1 = new JButton(); jButton1.setBounds(new Rectangle(115, 24, 77, 59)); } return jButton1; } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { SampleButtonSize thisClass = new SampleButtonSize(); thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); thisClass.setVisible(true); } }); } public SampleButtonSize() { super(); initialize(); } private void initialize() { this.setSize(300, 200); this.setContentPane(getJContentPane()); this.setTitle("JFrame"); } private JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); jContentPane.setLayout(null); jContentPane.add(getJPanel(), null); } return jContentPane; } }

    • ベストアンサー
    • Java
  • イベントリスナを調べる方法についての質問です。

    イベントリスナを調べる方法についての質問です。 現在twitterのページで使われているJavaScriptの挙動を分析しているのですが、コード量が非常に多く苦労しています。 ある要素にどのようなイベントリスナが追加されたか、または追加されているかということを調べるいい方法はないでしょうか? addEventListenerで関数を登録した場合、element.onclickにセットされた関数を取得するというような方法が使えないので困っています。 bookmarkletやユーザースクリプト、アドオンなど何でもいいので、要素に追加されているイベントリスナを直接調べたり、あるいはイベントリスナが追加される瞬間を検出できるようないい方法があれば教えてください。 (解析はFirefox上で行っていますが、他のブラウザを使う方法でも構いません) 宜しくお願いします。

  • Androidイベントリスナ、イベントハンドラ違い

    Androidににおける「イベントリスナ」「イベントハンドラ」の違いを教えてください ・イベントに対応するメソッドが、「View クラスのインターフェイス」「View クラス」に分かれている理由が分かりません ・なぜメソッドによって、「インターフェイス」にあったり、「クラス」にあったりするのでしょうか? ・「onKeyDown」みたいにAndroid 自体が自動検知(?)するイベント対応メソッドは、「View クラス」に書かれる決まり? ・「onClick」などのイベントは、リスナに登録しないと利用できないから(?)、「インターフェイス」に書いてある? ・「イベントリスナ」は、「イベントハンドラ」の一種類なのでしょうか? ▽6.5 UIイベントハンドリング - ソフトウェア技術ドキュメントを勝手に翻訳   https://sites.google.com/a/techdoctranslator.com/jp/android/guide/ui/ui-events#EventHandlers

    • ベストアンサー
    • Java
  • ボーダー上か否かの判定について

    いつもお世話になってます。 またお願いします。 画面上にパネルを配置して パネルに外枠を設定します。 その内部にボタンを2つ配置しました。 この設定した外枠をドラッグ&ドロップすることで パネル(外枠)のサイズを変更し、 外枠以外のパネル部分をドラッグ&ドロップすることで ボタンや外枠含むを含むパネル全体の移動を行いたいのです。 ★のところで枠上か否かを判定させれば良いのでしょうか? それとも他に方法がありますでしょうか? 宜しくお願いいたします。 public class SampleButtonSize extends JFrame { private static final long serialVersionUID = 1L; private JPanel jContentPane = null; private JPanel jPanel = null; private JButton jButton = null; private JButton jButton1 = null; public Point pMus; private JPanel getJPanel() { if (jPanel == null) { jPanel = new JPanel(); jPanel.setLayout(null); jPanel.setBounds(new Rectangle(30, 25, 205, 98)); jPanel.setBorder(new TitledBorder( new EtchedBorder(), "Power" )); jPanel.add(getJButton(), null); jPanel.add(getJButton1(), null); jPanel.addMouseMotionListener(new java.awt.event.MouseMotionListener() { public void mouseDragged(java.awt.event.MouseEvent e) { if( ★ ) { // 枠 pMus = jPanel.getLocation(); jPanel.setLocation(pMus.x + e.getX(), pMus.y + e.getY() ); } else { // 枠以外 jPanel.setSize(e.getX(), e.getY() ); } } public void mouseMoved(java.awt.event.MouseEvent e) { } }); } return jPanel; } private JButton getJButton() { if (jButton == null) { jButton = new JButton(); jButton.setBounds(new Rectangle(16, 25, 82, 58)); } return jButton; } private JButton getJButton1() { if (jButton1 == null) { jButton1 = new JButton(); jButton1.setBounds(new Rectangle(115, 24, 77, 59)); } return jButton1; } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { SampleButtonSize thisClass = new SampleButtonSize(); thisClass.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); thisClass.setVisible(true); } }); } public SampleButtonSize() { super(); initialize(); } private void initialize() { this.setSize(300, 200); this.setContentPane(getJContentPane()); this.setTitle("JFrame"); } private JPanel getJContentPane() { if (jContentPane == null) { jContentPane = new JPanel(); jContentPane.setLayout(null); jContentPane.add(getJPanel(), null); } return jContentPane; } }

    • ベストアンサー
    • Java
  • テキストエリアの大きさをドラッグで調節したい

    _____________________________ || | | | etc | | | ============================= | | | JTextArea | | | | | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 上の図の=の部分を上下にドラッグすると、 JTextAreaの大きさを調節できるようにした いのですが、どうしたら良いのでしょうか? ソースは次のようにしています。 JPanel mainPanel = new JPanel(new GridLayout(2,1)); JPanel panel_1 = new JPanel(); panel_1.add(...); : etc部の追加 : mainPanel.add(panel_1); JPanel panel_2 = new JPanel(); panel_2.add(textArea); mainPanel.add(panel_2); getContentPane().add(mainPanel);

  • Javaにおけるイベント処理

    JFrame  SpritPanel   SpritPanel    JPanel     JButton A     JButton B     JButton C    JList A   SpritPanel    JList B    JTable C という構成で、JButton A をクリックしたらJList AにJButton A用のなんらかのリストを表示し、JButton BをクリックしたらJList BにJButton B用のなんらかのリストを表示し、・・・ と1つGUI部品で発生するイベントで1つまたは複数のGUI部品の更新処理を行いたいのですが、イベントリスナをどこに実装させて、どこに更新処理を書くかで迷います。 例えば、押されるJButton Aにイベントリスナーのメソッドを実装し、そこで処理を書く場合はJList Aをこのメソッド内から見えるようにしなけなくて、それをするためにインスタンスを渡したりするのが面倒に感じています。 様々なGUI部品やパネルで構成され、イベントが起きたら複数のGUI部品が更新が必要となるようなGUIアプリケーションを作る場合、どのようにイベントを処理させるのが王道なのでしょうか。 うまく質問できないので、質問内容に不明な点があれば補足いたします。

    • ベストアンサー
    • Java
  • マウスイベント処理

    描いた図形(今の場合は長方形)をドラッグして移動させるプログラムを作りたいのですが、うまくいきません… アドバイスどうかよろしくお願いします。 あと、どうすればマウスイベントを使ったプログラム作成が苦手じゃなくなるのでしょうか。 重ねてアドバイスお願い致します。 以下が私が作ったプログラムです。 import java.awt.*; import java.applet.*; import java.awt.event.*; public class RectMove extends Applet implements MouseListener, MouseMotionListener{ Rectangle r1 = new Rectangle(10, 10, 50, 40); Point p1,p2; public void init(){ addMouseListener(this); addMouseMotionListener(this); } public void paint(Graphics g){ g.drawRect(r1.x, r1.y, r1.width, r1.height); } public void mousePressed(MouseEvent e){ p1 = e.getPoint(); if(!r1.contains(p1)) p1 = null; } public void mouseReleased(MouseEvent e){ if(p1 != null){ p2 = e.getPoint(); r1.translate((p2.x - p1.x), (p2.y - p1.y)); p1 = null; repaint(); } } public void mouseClicked(MouseEvent e){ p1 = null; repaint(); } public void mouseDragged(MouseEvent e){ if(p1 != null){ p2 = e.getPoint(); r1.translate((p2.x - p1.x), (p2.y - p1.x)); p1.setLocation(p2); repaint(); } } public void mouseMoved(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} }

    • ベストアンサー
    • Java
  • java gui のイベント処理が重い

    先日javaの勉強をはじめた初心者なのですが、javaのマウスイベントやキーイベントを同時にやろうとすると重くなってしまいます。 例えば、 テトリスのようなブロックがあり、 そのどれかを選んでマウスのカーソルに合わせて既存のマス目のある(14*14)ボード上に表示して、 上キーを押すと反転、左右キーを押すと押した方向に90度回転、 するという一連の動作に 1.ボタンにブロックの絵を表示してどれかを選ぶことでActionListenerを使って、イベントを実行して、 2.そのActionEventの中でMouseListenerを使ってMouseEnteredとMouseExitedを実行して、カーソルの位置の移動に合わせて、ボード上に選んだブロックを表示して、 3.更に、それらができてる状態で、KeyListenerからのKeyPressedで、上左右キーを押すことで任意の方向に回転できるようにしたくて 2までは、どうにか無駄な記述も多々あるだろうけどできました、が、3の記述をして、実行するととても重くなってしまいます。 あと、1,2の段階でほかのブロックを選びなおそうとしても、とたんに重くなってしまいます。 結構初心者の自分にとっては複雑な構造をしていて、たぶん無駄な記述が多くなってしまったり、Listenerの記述のタイミングが悪かったりなどが原因だと考えているのですが、 まったく解決方法が思いつきません。 あと、ブロックを選択してから、ボード上にマウスカーソルを移動して、カーソルの位置に合わせて選んだブロックを表示したいと書いてありましたが、 ボードにカーソルを移動したとたんに、以下のようなエラー?が大量発生します Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at java.awt.AWTEventMulticaster.mouseExited(Unknown Source) at java.awt.AWTEventMulticaster.mouseExited(Unknown Source) at java.awt.AWTEventMulticaster.mouseExited(Unknown Source) 以下ほぼ無限ループ。 簡単なlisetenerとeventの使い方しか勉強していないので、さっぱりでございます。 たぶんこのエラーも重くなっている原因の一つだとおもっていますが、、、、、、、、 詳しい方、エラー含め、解決方法、改善方法等、教えていただけませんでしょうか?? 情報不足だった場合、必要な物を教えていただければ、わかる範囲で追記します。 ヒントでも推測でもいいです。ここまで来て挫けたくないです><。 助けてください~><。

    • ベストアンサー
    • Java
  • イベント処理

    javaでプログラムを作り始めて間がないのですが、イベント処理に関して行き詰ってしまいました。望む動作は、メニュー→ゲーム→じゃんけんと選択すると、初期の状態として「じゃんけん・・・・」という文字とボタンが表示され、どれかボタンを押すと対応して「~ボタンが押されました」と表示させたいのですが、作ったプログラムだと、ボタンを押しても反応しません。後々メニューにもいくつかアイテムを追加したり、最終的にはコンピュータとじゃんけんをするプログラムを書きたいと思っています。ifを使った方法しか思いつかないのですが、どこがおかしいのでしょうか? import javax.swing.*; import java.awt.event.*; import java.awt.BorderLayout; public class question extends JFrame implements ActionListener{       JLabel label1;       JPanel p2;       public static void main(String[] args){            question test = new question("質問");            test.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);            test.setVisible(true);       }       question(String title){            setTitle(title);            setBounds( 10, 10, 300, 250);            JMenuBar menuBar = new JMenuBar();            JMenu menu = new JMenu("メニュー");            JMenu submenu = new JMenu("ゲーム");            JMenuItem subitem1 = new JMenuItem("じゃんけん");            subitem1.addActionListener(this);            subitem1.setActionCommand("Start");            submenu.add(subitem1);            menu.add(submenu);            menuBar.add(menu);            setJMenuBar(menuBar);            JPanel p1 = new JPanel();            p2 = new JPanel();            label1 = new JLabel("");            JButton btn1 = new JButton("グー");            btn1.addActionListener(this);            btn1.setActionCommand("goo");            JButton btn2 = new JButton("チョキ");            btn2.addActionListener(this);            btn2.setActionCommand("cyoki");            JButton btn3 = new JButton("パー");            btn3.addActionListener(this);            btn3.setActionCommand("paa");            p1.add(label1);            p2.add(btn1);            p2.add(btn2);            p2.add(btn3);            getContentPane().add(p1, BorderLayout.PAGE_START);            getContentPane().add(p2, BorderLayout.PAGE_END);            p2.setVisible(false);      }      public void actionPerformed(ActionEvent e){            String cmd = e.getActionCommand();            if (cmd.equals("Start")){                 p2.setVisible(true);                 label1.setText("じゃんけん・・・・");                 if (cmd.equals("goo")){                      label1.setText("グーが押されました");                 }else if (cmd.equals("cyoki")){                      label1.setText("チョキが押されました");                 }else if (cmd.equals("paa")){                      label1.setText("パーが押されました");                 }            }       } }

    • ベストアンサー
    • Java
  • パネルの上書きをしたい

    何個のJList等が作成されるか未定で、必要になればその都度JPanelに追加されるというプログラムを考えています。以下のクラスを作成し、呼び出し指定したJPanelに貼り付けることをしました。 2度目の呼び出しは一度目に呼び出して貼り付けられたJList等は不要で表示しないでよいのですが、残したまま追加という形で表示されました。 以前のものが残されているのはJPanelが新しいものではないということがわかりましたのでaddcomを呼び出す前に一度初期化しました。 ですが今度パネルが重なるのか文字が重なる(はっきり重なるわけではなくうっすら文字のようなものが見えます)状態になりました。 表示しているJPanelは別のJPanelのボーダーレイアウトのcenterにその都度貼り付けています。 クラスには問題はないと思われますか? 毎回同じパネルに貼り付ける場合貼り付ける直前に同じ箇所に貼り付けられていたパネルはどうなるのでしょうか?単に貼り付けられなくなるだけなのでしょうか?それとも上から貼り付けられるだけなのでしょうか?いろいろ試していると上から貼り付けられるような気がします。 class addcom{ JPanel addpanel; Vector listaddress; addcom(JPanel addpanel,Vector attribute,Vector listaddress){ this.listaddress = listaddress; this.addpanel = addpanel; } void addList(Vector setattribute){ JList list = new JList(setattribute); addpanel.add(list); listaddress.add(list); } void addLabel(String str,Vector labeladdress){ JLabel label = new JLabel(str); addpanel.add(label); labeladdress.add(label); } void addButton(String str,Vector buttonaddress){ JButton button = new JButton(str); addpanel.add(button); buttonaddress.add(button); } }

    • ベストアンサー
    • Java

専門家に質問してみよう