001:import java.awt.event.* ; // ActionEvent MouseEvent MouseAdapter WindowEvent WindowAdapter
002:import javax.swing.* ; // ButtonGroup JFrame JLabel JPanel JRadioButton JTextField
003:import java.awt.* ; // BorderLayout Color Container Dimension Graphics Graphics2D
004:import java.awt.geom.RectangularShape;
005:import java.awt.geom.Ellipse2D;
006:import java.awt.geom.Rectangle2D;
007:import java.awt.geom.PathIterator;
008:import java.awt.geom.AffineTransform;
009:import java.awt.geom.Point2D;
010:import java.awt.geom.GeneralPath;
011:
012:interface ColoredShape extends Shape {
013: public double getX();
014: public double getY();
015: public double getWidth();
016: public double getHeight();
017: public void setFrame(double x, double y, double w, double h);
018: public void draw(Graphics2D gg);
019:}
020:
021:class ColoredEllipse extends Ellipse2D.Double
022: implements ColoredShape {
023: Color color;
024: boolean spread;
025:
026: ColoredEllipse(double x, double y, double w, double h, Color c, boolean s) {
027: super(x, y, w, h);
028: color = c;
029: spread = s;
030: }
031:
032: public void draw(Graphics2D gg) {
033: gg.setColor(color);
034: if(spread) gg.fill(this);
035: else gg.draw(this);
036: }
037:}
038:
039:class ColoredRectangle extends Rectangle2D.Double
040: implements ColoredShape {
041: Color color;
042: boolean spread;
043:
044: ColoredRectangle(double x, double y, double w, double h, Color c, boolean s) {
045: super(x, y, w, h);
046: color = c;
047: spread = s;
048: }
049:
050: public void draw(Graphics2D gg) {
051: gg.setColor(color);
052: if(spread) gg.fill(this);
053: else gg.draw(this);
054: }
055:}
056:
057:class TrianglePath implements PathIterator {
058: int index = 0;
059: AffineTransform affine = new AffineTransform();
060: double[] x = new double[3];
061: double[] y = new double[3];
062:
063: TrianglePath(double x, double y, double w, double h, boolean ud) {
064: if(ud) {
065: this.x[0] = x+w*0.5;
066: this.y[0] = y;
067: this.x[1] = x;
068: this.y[1] = y+h;
069: this.x[2] = x+w;
070: this.y[2] = y+h;
071: } else {
072: this.x[0] = x;
073: this.y[0] = y;
074: this.x[1] = x+w;
075: this.y[1] = y;
076: this.x[2] = x+w*0.5;
077: this.y[2] = y+h;
078: }
079: }
080:
081: public int currentSegment(double[] path) {
082: if(index>2) return PathIterator.SEG_CLOSE;
083: Point2D.Double p = new Point2D.Double(x[index], y[index]);
084: affine.transform(p,p);
085: path[0] = p.x;
086: path[1] = p.y;
087: if(index==0) return PathIterator.SEG_MOVETO;
088: else return PathIterator.SEG_LINETO;
089: }
090:
091: public int currentSegment(float[] path) {
092: if(index>2) return PathIterator.SEG_CLOSE;
093: Point2D.Double p = new Point2D.Double(x[index], y[index]);
094: affine.transform(p,p);
095: path[0] = (float)p.x;
096: path[1] = (float)p.y;
097: if(index==0) return PathIterator.SEG_MOVETO;
098: else return PathIterator.SEG_LINETO;
099: }
100:
101: public int getWindingRule() { return PathIterator.WIND_EVEN_ODD; }
102:
103: public boolean isDone() {
104: if(index<4) return false;
105: else return true;
106: }
107:
108: public void next() { index++; }
109:
110: public void setAffine(AffineTransform at) { affine = at; }
111:}
112:
113:class ColoredTriangle extends RectangularShape
114: implements ColoredShape {
115: Color color;
116: boolean spread;
117: boolean upsidedown;
118: GeneralPath path = new GeneralPath();
119: TrianglePath pathIterator;
120: double x;
121: double y;
122: double w;
123: double h;
124:
125: ColoredTriangle(double x, double y, double w, double h,
126: Color c, boolean ud, boolean s) {
127: this.x = x;
128: this.y = y;
129: this.w = w;
130: this.h = h;
131: color = c;
132: upsidedown = ud;
133: spread = s;
134:
135: pathIterator = new TrianglePath(x, y, w, h, ud);
136: path.append(pathIterator, true);
137: }
138:
139: public double getX() { return x; }
140: public double getY() { return y; }
141: public double getWidth() { return w; }
142: public double getHeight() { return h; }
143: public void setFrame(double x, double y, double w, double h){
144: double xd = x - this.x;
145: double yd = y - this.y;
146: this.x = x;
147: this.y = y;
148: this.w = w;
149: this.h = h;
150: path.transform(AffineTransform.getTranslateInstance(xd,yd));
151: pathIterator.affine.concatenate(AffineTransform.getTranslateInstance(xd,yd));
152: }
153: public void draw(Graphics2D gg) {
154: gg.setColor(color);
155: if(spread) gg.fill(this);
156: else gg.draw(this);
157: }
158: public boolean isEmpty() { return false; }
159: public PathIterator getPathIterator(AffineTransform at) {
160: TrianglePath pi = new TrianglePath(x, y, w, h, upsidedown);
161: pi.setAffine(at);
162: return pi;
163: }
164: public Rectangle2D getBounds2D() {
165: throw(new UnsupportedOperationException());
166: }
167: public boolean intersects(double x, double y, double w, double h) {
168: if(this.x+this.w<x) return false;
169: if(x+w<this.x) return false;
170: if(this.y+this.h<y) return false;
171: if(y+h<this.y) return false;
172: return true;
173: }
174: public boolean contains(double x, double y, double w, double h) {
175: throw(new UnsupportedOperationException());
176: }
177: public boolean contains(double x, double y) {
178: if(x<this.x) return false;
179: if(x>(this.x+w)) return false;
180: if(y<this.y) return false;
181: if(y>(this.y+h)) return false;
182: return true;
183: }
184:}
185:
186:public class Graph2d2z extends JPanel {
187: static int shapetype = 0; // ものの形状 0:楕円、 1:矩形、
188: // 2:△、 3:▽
189: static boolean shapeSpread = false; // 塗りつぶしボタンの状態
190: final static Color bc = Color.white; // 背景色
191: static Color dc = Color.red; // 描画色
192: final static JTextField tw = new JTextField("30",3); // ものの幅
193: final static JTextField th = new JTextField("30",3); // ものの高さ
194: final int MAX_NUM = 100; // ものの最大個数
195: int nshape = 0; // ものの個数
196: ColoredShape[] shape = new ColoredShape[MAX_NUM]; // 矩形のもの
197: double x, y; // ドラッグ前の座標
198:
199: public Graph2d2z() {
200: addMouseListener(new MouseAdapter() {
201: public void mouseClicked(MouseEvent e) { // マウスがクリックされた場合
202: double x = (double)e.getX(); // カーソルの座標
203: double y = (double)e.getY();
204: double w = Double.parseDouble(tw.getText().trim()); // 下欄に表示中の幅
205: double h = Double.parseDouble(th.getText().trim()); // 高さ
206: if(nshape<MAX_NUM && shapetype==0) { // 下欄で楕円を指定中
207: shape[nshape++] =
208: new ColoredEllipse(x-w/2.0, y-h/2.0, w, h, dc, shapeSpread); // 楕円の生成
209: } else if(nshape<MAX_NUM && shapetype==1) {
210: shape[nshape++] =
211: new ColoredRectangle(x-w/2.0, y-h/2.0, w, h, dc, shapeSpread); // 矩形の生成
212: } else if(nshape<MAX_NUM && shapetype==2) {
213: shape[nshape++] =
214: new ColoredTriangle(x-w/2.0, y-h/2.0, w, h, dc, true, shapeSpread); // △の生成
215: } else if(nshape<MAX_NUM && shapetype==3) {
216: shape[nshape++] =
217: new ColoredTriangle(x-w/2.0, y-h/2.0, w, h, dc, false, shapeSpread); // ▽の生成
218: } else {
219: System.out.println("これ以上書けません");
220: }
221: repaint(); // 再描画
222: }
223: public void mousePressed(MouseEvent e) { // マウスが押された場合
224: x = (double)e.getX(); // カーソルの座標を保存
225: y = (double)e.getY();
226: }
227: });
228: addMouseMotionListener(new MouseMotionAdapter() {
229: public void mouseDragged(MouseEvent e) { // マウスがドラッグされた場合
230: double newx = (double)e.getX(); // 新しい座標
231: double newy = (double)e.getY();
232: for(int i=0; i<nshape; i++) { // 保存してある全図形について
233: if(shape[i].contains(x,y)){ // カーソルが触れている場合
234: shape[i].setFrame(shape[i].getX() + newx - x, // 図形を移動
235: shape[i].getY() + newy - y,
236: shape[i].getWidth(), shape[i].getHeight());
237: }
238: }
239: x = newx; // 新しい座標を保存
240: y = newy;
241: double w = (double)getWidth(); // 表示枠の幅と高さ
242: double h = (double)getHeight();
243: int j=0; // 保存してある全図形について
244: while(j<nshape) {
245: if(!shape[j].intersects(0.0, 0.0, w, h)) { // 表示枠の外にある場合
246: for(int i=j+1; i<nshape; i++) shape[i-1] = shape[i]; // その図形を消去
247: nshape--;
248: }
249: j++;
250: }
251: repaint(); // 再描画
252: }
253: });
254: setBackground(bc);
255: }
256:
257: public void paintComponent(Graphics g) {
258: super.paintComponent(g);
259: Graphics2D gg = (Graphics2D)g;
260: for(int i=0; i<nshape; i++) { // 保存してある全図形について
261: shape[i].draw(gg); // 描画
262: }
263: }
264:
265: public static void main(String[] args) {
266: JFrame frame = new JFrame();
267: frame.addWindowListener(new WindowAdapter() {
268: public void windowClosing(WindowEvent e) { System.exit(0); }
269: });
270: final Container cont = frame.getContentPane(); // コンテントペイン
271: cont.setLayout(new BorderLayout()); //
272: cont.add(new Graph2d2z(), BorderLayout.CENTER ); // 描画用パネルを CENTER に
273: JPanel southpan = new JPanel(); // ボタンをならべるパネル
274: JButton button = new JButton("色選択"); // カラーチューザを呼び出すボタン
275: button.addActionListener(new ActionListener() {
276: public void actionPerformed(ActionEvent e) {
277: Color c = JColorChooser.showDialog(cont, "Choose", Color.white);
278: if( c!=null ) dc = c;
279: }
280: });
281: southpan.add(button);
282: JRadioButton buttonE = new JRadioButton("楕円", true); // 図形選択用ボタン
283: buttonE.addActionListener(new ActionListener() {
284: public void actionPerformed(ActionEvent e) {
285: shapetype = 0;
286: }
287: });
288: JRadioButton buttonR = new JRadioButton("矩形", false); // 図形選択用ボタン
289: buttonR.addActionListener(new ActionListener() {
290: public void actionPerformed(ActionEvent e) {
291: shapetype = 1;
292: }
293: });
294: JRadioButton buttonT = new JRadioButton("△", false); // 図形選択用ボタン
295: buttonT.addActionListener(new ActionListener() {
296: public void actionPerformed(ActionEvent e) {
297: shapetype = 2;
298: }
299: });
300: JRadioButton buttonN = new JRadioButton("▽", false); // 図形選択用ボタン
301: buttonN.addActionListener(new ActionListener() {
302: public void actionPerformed(ActionEvent e) {
303: shapetype = 3;
304: }
305: });
306: JRadioButton buttonS = new JRadioButton("塗りつぶし", false);// ぬりつぶしor枠だけ
307: buttonS.addActionListener(new ActionListener() {
308: public void actionPerformed(ActionEvent e) {
309: shapeSpread = !shapeSpread;
310: }
311: });
312: ButtonGroup bg = new ButtonGroup(); //
313: bg.add(buttonE);
314: bg.add(buttonR);
315: bg.add(buttonT);
316: bg.add(buttonN);
317: southpan.add(buttonE);
318: southpan.add(buttonR);
319: southpan.add(buttonT);
320: southpan.add(buttonN);
321: southpan.add(new JLabel(" 幅"));
322: southpan.add(tw);
323: southpan.add(new JLabel(" 高さ"));
324: southpan.add(th);
325: southpan.add(buttonS);
326: cont.add( southpan, BorderLayout.SOUTH);
327: frame.setSize(560, 300);
328: frame.setVisible(true);
329: }
330:}