ページ 11

[Java]ペイントツールの機能が実装できない

Posted: 2016年1月17日(日) 00:13
by 河童惇
[1] 質問文
 [1.1] 自分が今行いたい事は何か
  Javaで作成する自由曲線と直線が描けるペイントツールを作りたいです。今の段階では、ソースコードを書き換えてのモード変更です。
 [1.2] どのように取り組んだか(プログラムコードがある場合記載)

コード:

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Vector;

public class tool{
	public static void main(String args[]){
		JFrame myfra = new mypaint();
		myfra.setSize(400, 350);//windowのサイズ設定
		myfra.setVisible(true);
		myfra.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
	}
}

class mypaint extends JFrame{

	int x1 = 0, y1 = 0; //始点
	int x2 = 0, y2 = 0; //終点
	int x3 = 0, y3 = 0; //前の終点
	String str = "Start!";

	public static final int FREE = 0; //FREE を0と定義する
	public static final int LINE = 1; //LINE を1と定義する


	int mode = FREE; //今はここでmodeの指定


	//描画した図形の保管
	Vector shapes = new Vector();

	//コンストラクタ
	//背景色に白を指定する
	//マウスイベントリスナーをつける
	public mypaint(){

		Container mycont = getContentPane();
		mycont.setForeground(Color.red);
		mycont.setBackground(Color.white);

		mycont.addMouseListener(new MyMouseListen());
		mycont.addMouseMotionListener(new MyMouseListen());

	}

	//modeを指定する
	public void setDrawMode(int mode){

		switch(mode){

			case FREE:
			case LINE:
				this.mode = mode;
				break;
			default:
				break;
		}
	}

	class MyMouseListen implements MouseListener, MouseMotionListener{

		public void mouseClicked(MouseEvent e){
		}
		
		//マウスボタンを押した際の処理
		public void mousePressed(MouseEvent e){

			Graphics g = getGraphics();

			switch(mode){

				case FREE:
					
					x1 = e.getX();
					y1 = e.getY();
					shapes.addElement(new Rectangle(x1,y1,x1,y1));

				case LINE:

					x1 = e.getX();
					y1 = e.getY();

					x2 = -1; //フラグ代わり
					break;

				default:
					break;
			}
		}

		public void mouseDragged(MouseEvent e){

			Graphics md = getGraphics();

			switch(mode){

				case FREE:

					x2 = e.getX();
					y2 = e.getY();
	
					md.drawLine(x1, y1, x2, y2);
					shapes.addElement(new Rectangle(x1,y1,x2,y2));

					x1 = x2; //新たな始点
					y1 = y2; //新たな始点
					break;

				case LINE:
					x3 = x2;
					y3 = y2;
					x2 = e.getX(); //終点
					y2 = e.getY();
					break;
				default:
					break;
			}
		}

		public void mouseReleased(MouseEvent e){

			Graphics g = getGraphics();

			switch(mode){

				case FREE:
					x1 = e.getX();
					y1 = e.getY();

				case LINE:

					shapes.addElement(new Rectangle(x1,y1,e.getX(),e.getY()));
					x2 = x3 = -1; //ラバーバンド描画消去処理が通らないようにフラグをセットする
					break;

				default:
					break;
			}
		}

		public void mouseEntered(MouseEvent e){
				}

		public void mouseExited(MouseEvent e){
				}
		public void mouseMoved(MouseEvent e){
				}
	}

	//描画処理
	public void paint(Graphics g){
		int number = shapes.size();
		for(int i = 0; i < number; i++){
			Rectangle data = (Rectangle)shapes.elementAt(i);
			g.drawLine(data.x, data.y, data.width, data.height);
		}
		if (mode == LINE){
			g.setColor(getBackground());
			if(x3 != -1){	//ドラッグの時のみ
				g.drawLine(x1, y1, x3, y3); //前に描いた線を背景色で消す
			}
			g.setColor(getForeground());
			if(x2 != -1){ //ボタンを押したときと、ドラッグのときに通る
				g.drawLine(x1, y1, x2, y2); //今度描こうとしている線を描く
			}
		}
		
		super.paint(g);
		setTitle(str);
	}
}
 [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
    ・modeをLINEにした際に直線が描かれない。
    ・プログラムを最小化した後、再度表示させたとき画面が初期化?されてしまう。

 [1.4] 今何がわからないのか、知りたいのか
 1.3のトラブルの解決方法が知りたいです。

[2] 環境  
 [2.1] OS : Windows, Linux等々
windowsです
 [2.2] コンパイラ名 : VC++ 2008EE, Borand C++, gcc等々
gccです

[3] その他
 ・どの程度Java言語を理解しているか
初心者です。

調べてみて、試行錯誤しましたが、解決することができませんでした。どなたかご教授お願いします・・・

Re: [Java]ペイントツールの機能が実装できない

Posted: 2016年1月17日(日) 18:01
by asd
どのようなことを調べ、どのような試行錯誤をされたのか分からないので道筋教示のみです。
河童惇 さんが書きました:  [1.3] どのようなエラーやトラブルで困っているか(エラーメッセージが解る場合は記載)
    ・modeをLINEにした際に直線が描かれない。
modeがFREEの場合は思った通り(マウスドラッグのタイミングで)描画されているようなので、
LINEの場合との違いを探してみてはいかがでしょうか?

*FREEの場合
 1.マウスプレス時に描画始点を記録
 2.ドラッグ発生時にその地点を描画終点としてラインを描画、その終点を描画始点として更新する
  また描画したラインの始点、終点をオブジェクトとして保持しておく
 3.2をマウスリリースまで繰り返す

*LINEの場合(私の想定含む)
 1.マウスプレス時に描画始点を記録
 2.ドラッグ発生時に前回描画した終点があればその地点を描画終点として背景色でラインを描画(1つ前のラインを消すため)
  続いてその地点を描画終点として前景色でラインを描画
 3.2をマウスリリースまで繰り返す
 4.マウスリリース時にその地点を描画終点としてラインの始点、終点をオブジェクトとして保持しておく
河童惇 さんが書きました:     ・プログラムを最小化した後、再度表示させたとき画面が初期化?されてしまう。
描画済みのオブジェクトはmodeがFREE時について保持できているようですが、
その描画順序に問題があるようです。
paintメソッド中でオブジェクトの描画の後、super.paint(g);にて親クラスのpaintメソッドを呼び出しています。
この親クラスのメソッドを呼び出した際にはどのような処理が行われるのかわかりますか?

細かい部分は指摘割愛してますが、下記の部分を調査するといいと思います。

・各メソッドがどのタイミングで呼ばれているのか?
・各メソッド中でのフィールドが自分の思っている通りの値になっているか?