前のページで行った透明を利用し、
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){//コンポーネントからマウスが出ると呼び出されます。 } }
上記を確認後、このボタンをクリックください。→