Java核心技术卷一基础知识-第7章-图形程序设计-读书笔记

第7章 图形程序设计

本章内容:
* Swing概述
* 创建框架
* 框架定位
* 在组件中显示信息
* 处理2D图形
* 使用颜色
* 文本使用特殊字体
* 显示图像
  1. 本章主要讲述如何编写定义屏幕上的窗口大小和位置的程序;如何在窗口中采用多种字体显示文本;如何显示图像等。

7.1 Swing概述

  1. 在Java 1.0刚刚出现的时候,包含了一个用于基本GUI程序设计的类库,Sun将它称为抽象窗口工具箱(Abstract Window Toolkit,AWT)。基本AWT库采用将处理用户界面元素的任务委派给每个目标平台(Window、Solaris、Macintosh等)的本地GUI工具箱的方式,由本地GUI工具箱负责用户界面元素的创建和动作。在不同的平台上,操作行为存在着一些微妙的差别。有的图形环境(如X11/Motif)并没有像Window或Macintosh这样丰富的用户界面组件集合。在不同平台上的AWT用户界面库中存在着不用的bug。研发人员必须在每一个平台上测试应用程序。
  2. 在1996年,Netscape创建了一种称为IFC(Internet Foundation Class)的GUI库,它采用了与AWT完全不同的工作方式。它将按钮、菜单这样的用户界面元素绘制在空白窗口上,面对等体只需要创建和绘制窗口。因此,Netscape的IFC逐渐在程序运行的所有平台上的外观和动作都一样。Sun与Netscape合作完善了这种方式,创建了一个名为Swing的用户界面库。Swing可作为Java 1.1的扩展部分使用,现已成为Java SE 1.2标准库的一部分。
  3. Swing没有完全替代SWT,而是基于AWT架构之上。Swing仅仅提供了能力更加强大的用户界面组件。尤其在采用Swing编写的程序中,还需要使用基本的AWT处理事件。从现在开始,Swing是指“被绘制的”用户界面类;AWT是指像事件处理这样的窗口工具箱的底层机制。
  4. 在用户屏幕上显示基于Swing用户界面的元素要比显示AWT的基于对等体组件的速度慢一些。鉴于以往的经验,对于任何一台现代的计算机来说,微小的速度差别无房大碍。另外,由于下列几点无法抗拒的原因,人们选择Swing:
    • Swing拥有一个丰富、便捷的用户界面元素集合。
    • Swing对底层平台依赖的很少,因此与平台相关的bug很少。
    • Swing给予不用平台的用户一致的感觉。

7.2 创建框架

  1. 在Java中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架(frame)。在AWT库中有一个称为Frame的类,用于描述顶层窗口。这个类的Swing版本名为JFrame,它扩展于Frame类。JFrame是极少数几个不绘制在画布上的Swing组件之一。因此,它的修饰部件(按钮、标题栏、图标等)由用户的窗口系统绘制,而不是由Swing绘制。
  2. 所有的Swing组件必须由时间分派线程(event dispatch thread)进行配置,线程将鼠标点击和按键控制转移到用户接口组件。
  3. 许多Swing程序并没有在事件分配线程中初始化用户界面。在主线程中完成初始化时通常采用的方式。

7.3 框架定位

  1. JFrame类本身包含若干个改变框架外观的方法。当然,通过继承,从JFrame的各个超类中继承了许多用于处理框架大小和位置的方法。其中最重要的有下面几个:
  • setLocation和setBounds方法用于设置框架的位置。
  • setIconImages用于告诉窗口系统在标题栏、任务切换窗口等位置显示哪个图标。
  • setTitle用于该表标题栏的文字。
  • setResizable利用一个boolean值确定框架的大小是否允许用户改变。
  1. Component类找你哥的setLocation方法是重定位组件的一个方法。Complement中的setBounds方法可以实现一步重定位组件大小和位置的操作。
  2. 对于框架来说,setLocation和setBounds中的坐标均相对于整个屏幕。
