JAVA图形编程Swing之——JPanel绘图
JAVA图形编程Swing之——JPanel绘图
http://blog.csdn.net/fanwenjieok/article/details/46757139
JAVA图形编程Swing之——JPanel绘图
一直搞不清怎么在JPanel中绘2D图像,主要是不知怎样得到Graphics类的对像来画图,今天查了查资料,测试N种方法,终于搞明白。下面做一个测试总结。
一、自定义一个类,继承JPanel,直接重写它的paint方法。
- /**
- * 定义一个继承自JPanel的类,重写它的paint方法 *
- */
- class MyPanel extends JPanel
- {
- private int x = 200;
- private int y = 200;
- public void display()
- {
- x ++;
- y ++;
- //重绘JPanel
- this.repaint();
- }
- /**
- * repaint方法会调用paint方法,并自动获得Graphics对像
- * 然后可以用该对像进行2D画图
- * 注:该方法是重写了JPanel的paint方法
- */
- public void paint(Graphics g)
- {
- //调用的super.paint(g),让父类做一些事前的工作,如刷新屏幕
- super.paint(g);
- Graphics2D g2d = (Graphics2D)g;
- g2d.setColor(Color.RED);//设置画图的颜色
- g2d.fill3DRect(x, y, 100, 100, true);//填充一个矩形
- }
- }
- public class PanelTest
- {
- public static void main(String[] args)
- {
- JFrame jf = new JFrame();
- MyPanel jp = new MyPanel();
- jf.setBounds(200, 200, 500, 500);
- jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- jf.add(jp);
- jf.setVisible(true);
- while(true)
- {
- //不停的重绘JPanel,实现动画的效果
- jp.display();
- try
- {
- Thread.sleep(300);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- }
- }
- }
二、图像缓冲
第二种方法就是使用Image和BufferImage技术,预先在一个图形缓冲中绘好要显示的内容,然后在paint方法中,一次性的把图形缓冲刷新到JPanel里肌,这种方法涉及到AWT中的Image和BufferImage,前者是一个接口,后者是一个可以实例化的类。其实,JPanel也是继承自AWT的Component类,该类有一个方法:Image createImage(int width, int height) ,这个方法也常在继承自JPanel的类中用于创建一幅用于双缓冲的、可在屏幕外绘制的图像。
实现方法一:
- /**
- * 定义一个继承自JPanel的类,重写它的paint方法 *
- */
- class MyPanel1 extends JPanel
- {
- private int x = 200;
- private int y = 200;
- private Image image; //图像缓冲
- private Graphics og;
- public void display()
- {
- x ++;
- y ++;
- if(og == null)
- {
- //JPanel继承自Component类,可以使用它的方法createImage创建一幅和JPanel大小相同的图形缓冲
- //然后用它Image接口的方法获得绘图对像
- image = this.createImage(this.getWidth(),this.getHeight());
- if(image != null)og = image.getGraphics();
- }
- if(og != null)
- {
- //调用的super.paint(g),让父类做一些事前的工作,如刷新屏幕
- super.paint(og);
- og.setColor(Color.RED); //设置画图的颜色
- og.fill3DRect(x, y, 100, 100, true);//绘图
- //this.paint(this.getGraphics());
- }
- //重绘JPanel
- this.repaint();
- }
- /**
- * repaint方法会调用paint方法,并自动获得Graphics对像
- * 然后可以用该对像进行2D画图
- * 注:该方法是重写了JPanel的paint方法
- */
- public void paint(Graphics g)
- {
- g.drawImage(image, 0, 0, this);
- }
- }
- public class PanelTest2
- {
- public static void main(String[] args)
- {
- JFrame jf = new JFrame();
- MyPanel1 jp = new MyPanel1();
- jf.setBounds(200, 200, 500, 500);
- jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- jf.add(jp);
- jf.setVisible(true);
- while(true)
- {
- //不停的重绘JPanel,实现动画的效果
- jp.display();
- try
- {
- Thread.sleep(300);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- }
- }
- }
实现方法二:
- class MyPanel3 extends JPanel
- {
- private int x = 200;
- private int y = 200;
- private Graphics g;
- private Image im ;
- //构造方法,获得外部Image对像的引用
- public MyPanel3(Image im)
- {
- if(im != null)
- {
- this.im = im;
- g = im.getGraphics();
- }
- }
- public void display()
- {
- x ++;
- y ++;
- if(g != null)
- {
- //调用的super.paint(g),让父类做一些事前的工作,如刷新屏幕
- super.paint(g);
- g.setColor(Color.RED); //设置画图的颜色
- g.fill3DRect(x, y, 100, 100, true); //填充一个矩形
- //更新缓图
- this.repaint();
- }
- }
- /**
- * repaint方法会调用paint方法,并自动获得Graphics对像
- * 然后可以用该对像进行2D画图
- * 注:该方法是重写了JPanel的paint方法
- */
- public void paint(Graphics g)
- {
- g.drawImage(im, 0, 0, this);
- }
- }
- public class PanelTEST4
- {
- public static void main(String[] args)
- {
- //在自定义Panel的外部定义一个Image绘图区
- Image im = new BufferedImage(500,500,BufferedImage.TYPE_INT_RGB);
- JFrame jf = new JFrame();
- //通过构造方法将缓冲缓冲区对像的引用传给自定义Panel
- MyPanel3 jp = new MyPanel3(im);
- jf.setBounds(200,200,500, 500);
- jp.setSize(300, 300);
- jf.add(jp);
- jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
- jf.setVisible(true);
- while(true)
- {
- jp.display();
- try
- {
- Thread.sleep(300);
- }
- catch (InterruptedException e)
- {
- e.printStackTrace();
- }
- }
- }
- }
总结:在绘制2D图形和实现动画的效果时,要用到AWT中的绘图技术和缓冲技术,如果只是简单的绘图,那么自定义Panel类,重写Paint方法,把要绘图代码放到paint方法中,由系统自动调用paint方法即可。
要实现动画效果则就要定时的调用repaint方法,repaint方法则会调用paint方法实现Panel重绘。
JPanel在什么情况下会被重绘呢?
1. 在repaint方法被显式的调用时。
2. 在窗口最小化然后又被显示时。
3. 在窗口被拉伸时。

浙公网安备 33010602011771号