透過や移動描画をブラシダイアログに設定

前のページで行った透明を利用し、 BrushDialogクラスにスクロールバーを付けます。このスクロールバーの 設定値を透明度にして、ブラシ描画をできるようにします。 そして、マウスの左では、SRC_OVERの合成規則で描画させ、 右ではCLAERの描画にします。
また BrushDialogの画像クリック位置が、描画する時のマウス位置と重なるように、 描画時の位置を移動させます。
以下が目標の作品です。

この動作を行わせるために、PaintPanelとBrushDialogを次のように変更します。

PaintPanelで、AffineTransformオブジェクトの座標変換を伴う描画に変更するので、 PaintPanel.javaに次のインポートを追加します。
import java.awt.geom.*; //AffineTransformのパッケージ

そして、PaintPanelクラスに、次の透明と移動用のインスタンス変数を追加します。
boolean rightMouseKey = false;//右ボタン操作でtrue
float alpha = 0.5F;//不透明(0〜1.0F)
int move_x = 0;//横移動の値
int move_y = 0;//縦移動の値

mousePressedでは次のrightMouseKeyの設定を追加します。

	public void mousePressed(MouseEvent e){// コンポーネント上でマウスボタンが押されると呼び出されます。 
		int evntCode = e.getModifiersEx();//e はmousePressedの引数MouseEvent
		rightMouseKey = (evntCode & MouseEvent.BUTTON3_DOWN_MASK) != 0;
		drawWith(e);
	}

mouseReleasedでも次のrightMouseKeyの設定を追加します。

	public void mouseReleased(MouseEvent e){// コンポーネント上でマウスボタンが離されると呼び出されます。 
		int evntCode = e.getModifiersEx();//e はmousePressedの引数MouseEvent
		rightMouseKey = (evntCode & MouseEvent.BUTTON3_DOWN_MASK) != 0;
	}

そして、パネルへの描画部分は、 このrightMouseKeyがfalseであれば AlphaComposite.CLEARの合成規則で消します。そうでなければ AlphaComposite.SRC_OVERの合成規則で、通常の描画を行います。
また、透明描画や移動描画を行えるよう、次のように変更します。

	public void drawWith(MouseEvent e){
		Point p = e.getPoint();//ドラックした所の座標取得
		Graphics2D g2 = (Graphics2D)this.offscrImg.getGraphics();//描画ツール取得
		AlphaComposite omposite = null;//イメージを合成(composite)する指定を行うクラス
		if (rightMouseKey == false)	{
			omposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
		} else {
			omposite = AlphaComposite.getInstance(AlphaComposite.CLEAR, alpha);
		}
		g2.setComposite(omposite);//合成情報を設定
		AffineTransform trans;//移動描画用
		trans = AffineTransform.getTranslateInstance(move_x, move_y);//移動オブジェクト生成
		trans.translate(p.x, p.y);//マウス位置分の平行移動
		g2.drawImage(brushImg, trans, this);//座標変換を伴う描画
		this.repaint();//再描画の指示
	}

また、上記に対応するようにブラシダイアログを変更します。
BrushDialogクラス に透明度設定用のスクロールバーを付けますが、 それにはJScrollBarクラスを使います。 JScrollBarのコンストラクタで、水平用や垂直用かの定数を指定します。 そして、スクロール幅の最小値を最大値、現在の設定値 (それぞれ、setMinimum、setMaximum、setValueメソッドを使う)を初期指定して使います。
またスクロールバーは、調整値が変更されると、 AdjustmentListenerインターフェイスのadjustmentValueChangedが呼び出されるように作られています。
よってBrushDialogクラスにこれを実装し、 この設定変更で、PaintPanel クラス内の不透明度合い用インスタンス変数alphaを 連動させます。 また、MouseListenerを実装して、そのクリックイベントで描画位置用の移動用インタンス変数を 連動させます
以下に、これら変更を行ったBrushDialogクラスを示します。 この色の部分が変更点です。