7.3.1 框架属性
  1. 从概念上讲,title是框架的一个属性。当设置这个属性时,希望这个标题能够改变用户屏幕上的显示。当获取这个属性时,希望能够返回已经设置的属性值。
  2. 针对get/set约定有一个例外:对于类型为boolean的属性,获取方法由is开头。
7.3.2 确保合适的框架大小
  1. 要记住:如果没有明确地指定框架的大小,所有框架的默认值为0x0像素。
  2. 为了得到屏幕的大小,需要按照下列步骤操作。调用Toolkit类的静态方法getDefaultToolkit得到一个Toolkit对象(Toolkit类包含很多与本地窗口系统打交道的方法)。然后,调用getScreenSize方法,这个方法以Dimension对象的形式返回屏幕的大小。Dimension对象同时用公有实例变量width和height保存着屏幕的宽度和高度。
  3. 下面是为了处理框架给予的一些提示:
  • 如果框架中只包含标准的组件,如按钮和文本框,那么可以通过调用pack方法设置框架大小。框架将被设置为刚好能够防止所有组件的大小。在通常情况下,将程序的主框架尺寸设置为最大。正如Java SE 1.4,可以通过调用下列方法将框架设置为最大。frame.setExtendedState(Frame.MAXINIZED_BOTH)
  • 牢记用户定位应用程序的框架位置、重置框架大小,并且在应用程序再次启动时恢复这些内容是一个不错的想法。
  • 如果缩写一个使用多个显示屏幕的应用程序,应该利用GraphicsEnvironment和Graphics Device类获得显示屏幕的大小。
  • GraphicsDevice类允许在全屏模式下执行应用程序。
  1. java.awt.Component 1.0
    • boolean isVisible()
    • void setVisible(boolean b)
      获取或设置visible属性。组件最初是可见的,但JFrame这样的顶层组件例外。
    • void setSize(int width,int height) 1.1
      使用给定的宽度和高度,重新设置组件的大小。
    • void setLocation(int x,int y) 1.1
      将组件移到一个新的位置上。如果这个组件不是顶层组件,x和y坐标(或者p.x和p.y)是容器坐标;否则是屏幕坐标(例如:aJFram)。
    • void setBounds(int x,int y,int width,int height) 1.1
      移动并重新设置组件的大小。
    • Dimension getSize() 1.1
    • void setSize(Dimension d) 1.1
      获取或设置当前组件的size属性。
  2. java.awt.Window 1.0
    • void toFront()
      将这个窗口显示在其他窗口前面。
    • void toBack()
      将这个窗口移到桌面窗口栈的后面,并重新排列所有的可见窗口。
    • boolean isLocationByPlatform() 5.0
    • void setLocationByPlatform(boolean b) 5.0
      获取或设置locationByPlatform属性。这个属性在窗口显示之前被设置,由平台选择一个合适的位置。
  3. java.awt.Frame 1.0
    • boolean isResizable()
    • void setResizable(boolean b)
      获取或设置resizable属性。这个属性设置后,用户可以重新设置框架的大小。
    • String getTitle()
    • void setTitle(String s)
      获取或设置title属性,这个属性确定框架标题栏中的文字。
    • Image getIconImage()
    • void setIconImage(Image image)
      获取或设置iconImage属性,这个属性确定框架的图标。窗口系统可能会将图标作为框架装饰或其他部位的一部分显示。
    • boolean isUndecorated() 1.4
    • void setUndecorated(boolean b) 1.4
      获取或设置undecorated属性。这个属性设置后,框架显示中将没有标题栏或关闭按钮这样的装饰。早框架显示之前,必须调用这个方法。
    • int getExtendedState() 1.4
    • void setExtendedState(int state) 1.4
      获取或设置窗口状态。状态是下列值之一。Frame.NORNAL、Frame.ICONIFIED、Frame.MAXIMIZED_HORIZ、Frame.MAXIMIZED_VERT、Frame.MAXIMIZED_BOTH。
  4. java.awt.Toolkit 1.0
    • static Toolkit getDefaultToolkit()
      返回默认的工具箱。
    • Dimension getDcreenSize()
      返回用户屏幕的尺寸。
  5. javax.swing.ImageIcon 1.2
    • ImageIcon(String filename)
      构造一个图标,其图像存储在一个文件中。
    • Image getImage()
      获取该图标的图像。

