teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

コード追加

2020/03/29 06:22

投稿

jimbe
jimbe

スコア13355

answer CHANGED
@@ -185,4 +185,167 @@
185
185
  new SimpleDraw02().setVisible(true);
186
186
  }
187
187
  }
188
+ ```
189
+ #追加2
190
+ リンク先での「線の色を指定できるように」という課題でのヒントにおきまして「『Javaって何ですか?』の章の例題が参考」とありますが, アプレット(AWT)ですので, アプリケーション(Swing)化しました.
191
+ 色の設定は Choice(AWT) から JComboBox(Swing) に変わりますが, 扱い方(addItem 等)はあえて変えていません.
192
+ ```java
193
+ //package teratail.q249928;
194
+
195
+ import java.awt.*;
196
+ import java.awt.event.*;
197
+
198
+ import javax.swing.*;
199
+
200
+ // Lineクラス
201
+ class Line {
202
+ Point sp, ep; // 始点と終点
203
+ Color color; // 色
204
+
205
+ // コンストラクタ
206
+ Line(Point p1, Point p2, Color c) {
207
+ sp=p1; ep=p2; color=c;
208
+ }
209
+ // 描画
210
+ void draw(Graphics g) {
211
+ g.setColor(color);
212
+ g.drawLine(sp.x, sp.y, ep.x, ep.y);
213
+ }
214
+ }
215
+
216
+ // JControlPanelクラス
217
+ class JControlPanel extends JPanel implements ActionListener {
218
+ private JSimpleDrawMain app;
219
+ // コンストラクタ
220
+ public JControlPanel(JSimpleDrawMain app) {
221
+ super(new FlowLayout());
222
+ this.app = app;
223
+ JComboBox<String> ch = new JComboBox<>();
224
+ ch.addItem("Black");
225
+ ch.addItem("Red");
226
+ ch.addItem("Blue");
227
+ ch.addItem("Green");
228
+ ch.addItem("Yellow");
229
+ ch.addItem("Gray");
230
+ ch.addItem("Pink");
231
+ ch.addActionListener(this);
232
+ add(ch);
233
+
234
+ JButton clearButton = new JButton("Clear");
235
+ clearButton.addActionListener(this);
236
+ add(clearButton);
237
+ }
238
+ // アクション処理
239
+ @Override
240
+ public void actionPerformed(ActionEvent e) {
241
+ if(e.getSource() instanceof JComboBox) {
242
+ String arg = (String)((JComboBox<?>)e.getSource()).getSelectedItem();
243
+ if(arg.equals("Black")) app.color=Color.BLACK;
244
+ else if(arg.equals("Red")) app.color=Color.RED;
245
+ else if(arg.equals("Blue")) app.color=Color.BLUE;
246
+ else if(arg.equals("Green")) app.color=Color.GREEN;
247
+ else if(arg.equals("Yellow")) app.color=Color.YELLOW;
248
+ else if(arg.equals("Gray")) app.color=Color.GRAY;
249
+ else if(arg.equals("Pink")) app.color=Color.PINK;
250
+ }
251
+ if(e.getSource() instanceof JButton) {
252
+ String arg = ((JButton)e.getSource()).getText();
253
+ if(arg.equals("Clear")) app.clear();
254
+ }
255
+ }
256
+ }
257
+
258
+ // JDrawCanvasクラス
259
+ class JDrawCanvas extends JPanel {
260
+ private JSimpleDrawMain app;
261
+ private Point p1, p2; // 描画中の始点と終点
262
+
263
+ // コンストラクタ
264
+ public JDrawCanvas(JSimpleDrawMain app) {
265
+ super(null);
266
+ this.app = app;
267
+ setBackground(Color.WHITE);
268
+
269
+ addMouseListener(new MouseAdapter() {
270
+ // マウスボタンが押された
271
+ @Override
272
+ public void mousePressed(MouseEvent e) {
273
+ Graphics g = getGraphics();
274
+ g.setXORMode(getBackground());
275
+ p2 = p1 = new Point(e.getX(), e.getY());
276
+ g.drawLine(p1.x, p1.y, p2.x, p2.y);
277
+ g.dispose();
278
+ }
279
+
280
+ // マウスボタンが離された
281
+ @Override
282
+ public void mouseReleased(MouseEvent e) {
283
+ Graphics g = getGraphics();
284
+ g.setXORMode(getBackground());
285
+ g.drawLine(p1.x, p1.y, p2.x, p2.y);
286
+ g.setPaintMode();
287
+ p2 = new Point(e.getX(), e.getY());
288
+ if(app.line_num < JSimpleDrawMain.LINEMAX) {
289
+ app.lines[app.line_num] = new Line(p1, p2, app.color);
290
+ app.lines[app.line_num++].draw(g);
291
+ }
292
+ g.dispose();
293
+ }
294
+ });
295
+
296
+ addMouseMotionListener(new MouseMotionAdapter() {
297
+ // マウスがドラッグされた
298
+ @Override
299
+ public void mouseDragged(MouseEvent e) {
300
+ Graphics g = getGraphics();
301
+ g.setXORMode(getBackground());
302
+ g.drawLine(p1.x, p1.y, p2.x, p2.y);
303
+ p2 = new Point(e.getX(), e.getY());
304
+ g.drawLine(p1.x, p1.y, p2.x, p2.y);
305
+ g.dispose();
306
+ }
307
+ });
308
+ }
309
+ // 再描画
310
+ public void paintComponent(Graphics g) {
311
+ super.paintComponent(g);
312
+ for(int i = 0; i < app.line_num; i++)
313
+ app.lines[i].draw(g);
314
+ }
315
+ }
316
+
317
+ public class JSimpleDrawMain extends JPanel {
318
+ static final int LINEMAX = 100; // 最大線数
319
+ int line_num; // 現在の線数
320
+ Line[] lines; // 線データ
321
+ Color color; // 現在の色
322
+ JDrawCanvas dc; // 描画キャンバス
323
+
324
+ // 初期化
325
+ public void init() {
326
+ setBackground(Color.white);
327
+ line_num = 0;
328
+ lines = new Line[LINEMAX];
329
+ color = Color.BLACK;
330
+ setLayout(new BorderLayout());
331
+ add(new JControlPanel(this), BorderLayout.SOUTH);
332
+ add(dc = new JDrawCanvas(this), BorderLayout.CENTER);
333
+ }
334
+
335
+ // メイン
336
+ public static void main(String[] args) {
337
+ JFrame f = new JFrame("JSimpleDrawMain");
338
+ f.setSize(400,300);
339
+ JSimpleDrawMain a = new JSimpleDrawMain();
340
+ f.add(a, BorderLayout.CENTER);
341
+ a.init();
342
+ f.setVisible(true);
343
+ }
344
+
345
+ // クリア
346
+ public void clear() {
347
+ line_num = 0;
348
+ dc.repaint();
349
+ }
350
+ }
188
351
  ```

2

コード追加

2020/03/29 06:22

投稿

jimbe
jimbe

スコア13355

answer CHANGED
@@ -4,4 +4,185 @@
4
4
  「何を見て解決」というなら, 参考にされている記事・コードしかありません.
5
5
  要は, 線をどうデータとして表現しているか, その表現の中で"消す"というのはどういうことかを理解しているかどうかです.
6
6
  複数のプラモデルを組み合わせて新しいものを作ろうとするなら, 元のプラモデルの構造を理解している必要があるはずです.
7
- (「理解が及んでいないことは重々承知している」なればこそ)参考にされている記事・コードの理解を進めることをお勧めします.
7
+ (「理解が及んでいないことは重々承知している」なればこそ)参考にされている記事・コードの理解を進めることをお勧めします.
8
+
9
+ #追加
10
+ リンク先の SimpleDraw02 を Swing 化するとこのような感じでしょうか.
11
+ なるべく元の状態を維持しつつ…と思ったのですが, 描画領域は専用クラス(CanvasPanel)にしないと面倒そうでしたので諦め, 各リスナも無名クラス化してしまいました.
12
+ ```java
13
+ //package teratail.q249928;
14
+
15
+ import java.awt.*;
16
+ import java.awt.event.*;
17
+ import java.util.ArrayList;
18
+ import java.util.List;
19
+
20
+ import javax.swing.*;
21
+
22
+ /**
23
+ * 線分情報クラス <p>
24
+ * 描画された1本の線分の情報を記憶しておくためのクラスです。
25
+ * 線分情報には、始点座標と終点座標とがあります。
26
+ */
27
+ class SegmentInfo {
28
+
29
+ /** 始点座標 */
30
+ private int x1, y1;
31
+
32
+ /** 終点座標 */
33
+ private int x2, y2;
34
+
35
+ /** 色 */
36
+ private Color color;
37
+
38
+ /** 始点と終点を与えて生成します。 */
39
+ SegmentInfo(int x1, int y1, int x2, int y2, Color color) {
40
+ this.x1 = x1;
41
+ this.y1 = y1;
42
+ this.x2 = x2;
43
+ this.y2 = y2;
44
+ this.color = color;
45
+ }
46
+
47
+ /** 自分自身を描画します。 */
48
+ void draw(Graphics g) {
49
+ g.setColor(color);
50
+ g.drawLine(x1, y1, x2, y2);
51
+ }
52
+ }
53
+
54
+ class CanvasPanel extends JPanel {
55
+ /** 線分の描画のための座標. */
56
+ private int lx1, ly1, lx2, ly2;
57
+
58
+ /** 線分情報を記憶しておくためのベクトル. */
59
+ private List<SegmentInfo> data = new ArrayList<SegmentInfo>();
60
+
61
+ private Color color = new Color(100,255,100);
62
+
63
+ CanvasPanel() {
64
+ super(null);
65
+ setBackground(Color.WHITE);
66
+
67
+ addMouseListener(new MouseAdapter() {
68
+ /**
69
+ * マウスボタンが押されると、その後のマウスの動きを追跡して仮の線を引く必要があります。
70
+ */
71
+ @Override
72
+ public void mousePressed(MouseEvent e) {
73
+ lx1 = lx2 = e.getX();
74
+ ly1 = ly2 = e.getY();
75
+ drawXORLine();
76
+ }
77
+
78
+ /**
79
+ * マウスボタンが離されると、以前の仮の線を消して、確定した直線を描きます。
80
+ */
81
+ @Override
82
+ public void mouseReleased(MouseEvent e) {
83
+ drawXORLine();
84
+ lx2 = e.getX();
85
+ ly2 = e.getY();
86
+ data.add(new SegmentInfo(lx1, ly1, lx2, ly2, color));
87
+ repaint();
88
+ }
89
+ });
90
+
91
+ addMouseMotionListener(new MouseMotionAdapter() {
92
+ /**
93
+ * マウスがドラッグされると、それまでの仮の線を消して、新しい仮の線を描きます。
94
+ */
95
+ @Override
96
+ public void mouseDragged(MouseEvent e) {
97
+ drawXORLine();
98
+ lx2 = e.getX();
99
+ ly2 = e.getY();
100
+ drawXORLine();
101
+ }
102
+ });
103
+ }
104
+
105
+ /** 仮の線分の描画. */
106
+ private void drawXORLine() {
107
+ // XORモードで仮の線分を描画します。
108
+ // XORモードで描かれた線分は、再度同じ線分を描画すると消えます。
109
+ Graphics g = getGraphics();
110
+ g.setXORMode(getBackground());
111
+ g.drawLine(lx1, ly1, lx2, ly2);
112
+ g.dispose();
113
+ }
114
+
115
+ /** すべての線分を描画します。 */
116
+ @Override
117
+ public void paintComponent(Graphics g) {
118
+ super.paintComponent(g);
119
+ for(SegmentInfo e : data) e.draw(g);
120
+ }
121
+
122
+ /** 全データを消して、再描画します。 */
123
+ void clear() {
124
+ data.clear();
125
+ repaint();
126
+ }
127
+ }
128
+
129
+ public class SimpleDraw02 extends JFrame {
130
+
131
+ public SimpleDraw02() {
132
+ super("SimpleDraw ver 0.2(Swing)");
133
+ setSize(1000, 1000);
134
+ setLocationRelativeTo(null);
135
+
136
+ setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
137
+ addWindowListener(new WindowAdapter() {
138
+ @Override
139
+ public void windowClosing(WindowEvent e) {
140
+ quit();
141
+ }
142
+ });
143
+
144
+ CanvasPanel canvas = new CanvasPanel();
145
+ add(canvas, BorderLayout.CENTER);
146
+
147
+ JPanel eastPanel = new JPanel(new FlowLayout());
148
+ add(eastPanel, BorderLayout.EAST);
149
+
150
+ JButton quitButton = new JButton("Quit");
151
+ quitButton.addActionListener(new ActionListener() {
152
+ /** Quit ボタンが押されたときの処理を行います。 */
153
+ @Override
154
+ public void actionPerformed(ActionEvent e) {
155
+ quit();
156
+ }
157
+ });
158
+ eastPanel.add(quitButton);
159
+
160
+ JButton clearButton = new JButton("Clear");
161
+ clearButton.addActionListener(new ActionListener() {
162
+ /** Clear ボタンが押されたときの処理を行います。 */
163
+ @Override
164
+ public void actionPerformed(ActionEvent e) {
165
+ canvas.clear();
166
+ }
167
+ });
168
+ eastPanel.add(clearButton);
169
+ }
170
+
171
+ /**
172
+ * プログラムを終了します。
173
+ * 終了にはいくつかの方法がありますが、すべてここでその処理を行うことで、動作の統一を図ります。
174
+ */
175
+ void quit() {
176
+ System.exit(0);
177
+ }
178
+
179
+ /**
180
+ * クラスを直接実行すると、このメソッドから開始されます。
181
+ * ここでは、クラス自身のインスタンスを作ってそれを表示しています。
182
+ * これにより、クラスの実行が開始されます。
183
+ */
184
+ public static void main(String[] args) {
185
+ new SimpleDraw02().setVisible(true);
186
+ }
187
+ }
188
+ ```

1

追加

2020/03/28 12:26

投稿

jimbe
jimbe

スコア13355

answer CHANGED
@@ -4,4 +4,4 @@
4
4
  「何を見て解決」というなら, 参考にされている記事・コードしかありません.
5
5
  要は, 線をどうデータとして表現しているか, その表現の中で"消す"というのはどういうことかを理解しているかどうかです.
6
6
  複数のプラモデルを組み合わせて新しいものを作ろうとするなら, 元のプラモデルの構造を理解している必要があるはずです.
7
- 参考にされている記事・コードの理解を進めることをお勧めします.
7
+ (「理解が及んでいないことは重々承知している」なればこそ)参考にされている記事・コードの理解を進めることをお勧めします.