JAVA图形编程Swing之——JPanel绘图
JAVA图形编程Swing之——JPanel绘图
一直搞不清怎么在JPanel中绘2D图像,主要是不知怎样得到Graphics类的对像来画图,今天查了查资料,测试N种方法,终于搞明白。下面做一个测试总结。
一、自定义一个类,继承JPanel,直接重写它的paint方法。
1. /**
2. * 定义一个继承自JPanel的类,重写它的paint方法 *
3. */
4. class MyPanel extends JPanel
5. {
6. private int x = 200;
7. private int y = 200;
8.
9. public void display()
10. {
11. x ++;
12. y ++;
13.
14. //重绘JPanel
15. this.repaint();
16. }
17.
18. /**
19. * repaint方法会调用paint方法,并自动获得Graphics对像
20. * 然后可以用该对像进行2D画图
21. * 注:该方法是重写了JPanel的paint方法
22. */
23. public void paint(Graphics g)
24. {
25. //调用的super.paint(g),让父类做一些事前的工作,如刷新屏幕
26. super.paint(g);
27. Graphics2D g2d = (Graphics2D)g;
28.
29. //设置画图的颜色
30. 100, 100, true);//填充一个矩形
31. }
32. }
33.
34. public class PanelTest
35. {
36. public static void main(String[] args)
37. {
38. new JFrame();
39. new MyPanel();
40.
41. 200, 200, 500, 500);
42. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
43. jf.add(jp);
44. true);
45.
46. while(true)
47. {
48. //不停的重绘JPanel,实现动画的效果
49. jp.display();
50.
51. try
52. {
53. 300);
54. }
55. catch (InterruptedException e)
56. {
57. e.printStackTrace();
58. }
59. }
60. }
61. }
二、图像缓冲
第二种方法就是使用Image和BufferImage技术,预先在一个图形缓冲中绘好要显示的内容,然后在paint方法中,一次性的把图形缓冲刷新到JPanel里肌,这种方法涉及到AWT中的Image和BufferImage,前者是一个接口,后者是一个可以实例化的类。其实,JPanel也是继承自AWT的Component类,该类有一个方法:Image createImage(int width, int height) ,这个方法也常在继承自JPanel的类中用于创建一幅用于双缓冲的、可在屏幕外绘制的图像。
实现方法一:
1. /**
2. * 定义一个继承自JPanel的类,重写它的paint方法 *
3. */
4. class MyPanel1 extends JPanel
5. {
6. private int x = 200;
7. private int y = 200;
8. private Image image; //图像缓冲
9. private Graphics og;
10.
11. public void display()
12. {
13. x ++;
14. y ++;
15.
16. if(og == null)
17. {
18. //JPanel继承自Component类,可以使用它的方法createImage创建一幅和JPanel大小相同的图形缓冲
19. //然后用它Image接口的方法获得绘图对像
20. this.createImage(this.getWidth(),this.getHeight());
21. if(image != null)og = image.getGraphics();
22. }
23.
24. if(og != null)
25. {
26. //调用的super.paint(g),让父类做一些事前的工作,如刷新屏幕
27. super.paint(og);
28.
29. //设置画图的颜色
30. 100, 100, true);//绘图
31. //this.paint(this.getGraphics());
32. }
33. //重绘JPanel
34. this.repaint();
35. }
36.
37. /**
38. * repaint方法会调用paint方法,并自动获得Graphics对像
39. * 然后可以用该对像进行2D画图
40. * 注:该方法是重写了JPanel的paint方法
41. */
42. public void paint(Graphics g)
43. {
44. 0, 0, this);
45. }
46. }
47.
48. public class PanelTest2
49. {
50. public static void main(String[] args)
51. {
52. new JFrame();
53. new MyPanel1();
54.
55. 200, 200, 500, 500);
56. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
57. jf.add(jp);
58. true);
59.
60. while(true)
61. {
62. //不停的重绘JPanel,实现动画的效果
63. jp.display();
64.
65. try
66. {
67. 300);
68. }
69. catch (InterruptedException e)
70. {
71. e.printStackTrace();
72. }
73. }
74. }
75. }
实现方法二:
1. class MyPanel3 extends JPanel
2. {
3. private int x = 200;
4. private int y = 200;
5.
6. private Graphics g;
7. private Image im ;
8.
9. //构造方法,获得外部Image对像的引用
10. public MyPanel3(Image im)
11. {
12. if(im != null)
13. {
14. this.im = im;
15. g = im.getGraphics();
16. }
17. }
18.
19. public void display()
20. {
21. x ++;
22. y ++;
23. if(g != null)
24. {
25. //调用的super.paint(g),让父类做一些事前的工作,如刷新屏幕
26. super.paint(g);
27. //设置画图的颜色
28. 100, 100, true); //填充一个矩形
29. //更新缓图
30. this.repaint();
31. }
32. }
33.
34. /**
35. * repaint方法会调用paint方法,并自动获得Graphics对像
36. * 然后可以用该对像进行2D画图
37. * 注:该方法是重写了JPanel的paint方法
38. */
39. public void paint(Graphics g)
40. {
41. 0, 0, this);
42. }
43. }
44.
45. public class PanelTEST4
46. {
47. public static void main(String[] args)
48. {
49. //在自定义Panel的外部定义一个Image绘图区
50. new BufferedImage(500,500,BufferedImage.TYPE_INT_RGB);
51.
52. new JFrame();
53. //通过构造方法将缓冲缓冲区对像的引用传给自定义Panel
54. new MyPanel3(im);
55.
56. 200,200,500, 500);
57. 300, 300);
58. jf.add(jp);
59. jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
60. true);
61.
62. while(true)
63. {
64. jp.display();
65.
66. try
67. {
68. 300);
69. }
70. catch (InterruptedException e)
71. {
72. e.printStackTrace();
73. }
74. }
75. }
76. }
总结:在绘制2D图形和实现动画的效果时,要用到AWT中的绘图技术和缓冲技术,如果只是简单的绘图,那么自定义Panel类,重写Paint方法,把要绘图代码放到paint方法中,由系统自动调用paint方法即可。
要实现动画效果则就要定时的调用repaint方法,repaint方法则会调用paint方法实现Panel重绘。
JPanel在什么情况下会被重绘呢?
1. 在repaint方法被显式的调用时。
2. 在窗口最小化然后又被显示时。
3. 在窗口被拉伸时。