7.4 在组件中显示信息

  1. 在JFrame中有四层面板。其中的根面板、层级面板和玻璃面板人们并不太关心;它们是用来组织菜单栏和内容窗格以及实现观感的。Swing程序员最关心的是内容窗格(content pane)。在设计框架的时候,将所有的组件添加到内容窗格中。
  2. 绘制一个组件,需要定义一个扩展JComponent的类,并覆盖其中的paintComponent方法。paintComponent方法有一个Graphics类型的参数,这个参数保存着用于绘制图像和文本的设置。在Java中,所有的绘制都必须使用Graphics对象,其中包含了绘制图案、图像和文本的方法。
  3. 无论何种原因,只要窗口需要重新绘图,事件处理器就会通告组件,从而引发执行所有组件的paintComponent方法。
  4. 一定不要自己调用paintComponent方法。在应用程序需要重新绘图的时候,这个方法将被在佛那个地调用,不要人为的干预这个自动的处理过程。
  5. 如果需要强制刷新屏幕,就需要调用repaint方法,而不是paintComponent方法。它将引发采用相应配置的Graphics对象调用所有组件的paintComponent方法。
  6. 在框架中添加一个或多个组件时,如果只想使用它们的首选大小,可以调用pack方法而不是setSize方法。
  7. 有些程序员更喜欢扩展JPanel,而不是JComponent。JPanel是一个可以包含其他组件的容器(container),但同样也可以在其上面进行绘制。有一点不同之处是,面板不透明,这意味着需要在面板的边界内绘制所有的像素。最容易实现的方法是,在每个面板子类的paintComponent方法中调用super.paintComponent来用背景色绘制面板。
  8. javax.swing.JFrame 1.2
    • Container getContentPane()
      返回这个JFrame的内容窗格对象。
    • Component add(Component c)
      将一个给定的组件添加到改框架的内容窗格中(在Java SE 5.0以前的版本中,这个方法将抛出一个异常)。
  9. java.awt.Component 1.0
    • void repaint()
      “尽可能快地”重新绘制组件。
    • Dimension getPreferredSize()
      要覆盖这个方法,发挥这个组件的首选大小。
  10. javax.swing.JComponent 1.2
    • void paintComponent(Grphics g)
      覆盖这个方法来描述应该如何绘制自己的组件。
  11. java.awt.Window 1.0
    • void pack()
      调整窗口大小,要考虑到其组件的首选大小。

