• 1. Java图形程序设计伍淳华 北京邮电大学计算机学院
  • 2. 学习内容采用Swing编写窗口程序; 如何在窗口中采用多种字体显示文本; 如何显示图像;Java
  • 3. Swing概述两种基本GUI程序设计类库 AWT(Abstract Window Toolkit)抽象窗口工具箱 -对等体方法 将处理用户界面元素的任务委派给每个目标平台的本地GUI工具箱,由本地GUI工具箱负责用户界面元素的创建和动作。 “一次编写,随处使用”。 “一次编写,到处调试”。 Java
  • 4. Swing概述两种基本GUI程序设计类库 SWING -1996,Netscape创建了一种IFC(Internet Foundation Class)的GUI库,它将菜单、按钮等用户界面元素绘制在空白窗口上,而对等体只需创建和绘制窗口。 在所有平台上的外观和动作都一样。 -Sun和Netscape合作完善了这种方式,创建了一个名为Swing的用户界面库。 Java
  • 5. Swing概述两种基本GUI程序设计类库 SWING vs. AWT -SWING显示用户界面的元素的速度比AWT慢一些; -SWING拥有一个丰富、便捷的用户界面元素集合; -SWING对低层平台的依赖很少,因此与平台相关的bug很少; -SWING给予不同平台的用户一致的感观效果; Java
  • 6. Swing概述两种基本GUI程序设计类库 SWING vs. AWT -SWING显示用户界面的元素的速度比AWT慢一些; -SWING拥有一个丰富、便捷的用户界面元素集合; -SWING对低层平台的依赖很少,因此与平台相关的bug很少; -SWING给予不同平台的用户一致的感观效果; SWING没有完全替代AWT,而是基于AWT架构之上,其提供了能力更加强大的用户界面组件,但还需要使用基本的AWT事件处理。 Java
  • 7. GUI基本组成Java的图形用户界面的最基本组成成分是组件,组件是一个可以以图形化的方式显示在屏幕上并能与用户进行交互的对象,例如一个按钮,一个标签等。 组件不能独立地显示出来,必须将组件放在一定的容器中才可以显示出来。 容器(Container)实际上是Component的子类,因此容器本身也是一个组件,具有组件的所有性质,另外还具有容纳其他组件和容器的功能Java
  • 8. 创建框架框架(frame) 顶层窗口被称为框架 Swing用JFrame类来表示框架,该 类扩展于AWT的frame。 JFrame是极少数几个不绘制在画布上的Swing组件之一。其修饰部件(按钮、标题栏、图标等)由用户的窗口系统绘制,而不是由Swing绘制。 Java
  • 9. 创建框架JFrame java.long.Object | +----java.awt.Component | +----java.awt.Container | +----java.awt.Window | +----java.awt.Frame | +----javax.swing.JFrameJava
  • 10. 创建框架import javax.swing.*; public class SimpleFrameTest { public static void main(String[] args) { SimpleFrame sFrame = new SimpleFrame(); sFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); sFrame.setVisible(true); } } class SimpleFrame extends JFrame{ public SimpleFrame(){ setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); } public static int DEFAULT_WIDTH = 300; public static int DEFAULT_HEIGHT = 200; }Java
  • 11. 创建框架框架(frame)Java
  • 12. 创建框架框架(frame) 默认情况下,框架的大小为0*0象素; 默认情况下,用户关闭窗口只是将框架隐藏了起来,程序并没有终止; 构造一个框架并不自动显示,框架起初并不可见; Java
  • 13. 框架设置设置合适的框架大小 -获得用户系统的基于像素的屏幕分辩率信息,然后利用这些信息计算最佳的窗口大小。 -获得用户系统的屏幕分辩率信息 Toolkit tk = Toolkit.getDefaultToolkit(); Dimension ds = tk.getScreenSize(); int width = ds.width; int hight = ds.height; Java
  • 14. 框架设置例:将一个可关闭框架设置为: 其大小是整个屏幕的二分之一; 位于屏幕的中央。 Java
  • 15. 框架设置void setLocation(x,y); 将框架放置在左上角水平x像素,垂直y像素的位置;坐标(0,0)位于屏幕的左上角; void setTitle(String s); 设置框架的标题; void setIconImage(Image c); 设置框架的图标; Java
  • 16. 框架设置import java.awt.*; import java.awt.event.*; import javax.swing.*; public class CenteredFrameTest { public static void main(String[]args){ CenteredFrame cf = new CenteredFrame(); cf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); cf.setVisible(true); } } Java
  • 17. 框架设置class CenteredFrame extends JFrame{ public CenteredFrame(){ Toolkit tk = Toolkit.getDefaultToolkit(); Dimension ds = tk.getScreenSize(); int width = ds.width; int hight = ds.height; setSize(width/2,hight/2); setLocation(width/4,hight/4); Image img = tk.getImage("icon.gif"); setIconImage(img); setTitle("Centered Frame"); } }Java
  • 18. 框架设置Java
  • 19. 面板与信息显示如何在框架中显示文本信息? 可以直接在框架中绘制信息,但这不是一种良好的编程习惯; 框架在JAVA中是一个容器,用来放置其它组件,如:放置一个按钮、一个文本框等; 通常在一个称为面板(panel)的组件上绘制信息,并将该面板添加到框架中; Java
  • 20. 面板与信息显示如何在框架中添加一个面板(panel)? Java
  • 21. 面板与信息显示Swing程序员关心的是内容窗格,可使用下面的代码将组件添加到内容窗格中: Container contentPane = frame.getContentPane(); Component c=new …; contentPane.add(c); 在JDK 5.0后,可直接调用JFrame.add方法将组件添加到框架中,该方法实际上调用了内容窗格中的add方法 frame.add(c); 将面板(panel)的添加到框架中 frame.add(panel); Java
  • 22. 面板与信息显示JPanel类 包含一个可以用于绘图的表面; 本身也是一个容器; 为了能够在面板上进行绘图,需要进行 定义一个扩展于JPanel的类 在这个类中,覆盖paintComponent方法 Java
  • 23. 面板与信息显示paintComponent方法 该方法定义在JComponent类中,这个类是所有非窗口Swing组件的超类; 该方法有一个Graphics类型的参数,通过该对象,可以进行绘制图案、图像和文本; 程序员不用手工调用paintComponent方法,当应用程序需要绘图时(如窗口第一次出现、窗口大小调整等),事件处理器就会通告组件,使得paintComponent自动调用。 Java
  • 24. 面板与信息显示绘制文本 通过Graphics类中的drawString方法可在面板上绘制文本 g.drawString(text,x,y); class NotHelloWorldPanel extends JPanel{ public void paintComponent(Graphics g){ … g.drawString("Not a HelloWorld Program", MESSAGE_X, MESSAGE_Y); } public static final int MESSAGE_X = 75; public static final int MESSAGE_Y = 100; } Java
  • 25. 面板与信息显示绘制文本 NotHelloWorldPanel类扩展了JPanel类,在填充面板的背景颜色时,JPanel类有自己的处理方式,为了确保超类完成自己的工作,必须在绘制自己的内容之前调用super.paintComponent( ); class NotHelloWorldPanel extends JPanel{ public void paintComponent(Graphics g){ super.paintComponent( ); ……. } }Java
  • 26. 面板与信息显示import java.awt.*; import javax.swing.*; public class NotHelloWorldFrameTest { public static void main(String[] args){ NotHelloWorldFrame f = new NotHelloWorldFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } } Java
  • 27. 面板与信息显示class NotHelloWorldFrame extends JFrame{ public NotHelloWorldFrame(){ Toolkit tk = Toolkit.getDefaultToolkit(); Dimension dm = tk.getScreenSize(); int width = dm.width; int height = dm.height; setSize(width/2,height/2); setLocation(width/4,height/4); Image icon = tk.getImage("icon.gif"); setIconImage(icon); setTitle("Not Hello World Frame"); add(new NotHelloWorldPanel()); } }Java
  • 28. 面板与信息显示 class NotHelloWorldPanel extends JPanel{ public void paintComponent(Graphics g){ super.paintComponent(g); g.drawString("Not a HelloWorld Program", MESSAGE_X, MESSAGE_Y); } public static final int MESSAGE_X = 75; public static final int MESSAGE_Y = 100; }Java
  • 29. 面板与信息显示Java
  • 30. 2D图形图形绘制主要有两个类 Graphics(JDK 1.0):绘制图形的能力有限; Graphics2D(JDK 1.2):Graphics 的子类,绘制图形的能力强大; 如果使用的是支持Java 2D的版本,paintComponent方法可自动地获得一个Graphics2D类对象,只需进行一次类型转换 public void paintComponent(Graphics g) { Graphics2D g2 = (Graphics2D)g; …… }Java
  • 31. 2D图形常用的几何图形类 Line2D Rectangle2D Ellipse2D …. 这些几何图形类实现了Shape接口 绘制图形 首先创建一个实现了Shape接口的类对象; 调用Graphics2D类中的draw方法; Rectangle2D rect = …; g2.draw(rect);Java
  • 32. 2D图形Java2D图形类采用的是浮点坐标; 每个图形类有两个版本:一个是为节省空间设置的float类型的坐标;另一个是double类型的坐标; 例: Rectangle2D类有两个子类 Rectangle2D.Float Rectangle2D.Double Rectangle2D.Float fRect = new Rectangle2D.Float(10.0f,25.0f,22.5f,20.0f); Rectangle2D.Double dRect = new Rectangle2D.Double(10.0,25.0,22.5,20.0) Java
  • 33. 2D图形 Rectangle2D.Float和 Rectangle2D.Double均继承于Rectangle2D,并且子类只覆盖了Rectangle2D超类中的方法,故没有必要记住图形类型,可直接使用Rectangle2D变量保存矩形的引用: Rectangle2D fRect = new Rectangle2D.Float(10.0f,25.0f,22.5f,20.0f); Rectangle2D dRect = new Rectangle2D.Double(10.0,25.0,22.5,20.0); 对Rectangle2D的论述适用于其它所有的2D图形类,如Point2D也有两个子类Point2D.Float和Point2D.Double,子类也仅实现了父类的方法,可直接使用父类变量保存子类对象的引用。 Java
  • 34. 2D图形常用2D图形类 abstract RectangularShape 几何框架类图形的父类; public double getWidth( ); public double getHeight( ); public double getCenterX( ); public double getCenterY( );Java
  • 35. 2D图形常用2D图形类 Java
  • 36. 2D图形常用2D图形类 Rectangle2D.Double Rectangle2D.Double(double x,double y,double w,double h) x,y---矩形左上角的坐标(x,y); w ---矩形宽度 h ---矩形高度 Rectangle2D.Double( ) x=y=w=h=0 Java
  • 37. 2D图形常用2D图形类 Rectangle2D.Double 如果已知两个矩形的两个对角点,也可以依此构造一个矩形, 假设此两点的坐标分别为p(px,py),q(qx,qy): Rectangle2D rect = new Rectangle2D.Double( ); rect.setFrameFromDiagonal(px,py,qx,qy); 或 rect.setFrameFromDiagonal(p,q); (p,q是用Point2D对象表示的两个对角点) public void setFrameFromDiagonal(double x1,double y1,double x2,double y2); public void setFrameFromDiagonal(Point2D p1, Point2D p2);Java
  • 38. 2D图形常用2D图形类 Ellipse2D.Double Ellipsee2D.Double(double x,double y,double w,double h) x,y---椭圆所在矩形外框左上角的坐标(x,y); w ---椭圆所在矩形外框矩形宽度 h ---椭圆所在矩形外框矩形高度 Ellipse2D.Double( ) 椭圆所在矩形外框为x=y=w=h=0 Java
  • 39. 2D图形常用2D图形类 Ellipse2D.Double 通过椭圆中心点c(centerX,centerY)、宽和高来构造一个椭圆: Ellipse2D ellipse=new Ellipse2D.Double(certerX-width/2,centerY-height/2,width,height); 通过椭圆中心点及外矩形框中四个顶点中的一个来构造椭圆: Ellipse2D ellipse = new Ellipse2D.Double( ); ellipse.setFrameFromCenter(centerX,centerY,concerX,concerY); 通过外矩形框来构造一个椭圆: Ellipse2D ellipse = new Ellipse2D.Double( ); ellipse.setFrame(rect); Java
  • 40. 2D图形常用2D图形类 Line2D.Double Line2D.Double( ); Line2D.Double(double x1, double y1, double x2, double y2); Line2D.Double(Point2D p1, Poiont2D p2;) Java
  • 41. 2D图形常用2D图形类 Point2D.Double Point2D.Double( ); Point2D.Double(double x, double y); Java
  • 42. 2D图形绘制图形 一个矩形 这个矩形的内接椭圆 矩形的一条对角线 以矩形中心为圆心的一个圆Java
  • 43. 2D图形import java.awt.*; import java.awt.geom.*; import javax.swing.*; public class DrawTest { public static void main(String[]args){ DrawFrame f = new DrawFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }Java
  • 44. 2D图形class DrawFrame extends JFrame{ public DrawFrame(){ Toolkit tl = Toolkit.getDefaultToolkit(); Dimension ds = tl.getScreenSize(); int width = ds.width; int height = ds.height; setSize(500,500); setLocation(width/4,height/4); Image icon = tl.getImage("icon.gif"); setIconImage(icon); setTitle("Draw test"); add(new DrawPanel()); } }Java
  • 45. 2D图形class DrawPanel extends JPanel{ public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; int leftX = 100; int leftY = 120; int width = 300; int height = 200; Rectangle2D rec = new Rectangle2D.Double(leftX,leftY,width,height); g2.draw(rec); Ellipse2D eps = new Ellipse2D.Double(); eps.setFrame(rec); g2.draw(eps); Java
  • 46. 2D图形 g2.draw(new Line2D.Double(leftX,leftY,leftX+width,leftY+height)); double x = eps.getCenterX(); double y = eps.getCenterY(); double radius = 180; Ellipse2D circle = new Ellipse2D.Double(); circle.setFrameFromCenter(x, y, x+radius, y+radius); g2.draw(circle); } }Java
  • 47. 2D图形Java
  • 48. 颜色Java.awt.Color类用于定义颜色 类中提供了13个预定义的常量,分别表示13种标准颜色 BLACK GREEN RED BLUE WHITE LIGHT_GRAY CYAN MAGENTA YELLOW DARK_GRAY ORANGE GRAY PINK Color.RED Color.GREENJava
  • 49. 颜色Java.awt.Color类用于定义颜色 利用三原色(红、绿和蓝)来创建一个Color对象,三种颜色都是用(0~255)之间的数值来表示; public Color(int red, int green, ing blue);Java
  • 50. 颜色Graphics2D类的setPaint方法可以为图形环境上的所有后续的绘制操作选择颜色。绘制颜色的过程: 选择颜色 绘制图形 g2.setPaint(Color.RED); g2.drawString(“Warning!”,100,100); void setPaint(Paint p); ----Color类实现了Paint接口, Java
  • 51. 颜色设置组件的背景颜色和前景颜色 Component 类中的两个方法 public void setBackground(Color c); public void setForeground(Color c); MyPanel p = new MyPanel( ); p.setBackground(Color.PINK);Java
  • 52. 颜色填充图形 可选用一种颜色,填充闭合图形的内部 ,调用Graphics2D的fill方法; public void fill(Shape s); Rectangle2D rect = …; g2.setpaint(Color.RED); g2.fill(rect);Java
  • 53. 颜色例:用红色填充一个矩形,并用暗绿色填充该矩形的内接椭圆。 import javax.swing.*; import java.awt.*; import java.awt.geom.*; public class FillTest { public static void main(String[] args){ FillFrame f = new FillFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }Java
  • 54. 颜色class FillFrame extends JFrame{ public FillFrame(){ this.setTitle("Fill Window"); setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); setLocation(100,100); this.add(new FillPanel()); } public static final int DEFAULT_WIDTH = 400; public static final int DEFAULT_HEIGHT = 400; } Java
  • 55. 颜色class FillPanel extends JPanel{ public void paintComponent(Graphics g){ super.paintComponents(g); Graphics2D g2 = (Graphics2D)g; double leftX = 50; double leftY = 50; double width = 260; double height = 200; Rectangle2D rec = new Rectangle2D.Double(leftX, leftY, width, height); g2.setPaint(Color.RED); g2.fill(rec); Ellipse2D ese = new Ellipse2D.Double(); ese.setFrame(rec); g2.setPaint(new Color(0,128,128)); g2.fill(ese); }}Java
  • 56. 颜色Java
  • 57. 设置字体java.awt.Font Font(Stirng name, int style, int size) -name:字体名; -style:字体风格 Font.PLAIN :常规 Font.BOLD :粗体 Font.ITALIC:斜体 Font.BOLD+Font.ITALIC:粗体+斜体 -size:字体大小,以点为单位,每英寸包含72个点 Eg: Font serif14 = new Font(“Serif”,Font.BOLD,14);Java
  • 58. 设置字体java.awt.Font 字体名是指一台机器上所允许使用的字体的名字;不同的机器所支持的字体有所不同; 列出机器上所允许的字体名 调用GraphicsEnvironment类中的getAvailableFontFamilyNames方法,该方法返回一个字符型数组,包含了所有可用的字体名; GraphicsEnvironment类描述了用户系统的图形环境,可调用静态的getLocalGraphicsEnvironment方法得到该类的一个对象;Java
  • 59. 设置字体import java.awt.*; public class ListFonts { public static void main(String[]args){ String[] fontsName = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames(); For(String s:fontsName) System.out.println(s); } }Java
  • 60. 设置字体Algerian Arial Arial Black Arial Narrow Arial Unicode MS Baskerville Old Face Batang BatangChe ……..Java
  • 61. 设置字体java.awt.Font JAVA AWT定义了五个逻辑(logical)字体名: SansSerif Serif Monospaced Dialog DialogInput 这五种字体会被映射到客户机上的实际字体。不同的机器映射方式可能不同。Java
  • 62. 设置字体设置字符串位置 获得描述字符串位置的矩形 FontRenderContext context = g2.getFontRenderContext( ); Rectangle2D bounds = f.getStringBounds(message,context);Java(0,0)-通过该矩形的getWidth( )和getHeight( )可以得到字符串所占的宽度和高度-该矩形的坐标原点在字符串的基线开始的地方,故通过getY( )得到的是上坡度的负值; -drawString(s, x, y)方法中参数标识的点就是基线开始的点在屏幕中的坐标位置
  • 63. 设置字体设置字符串位置 设置字符串的位置,即是求得基准线起始点在屏幕中的坐标值,该值以屏幕左上角(0,0)为基准Java(x,y)(x,y-bounds.getY())
  • 64. 设置字体将字符串写在面板的中央 FontRenderContext frc = g2.getFontRenderContext(); Rectangle2D rec = f.getStringBounds(s,frc); double x = (this.getWidth()-rec.getWidth())/2; double y = (this.getHeight()-rec.getHeight())/2; double ascent = -rec.getY(); g2.drawString(s, (int)x, (int)(y+ascent)); Java
  • 65. 设置字体例:将字符串写在面板的中央 import java.awt.*; import javax.swing.*; import java.awt.geom.*; import java.awt.font.*; public class FontTest { public static void main(String[]args){ FontFrame f = new FontFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } }Java
  • 66. 设置字体例:将字符串写在面板的中央 class FontFrame extends JFrame{ public FontFrame(){ this.setTitle("Font Window"); this.setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT); this.setLocation(this.getWidth()/4,this.getHeight()/4); this.add(new FontPanel()); } public static final int DEFAULT_WIDTH = 300; public static final int DEFAULT_HEIGHT = 200; } Java
  • 67. 设置字体例:将字符串写在面板的中央 class FontPanel extends JPanel{ public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; String s = new String("Hello World, angle!"); Font f = new Font("Serif",Font.BOLD+Font.ITALIC,30); g2.setFont(f); FontRenderContext frc = g2.getFontRenderContext(); Rectangle2D rec = f.getStringBounds(s,frc); double x = (this.getWidth()-rec.getWidth())/2; double y = (this.getHeight()-rec.getHeight())/2; double ascent = -rec.getY(); g2.drawString(s, (int)x, (int)(y+ascent));Java
  • 68. 设置字体例:将字符串写在面板的中央 g2.setPaint(Color.GRAY); g2.draw(new Line2D.Double(x,y+ascent, x+rec.getWidth(), y+ascent)); g2.draw(new Rectangle2D.Double(x,y, rec.getWidth(), rec.getHeight())); } }Java
  • 69. 图像读取图像文件 表示图像文件的类 java.awt.Image; java.awt.image.BufferedImage; 读图像 String filename=“…”; Image image = ImageIO.read(new File(filename));Java
  • 70. 图像显示图像 java.awt.Graphics boolean drawImage(Image ima, int x, int y, imageObserver observer) boolean drawImage(Image ima, int x, int y, int width, int height, ImageObserver observer) 例: public void paintComponent(Graphics g){ …; g.drawImage(image,x,y,null); }Java
  • 71. 图像例:平铺显示图像 import javax.swing.*; import java.io.*; import java.awt.geom.*; import java.awt.*; import javax.imageio.*; public class ImageTest { public static void main(String[]args){ ImageFrame f = new ImageFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setVisible(true); } } Java
  • 72. 图像例:平铺显示图像 class ImageFrame extends JFrame{ public ImageFrame(){ this.setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); this.setTitle("Image Window"); this.add(new ImagePanel()); } public static final int DEFAULT_WIDTH = 400; public static final int DEFAULT_HEIGHT = 300; } Java
  • 73. 图像例:平铺显示图像 class ImagePanel extends JPanel{ public ImagePanel(){ try{ ima = ImageIO.read(new File("blue-ball.gif")); }catch(IOException e){ System.out.println(e); } } public void paintComponent(Graphics g){ super.paintComponent(g); Graphics2D g2 = (Graphics2D)g; f(ima == null)return; Java
  • 74. 图像例:平铺显示图像 int imageWidth = ima.getWidth(this); int imageHeight = ima.getHeight(this); g2.drawImage(ima,0,0,null); for(int i = 0; i*imageWidth < this.getWidth(); i++) for(int j = 0; j*imageHeight
  • 75. 图像Java原图像平铺后得到的图像
  • 76. 小结Java框架的显示; 如何在窗体中绘制各类信息(文字、几何图形、图像); 文本信息的显示; 图形的绘制; 颜色的设置; 图象的绘制;
  • 77. 作业Java尝试在窗体上画一张笑脸.