- - PR -
Appletでマウスの座標の取得について
1
| 投稿者 | 投稿内容 | ||||||||
|---|---|---|---|---|---|---|---|---|---|
|
投稿日時: 2003-11-05 09:36
はじめまして。最近、Appletを始めました。色々とわからないところがあり、
教えていただきたく思います。 現在、Canvasに画像を表示し、その画像をマウスでクリックした座標を 取得したいと思っております。そこでマウスイベントを取得して ダイアログで座標を表示させているのですが、座標の取り方がおかしくてで 上手くいきません。 あと、ある範囲の座標をクリックしたらCanvasの画像を切り替えたりしてみたいの ですが、どのように行ったらよいのかよくわかりません。 下に記述しているプログラムの一部を記述しましたので、おかしい点がありましたら ご指摘よろしくお願いします。Canvasのメソッドは、長くなってしまうため 書いていません。 よろしくお願いいたします。 public class scroll_img extends Applet implements MouseListener{ public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mousePressed(MouseEvent e){ Frame dummy = new Frame(); msgDialog d = new msgDialog(dummy,e); d.setVisible(true); } public void mouseReleased(MouseEvent e){} public void mouseExited(MouseEvent e){} class msgDialog extends Dialog implements ActionListener { Button closeButton; msgDialog(Frame f,MouseEvent e) { super(f,"メッセージダイアログ",true); add("North", new Label("getX()=" + e.getX())); add("Center", new Label("getY()=" + e.getY())); closeButton = new Button("Close"); closeButton.addActionListener(this); add("South", closeButton); pack(); } public void actionPerformed( ActionEvent e){ dispose(); } } | ||||||||
|
投稿日時: 2003-11-05 10:56
MouseListenerをどこに登録しているのか分からないですが、取得できる座標は登録したコンポーネントのローカル座標(コンポーネントの左上を原点とした座標)だったような気がします。Appletの位置を動かしても、同じ所をクリックしていれば、取得される座標は同じになりますよ。
複数枚の画像(Canvas)をループさせる(切り替えるの)であれば、CardLayoutが使えるでしょう。 使用方法は、WEBで検索かければ、たぶん見つかることでしょう。 切り替えのトリガーはMouseListener#mouseClicked()でクリックした座標を監視すれば良いでしょう。もちろんこの時の座標もローカル座標で返ってきますよ。 AppletはWEB Browserから用意された、Frameに張りつけているはずなので、わざわざダミーでフレーム作らなくても、親コンポーネントをたどっていけば、Frameにたどり着くと思います。やり方の詳細は、JOptionPane#getWindowForComponent()のソースコードが参考になると思います。 # mouse clickの度にFrameとDialog作るのを見て目が丸くなってしまった (@_@) 最近、Appletに触っていないので、あまり当てにならないかもしれません。 | ||||||||
|
投稿日時: 2003-11-05 12:22
かずくんさんありがとうございます。
>取得できる座標は登録したコンポーネントのローカル座標(コンポーネントの左上を原点と >した座標)だったような気がします。Appletの位置を動かしても、同じ所をクリックして >いれば、取得される座標は同じになりますよ。 その通りでした。ローカルの座標を取っていました。 例えば、Canvasに貼ってある画像をスクロールバーで動かしたときその画像の 座標って取得できないのでしょうか? >複数枚の画像(Canvas)をループさせる(切り替えるの)であれば、CardLayoutが使えるでしょう。 CardLayoutは使った事がなかったので、現在調べていますが、できそうな感じです 。 >JOptionPane#getWindowForComponent()のソースコードが参考になると思います。 getWindowForComponent()メソッドなのですが、Webで検索すると日本語ページって ないですよね??これってどのようなメソッドなのですか?? よろしくお願いします。 | ||||||||
|
投稿日時: 2003-11-05 13:18
unibon です。こんにちわ。
Swing になりますが、SwingUtilities クラスの convertPoint メソッドが使えます。 http://java.sun.com/j2se/1.4/ja/docs/ja/api/javax/swing/SwingUtilities.html#convertPoint(java.awt.Component,%20java.awt.Point,%20java.awt.Component) なお、もしもアプレットを JDK 1.1 相当の環境で動かされたい場合は、このメソッドは使えませんが、 後述のように JDK に付属のソースコードを見ることはできますので、 動作原理の参考にはできます。
このメソッドはアクセス修飾がデフォルト(package)なので、日本語の解説はないです。 そもそも英語でも API リファレンスには載っていません。 ソースコードは JDK に付属する src.zip などを展開すれば見ることができます。 | ||||||||
|
投稿日時: 2003-11-05 16:06
unibonさん返答ありがとうございます。
convertPointでできそうなのですが、もう少し質問させてください。 認識違いしている可能性があるので。。。 public static Point convertPoint(Component source, Point aPoint, Component destination) ですよね?この引数のsourceとdestinationの部分がよくわからないのですが、 sourceは、Canvasに貼ってある画像でdestinationは、画像全体を 指定すればよいのかと思ったのですが、destinationは、Componentなので Image型の変数は、使用できませんよね?Panelに貼り付けようとしても Panel pane = new Panel(); pane.add(img); としてみたのですが、エラーになってしまいます。 画像全体をComponent型にするにはどうすればよいのでしょうか? すみません。わかりにくい質問になってしまいました。 | ||||||||
|
投稿日時: 2003-11-05 20:37
unibon です。こんにちわ。
現在は Image をどうやって表示していて、 どのようにスクロールされようと目論まれているのでしょうか。 提示されたコードからはそのへんがあまり良く見えません。 Image は Component ではないので、Image を表示しようとすれば、 Component の paint メソッドで drawImage するか、 あるいは、Swing なら JLabel と ImageIcon を組み合わせるなどの 簡易的な描画方法もありますが。 ちなみに convertPoint メソッドは ScrollPane/JScrollPane など、 Container に Component を入れた構成の場合には役に立ちますが、 入れ子になっていないような構成の場合には使えません。 | ||||||||
|
投稿日時: 2003-11-05 22:08
unibonさん本当にありがとうございます。
今、作成しているプログラムです。 お手数ですが、おかしい箇所などを指摘していただけると 嬉しく思います。 import java.applet.*; import java.awt.*; import java.awt.event.*; import javax.swing.*; public class testimg extends Applet implements MouseListener{ int image_width = 893; int image_height = 738; Scrollbar horz_sb = new Scrollbar(Scrollbar.HORIZONTAL); Scrollbar vert_sb = new Scrollbar(Scrollbar.VERTICAL); ImgCanvas image_canvas; Image img; public void init() { img = getImage(getCodeBase(),"test.jpg"); image_canvas = new ImgCanvas(img); image_canvas.addMouseListener(this); setLayout(new BorderLayout()); add("South", horz_sb); add("East", vert_sb); add("Center", image_canvas); } public void start() { Dimension canvas_size = image_canvas.getSize(); horz_sb.setValues(0, canvas_size.width, 0, image_width); vert_sb.setValues(0, canvas_size.height, 0, image_height); } public boolean handleEvent(Event evt) { if ((evt.target == vert_sb) || (evt.target == horz_sb)) { image_canvas.set_image_offset(-horz_sb.getValue(),-vert_sb.getValue()); return true; } return false; } } public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mousePressed(MouseEvent e){ Point pointX = e.getPoint(); Point point = SwingUtilities.convertPoint(image_canvas,pointX,image_canvas1); } public void mouseReleased(MouseEvent e){} public void mouseExited(MouseEvent e){} } class ImgCanvas extends Canvas { Image canvas_image; int x_offset, y_offset; public ImgCanvas(Image img) { super(); canvas_image = img; x_offset = y_offset = 0; } public void set_image_offset(int x, int y){ x_offset = x; y_offset = y; repaint(); } public void paint(Graphics g) { g.drawImage(canvas_image, x_offset, y_offset, this); } | ||||||||
|
投稿日時: 2003-11-05 23:08
unibon です。こんにちわ。
自前で、Scrollbar の値から Canvas のスクロール量を決定しているので、 mousePressed の位置の補正も逆の手順でやるだけで良いと思います。 以下、それを追加した例です。
ただ、画に縦・横のスクロールバーを備えるならば、 通常は ScrollPane を使ったほうが標準的なユーザインターフェースなので良いです。 その場合は mousePressed の引数 MouseEvent の値が、 そのまま求める座標として得られますので、別段 convertPoint も不要です。 convertPoint は、逆に、スクロールする Canvas のスクロール量を無視して フレームを基準とした座標を得たいような感じの場面で使ったりします。 | ||||||||
1