7.5 处理2D图形

  1. Graohics类包含绘制直线、矩形和椭圆等方法。但是,这些绘制图形的操作能力非常有限。例如,不能改变先的粗细,不能旋转这个图形。
  2. Java SE 1.2引入了Java 2D库,这个库实现了一组功能强大的图形操作。
  3. 要想使用Java 2D库绘制图形,需要获得一个Graphics2D类对象。这个类是Graphics类的子类。自从Java SE 2版本依赖,paintComponent方法就会自动地获取一个Graphics2D类对象,只需要进行一次类型转换就可以了。
  4. Java 2D库采用面向对象的方式将几何图形组织起来。包括描述直线、矩形的椭圆的类:LINE2D、Rectangle2D、Ellipse2D这些类都实现了Shape接口。
  5. 要想绘制图形,首先要创建一个实现了Shape接口的类的对象,然后调用Graphics2D类中的draw方法。
  6. 使用Java 2D图形或许会增加一些复杂度。在1.0的绘制方法中,采用的是整型像素坐标,而Java 2D图形采用的是浮点坐标。在很多情况下,用户可以使用更有意义的形式(例如,微米或英寸)指定图形的坐标,然后再将其转换成像素,这样做很方便。在Java 2D库中,内部的很多浮点极端都采用单精度float。毕竟,几何计算的最终目的是要设置屏幕或打印机的像素,所以单精度完全可以满足要求了。只要舍入误差限制在一个像素的范围内,视觉效果就不会受到任何影响。另外,在某些平台上,float计算的速度比较快,并且只占据double值的一般存储量。
  7. 由于后缀和类型转换都有点麻烦,所以2D库的设计者决定为每个图形类提供两个版本:一个是为那些节省空间的程序员提供的float类型的坐标;另一个是为那些懒惰的程序员提供的double类型的坐标。
  8. Rectangle2D方法的参数和返回值均为double类型。
  9. 直接使用Double图形类可以避免处理float类型的值,然后如果需要创建上千个图形对象,还是应该考虑使用Float类,这样可以节省存储空间。
  10. Rectangle2D和Ellipse2D类都是由公共超类RectangularShape继承来的。
  11. RectangularShape类定义了20多个有关图形操作的通用方法,其中比较常用的方法有getWidth、getHeight、getCenterX、getCenterY等。
  12. 从Java 1.0遗留下来的两个类也被放置在图形类的继承层次中。它们是Rectangle和Point类,分别扩展于Rectangle2D和Point2D类,并用整型坐标存储矩形和点。
  13. Rectangle2D和Ellipse2D对象很容易构造,需要给出
  • 左上角的x和y坐标。
  • 宽和高。
  1. java.awt.geom.RectangularShape 1.2
    • double getCenterX()
    • double getCenterY()
    • double getMinX()
    • double getMinY()
    • double getMaxX()
    • double getMaxY()
      返回闭合矩形的中心,以及最小、最大x和y坐标值。
    • double getWidth()
    • double getHeight()
      返回闭合矩形的宽和高。
    • double getX()
    • double getY()
      返回闭合矩形左上角的x和y坐标。
  2. java.awt.geon.Rectengle2D.Double 1.2
    • Rectangle2D.Double(double x,double y,double w,double h)
      利用给定的左上角、宽和高,构造一个矩形。
  3. java.awt.geom.Rectangle2D.Float 1.2
    • Rectangle2D.Float(float x,float y,float w,float h)
      利用给定的左上角、宽和高,构造一个矩形。
  4. java.awt.geom.Ellipse2D.Double 1.2
    • Ellopse2D.Double(double x,double y,double w,double h)
      利用给定的左上角、宽和高的外接矩形,构造一个椭圆。
  5. java.awt.geom.Point2D.Double 1.2
    • Point2D.Double(double x,double y)
      利用给定坐标构造一个点。
  6. java.awt.geom.Line2D.Double 1.2
    • Line2D.Double(Point2D start,Point2D end)
    • Line2D.Double(double startX,double startY,double endX,double endY)
      使用给定的起点和终点,构造一条直线。

