質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

1回答

2869閲覧

Javaでペイントツールを製作しています。

koys

総合スコア8

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

0グッド

0クリップ

投稿2016/02/24 07:01

###前提・実現したいこと
Javaでペイントツールを製作しています。
ドラッグ中は破線で四角形を描画し、ドラッグから離れたら実線で四角形を描画する機能と、
1回だけundoできる機能の実装を考えているのですが、
undo機能の方がうまく動きません。

###発生している問題・エラーメッセージ
要素数2の配列に対して実線が描画された画面の画像を交互に保存し、
undoが呼び出されたら配列から直前の画像を呼び出してrepaintを行う。という方法をとりたいのですが、
repaintメソッドの処理の順番をよく理解できておらず、実線が描画された状態の画像を保存するつもりが
破線の状態の画像を保存してしまいundoに失敗しています。
なにか方法がありましたら教えていただけると助かります。
よろしくお願いいたします。

###ソースコード

Java

1public class DrawTest extends JPanel implements MouseListener, MouseMotionListener, KeyListener{ 2 /*** フィールド ***/ 3 //ウィンドウ 4 JFrame frame; 5 //線 6 BasicStroke graphicStroke; //範囲確定後描画用の実線 7 BasicStroke dashStroke; //範囲確定前描画用の点線 8 9 //画像 10 BufferedImage buf; //キャプチャ画像 11 Graphics2D b2; //キャプチャ画像の描画情報 12 BufferedImage[] imgList; //undo用配列 13 Boolean confirm; //範囲確定判断 14 int imageCount; //描画した回数 15 16 //座標 17 int x1,y1; //始点座標 18 int x2,y2; //終点座標 19 20 /*** コンストラクタ ***/ 21 public DrawTest() { 22 // ウィンドウ 23 java.awt.GraphicsEnvironment env = java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment(); 24 java.awt.DisplayMode displayMode = env.getDefaultScreenDevice().getDisplayMode(); 25 int frameWidth = displayMode.getWidth(); 26 int frameHeight = displayMode.getHeight(); 27 frame = new JFrame(); 28 frame.setUndecorated(true); 29 frame.setSize(frameWidth, frameHeight); 30 31 // 画像 32 buf = captureDisplay(); 33 imgList = new BufferedImage[2]; 34 imgList[0] = deepCopy(buf); 35 imgList[1] = deepCopy(buf); 36 Graphics b = buf.createGraphics(); 37 b2 = (Graphics2D) b; 38 39 // 線 40 float[] dash = { 10.0f, 5.0f, 20.0f, 5.0f }; 41 graphicStroke = new BasicStroke(15, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER); 42 dashStroke = new BasicStroke(5.0f, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER, 10.0f, dash, 0.0f); 43 b2.setStroke(graphicStroke); 44 b2.setColor(Color.BLACK); 45 46 // 初期化 47 confirm = false; 48 imageCount = 0; 49 50 // リスナー 51 frame.addMouseListener(this); 52 frame.addMouseMotionListener(this); 53 frame.addKeyListener(this); 54 55 // 可視化 56 frame.getContentPane().add(this); 57 frame.setVisible(true); 58 frame.isFocusable(); 59 } 60 61 /*** 描画 ***/ 62 public void paintComponent(Graphics g){ 63 Graphics2D g2 = (Graphics2D) g; 64 g2.setStroke(dashStroke); 65 g2.setColor(Color.BLACK); 66 67 // 左上の座標と幅と高さ 68 int rectX = x1; 69 int rectY = y1; 70 int rectW = x2 - x1; 71 int rectH = y2 - y1; 72 73 // 座標調整 74 if (rectW < 0 && rectH >= 0) { 75 rectX = x2; 76 rectW = x1 - x2; 77 } else if (rectH < 0 && rectW >= 0) { 78 rectY = y2; 79 rectH = y1 - y2; 80 } else if (rectH < 0 && rectW < 0) { 81 rectX = x2; 82 rectY = y2; 83 rectW = x1 - x2; 84 rectH = y1 - y2; 85 } 86 87 // mouseReleasedから呼び出されていればtrue 88 if(confirm){ 89 // 画像に実線で描画 90 b2.drawRect(rectX, rectY, rectW, rectH); 91 int rem = imageCount % 2; 92 imgList[rem] = captureDisplay(); 93 94 imageCount++; 95 confirm = false; 96 } 97 98 // キャプチャ画像をパネルに反映 99 g2.drawImage(buf, 0, 0, this); 100 101 // パネルに破線で描画 102 g2.drawRect(rectX, rectY, rectW, rectH); 103 104 } 105 106 /*** 画面をキャプチャ ***/ 107 public BufferedImage captureDisplay() { 108 BufferedImage image = null; 109 try { 110 image = new Robot().createScreenCapture(new Rectangle(Toolkit.getDefaultToolkit().getScreenSize())); 111 } catch (HeadlessException | AWTException e) { 112 e.printStackTrace(); 113 } 114 return image; 115 } 116 117 /*** BufferedImage型のclone作成 ***/ 118 public static BufferedImage deepCopy(BufferedImage original) { 119 ColorModel cm = original.getColorModel(); 120 boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); 121 WritableRaster raster = original.copyData(original.getRaster().createCompatibleWritableRaster()); 122 return new BufferedImage(cm, raster, isAlphaPremultiplied, null); 123 } 124 125 /*** undo ***/ 126 public void undo(){ 127 int rem = imageCount % 2; 128 if(rem == 0){ 129 buf = deepCopy(imgList[0]); 130 imgList[1] = deepCopy(imgList[0]); 131 }else{ 132 buf = deepCopy(imgList[1]); 133 imgList[0] = deepCopy(imgList[1]); 134 } 135 } 136 137 /*** 以下リスナーで呼び出されるメソッド ***/ 138 public void mousePressed(MouseEvent e) { 139 // 始点更新 140 x1 = e.getX(); 141 y1 = e.getY(); 142 } 143 144 public void mouseDragged(MouseEvent e) { 145 // 終点更新 146 x2 = e.getX(); 147 y2 = e.getY(); 148 149 repaint(); 150 } 151 152 public void mouseClicked(MouseEvent e) { 153 // 右クリックが押されたらundo実行 154 if(e.getButton() == MouseEvent.BUTTON3){ 155 undo(); 156 } 157 } 158 159 public void mouseReleased(MouseEvent e) { 160 // 終点更新後、範囲確定フラグにtrueを入れて再描画 161 x2 = e.getX(); 162 y2 = e.getY(); 163 164 confirm = true; 165 repaint(); 166 } 167 168 public void keyPressed(KeyEvent e) { 169 // ESCが押されたら終了 170 if(e.getKeyCode() == KeyEvent.VK_ESCAPE){ 171 System.exit(0); 172 } 173 } 174 175 /*** main ***/ 176 public static void main(String[] args) { 177 DrawTest dtest = new DrawTest(); 178 }

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

自己解決したため質問を取り下げさせていただきます

投稿2016/02/25 06:28

koys

総合スコア8

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

argius

2016/02/26 13:08

解決されたようですので、ベストアンサーを付けて解決済みにしていただけると助かります。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問