• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:長方形を描いて、それを移動させるアップレット)

長方形を描いて、それを移動させるアップレット

tekebonの回答

  • ベストアンサー
  • tekebon
  • ベストアンサー率62% (36/58)
回答No.3

まずpaint()メソッドの中で表示と操作が混ざってしまっているのが問題ですね。 paint()メソッドはウィンドウが重なってて上になった時などその瞬間の表示を するために呼び出されます。 したがって表示のみを行います。現在のr1の表示、drawRectだけすればいいわけです。 そしてマウスのイベントのところでr1を変更し、最後にrepaint()すれば四角の表示が 更新されていきます。r1を変更することが操作になるわけです。 今回は(1)「新規に四角を書く」という操作と(2)「既存の四角を移動させる」という操作があります。 ユーザの操作としてはmousePressedのタイミングで(1)か(2)が決まりますのでフラグ変数を セットしてmouseDraggedやmouseReleasedで条件分岐するとわかりやすいでしょう。 四角形の移動ですが、座標Aでボタンを押し座標Bをとおって座標Cと移動させたとき、座標ABの 差分が移動量になります。Rectangleクラスのtranslate()メソッドを使うと Rectangleオブジェクトに対して移動量を指定することができます。 そして次回のために座標Bを示すp2をp1にコピーし、次回の始点としておきます。 次に座標Cに移動したときには座標BCの差分を求めますので座標Cをp2とすればまた移動量が 求められます。 蛇足ですが移動かどうかを判断するメソッドを作ってすっきりさせることもできます。 たとえばこんな感じ。(操作の違いを色で分かるようにしてみました) 元のプログラムを利用していますので、新規に描画する際、マウスを左上にドラッグすると 右下に大きくなるのは次の課題ですかね(^^; public class RectFrame <略>{ //移動として操作中かどうか boolean isDragged = false; //長方形 Rectangle r1 = new Rectangle(0,0,0,0); //Shiftキーを押したまま、マウスを押した位置と離した位置 Point p1; Point p2; //確認用の色指定 Color col; public void init(){ addMouseListener(this); addMouseMotionListener(this); col = Color.black; //既定値を黒 } public void paint(Graphics g){ //表示処理のみ行う g.setColor(col); g.drawRect(r1.x, r1.y, r1.width, r1.height); } //移動操作かどうかの判定用メソッド private boolean isDraggMode(MouseEvent e){ return ((e.getModifiersEx() & MouseEvent.SHIFT_DOWN_MASK) == MouseEvent.SHIFT_DOWN_MASK) && r1.contains(e.getPoint()); } public void mousePressed(MouseEvent e){ //マウスが長方形の内部に入っているかどうか if(isDraggMode(e)){ //p1はマウスを押した位置, p2はnull p1 = e.getPoint(); p2 = null; isDragged = true; col = Color.red; }else{ r1.setLocation(e.getPoint()); r1.setSize(0,0); col = Color.green; } repaint(); } public void mouseDragged(MouseEvent e){ //マウスの位置 p2 = e.getPoint(); if(isDragged){ r1.translate((p2.x - p1.x),(p2.y - p1.y)); p1 = p2;//次回はこれが始点になる }else{ //最初に描く長方形のサイズを決める r1.setSize(Math.abs(e.getX() - r1.x), Math.abs(e.getY() - r1.y)); } repaint(); } public void mouseReleased(MouseEvent e){ //マウスを離す位置を指定 p2 = e.getPoint(); if(isDragged){ isDragged = false; r1.translate((p2.x - p1.x),(p2.y - p1.y)); p1 = null; p2 = null; }else{ //最初に描く長方形のサイズを決める r1.setSize(Math.abs(p2.x - r1.x), Math.abs(p2.y - r1.y)); } col = Color.black; repaint(); } <マウスリスナのメソッド略> }

buzzard2415
質問者

お礼

うまくいきました。分かりやすい説明をありがとうございました。 paintは表示のみを行うこと、移動にtranslateを使うこと、などがよく分かりました。

関連するQ&A

  • 長方形をドラッグするJavaアップレット

    Javaアップレットについてです。長方形の内部でドラッグすることで、長方形を移動できるプログラ厶を作りたいのですが、うまくいきません。どうしても分からないので、改善点がありましたらアドバイスをお願いします。 詳しい仕様は、 ・長方形の内部でマウスボタンを押し、マウスボタンを押したままマウスを移動すると、移動した量だけ長方形を移動して表示する。 ・マウスボタンを離すと、その位置に長方形を描く。 ・長方形を持ち上げている感じを出すために、マウスボタンを押したときとドラッグ中は、長方形を正確な位置から少しずらして表示し、その下に影を描く。 です。 プログラ厶は以下のとおり import java.awt.*; import java.applet.*; import java.awt.event.*; public class ex1118 extends Applet implements MouseListener, MouseMotionListener{ //長方形の最初の位置 Rectangle r1 = new Rectangle(80,100,80,60); //マウスボタンを押した位置 Point p1; //マウスボタンを離した位置 Point p2; //長方形の内部にあるかどうか boolean enter = false; public void init(){ addMouseListener(this); addMouseMotionListener(this); } public void paint(Graphics g){ g.fillRect(r1.x, r1.y, r1.width, r1.height); if(enter){ //影をつける g.setColor(Color.gray); g.fillRect(p1.x, p1.y, r1.width, r1.height); //少しずらす g.setColor(Color.black); g.fillRect(p1.x - 10, p1.y - 10, r1.width, r1.height); } else if(!enter){ r1.x = r1.x + (p2.x - p1.x); r1.y = r1.y + (p2.y - p1.y); g.fillRect(r1.x, r1.y, r1.width, r1.height); } } public void mousePressed(MouseEvent e){ enter = r1.contains(e.getPoint()); if(enter) p1 = e.getPoint(); p2 = null; repaint(); } public void mouseDragged(MouseEvent e){ if(enter) p2 = e.getPoint(); repaint(); } public void mouseReleased(MouseEvent e){ enter = false; p2 = e.getPoint(); repaint(); } public void mouseClicked(MouseEvent e){} public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){} public void mouseMoved(MouseEvent e){} }

    • ベストアンサー
    • 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
  • 互換性のない型?

    以下のようなプログラムを書いたのですが…。 import java.applet.*; import java.awt.*; import java.awt.event.*; public class okweb extends Applet implements MouseMotionListener{ boolean enter = false; Rectangle r1; Point p1; public void init(){ addMouseMotionListener(this); r1 = getBounds(); } public void paint(Graphics g){ if(p1 != null){ if(enter){ g.drawLine(0, p1.y, r1.width, p1.y); g.drawLine(p1.x ,0, p1.x, r1.height); g.drawString("("+p1.x+", "+p1.y+")", p1.x+10, p1.y-10); } } } public void mouseMoved(MouseEvent e){ enter = r1.contains(e.getPoint()); p1 = e.getPoint(); repaint(); } public void mouseDragged(MouseEvent e){}; } これでコンパイルすると、 okweb.java:29: 互換性のない型 検出値:java.awt.Point 期待値:Point p1 = e.getPoint(); と出るんです。 どうすればいいのでしょうか?

    • ベストアンサー
    • Java
  • アプレットでマウスイベントが出ない

    クリックしても反応しません。 また、マウスイベントが発生したときに飛ぶメソッドにSystem.out.printlnを入れるとException in thread "AWT-EventQueue-0" java.lang.NullPointerException: component argument pDataが出ることがあります。 import java.applet.Applet; import java.awt.Graphics; import java.awt.event.MouseListener; import java.awt.event.MouseEvent; public class NewJApplet extends javax.swing.JApplet implements MouseListener{ int x = 10; int y = 10; public void init() { x = 50; y = 50; } public void mouseClicked(MouseEvent e) { } public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { } public void mousePressed( MouseEvent e ){ x = e.getX(); // マウスがクリックされた位置のx座標を取得する y = e.getY(); // マウスがクリックされた位置のy座標を取得する repaint(); // アプレットの再描画を指示する } public void mouseReleased(MouseEvent e) { } public void paint(Graphics g) { g.fillOval(x,y,10,10); } } 使ってるのは jre1.6.0_01 NetBeans 5.5です

    • ベストアンサー
    • Java
  • 出力するとエラーメッセージが出ます

    FLASHCS4でAS3.0を使ってます。 インスタンス名「_1mc」と言うオブジェクトを作成し、そのオブジェクトが浮遊するアニメーションを作成して、そのオブジェクトにマウスカーソルが触れるとマウスオーバーで「_1mc」の「61」へ移動し、マウスアウトで「1」に移動するように作りました。 そしてプレビューすると動作は特に問題なく作動しますが、出力には下記のようなメッセージが表示されます。このままでも問題ないのでしょうか?または別の記述方法を行う事で、このメッセージは回避出来るのでしょうか?その場合の記述方法を教えてください。 --------------------------------------------------------------- TypeError: Error #1009: null のオブジェクト参照のプロパティまたはメソッドにアクセスすることはできません。 at takaragawa_fla::MainTimeline/xEnterFrame() --------------------------------------------------------------- 「_1mc」を設置してあるフレームには下記のスクリプトを記述しました var step1X:int=Math.floor(Math.random()*1)+5; var step1Y:int=Math.floor(Math.random()*1)+5; if (Math.random()<0.5) { step1X*=-1; } if (Math.random()<0.5) { step1Y*=-1; } _1mc.addEventListener(Event.ENTER_FRAME, x1EnterFrame); function x1EnterFrame(evt) { _1mc.x+=step1X; _1mc.y+=step1Y; if (_1mc.x>=800||_1mc.x<=0) { step1X*=-1; } if (_1mc.y>=550||_1mc.y<=0) { step1Y*=-1; } } //ロールオーバーの設定 _1mc.addEventListener(MouseEvent.ROLL_OVER,xOver); //ロールアウトの設定 _1mc.addEventListener(MouseEvent.ROLL_OUT,xOut); //ロールオーバーしたとき function xOver(evt:MouseEvent):void { _1mc.gotoAndPlay(61); } //ロールアウトしたとき function xOut(evt:MouseEvent):void { _1mc.gotoAndPlay(1); } -------------------------------------------------------------- 以上ですので、アドバイスをお願い致します。よろしくお願い致します。

  • javaアプレット

    javaアプレットの勉強をしているのですが、教えてください。 マウスを押すと位置を取得して、線を描くアプレットをつくってみたいと思っています。 一回目に押した位置を始点として、二回目の位置まで線を引きます。このとき、二回目にマウスを押したときにはじめて線を描画するとします。その後、三回目、四回目とマウスを押していくと、前に押した位置を始点として線を引くようなアプレットです。 そこで以下のようにコードを書いて実行してみました。(部分) public void mousePressed(MouseEvent e) { n=n+1; if(n==1){ x1=e.getX(); y1=e.getY();} else{ x2=e.getX(); y2=e.getY(); repaint(); x1=x2; y1=y2; } } public void paint(Graphics g) { g.drawLine(x1,y1,x2,y2); } ところが、実行してみると、マウスを押す位置に点が移動するだけでした。おそらく、コード中のx1=x2;y1=y2;がrepaint();より前に実行されてしまうのではないかと思います。どう書き直せばいいのでしょうか?また、どうしてrepaint();より前に実行されてしまうのでしょうか?

    • ベストアンサー
    • Java
  • ペイントソフトを作っているのですが・・・

    簡単な絵を書くプログラムを下のようにつくりました。 こんなようなソースが公開されているサイトをご存知のかたは教えていただけないでしょうか?? おねがいします!! import java.awt.*; import java.awt.event.*; public class mouse5 extends Frame implements MouseListener , MouseMotionListener{ //グローバル変数 int x0,y0; Color objectColor = Color.red; //コンストラクタ public mouse5(){ setSize(400,300); //マウスイベント addMouseListener(this); addMouseMotionListener(this); addWindowListener(new WindowAdapter(){ public void windowClosing(WindowEvent e){ System.exit(0); } }); } //paint public void paint(Graphics g){ } //マウスが押されたら public void mousePressed(MouseEvent e){ //始点の座標 x0 = e.getX(); y0 = e.getY(); } //マウスが放されたら public void mouseReleased(MouseEvent e){ } //マウスがクリックされたら public void mouseClicked(MouseEvent e){ } //マウスが画面に入ったら public void mouseEntered(MouseEvent e){ } //マウスが画面から出たら public void mouseExited(MouseEvent e){ } //マウスがドラックされたら public void mouseDragged(MouseEvent e){ //線を引く Graphics g = getGraphics(); g.drawLine(x0,y0,e.getX(),e.getY()); g.dispose(); //次のために始点を更新 x0 = e.getX(); y0 = e.getY(); } //マウスが動いたら public void mouseMoved(MouseEvent e){ } //main public static void main(String[] args) { Frame w = new mouse5(); w.show(); } }

    • ベストアンサー
    • Java
  • MouseEventおよびMouseListenerについて、、

    JAVAの初心者です。。 ただいまMouseEventおよびMouseListenerをもちいて、 とある画像でMouseを用いた距離の測定を行うプログラムを作成中なのですが、、 public void run(){ addMouseListener(this) } public void mouseClicked(MouseEvent e){} public void mousePressed(MouseEvent e){ int x1 = e.getX(); int y1 = e.getY(); } public void mouseReleased(MouseEvent e){ int x2 = e.getX(); int y2 = e.getY(); Line = Math.sqrt((x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1)); } public void mouseEntered(MouseEvent e){] public void mouseExites(MouseEvent e){} プログラムとしてはプレスとリリースで直線距離を測定し、 その後、その距離を用いて他の計算を行うものなのですが、 mouseReleased時にgetX()メソッドをもちいて測定した距離(変数Line)を他のクラスに継承させたいのですがうまくいかないのです。 mouseReleasedメソッドにSystem.out.println(Line)を加えると確かに期待通りの値が出るのですが、 return Line;ではMouseEventメソッドにvoidをつけなければならないために不具合が生じてしまいます。 この変数Lineを他のクラスで使用する場合どのようにすればよいでしょうか、ご指導おねがいします。 また、もう一つの問題点として、このMouseEventを一度起動させると何度マウスを動かしても何度も処理をおこなってしまいます。このMouseEventの終了(可能ならばmouseReleased時に終了)させるためにはどのようなメソッドを加える必要があるでしょうか?? あわせてご教授願います。。

    • ベストアンサー
    • Java
  • JAVAのアプレットのアニメーションの質問

    javaのアプレットに関する質問なんですが、今次の条件でアニメーションを作っているんですが、どうしても解決できない問題があります。 赤い長方形が左から右に動いていくプログラムを作成する。 ・ 長方形が描画領域 の右端に消えると左端から再 度出現するようにせよ。 ・ Reverseと書かれたボタンを押すと長方形の進行方 向が左右反対になる。 ・ このとき、左右どちらの端に長方形が消えた場合も 反対端から長方形は出現する。 ・ 長方形をクリック(ボタン押下)すると長方形の色が 変化する。 ・ 赤い長方形であれば青に、青い長方形であれば赤 に変化する。 この条件でつくろうと思っているのですが、長方形をクリックしたときに、色の変化がどうしてもできません。どこに問題があるか分かりません。御教授お願いします。 import java.applet.Applet; import java.awt.Graphics; import java.awt.Color; import java.awt.Font; import java.awt.Button; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; import java.awt.event.MouseListener; public class Report2 extends Applet implements Runnable,ActionListener,MouseListener{ int x=100; int y=50; int width=80; int height=120; int dir=-2; int w; int z; Button bt; boolean direction; boolean colorRed; public void actionPerformed(ActionEvent ae){ if(direction==true){ direction=false; } else{ direction=true; } } public void init(){ bt=new Button("Reverse"); add(bt); bt.addActionListener(this); Thread th; th =new Thread(this); th.start(); addMouseListener(this); } public void mouseClicked(MouseEvent e){ w=e.getX(); z=e.getY(); repaint(); if(e.getX()>=x && e.getX()<=x+width && e.getY()>=y && e.getY()<=y+height){ colorRed=!colorRed; } } public void mouseEntered(MouseEvent e){ } public void mouseExited(MouseEvent e){ } public void mouseReleased(MouseEvent e){ } public void mousePressed(MouseEvent e){ w=e.getX(); z=e.getY(); repaint(); if(e.getX()>=x && e.getX()<=x+width && e.getY()>=y && e.getY()<=y+height){ colorRed=!colorRed; } } public void run() { while(true){ x++; if(x==400){ x=-80; } if(direction==true){ x=x+dir; } else{ } repaint(); try{ Thread.sleep(30); } catch(InterruptedException e){} } } public void paint(Graphics g){ g.setColor(Color.white); g.fillRect(0,0,400,200); g.setColor(Color.red); g.fillRect(x,y,80,120); if(colorRed=true){ g.setColor(Color.red); } if(colorRed=false){ g.setColor(Color.blue); } g.fillRect(x,y,width,height); g.setColor(Color.black); g.fillRect(x,y,10,10); } }

    • ベストアンサー
    • Java
  • java リアルタイムでマウスの座標を取得したい

    マウスのリアルタイム座標を取得したいのですが、 以下のソースを作りました。 しかし、リアルタイムどころか、マウスをクリックしても座標が取得できません どこを修正すればいいのでしょうか? import java.applet.Applet; import java.awt.*; import java.awt.event.*; import java.awt.event.MouseEvent; import java.net.URL; import java.awt.Image; /*<applet code="applet001" width="640" height="480"></applet>*/ public class applet001 extends Applet implements MouseListener, MouseMotionListener { Dimension dim; int mouse_x, mouse_y; //アプレットの初期化時呼び出される public void init() { dim = getSize(); addMouseListener( this ); } public void update(Graphics g) //オーバーライドして最低限のことだけをする { paint(g); } public void paint(Graphics g) { g.drawString( "マウス:" + mouse_x + "," + mouse_y, 60, 120 ); g.fillOval(mouse_x,mouse_y,30,30); } // マウスの処理 public void mousePressed( MouseEvent e ) { mouse_x = e.getX(); mouse_y = e.getY(); } public void mouseClicked( MouseEvent e ) {} public void mouseReleased( MouseEvent e ) {} public void mouseEntered( MouseEvent e ) {} public void mouseDragged( MouseEvent e ) {} // public void mouseExited( MouseEvent e ) {} // public void mouseMoved( MouseEvent e ) { mouse_x = e.getX(); mouse_y = e.getY(); repaint(); } }

    • ベストアンサー
    • Java