7.6 使用颜色

  1. 使用Graphics2D类的setPaint方法可以为图形环境上的所有后续的绘制操作选择颜色。
  2. 只需要将调用dra替换为调用fill就可以用一种颜色填充一个封闭图形的内部。
  3. 要想绘制多种颜色,就需要按照选择颜色、绘制图形、再选择另外一种颜色、再绘制图形的过程实施。
  4. fill方法会在右侧和下方少绘制一个像素。
  5. Color类用于定义颜色。在java.awt.Color类中提供了13个预定义的常量,它们分别表示13种标准颜色。BLANK、BLUE、CYAN、DARK_GRAY、GRAY、LIGHT_GRAY、MAGENTA、ORANGE、PINK、RED、WHITE、WELLOW。
  6. 可以通过提供红、绿和蓝三色成分来创建一个Color对象,以达到定制颜色的目的。
  7. 要想设置背景颜色,就需要使用Component类中的setBackground方法。Component类是JComponent类的祖先。
  8. setForeground方法是用来设定在组件上进行绘制时使用的默认颜色。
  9. Color类中的brighter()方法和darker()方法的功能,它们分别加亮或变暗当前的颜色。使用brighter方法也是加亮条目的好办法。实际上,brighter()只微微地加亮一点。要达到耀眼的效果,需要调用三次这个方法:c.brighter().brighter().brighter()
  10. java在SystemColor类中与定义了很多颜色的名字。在这个类中的常量,封装了用户系统的各个元素的颜色。
  11. 系统颜色
    desktop桌面的背景颜色textText文本的前景颜色
    activeCaption标题的背景颜色textInactiveText非活动组件的文本颜色
    activeCaptionText标题的文本颜色textHighlight高亮度文本的背景颜色
    activeCaptionBorder标题文本的边框颜色textHighlightText高亮度文本的文本颜色
    inactiveCaption非活动标题的背景颜色control组件的背景颜色
    inactiveCaptionText非活动标题的文本颜色controlText组件的文本颜色
    inactiveCaptionBorder非活动标题的边框颜色controlLtHightlight组件的浅高亮度颜色
    Window窗口的背景controlHightlight组件的高亮度颜色
    windowBorder窗口边框的颜色controlShadow组件的阴影颜色
    windowText窗口内的文本颜色controlDkShadow组件的暗阴影颜色
    menu菜单的背景颜色scrollbar滚动条的背景颜色
    menuText菜单的文本颜色info帮助区文本的颜色
    text文本的背景颜色infoText帮助区的文本颜色
  12. java.awt.Color 1.0
    • Color(int r,int g,int b)
      创建一个颜色对象。
      参数: r 红色值(0-255)、g 绿色值(0-255)、b 蓝色值(0-255)。
  13. java.awt.Graphics 1.0
    • Color getColor()
    • void setColor(Color c)
      获取或改变当前的颜色。所有后续的绘图操作都是用这个新颜色。
      参数:c 新颜色
  14. java.awt.Graphics2D 1.2
    • Paint getPaint()
    • void setPaint(Paint p)
      获取或设置这个图形环境的绘制属性。Color类实现了Paint接口。因此,可以使用这个方法将绘制属性设置为纯色。
    • void fill(Shape s)
      用当前的颜料填充该图形。
  15. java.awt.Component 1.0
    • Color getBackground()
    • void setBackground(Color c)
      获取或设置背景颜色。
      参数:c 新背景颜色
    • Color getForeground()
    • void setForeground(Color c)
      获取或设置前景颜色。
      参数:c 新前景颜色。