//ブラシ用ダイアログ
class BrushDialog extends JDialog implements WindowListener, ComponentListener
			, AdjustmentListener, MouseListener
{
	PaintPanel paintPanel;//作品の描画パネル
	BufferedImage bufImg;//使用するメモリイメージ
	Dimension imgSize;	//上記イメージのサイズ
	
	Dimension panelSize;//パネルサイズ

	JScrollBar scrollBar = new JScrollBar(Adjustable.HORIZONTAL);//透明度合い用
	int move_x = 0;//横移動の値
	int move_y = 0;//縦移動の値

	//----インナー(内部)クラス パネル---------------------------------------
	class BrushPanel extends JPanel
	{
		public BrushPanel(Dimension size)
		{
			imgSize = size;
			this.setPreferredSize(size); //適切なサイズを設定

			//メモリーイメージを作成
			bufImg = new BufferedImage(size.width, size.height, BufferedImage.TYPE_4BYTE_ABGR);
		}

		//描画すべきタイミングで、呼び出されるメソッド
		public void paintComponent(Graphics g)
		{
			super.paintComponent(g);
			Graphics2D g2 = (Graphics2D)g;//これでGraphics2Dの機能も使える
			g2.drawImage(bufImg, 0, 0, this);//メモリイメージをパネルへ描画する追加
		}
	}//----インナー(内部)クラスの終端--------------------
	BrushPanel brushPanel;// 上記インナークラスを管理するインスタンス変数

	//コンストラクタ
	public BrushDialog09(JFrame owner, PaintPanel  panel, Dimension size){
		super(owner);
		this.paintPanel = panel;//作品のパネルを管理
		this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		brushPanel = new BrushPanel(size);//内部
		this.getContentPane().add(brushPanel);
		//スクロールバーの設定値は整数です。そこで、
		//不透明度合いの実際の値を100倍する値を記憶するような設定をしています。
		this.getContentPane().add(this.scrollBar, BorderLayout.SOUTH);
		this.scrollBar.setMinimum(0);
		this.scrollBar.setMaximum(100);
		this.scrollBar.setValue(50);//不透明度合い
		this.pack();//サブコンポーネントの推奨サイズおよびレイアウトに合わせたサイズ変更
		this.setVisible(true);//表示する
		
		panelSize = brushPanel.getSize(null);//初期サイズを記憶
		this.addWindowListener(this);

		this.scrollBar.addAdjustmentListener(this);
		this.addComponentListener(this);
		brushPanel.addMouseListener(this);
	}

	//メモリイメージ中央に、/4サイズの楕円を描画して、PaintPanelのブラシを指定する。
	public void drawOval(Color color){
		Graphics g = bufImg.getGraphics();
		this.setTitle(Integer.toHexString(color.getRGB()));//色の16進数値へ変換し、タイトル設定
		g.setColor(color);
		g.fillOval(0, 0, imgSize.width, imgSize.height);
		this.paintPanel.brushImg = bufImg;//PaintPanelのブラシを変更
		this.repaint();
	}

	//Window がアクティブに変化した時、呼び出されます。
	public void windowActivated(WindowEvent e){
		this.paintPanel.brushImg = bufImg;//PaintPanelのブラシを変更
		this.paintPanel.move_x = this.move_x;//横移動の値
		this.paintPanel.move_y = this.move_y;//縦移動の値
		this.paintPanel.alpha = (float)this.scrollBar.getValue() / 100;
	}
	//dispose の呼び出し結果で、ウィンドウクローズ処理終了時に呼び出されます。
	public void windowClosed(WindowEvent e){
	}
	//ユーザによる閉じるボタン操作などで、閉じる処理直前に呼び出されます。
	public void windowClosing(WindowEvent e){
	}
	//Window がアクティブでなくなったときに呼び出されます。
	public void windowDeactivated(WindowEvent e){
	}
	//最小化状態から通常の状態に変更された時、呼び出されます。
	public void windowDeiconified(WindowEvent e){
	}
	//通常の状態から最小化された状態に変更された時、呼び出されます。
	public void windowIconified(WindowEvent e){
	}
	//ウィンドウが最初に可視になった時、呼び出されます。
	public void windowOpened(WindowEvent e){
	}
	
		
	//コンポーネントが不可視になる時に呼び出される
	public void componentHidden(ComponentEvent e){
	}
	//コンポーネントの位置が変わる時に呼び出される	
	public void componentMoved(ComponentEvent e){
	}
	//コンポーネントのサイズが変わる時に呼び出される	
	public void componentResized(ComponentEvent e){

		Dimension previousSize = panelSize;//以前のパネルサイズ
		panelSize = brushPanel.getSize(null);//変更後サイズを記憶
	
		int type = bufImg.getType();
		int w = imgSize.width * panelSize.width / previousSize.width;
		int h = imgSize.height * panelSize.height / previousSize.height;
		//新しいイメージバッファの生成
		BufferedImage tmpImg = new BufferedImage(w, h, type);
		
		Graphics tmpG = tmpImg.getGraphics();
		tmpG.drawImage(bufImg, 0, 0, w, h,
			0, 0, imgSize.width, imgSize.height, this);//新しいサイズに合わせてサイズ変更コピー
		bufImg = tmpImg;//上記で作成した新しいバッファへ変更

		//System.out.println(imgSize.width + "⇒" + w + "   ,  " + imgSize.height + "⇒" + h);
		imgSize.setSize(new Dimension(w, h));
		paintPanel.brushImg = bufImg;//PaintPanelのブラシを変更
	}
	//コンポーネントが可視になる時に呼び出される
	public void componentShown(ComponentEvent e){
	}

	//スクロールバーの調整値が変更されると呼び出されます
	public void adjustmentValueChanged(AdjustmentEvent e){
		this.paintPanel.alpha = (float)this.scrollBar.getValue() / 100;
		//System.out.println("adjustmentValueChanged" + this.paintPanel.alpha);
	}

	public void mouseEntered(MouseEvent e){// コンポーネントにマウスが入ると呼び出されます。
	}
	public void mousePressed(MouseEvent e){// コンポーネント上でマウスボタンが押されると呼び出されます。 
	}
	public void mouseReleased(MouseEvent e){// コンポーネント上でマウスボタンが離されると呼び出されます。 
	}
	public void mouseClicked(MouseEvent e){//マウスクリック
		Point p = e.getPoint();//ドラックした所の座標取得
		this.paintPanel.move_x = this.move_x = -p.x;//横移動の値
		this.paintPanel.move_y = this.move_y = -p.y;//縦移動の値
	}
	public void mouseExited(MouseEvent e){//コンポーネントからマウスが出ると呼び出されます。 
	}
}

上記を確認後、このボタンをクリックください。→