第七章 图形程序设计

在JDK1.0刚刚出现的时候,包含了一个用于基本GUI程序设计的类库,Sun将它称为抽象窗体工具箱(Abstract Window Toolkit,AWT)。基本AWT库采用将处理用户界面元素的任务委派给每个目标平台(Windows、Solaris、Macintosh等等)的本地GUI工具箱的方式,由本地GUI工具箱负责用户界面元素的创建和动作。
Swing是不对等基于GUI工具箱的正式名字。它已是Java基础类库(Java Foundation Class,JFC)的一部分。
注意:Swing没有完全替代AWT,而是基于AWT的架构之上。Swing仅仅提供了能力更加强大的用户界面组件。尤其在采用Swing编写的程序中,还需要使用基本的AWT处理事件。从现在开始,“Swing”是指“被绘制的”非对等体用户界面类;“AWT”是指像事件处理这样的窗口工具箱的低层机制。
当然,在用户屏幕上显示基于Swing用户界面的元素要比显示AWT的基于对等体组件的速度慢一些。
7.2 创建框架
在Java中,顶层窗口(就是没有包含在其他窗口中的窗口)被称为框架(frame)。JFrame是极少数几个不绘制在画布上的Swing组件之一。因此,它的修饰部件(按钮、标题栏、图标等)由用户的窗口系统绘制,而不是由Swing绘制。
警告:大多数的Swing组件类都以“J”开头,例如,JButton、JFrame等等。在Java中有Button和Frame这样的类,但他们属于AWT组件。如果偶然地忘记了书写“J”,程序仍然可以进行编辑和运行,但是将Swing和AWT组件混合在一起使用将会导致视觉和行为的不一致。
简单地构造一个框架并不自动显示出来,框架起初是不可见的。这就给了程序员一个机会,可以在框架第一次显示之前往其中添加组件。为了显示框架,main方法需要调用框架的setVisible方法。
7.3 框架定位                               2010-09-13    239页
注意:对于框架来说,setLocation和setBounds中的坐标均相对于整个屏幕。如果在容器中包含的其他组件,则组件坐标相对于容器。
为了得到屏幕的大小,需要按照下列步骤操作。调用Toolkit类的静态方法getDefaultToolkit得到一个Toolkit对象。(Toolkit类包含很多与本地窗口系统进行交互的方法)。然后,调用getScreenSize方法,该方法以Dimension对象的形式返回屏幕的大小。Dimension对象同时用公有实例变量width和height保存屏幕的宽度和高度。
Toolkit kit=Toolkit.getDefaultToolkit();
Dimension screenSize=kit.getScreenSize();
int screenWidth=screenSize.width;
int screenHeight=screenSize.height;
注意:如果编写一个利用多个显示屏幕的应用程序,就应该使用GrapicsEnvironment和GraphicsDevice类获得显示屏幕的大小。
如果要设置JFrame只显示其内部组件,不显示框架装饰(即不包括最大化、最下化、还原按钮及窗体边框)可以通过调用setUndecorated(true);
7.4 在面板中显示信息                        2010-09-14      243页
在JFrame中有四层面板。其中的根面板、层级面板和玻璃面板是用来组织菜单栏和内容窗格以及实现观感的。
为了能够在面板上进行绘图,需要:
1)定义一个扩展于JPanel的类;
2)在这个类中,覆盖paintComponent方法。
在Java中,所有的绘图都必须通过Graphics对象,其中包含绘制图案、图像和文本的方法。
注意:Graphics参数与Windows中的设备环境或X11程序设计中的图形环境基本类似。
不管何种原因,只要窗口需要重新绘图,事件处理器就会通告组件,从而引发执行所有组件的painComponent方法。
一定不要自己调用painCompontent方法。在应用重新需要重新绘图的时候,这个方法将被自动地调用,不要人为地干扰这个自动的处理过程。
提示:如果需要强制刷新屏幕,就需要调用repaint方法,而不是paintComponent方法。它将引发采用相应配置的Graphics对象调用所有组件的paintComponent方法。
Graphics对象对屏幕显示的度量单位是像素。
7.5 2D图形
JDK1.2引入了Java 2D库,这个库实现了一组功能强大的图形操作。
要想绘制图形,首先要创建一个实现了Shape接口的类的对象,然后调用Graphics2D类中的draw方法。
提示:直接使用Double图形类可以避免处理float类型的值,然而如果需要创建上千个图形对象,还是应该考虑使用Float类,这样可以节省存储空间。
7.6 颜色
使用Graphics2D类的serPaint方法可以为图形环境上的所有后续的绘制操作选择颜色。想要绘制多种颜色,就需要按照选择颜色,绘制图形,再选择颜色,在绘制图形的过程实施。
注意:如果使用Graphics对象,而不是Graphics2D对象,就需要使用setColor方法设置颜色。
提示:从名字就可以看出,Color类中的brighter()方法和darker()方法的功能,它们分别加亮或者变暗当前的颜色。使用brighter方法也是加亮条目的好办法。实际上,brighter()只微微加亮一点。要达到耀眼的效果,应该调用这个方法三次:c.brighter().brighter().brighter().
7.7 为文本设定特殊字体
要想知道某台特定计算机上所允许使用的字体,就需要调用GraphicsEnviroment类中的getAvailableFontFamilyNames方法。这个方法将返回一个字符串型数组,其中包含类所有可用的字体名。GraphicsEnviroment类描述了用户系统的图形环境,为了得到这个类的对象,需要调用静态的getLocalGraphicsEnviroment方法。
注意:字体映射定义在Java安装的jre/lib子目录中的fontconfig.properties文件中。
要想使用某种字体绘制字符,必须首先利用指定的字体名、字体风格和字体大小来创建一个Font对象。第三个参数是以点的数目计算的字体大小。点的数目是排版中普遍使用的表示字体大小的单位,每英寸包含72个点。
警告:deriveFont方法有两个重载版本。一个(有一个float参数)设置字体的大小;另一个(有一个int参数)设置字体风格。所以f.deriveFont(14)设置的是字体风格,而不是大小!
Java字体包含了通用的ASCII字符和符号。
要想得到屏幕设备字体属性的描述对象,需要调用Graphic2D类中的getFontRenderContext方法。它将返回一个FontRenderContext类对象。可以直接将这个对象传递给Font类的getStringBounds方法:
FontRenderContext context=g2.getFontRenderContext();
Rectangle2D bounds=f.getStringBounds(message,context);
getStringBounds方法将但会包围字符串的矩形。
基线(baseline)是一条虚构的线,例如,字母“e”所在的底线。上坡度(ascent)是从基线到坡顶(ascenter)的距离。例如,“b”和“k”以及大写字母的上面部分。下坡度(descent)是从基线到坡底(descenter)的距离,坡底是“p”和“g”这种字母的底线
行间距(leading)是某一行的坡底与其下一行的坡顶之间的空隙(这个术语源自于排字机分隔行的引导带)。字体的高度是连续两个基线之间的距离,它等于下坡度+行间距+上坡度。
getStringBounds方法返回的矩形宽度是字符串水平方向的宽度,矩形的高度是上坡度、下坡度、行间距的总和。该矩形始于字符串的基线,矩形顶部的y坐标为负值。因此,可以采用下面的方法获得字符串的宽度高度和上坡度:
double stringWidth=bounds.getWidth();
double stringHeight=bounds.getHeight();
double ascent=-bounds.getY();
如果需要知道下坡度或者行间距,可以使用Font类的getLineMetrics方法,这个方法将返回一个LineMetrics类对象,获得下坡度和行间距的方法是:
LineMetrics metrics=f.getLineMetrics(message,context);
float descent=metrics.getDescent();
float leading=metrics.getLeading();
7.8 图像                                   

你可能感兴趣的:(windows,框架,swing,F#,Solaris)