7.7 文本使用特殊字体

  1. 可以通过字体名(font dace name)指定一个字体。字体名由”Helvetica”这样的字体家族名(font family name)和一个可选的”Bold”后缀组成。
  2. 要想知道某台特定计算机上允许使用的字体,就需要调用GraphicsEnvironment类中的getAvailableFontFamilyNames方法。这个方法将返回一个字符型数组,其中包了所有可用的字体名。GraphicsEnvironment类描述了用户系统的图形环境,为了得到这个类的对象,需要调用静态的getLocalGraphicsEnvironment方法。
  3. 点数目是排版中普遍使用的表示字体大小的单位,每英寸包含72个点。
  4. 字体风格值:Font.PLAIN、Font.BOLD、Font.ITALIC、Font.BOLD+Font.ITALIC。
  5. 要想得到屏幕设备字体属性的描述对象,需要调用Graphics2D类中的getFontRenderContext方法。它将返回一个FontRenderContext类对象。
  6. 基线(baseline)是一条虚构的线。上坡度(ascent)是从基线到坡顶(ascenter)的距离。下坡度(descent)是从基线到坡顶(descenter)的距离。
  7. 行间距(leading)是某一行的坡底与其下一行的坡顶之间的空隙。字体的高度是连续两个基线之间的距离,它等于下坡度+行间距+上坡度。
  8. getStringBounds方法返回的矩形宽度是字符串水平方向的宽度。矩形的高度是上坡度、下坡度、行间距的总和,如果需要知道下坡度或行间距,可以使用Font类的getLineMetrics方法,这个方法将返回一个LineMetrics类对象。
  9. 为了能够获得中央的位置,可以使用getWidth()得到组件的宽度。使用bounds.getWidth()得到字符串的宽度。前者减去后者就是两侧应该剩余的空间,因此,每侧剩余的空间应该是这个差值的一般。高度也一样。
  10. java.awt.Font 1.0
    • Font(String name,int style,int size)
      创建一个字体对象。
      参数: name 字体名。不是字体名(例如,“Helvetica Bold”),就是逻辑字体名(例如,“Serif”、“SansSerif”)。style 字体风格(Font.PLAIN、Font.BOLD、Font.ITALIC或Font.BOLD+Font.ITALIC)。size 字体大小(例如,12)。
    • String getFontName()
      返回字体名,例如,“Helvetica Bold”。
    • String getFamily()
      返回字体家族名,例如,“Helvetica”。
    • String getName()
      如果采用逻辑字体名创建字体,将返回逻辑字体,例如,“SansSerif”;否则,返回字体名。
    • Rectangle2D getStringBounds(String s,FontRenderContext context) 1.2
      返回包围这个字符串的矩形。矩形的起点为基线。矩形顶端的y坐标等于上坡度的负值。矩形的高度等于上坡度、下坡地和行间距之和。宽度等于字符串的宽度。
    • LineMetrics getLineMetrics(String s,FontRenderContext context) 1.2
      返回测定字符串宽度的一个线性metrics对象。
    • Font deriveFont(int style) 1.2
    • Font deriveFont(float size) 1.2
    • Font deriveFont(int style,float size) 1.2
      返回一个新字体,除给定大小和字体风格外,其余与原字体一样。
  11. java.awt.font.LineMetrics 1.2
    • float getAscent()
      返回字体的上坡度—从基线到大写字母顶端的距离。
    • float getDescent()
      返回字体的下坡度—从基线到坡底的距离。
    • float getLeading()
      返回字体的行间距—从一行文本底端到下一行文本顶端之间的空隙。
    • float getHeight()
      返回字体的总高度—两条文本基线之间的距离(下坡度+行间距+上坡度)。
  12. java.awt.Graphics 1.0
    • Font getFont()
    • void setFont(Font font)
      获取或设置当前的字体。这种字体将被应用于后续的文本绘制操作中。
      参数:font 一种字体。
      • void drawString(String str,int x,int y)
        参数:str 将要绘制的字符串。x 字符串开始的x坐标。y 字符串基线的y坐标。
  13. java.awt.Graphics 1.2
    • FontRenderContext getFontRenderContext()
      返回这个图形文本中,指定字体特征的字体绘制环境。
    • void drawString(String str,float x,float y)
      采用当前的字体和颜色绘制一个字符串。
      参数:str 将要绘制的字符串。 x 字符串开始的x坐标。y 字符串基线的y坐标。
  14. javax.swing.JComponent 1.2
    • FontMetrics getFontMetrics(Font f) 5.0
      获取给定字体的度量。FontMetrics类是LineMetrics类的早先版。
  15. java.awt.FontMetrics 1.0
    • FontRenderContext getFontRenderContext() 1.2
      返回字体的字体绘制环境。

7.8 显示图像

  1. 使用Graphics类的drawImage方法将图像显示出来。
  2. java.awt.Graphics 1.0
    • boolean drawImage(Image img,int x,int y,ImageObserver observer)
      绘制一副非比例图像。注意:这个调用可能会在图像还没有绘制完毕就返回。
      参数:img 将要绘制的图像。x 左上角的x坐标。y 左上角的y坐标。observer 绘制进程中以通告为目的的对象(可能为null)。
    • boolean drawImage(Image img,int x,int y,int width,int height,ImageObserver observer)
      绘制一副比例图像。系统按照比例将图像放入给定宽和高的区域。注意:这个调用可能会在图像还没有绘制完毕就返回。
      参数:img 将要绘制的图像。x 左上角的x坐标。y 左上角的y坐标。width 描述图像的宽度。height 描述图像的高度。observer 绘制进程中以通告为目的的对象(可能为null)。
    • void copyArea(int x,int y,int width,int height,int dx,int dy)
      拷贝屏幕的一块区域。
      参数:x 原始区域左上角的x坐标。y 原始区域左上角的y坐标。width 原始区域的宽度。 height 原始区域的高度。dx 原始区域到目的区域的水平距离。dy 原始区域到目的区域的数值距离。

转载于:https://www.cnblogs.com/zhangmiao14/p/9630211.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值