也是刚刚从邮箱里发现的古董。。。
![](/images/cppblog_com/corebugzj/JavaPainter.jpg)
我的代码:
1 // ubuntu windows endl
2
3 import java.awt.*;
4 import java.awt.event.*;
5 import java.awt.image.*;
6 import java.io.*;
7 import javax.swing.*;
8 import javax.imageio.*;
9
10 class PainterCanvas extends Canvas {
11
12 public PainterCanvas( Color foregroundColor, int initPaintType, float lineWidth, float [] dashArray, float dashPhase, Dimension size ) {
13 setColor( foregroundColor );
14 setBackground( COLOR_BACK );
15 paintType = LINE;
16 setPaintType( initPaintType );
17 paintStroke = new BasicStroke();
18 setLineWidth( lineWidth );
19 setLineDash( dashArray, dashPhase );
20 setBufferedDimension( size );
21 startX = startY = endX = endY = 0;
22 drawBuffer = false;
23 pressed = false;
24 setCursor( Cursor.getPredefinedCursor( Cursor.CROSSHAIR_CURSOR ) );
25 addMouseListener( new
26 MouseAdapter() {
27 public void mousePressed( MouseEvent me ) {
28 if ( ! pressed ) {
29 startX = me.getX();
30 startY = me.getY();
31 pressed = true;
32 }
33 }
34 public void mouseReleased( MouseEvent me ) {
35 if ( pressed ) {
36 endX = me.getX();
37 endY = me.getY();
38 pressed = false;
39 drawBuffer = true;
40 repaint();
41 }
42 }
43 }
44 );
45 addMouseMotionListener( new MouseMotionAdapter() {
46 public void mouseDragged( MouseEvent me ) {
47 endX = me.getX();
48 endY = me.getY();
49 repaint();
50 }
51 } );
52 }
53
54 public void setPaintType( int t ) {
55 if ( ( t == LINE ) || ( t == TRIA ) || ( t == OVAL ) || ( t == RECT ) ) {
56 paintType = t;
57 }
58 }
59
60 public void setColor( Color col ) {
61 colorFore = col;
62 }
63
64 public void setLineWidth( float lineWidth ) {
65 if ( lineWidth > 0.0f ) {
66 paintStroke = new BasicStroke( lineWidth, paintStroke.getEndCap(),
67 paintStroke.getLineJoin(), paintStroke.getMiterLimit(),
68 paintStroke.getDashArray(), paintStroke.getDashPhase() );
69 }
70 }
71
72 public void setLineDash( float [] dashArray, float dashPhase ) {
73 paintStroke = new BasicStroke( paintStroke.getLineWidth(), paintStroke.getEndCap(),
74 paintStroke.getLineJoin(), paintStroke.getMiterLimit(),
75 dashArray, dashPhase );
76 }
77
78 public void setBufferedDimension( Dimension size ) {
79 setSize( size );
80 dimSize = size;
81 img = new BufferedImage( dimSize.width, dimSize.height, BufferedImage.TYPE_4BYTE_ABGR );
82 graImg = img.createGraphics();
83 graImg.setColor( COLOR_BACK );
84 graImg.fillRect( 0, 0, dimSize.width, dimSize.height );
85 }
86
87 public void setBufferedImage( BufferedImage bufImg ) {
88 dimSize.width = bufImg.getWidth();
89 dimSize.height = bufImg.getHeight();
90 setSize( dimSize );
91 img = bufImg;
92 graImg = img.createGraphics();
93 }
94
95 public Color getColor() {
96 return colorFore;
97 }
98
99 public BufferedImage getBufferedImage() {
100 return img;
101 }
102
103 public void paint( Graphics g ) {
104 g.drawImage( img, 0, 0, dimSize.width, dimSize.height, this );
105 paintUpdate( g );
106 }
107
108 public void update( Graphics g ) {
109 g.drawImage( img, 0, 0, dimSize.width, dimSize.height, this );
110 paintUpdate( g );
111 }
112
113 public void paintUpdate( Graphics gra ) {
114 Graphics2D g = (Graphics2D)gra;
115 g.setColor( colorFore );
116 g.setStroke( paintStroke );
117 graImg.setColor( colorFore );
118 graImg.setStroke( paintStroke );
119 int x = Math.min( startX, endX );
120 int y = Math.min( startY, endY );
121 int w = startX + endX - x - x;
122 int h = startY + endY - y - y;
123 switch ( paintType ) {
124 case LINE :
125 g.drawLine( startX, startY, endX, endY );
126 if ( drawBuffer ) {
127 graImg.drawLine( startX, startY, endX, endY );
128 }
129 break;
130 case TRIA :
131 g.drawPolygon( new int[]{ startX, x, endX }, new int[]{ startY, ( startY + endY ) / 2, endY }, 3 );
132 if ( drawBuffer ) {
133 graImg.drawPolygon( new int[]{ startX, x, endX }, new int[]{ startY, ( startY + endY ) / 2, endY }, 3 );
134 }
135 break;
136 case OVAL :
137 g.drawOval( x, y, w, h );
138 if ( drawBuffer ) {
139 graImg.drawOval( x, y, w, h );
140 }
141 break;
142 case RECT :
143 g.drawRect( x, y, w, h );
144 if ( drawBuffer ) {
145 graImg.drawRect( x, y, w, h );
146 }
147 break;
148 }
149 drawBuffer = false;
150 }
151
152 private int startX, startY, endX, endY, paintType;
153 private Color colorFore;
154 private boolean pressed, drawBuffer;
155 private BasicStroke paintStroke;
156 private Graphics2D graImg;
157 private BufferedImage img;
158 private Dimension dimSize;
159
160 private static final Color COLOR_BACK = Color.WHITE;
161 public static final int LINE = 0, TRIA = 1, OVAL = 2, RECT = 3;
162
163 }
164
165
166 //------------------------------------------------------------------------------------------
167
168
169 class PainterWin extends Frame implements ActionListener, ItemListener {
170
171 public PainterWin() {
172 super( "画板 --- 赵杰" );
173 initFrame();
174 initMenu();
175 initTool();
176 initCanvas();
177 setVisible( true );
178 validate();
179 }
180
181 public void actionPerformed( ActionEvent ae ) {
182 Object obj = ae.getSource();
183 if ( obj == menuNew ) {
184 onMenuNew();
185 }
186 else if ( obj == menuOpen ) {
187 onMenuOpen();
188 }
189 else if ( obj == menuSave ) {
190 onMenuSave();
191 }
192 else if ( obj == menuExit ) {
193 onMenuExit();
194 }
195 else if ( obj == butLine ) {
196
197 canvas.setPaintType( PainterCanvas.LINE );
198 }
199 else if ( obj == butTria ) {
200 canvas.setPaintType( PainterCanvas.TRIA );
201 }
202 else if ( obj == butOval ) {
203 canvas.setPaintType( PainterCanvas.OVAL );
204 }
205 else if ( obj == butRect ) {
206 canvas.setPaintType( PainterCanvas.RECT );
207 }
208 }
209
210 public void itemStateChanged( ItemEvent ie ) {
211 Object obj = ie.getSource();
212 if ( obj == choLineType ) {
213 onChoiceLineType();
214 }
215 else if ( obj == choLineWidth ) {
216 onChoiceLineWidth();
217 }
218 else if ( obj == choColor ) {
219 onChoiceColor();
220 }
221 }
222
223 private void initFrame() {
224 setBounds( 300, 200, 600, 500 );
225 addWindowListener( new WindowAdapter() {
226 public void windowClosing( WindowEvent we ) {
227 onExit();
228 }
229 }
230 );
231 setLayout( new BorderLayout() ); // default
232 }
233
234 private MenuItem newMenuItem( Menu menu, String label, MenuShortcut sc ) {
235 MenuItem item = new MenuItem( label, sc );
236 item.addActionListener( this );
237 menu.add( item );
238 return item;
239 }
240
241 private void initMenu() {
242 MenuBar menuBar = new MenuBar();
243 Menu menu = new Menu( "文件" );
244 menuNew = newMenuItem( menu, "新建", new MenuShortcut( KeyEvent.VK_N ) );
245 menuOpen = newMenuItem( menu, "打开", new MenuShortcut( KeyEvent.VK_O ) );
246 menuSave = newMenuItem( menu, "保存", new MenuShortcut( KeyEvent.VK_S ) );
247 menuExit = newMenuItem( menu, "退出", new MenuShortcut( KeyEvent.VK_E ) );
248 menuBar.add( menu );
249 setMenuBar( menuBar );
250 }
251
252 private Choice newChoice( Panel pan, String label ) {
253 Choice cho = new Choice();
254 cho.addItemListener( this );
255 pan.add( new Label( label ) );
256 pan.add( cho );
257 return cho;
258 }
259
260 private Button newButton( Panel pan, String label ) {
261 Button but = new Button( label );
262 but.addActionListener( this );
263 pan.add( but );
264 return but;
265 }
266
267 private void initTool() {
268 Panel pan = new Panel();
269 pan.setLayout( new FlowLayout( FlowLayout.CENTER, 10, 1 ) );
270
271 choLineType = newChoice( pan, "线条" );
272 choLineType.add( "实线" );
273 choLineType.add( "虚线" );
274 choLineType.select( 0 );
275
276 choLineWidth = newChoice( pan, "线宽" );
277 choLineWidth.add( "1" );
278 choLineWidth.add( "4" );
279 choLineWidth.select( 0 );
280
281 choColor = newChoice( pan, "颜色" );
282 choColor.add( "黑" );
283 choColor.add( "红" );
284 choColor.add( "自定义" );
285 choColor.select( 0 );
286
287 butLine = newButton( pan, "直线" );
288 butTria = newButton( pan, "三角形" );
289 butOval = newButton( pan, "圆" );
290 butRect = newButton( pan, "矩形" );
291
292 add( pan, BorderLayout.NORTH );
293 }
294
295 private void initCanvas() {
296 float [] dashArray = new float[]{ 1.0f, 0.0f };
297 canvas = new PainterCanvas( Color.BLACK, PainterCanvas.LINE, 1.0f, dashArray, 0.0f, new Dimension( 600, 400 ) );
298 pl = new Panel( null );
299 pl.add( canvas );
300 canvas.setBounds( 0, 0, canvas.getSize().width, canvas.getSize().height );
301 pl.setBounds( 0, 0, canvas.getSize().width, canvas.getSize().height );
302 if ( pane != null ) {
303 remove( pane );
304 }
305 pane = new JScrollPane( pl );
306 add( pane, BorderLayout.CENTER );
307 }
308
309 private void onMenuNew() {
310 if ( onLeaveButCancel() ) {
311 return;
312 }
313 initCanvas();
314 validate();
315 }
316
317 private void onMenuOpen() {
318 if ( onLeaveButCancel() ) {
319 return;
320 }
321 JFileChooser fc = new JFileChooser();
322 int cho = fc.showOpenDialog( this );
323 if ( cho == JFileChooser.APPROVE_OPTION ) {
324 file = fc.getSelectedFile();
325 BufferedImage img;
326 try {
327 img = ImageIO.read( file );
328 }
329 catch ( IOException ex ) {
330 JOptionPane.showMessageDialog( this, "图像载入失败!" );
331 file = null;
332 return;
333 }
334 pl.setSize( img.getWidth(), img.getHeight() );
335 canvas.setBufferedImage( img );
336 file = null;
337 }
338 }
339
340 private boolean onLeaveButCancel() {
341 int cho = JOptionPane.showConfirmDialog( this, "保存当前图片?" );
342 switch ( cho ) {
343 case JOptionPane.YES_OPTION :
344 onSave();
345 case JOptionPane.NO_OPTION :
346 file = null;
347 return false;
348 }
349 return true;
350 }
351
352 private void onMenuSave() {
353 onSave();
354 }
355
356 private void onSave() {
357 if ( file == null ) {
358 JFileChooser fc = new JFileChooser();
359 int cho = fc.showSaveDialog( this );
360 if ( cho == JFileChooser.APPROVE_OPTION ) {
361 file = fc.getSelectedFile();
362 }
363 }
364 if ( file != null ) {
365 try {
366 ImageIO.write( canvas.getBufferedImage(), "PNG", file );
367 }
368 catch ( IOException ex ) {
369 JOptionPane.showMessageDialog( this, "保存失败!" );
370 }
371 }
372 }
373
374 private void onMenuExit() {
375 onExit();
376 }
377
378 private void onExit() {
379 if ( ! onLeaveButCancel() ) {
380 System.exit( 0 );
381 }
382 }
383
384 private void onChoiceLineType() {
385 float [] da;
386 switch ( choLineType.getSelectedIndex() ) {
387 case 0 :
388 da = new float[]{ 1.0f, 0.0f };
389 canvas.setLineDash( da, 0.0f );
390 break;
391 case 1 :
392 da = new float[]{ 4.0f, 8.0f };
393 canvas.setLineDash( da, 0.0f );
394 break;
395 }
396 }
397
398 private void onChoiceLineWidth() {
399 switch ( choLineWidth.getSelectedIndex() ) {
400 case 0 :
401 canvas.setLineWidth( 1.0f );
402 break;
403 case 1 :
404 canvas.setLineWidth( 4.0f );
405 break;
406 }
407 }
408
409 private void onChoiceColor() {
410 switch ( choColor.getSelectedIndex() ) {
411 case 0 :
412 canvas.setColor( Color.BLACK );
413 break;
414 case 1 :
415 canvas.setColor( Color.RED );
416 break;
417 case 2 :
418 canvas.setColor( JColorChooser.showDialog( this, "自定义颜色", canvas.getColor() ) );
419 break;
420 }
421 }
422
423 private MenuItem menuNew, menuOpen, menuSave, menuExit;
424 private Choice choLineType, choLineWidth, choColor;
425 private Button butLine, butTria, butOval, butRect;
426 private PainterCanvas canvas;
427 private Panel pl;
428 private JScrollPane pane = null;
429 private File file = null;
430
431 }
432
433
434 //------------------------------------------------------------------------------------------
435
436
437 public class Painter {
438
439 public static void main( String [] args ) {
440 new PainterWin();
441 }
442
443 }
444
445