分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.youkuaiyun.com/jiangjunshow
也欢迎大家转载本篇文章。分享知识,造福人民,实现我们中华民族伟大复兴!
56.java编程思想——创建窗口和程序片 用户接口API
Java 1.1 版同样增加了一些重要的新功能,包括焦点遍历,桌面色彩访问,打印“沙箱内”及早期的剪贴板支持。
焦点遍历十分的简单,因为它显然存在于AWT 库里的组件并且我们不必为使它工作而去做任何事。如果我们制造我们自己组件并且想使它们去处理焦点遍历,我们过载isFocusTraversable()以使它返回真值。如果我们想在一个鼠标单击上捕捉键盘焦点,我们可以捕捉鼠标按下事件并且调用requestFocus()需求焦点方法。
1 桌面颜色
利用桌面颜色,我们可知道当前用户桌面都有哪些颜色选择。这样一来,就可在必要的时候通过自己的程序来运用那些颜色。颜色都会得以自动初始化,并置于SystemColor 的static 成员中,所以要做的唯一事情就是读取自己感兴趣的成员。各种名字的意义是不言而喻的:desktop,activeCaption,activeCaptionText,activeCaptionBorder, inactiveCaption, inactiveCaptionText,inactiveCaptionBorder, window, windowBorder, windowText, menu,menuText,text, textText,textHighlight, textHighlightText,textInactiveText,control, controlText, controlHighlight,controlLtHighlight,controlShadow ,controlDkShadow, scrollbar, info(用于帮助)以及infoText(用于帮助文字)。
2 打印
非常不幸,打印时没有多少事情是可以自动进行的。相反,为完成打印,我们必须经历大量机械的、非OO(面向对象)的步骤。但打印一个图形化的组件时,可能多少有点儿自动化的意思:默认情况下,print()方法会调用paint()来完成自己的工作。大多数时候这都已经足够了,但假如还想做一些特别的事情,就必须知道页面的几何尺寸。下面这个例子同时演示了文字和图形的打印,以及打印图形时可以采取的不同方法。此外,它也对打印支持进行了测试:
2.1 代码
import java.awt.*;
import java.awt.event.*;
publicclass PrintDemo extends Frame {
Button printText =new Button("Print Text"),printGraphics = new Button("Print Graphics");
TextField ringNum =new TextField(3);
Choice faces =new Choice();
Graphics g =null;
Plot plot =new Plot3(); // Try different plots
Toolkit tk = Toolkit.getDefaultToolkit();
public PrintDemo() {
ringNum.setText("3");
ringNum.addTextListener(new RingL());
Panel p =new Panel();
p.setLayout(new FlowLayout());
printText.addActionListener(new TBL());
p.add(printText);
p.add(new Label("Font:"));
p.add(faces);
printGraphics.addActionListener(new GBL());
p.add(printGraphics);
p.add(new Label("Rings:"));
p.add(ringNum);
setLayout(new BorderLayout());
add(p, BorderLayout.NORTH);
add(plot, BorderLayout.CENTER);
String[] fontList =tk.getFontList();
for (inti = 0; i < fontList.length; i++)
faces.add(fontList[i]);
faces.select("Serif");
}
class PrintData {
public PrintJobpj;
publicint pageWidth,pageHeight;
PrintData(String jobName) {
pj = getToolkit().getPrintJob(PrintDemo.this,jobName, null);
if (pj !=null){
pageWidth =pj.getPageDimension().width;
pageHeight =pj.getPageDimension().height;
g =pj.getGraphics();
}
}
void end() {
pj.end();
}
}
class ChangeFont {
privateint stringHeight;
ChangeFont(String face, int style, int point) {
if (g !=null){
g.setFont(new Font(face,style, point));
stringHeight =g.getFontMetrics().getHeight();
}
}
int stringWidth(Strings) {
returng.getFontMetrics().stringWidth(s);
}
int stringHeight() {
returnstringHeight;
}
}
class TBLimplementsActionListener {
publicvoid actionPerformed(ActionEvent e) {
PrintData pd = new PrintData("Print Text Test");
// Null means print job canceled:
if (pd ==null)
return;
String s ="PrintDemo";
ChangeFont cf = new ChangeFont(faces.getSelectedItem(), Font.ITALIC, 72);
g.drawString(s, (pd.pageWidth-cf.stringWidth(s)) / 2, (pd.pageHeight -cf.stringHeight()) / 3);
s ="Asmaller point size";
cf =new ChangeFont(faces.getSelectedItem(), Font.BOLD, 48);
g.drawString(s, (pd.pageWidth-cf.stringWidth(s)) / 2, (int) ((pd.pageHeight -cf.stringHeight()) /1.5));
g.dispose();
pd.end();
}
}
class GBLimplementsActionListener {
publicvoid actionPerformed(ActionEvent e) {
PrintData pd = new PrintData("Print Graphics Test");
if (pd ==null)
return;
plot.print(g);
g.dispose();
pd.end();
}
}
class RingLimplements TextListener {
publicvoid textValueChanged(TextEvent e) {
inti = 1;
try {
i = Integer.parseInt(ringNum.getText());
} catch (NumberFormatExceptionex) {
i = 1;
}
plot.rings =i;
plot.repaint();
}
}
publicstaticvoidmain(String[]args){
Frame pdemo =new PrintDemo();
pdemo.setTitle("Print Demo");
pdemo.addWindowListener(new WindowAdapter() {
publicvoid windowClosing(WindowEvent e) {
System.exit(0);
}
});
pdemo.setSize(500, 500);
pdemo.setVisible(true);
}
}
classPlot extends Canvas {
publicintrings= 3;
}
classPlot1 extends Plot {
// Defaultprint() calls paint():
publicvoidpaint(Graphics g){
intw = getSize().width;
inth = getSize().height;
intxc = w / 2;
intyc = w / 2;
intx = 0, y = 0;
for (inti = 0; i < rings; i++) {
if (x <xc&& y < yc) {
g.drawOval(x,y, w, h);
x += 10;
y += 10;
w -= 20;
h -= 20;
}
}
}
}
classPlot2 extends Plot {
// To fit thepicture to the page, you must
// knowwhether you're printing or painting:
publicvoidpaint(Graphics g){
intw, h;
if (ginstanceofPrintGraphics) {
PrintJob pj = ((PrintGraphics) g).getPrintJob();
w =pj.getPageDimension().width;
h =pj.getPageDimension().height;
} else {
w = getSize().width;
h = getSize().height;
}
intxc = w / 2;
intyc = w / 2;
intx = 0, y = 0;
for (inti = 0; i < rings; i++) {
if (x <xc&& y < yc) {
g.drawOval(x,y, w, h);
x += 10;
y += 10;
w -= 20;
h -= 20;
}
}
}
}
classPlot3 extends Plot {
// Somewhatbetter. Separate
// printingfrom painting:
publicvoidprint(Graphics g){
// Assume it's a PrintGraphics object:
PrintJob pj = ((PrintGraphics)g).getPrintJob();
intw = pj.getPageDimension().width;
inth = pj.getPageDimension().height;
doGraphics(g,w, h);
}
publicvoidpaint(Graphics g){
intw = getSize().width;
inth = getSize().height;
doGraphics(g,w, h);
}
privatevoiddoGraphics(Graphics g,intw,int h) {
intxc = w / 2;
intyc = w / 2;
intx = 0, y = 0;
for (inti = 0; i < rings; i++) {
if (x <xc&& y < yc) {
g.drawOval(x,y, w, h);
x += 10;
y += 10;
w -= 20;
h -= 20;
}
}
}
} /// :~
这个程序允许我们从一个选择列表框中选择字体(并且我们会注意到很多有用的字体在Java 1.1 版中一直受到严格的限制,我们没有任何可以利用的优秀字体安装在我们的机器上)。它使用这些字体去打出粗体,斜体和不同大小的文字。另外,一个新型组件调用过的绘图被创建,以用来示范图形。当打印图形时,绘图拥有的ring 将显示在屏幕上和打印在纸上,并且这三个衍生类Plot1,Plot2,Plot3 用不同的方法去完成任务以便我们可以看到我们选择的事物。同样,我们也能在一个绘图中改变一些ring——这很有趣,因为它证明了Java 1.1 版中打印的脆弱。在我的系统里,当ring 计数显示“too high”(究竟这是什么意思?)时,打印机给出错误信息并且不能正确地工作,而当计数给出“low enough”信息时,打印机又能工作得很好。我们也会注意到,当打印到看起来实际大小不相符的纸时页面的大小便产生了。这些特点可能被装入到将来发行的Java 中,我们可以使用这个程序来测试它。
这个程序为促进重复使用,不论何时都可以封装功能到内部类中。例如,不论何时我想开始打印工作(不论图形或文字),我必须创建一个PrintJob 打印工作对象,该对象拥有它自己的连同页面宽度和高度的图形对象。创建的PrintJob打印工作对象和提取的页面尺寸一起被封装进PrintData class 打印类中。
1. 打印文字
打印文字的概念简单明了:我们选择一种字体和大小,决定字符串在页面上存在的位置,并且使用Graphics.drawSrting()方法在页面上画出字符串就行了。这意味着,不管怎样我们必须精确地计算每行字符串在页面上存在的位置并确定字符串不会超出页面底部或者同其它行冲突。如果我们想进行字处理,我们将进行的工作与我们很相配。ChangeFont 封装进少量从一种字体到其它的字体的变更方法并自动地创建一个新字体对象和我们想要的字体,款式(粗体和斜体——目前还不支持下划线、空心等)以及点阵大小。它同样会简单地计算字符串的宽度和高度。当我们按下“Print text”按钮时,TBL 接收器被激活。我们可以注意到它通过反复创建ChangeFont 对象和调用drawString()来在计算出的位置打印出字符串。注意是否这些计算产生预期的结果。(我使用的版本没有出错。)
2. 打印图形
按下“Print graphics”按钮时,GBL 接收器会被激活。我们需要打印时,创建的PrintData 对象初始化,然后我们简单地为这个组件调用print()打印方法。为强制打印,我们必须为图形对象调用dispose()处理方法,并且为PrintData 对象调用end()结束方法(或改变为为PrintJob 调用end()结束方法。)这种工作在绘图对象中继续。我们可以看到基础类绘图是很简单的——它扩展画布并且包括一个中断调用ring 来指明多少个集中的ring 需要画在这个特殊的画布上。这三个衍生类展示了可达到一个目的的不同的方法:画在屏幕上和打印的页面上。
Plot1 采用最简单的编程方法:忽略绘画和打印的不同,并且过载paint()绘画方法。使用这种工作方法的原因是默认的print()打印方法简单地改变工作方法转而调用Paint()。但是,我们会注意到输出的尺寸依赖于屏幕上画布的大小,因为宽度和高度都是在调用Canvas.getSize()方法时决定是,所以这是合理的。如果我们图像的尺寸一值都是固定不变的,其它的情况都可接受。当画出的外观的大小如此的重要时,我们必须深入了解的尺寸大小的重要性。不凑巧的是,就像我们将在Plot2 中看到的一样,这种方法变得很棘手。因为一些我们不知道的好的理由,我们不能简单地要求图形对象以它自己的大小画出外观。这将使整个的处理工作变得十分的优良。相反,如果我们打印而不是绘画,我们必须利用RTTI instanceof 关键字来测试PrintGrapics,然后下溯造型并调用这独特的PrintGraphics 方法:getPrintJob()方法。现在我们拥有PrintJob 的句柄并且我们可以发现纸张的高度和宽度。这是一种hacky 的方法,但也许这对它来说是合理的理由。(在其它方面,到如今我们看到一些其它的库设计,因此,我们可能会得到设计者们的想法。)
我们可以注意到Plot2 中的paint()绘画方法对打印和绘图的可能性进行审查。但是因为当打印时Print()方法将被调用,那么为什么不使用那种方法呢?这种方法同样也在Plot3 中也被使用,并且它消除了对instanceof 使用的需求,因为在Print()方法中我们可以假设我们能对一个PrintGraphics 对象造型。这样也不坏。这种情况被放置公共绘画代码到一个分离的doGraphics()方法的办法所改进。
2. 在程序片内运行帧
如果我们想在一个程序片中打印会怎以样呢?很好,为了打印任何事物我们必须通过工具组件对象的getPrintJob()方法拥有一个PrintJob 对象,设置唯一的一个帧对象而不是一个程序片对象。于是它似乎可能从一个应用程序中打印,而不是从一个程序片中打印。但是,它变为我们可以从一个程序片中创建一个帧(相反的到目前为止,我在程序片或应用程序例子中所做的,都可以生成程序片并安放帧。)。这是一个很有用的技术,因为它允许我们在程序片中使用一些应用程序(只要它们不妨碍程序片的安全)。但是,当应用程序窗口在程序片中出现时,我们会注意到WEB 浏览器插入一些警告在它上面,其中一些产生“Warning:AppletWindow. (警告:程序片窗口)”的字样。
我们会看到这种技术十分直接的安放一个帧到程序片中。唯一的事是当用户关闭它时我们必须增加帧的代码(代替调用System.exit()):
2.2 代码2
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
publicclass PrintDemoApplet extends Applet {
publicvoidinit() {
Button b =new Button("Run PrintDemo");
b.addActionListener(new PDL());
add(b);
}
class PDLimplementsActionListener {
publicvoid actionPerformed(ActionEvent e) {
final PrintDemopd = new PrintDemo();
pd.addWindowListener(new WindowAdapter() {
publicvoid windowClosing(WindowEvent e) {
pd.dispose();
}
});
pd.setSize(500, 500);