1、zhaozk,Java,在组件上绘制图形,图形可以绘制在任意Swing组件上,但一般绘制在面板(JPanel)上,因为面板是空白的。绘制图形需要三步: 定义一个扩展自JPanel的新类; 覆盖其paintComponent方法,将绘图的语句添加在这个方法中; 创建一个新类的对象,添加到要显示的容器中。,见PanelExample.java public class PanelExample extends JFrame public PanelExample() contentPane.add(new MyPanel(); class MyPanel extends JPanel public
2、 void paintComponent(Graphics g) /绘图部分代码 super.paintComponent(g); g.drawRect(10,10,100,50); ,paintComponent方法,此方法是一个回调方法,声明如下: public void paintComponent(Graphics g) paintComponent方法在组件需要绘制时被自动调用: 面板首次显示时; 面板尺寸变化时; 其它窗口遮住面板时; 组件的repaint()方法被调用时。 paintComponent方法的参数: Graphics g:绘图对象,所有绘图动作都是对其方法的调用。g
3、相当于一块画布,主要有以下几类方法: 绘制简单几何图形,如矩形、椭圆等; 绘制图像,如图片; 绘制文字; 设置画笔属性,如颜色、文字字体、绘图模式等。,绘制直线,void drawLine(int x1, int y1, int x2, int y2) 绘制一条线。,见GraphicsExample.java g.drawLine(10,20,60,50);,绘制矩形,void drawRect(int x, int y, int width, int height) 绘制一个矩形。 void fillRect(int x, int y, int width, int height) 填充一个
4、矩形。,见GraphicsExample.java g.drawRect(10,20,60,50); g.fillRect(80,20,60,50);,绘制圆角矩形,void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) 绘制一个圆角矩形 void fillRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) 填充一个圆角矩形,见GraphicsExample.java g.drawR
5、oundRect(10,10,100,50,20,15); g.fillRoundRect(160,10,100,50,20,15);,arcHeight,绘制椭圆,void drawOval(int x, int y, int width, int height) 绘制一个椭圆 void fillOval(int x, int y, int width, int height) 填充一个椭圆,见GraphicsExample.java g.drawOval(10,10,100,50); g.fillOval(160,10,100,50);,绘制弧线,void drawArc(int x, i
6、nt y, int width, int height, int startAngle, int arcAngle) 绘制一条弧。 void fillArc(int x, int y, int width, int height, int startAngle, int arcAngle) 填充一个扇形。,见GraphicsExample.java g.drawArc(10,10,100,50,0,60); g.fillArc(160,10,100,50,0,60);,绘制多边形,void drawPolygon(Polygon p) 绘制一个多边形 void fillPolygon(Poly
7、gon p) 填充一个多边形,见GraphicsExample.java Polygon p = new Polygon(); p.addPoint(10,10); p.addPoint(100,30); p.addPoint(50,50); p.addPoint(100,70); p.addPoint(30,100); g.drawPolygon(p); p.translate(150,0); g.fillPolygon(p);,设置颜色,void setColor(Color c):将当前画笔颜色设置为c。 Color getColor():读取当前画笔颜色。 颜色的构造: 构造函数Col
8、or(int r, int g, int b):参数为红、绿、蓝的值(0-255)。 直接使用Color类中的静态对象:如Color.blue, Color.yellow, Color.orange, ,见ColorExample.java int red = 0; int green = 0; int blue = 0; int gray = 0; for(red = 0; red = 255; red += 16) g.setColor(new Color(red,green,blue); g.fillRect(red+16,16,15,15); ,输出文字,将字符串输出到特定位置: vo
9、id drawString(String str, int x, int y),见TextExample.java g.drawString(Hello World!,50,50); g.drawString(世界你好!,50,100);,设置字体,设置当前字体:void setFont(Font font) 获取当前字体:Font getFont() Font的构造器:Font(String name, int style, int size) name:字体名称,可以用下面的方法获取系统支持的所有字体: String GraphicsEnvironment. getLocalGraphic
10、sEnvironment(). getAvailableFontFamilyNames() style:字体形式,为Font.PLAIN,Font.BOLD,Font.ITALIC。 size:字体的高度,单位为像素。 这些设置字体的方法同样可以应用于组件上显示的字体。,见FontExample.java public void paintComponent(Graphics g) super.paintComponent(g); g.setFont(new Font(fontName,fontStyle,fontSize); g.drawString(Hello World!,50,50);
11、 g.drawString(世界你好!,50,100); ,见ImageExample.java class ImagePanel extends JPanel private Image unitsImage = null; private int unitX; private int unitY; public ImagePanel() Toolkit kit = Toolkit.getDefaultToolkit(); unitsImage = kit.getImage(globe.gif); public void paintComponent(Graphics g) super.pa
12、intComponent(g); g.drawRect(10,10,100,100); g.drawImage(unitsImage,unitX,unitY,null); public void setUnitLocation(int aX, int aY) unitX = aX; unitY = aY; repaint(); ,绘制图像-1,drawImage(Image img, int dx, int dy, ImageObserver observer) 将img中图片绘制到当前画布。,见ImageExample1.java public void paintComponent(Gra
13、phics g) int sx1 = 118 * unitIndex; int sy1 = 0; int sx2 = sx1 + 117; int sy2 = sy1 + 97; int dx1 = unitX; int dy1 = unitY; int dx2 = dx1 + 117; int dy2 = dy1 + 97; g.drawImage(unitsImage,dx1,dy1,dx2,dy2,sx1,sy1,sx2,sy2,null); public void setUnitLocation(int aX, int aY) unitIndex = (unitIndex + 1) %
14、 4; repaint(); ,绘制图像-2,drawImage(Image img, int dx1, int dy1, int dx2, int dy2, int sx1, int sy1, int sx2, int sy2, ImageObserver observer) 将img中的一个矩形区域绘制到当前画布的一个矩形区域,且可拉伸。 透明的部分不绘制(gif图片可以指定一个透明色),用于绘制不规则图像。,unitsImage,等待图像加载,问题: Java加载图片文件(kit.getImage)的时候,采用异步的方式,即图片文件可能还没有加载完,getImage方法就返回了。这是为了
15、适应网络速度慢下加载图片的时间比较长的情况。 此时,如果使用图片的数据,则是错误的。因此需要一种机制等待图片加载完成。 解决: Java采用一个MediaTracker来跟踪图片的加载过程。,见ImageExample1.java public ImagePanel() Toolkit kit = Toolkit.getDefaultToolkit(); unitsImage = kit.getImage(duke.gif); MediaTracker tracker = new MediaTracker(this); tracker.addImage(unitsImage,0); try t
16、racker.waitForID(0); catch(Exception e) System.out.println(e); ,使用MediaTracker的方法: 1、创建一个MediaTracker对象; 2、用addImage方法将正在装入的 图片加入到MediaTracker对象,并 赋予一个编号; 3、用waitForID(编号)方法等待图 片装入完成。,Java支持的图片格式,Java支持三种图片格式: JPEG:Joint Photographic Experts Group,支持全24位色彩。它是通过精确地记录每个像素的光亮但同时平均它们的色调的方法压缩图片,是有损压缩。 GI
17、F:Graphics Interchange Format,采用颜色索引的方式存储图片。一个GIF图片中只能有不多于256种的色彩,因此无法存储高质量照片。一个GIF文件可以包含几张图形以及每张图形的持续值,以产生动画效果。它也有有限度的可透明性:调色板中的某个色彩可被指定为透明色。 PNG:Portable Network Graphics,无损压缩,适合在网络中传播;具有8位、24位和32位三中色彩深度;支持Alpha通道透明( 32位)和色彩索引透明( 8位)。,Graphics2D,Graphics类是一个抽象类,所以paintComponent(Graphics g)方法中的参数g不
18、可能是一个Graphics类型的对象。参数g实际上是Graphics的子类Graphics2D类型的对象。 Graphics2D类提供的功能比Graphics类强大,包括: 支持绘制更复杂的形状,如二次曲线、三次曲线; 支持更复杂的坐标变换,如旋转等; 支持设置线型,如实线、虚线、线条粗细; 支持更复杂的填充方法,如多种颜色着色。 要使用Graphics2D类的功能时,可以直接进行造型。,public void paintComponent(Graphics g) super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; /g2支持Grap
19、hics2D类的所有方法 ,缓冲区绘图,问题: Graphics类没有能够取得某一点的颜色的方法。 组件没有将图片保存到文件的方法。 解决: BufferedImage类(Image类的子类)有取色功能(getRGB方法)和保存到文件功能。 采用双缓冲区绘图的方法,将BufferedImage和JPanel联系起来: 创建一个BufferedImage对象,作为后台绘图缓冲区; 所有绘图操作均在BufferedImage对象上进行; 绘制完成后,将BufferedImage对象整个绘制到JPanel上; 这样,BufferedImage对象和JPanel的图像将完全一样。,见DoubleBuf
20、ferExample.java class PhotoPanel extends JPanel private BufferedImage backImage = new BufferedImage(1024,800, BufferedImage.TYPE_BYTE_INDEXED); public void paintComponent(Graphics g) super.paintComponent(g); Graphics backG = backImage.getGraphics(); backG.drawImage(photoImage,0,0,null); g.drawImage(
21、backImage,0,0,null); backG.dispose(); public Color getColor(int x, int y) int c = backImage.getRGB(x,y); return new Color(c); ,读取图像数据,采用双缓冲区绘图的方法后,将BufferedImage和JPanel的图像完全相同。因此,若想从JPanel某个位置取色,可以直接从BufferedImage对象同一个位置取。 BufferedImage取色的方法: int getRGB(int x, int y):取点(x,y)处的颜色,返回一个int值; Color类有一个构
22、造函数Color(int c)直接用int值构造一个颜色对象。,将图片保存到文件,将图片保存到文件使用ImageIO类的静态方法write: static boolean write(RenderedImage im, String formatName, File output) RenderedImage为一个接口,BufferedImage类实现了此接口; formatName为字符串“JPEG”或“PNG”; Java支持GIF、JPEG、PNG图形文件的读取,但只支持JPEG、PNG图形文件的写入。,见DoubleBufferExample.java import javax.ima
23、geio.*; class PhotoPanel extends JPanel private BufferedImage backImage = new BufferedImage(1024,800, BufferedImage.TYPE_BYTE_INDEXED); public void saveToFile(String aFileName) File f = new File(aFileName); try ImageIO.write(backImage,JPG,f); catch(Exception e) System.out.println(e); ,感谢!,本课程全部ppt和源代码可以从“网上课堂”下载,