1. 为啥使用applet?
如果不是因为计算机二级或是某些该死的考试中需要出题,,我想我是不会理会这中东西的,毕竟这货淘汰了,为啥使用?为了考试。
注:applet是和html或者是jsp一起使用的,不能单独运行(当然你可以使用appletviewer命令或者是ide去运行),具体的使用将在代码中体现。
2. applet生命周期
- 初始化
init()
:在这个方法中可以设置一些初始值,像是界面的布局,会在param
标签被处理后调用这个方法。 - 启动
start()
:浏览器调用完init()
方法后,该方法被自动调用。每当用户从其他页面返回到包含Applet的页面时,则调用该方法。 - 停止
start()
:当用户从包含applet的页面移除的时候,该方法自动被调用。因此,可以在相同的applet中反复调用该方法。 - 销毁
stop
:此方法仅当浏览器正常关闭时调用。因为applets只有在HTML网页上有效,所以你不应该在用户离开包含Applet的页面后遗漏任何资源. paint()
:该方法在start()方法之后立即被调用,或者在applet需要重绘在浏览器的时候调用。paint()方法实际上继承于java.awt。
如图
3. 第一个applet程序
applet必须通过html文件使用浏览器或者是命令行中的appletviewer命令才能运行,在此使用浏览器过于麻烦,所以在下面我们都将使用命令行,来执行。
1). 建立html文件。
在java_test_two/jht文件夹中新建一个名为Hello.html
的文件。
<applet code="Hello.class" height=200 width=200></applet>
上面代码中,applet
标签是必须的,代表了在此处执行applet程序,而code则是程序的字节码文件名(如果有包名需要加上包名),如果是要基于根目录的(比如和html不在一个文件夹内),需要指定根目录路径,使用codebase
,就像这样。
如果我的字节码文件在当前目录的app目录里面
<applet code="app.Hello.class" codebase="../app" height=200 width=200></applet>
上面的code是我所需要运行的类,如果有包名一定要加上包名,至于codebase是相对包的根目录,目录如下图
可以看到Hello.class
文件是在app包中的,而app包是在java_test_two
中的,而我们的Hello.html
是在jht目录中的,相对于app目录需要向后退一步,才能进去app目录,而codebase
就是指这个app所在的根目录,也就是java_test_two
,所以,需要../
来从jht
回退到java_test_two
目录中。才好在code
中使用包名加类名。
2).建立applet
我们先在java_test_two
文件夹中建立一个简单的applet,只拿标签输出一个你好。使用applet,必须继承java.applet.Applet
类或者是javax.swing.JApplet
类,我在这里为了迎合计算机二级,就继承java.applet.Applet
类。
package app;
import java.applet.Applet;
import javax.swing.JLabel;
public class Hello extends Applet{
public void init(){
JLabel lable = new JLabel("你好");
add(lable);
}
}
上面的代码是不是很简单,没错就是这样,很无语吧。
3).运行
这里的运行需要加上编码格式和-d .
,编码使用utf-8是因为需要中文,-d .
是因为有package app
语法来生成对应的包目录。
G:\java_test_two>javac -encoding utf-8 -d . Hello.java
编译成功后会在app
文件夹中生成Hello.class
文件。
然后进入jht文件夹中使用
appletviewer Hello.html
命令来运行这个applet。**注意,appletviewer
后面接着的是html文件,不是java的class文件!
你会发现
4.使用标签来给applet传值
在html文件中我们可以继续加入<param>
标签来为applet传值。
<param name ="aaa"value = "bbb">
设置的方法如上,这个标签是写在<applet>
标签内的。
我们的html文件看来就像这样
<applet code="app.Hello.class" codebase="../" height=200 width=200>
<param name="what" value="12"/>
</applet>
那么我们如何在java代码中获取到这个值呢?
package app;
import java.applet.Applet;
import javax.swing.JLabel;
public class Hello extends Applet{
public void init(){
String age = getParameter("what");
JLabel lable = new JLabel(age);
add(lable);
}
}
上面的代码中,使用了getParameter()方法来获取<param>
标签中的值。然后放入lable中。这里为啥没通过对象调用getParameter呢?很显然,这是因为Hello继承过来了属于Applet的getParameter()方法。然后因为在运行applet的时候,首先是处理 <param>
标签中的内容,然后执行init()方法里面的内容,所以,输出12。
5.applet的两种类
上面我们已经讲解了初步的运行方法和基本的代码,下面我会加快速度,不再对一些基础的地方进行解释了。
为了方便,我不再使用上面的命令行启动了,我使用myEclispse
来进行编写这样然后能直接运行,这样更快。如果你没有像MyEclispse这样的ide,所谓的NetBeans也行,或者你干脆拿命令行输入appletviewer xxx.html
,去启动。
1. java.applet.Applet以及javax.swing.Applet继承的类
Java.lang.Object
Java.awt.Component//组件
Java.awt.Container//容器
Java.awt.Panel//面板
Java.applet.Applet:默认的布局方式是FlowLayout
Javax.swing.JApplet:默认的布局方式是BorderLayout
2. 组件的添加
可以直接向Java.applet.Applet容器添加组件:如下
theApplet.add(Component awtComponent);//其中theApplet是Java.applet.Applet类型的对象
向Javax.swing.JApplet容器添加组件的语句格式为:
theJApplet.getContentPane().add(Component swingComponent);
//其中theApplet是Javax.swing.JApplet类型的对象
特别注明:JApplet是顶层的Swing容器,其内部用一个隐含的根面板(JRootPanel)作为惟一的直接后代,而根面板中的内容面板(Content Pane)才是JApplet除菜单条外所有构件的双亲。由于内容面板的存在,通常对JApplet添加构件有两种方式:
1. 用getContentPane()方法获得JApplet的内容面板,再向内容面板中添加构件:
Container contentPane=getContentPane();
contentPane.add(SomeComponent);
2. 建立一个JPanel之类的中间容器,把构件添加到容器中,再用setContentPane()方法把该容器置为JApplet的内容面板:
JPanel contentPane=new JPanel(); contentPane.add(SomeComponent); setContentPane(contentPanel);
之后,我们仍需注意的问题是,明确区分容器和构件(组件),容器中是不能直接再添加容器的。
常用的容器有Frame(窗口容器),Panel(面板容器),Applet(java小程序的容器),Dialog(对话框容器)等。需要注意的是,applet中是直接添加不了窗体的,会爆一个这样的错误java.lang.IllegalArgumentException: adding a window to a container
上面的代码中明显区分java.applet.Applet
和javax.swing.JApplet
,前者能够直接添加组件,而后者需要使用面板来添加。至于后者的添加方法已经写了两种,下面我们去实践一下。
对于JApplet的第一种添加构件形式
import javax.swing.JApplet;
import javax.swing.JButton;
public class Test2 extends JApplet{
public void init(){
JButton button = new JButton("点我");
getContentPane().add(button);
add(button);
}
}
上面代码中,运行可以看到布局是BorderLayout
,getContentpane
是获取当前的JApplet的面板,然后在上面添加构件JButton。(每个JApplet都有一个默认的面板)
对于JApplet的第二种添加构件的形式
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Test2 extends JApplet{
public void init(){
JButton button = new JButton("点我");
JPanel panel = new JPanel();
panel.add(button);
setContentPane(panel);
add(button);
}
}
上面代码就是先设置一个面板,然后再给JApplet将这个面板设定为自己的面板,运行完后会发现布局变成了FlowLayout
。
6.applet去画文字和图形
Graphics类介绍
- Graphics类是表示applet显示区域的抽象类,它是java.awt包的部分,用于在applet的显示区域上画图。
- 为了在applet窗口中绘制图形,可不需要创建Graphics的实例。JApplet的paint()方法给出Graphics对象,通过使用该对象,结果就会出现在浏览器中。
- java的坐标系统规定在屏幕左上角为原点(0,0),正x值向右,正y值向下。所有的像素值均为整数。
- Graphics类提供画许多图像的方法,文本,线,圆,多边形,图像等。
画applet
- 当屏幕需要更新以显示新的内容,由update()和paint()方法完成。
- update():取Graphics类对象为参数。当applet区域需要重画时,windows系统开始画画过程。调用update()方法清除屏幕再调用paint()方法,屏幕然后由系统更新。
- paint()方法:取Graphics类对象为参数,在绘画区画applet的图像。
- 当想要重画applet的区域时调用该方法。repaint()方法是调用update()方法发出applet需要更新的信号。
- update()方法的缺省操作是清除applet区域和调用paint()方法,如果不想清除applet区域可以超越update()方法。
使用paint()和print帮助理解applet的生命周期
import java.awt.Graphics;
import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JPanel;
public class Test2 extends JApplet{
int a = 0;
public void init(){
a++;
System.out.println("init"+a);
}
public void start(){
a++;
System.out.println("start"+a);
}
public void stop(){
a++;
System.out.println("stop"+a);
}
public void destroy(){
a++;
System.out.println("destroy"+a);
}
public void paint(Graphics g){
a++;
System.out.println("paint"+a);
g.drawString("什么神奇"+a+"次", 20, 20);
}
}
先开始运行时在控制台输出
init1
start2
paint3
在applet中输出什么神奇3次
。
当你点击最小化后
会发现多了个stop4
init1
start2
paint3
stop4
当你再次最大化这个applet后
init1
start2
paint3
stop4
start5
paint6
当你关闭这个applet
init1
start2
paint3
stop4
start5
paint6
stop7
destroy8
多了最后两个吧,由此可以看出函数的调用顺序了,在此不再多说了。
上面的代码中主要是通过paint()中的Graphics对象来使用drawString方法去画字,并且指定了字的坐标。
使用repaint()和多线程来再applet中显示时钟
这个时钟就是电子表的形式,如果做成机械表的样式需要另画钟表,再此不再叙述。
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util.Date;
import javax.swing.JApplet;
public class Test2 extends JApplet implements Runnable{
int a = 0;
public void init(){
a++;
System.out.println("init"+a);
Thread thread = new Thread(this);//这里的this是指当前对象,其实就是指运行的applet了,在启动时,java程序给我们自动将Test2进行实例化。这个this就指代这个实例化的对象。
thread.start();
}
public void start(){
a++;
System.out.println("start"+a);
}
public void stop(){
a++;
System.out.println("stop"+a);
}
public void destroy(){
a++;
System.out.println("destroy"+a);
}
public void paint(Graphics g){
super.paint(g);//这里得调用父类构造方法清空原来的绘图,否则是在以前的基础上画
a++;
System.out.println("paint"+a);
Date date = new Date();
SimpleDateFormat format = new SimpleDateFormat("YY-MM-dd HH:mm:ss");
String dates=format.format(date);
g.drawString("什么神奇"+a+"次", 20, 20);
g.drawString(dates,30,40);
}
public void run(){
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.repaint();//此处this同上
}
}
}
上面的代码比较容易理解,如果你多线程完全没看过的话请跳过这段代码。运行之后,会在控制台看到调用的方法。在此不再叙述了。
设置字体大小和颜色属性
- Graphics类和Font类和FontMetrics类结合在一起,就能在屏幕上显示文本。
- Font类表示一个给定的字体,它的文本类型和点的大小。
- FontMetrics类给出有关字体的信息,如一个给定字符的实际高度和宽度。下面我们不使用这个。
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JApplet;
public class Test3 extends JApplet {
public void init(){
}
public void paint(Graphics g){
Font font = new Font("宋体",Font.BOLD,24);
g.setFont(font);
g.drawString("什么神奇", 40, 40);
}
}
上面代码中先是实例化Font,然后将该对象给g.setFont(),这样就能设置字体了,然后在画出这个字体。下面就是颜色的使用。
颜色主要就是Color
类,可以用下面的方法来创建颜色
Color c = new Color(0.55,0.55,0.55);
构造函数的参数是rgb值,这个值就代表了颜色。当然,Color
类中也提供了静态的属性直接使用颜色名获得颜色
Color.red
使用一个Graphics类对象的方法来设置颜色:g.setColor(Color.red);
也可以设置当前applet颜色:setForeground(g.getColor());//如果已经设置了字体颜色,那个这个setForeground将不作用于字体
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JApplet;
public class Test3 extends JApplet {
public void init(){
}
public void paint(Graphics g){
Font font = new Font("宋体",Font.BOLD,24);
g.setColor(Color.red);
g.setFont(font);
g.drawString("什么神奇", 40, 40);
}
}
7. AppletContext接口
- 使用
getAppletContext()
获取当前applet的上下文环境。 - 使用
showStatus()
方法改变显示在浏览器状态栏上的信息。 - 使用
showDocument()
方法请求浏览器显示一个URL地址对应的HTML文件。
java
showDocument(URL);
showDocument(URL urlObj.String target);//target可以为各级窗口
URL getCodeBase()
是从浏览器获取applet的URL地址URL getDocumentBase()
用于从浏览器获得applet所嵌入的HTML文件的URL地址。
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.JApplet;
public class Test3 extends JApplet {
public void init(){
getAppletContext().showStatus("连接中");
try {
getAppletContext().showDocument(new URL("http://www.baidu.com"));
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
}
上面代码是演示不出效果的,只有在浏览器中才能看到,我这里的浏览器已经全面禁止了applet,就算加载插接件也没办法。在计算机二级中,只需要死记以上几种方法的作用即可。
8.applet加载图片
public URL getDocumentBase()
方法:返回的是Applet类文件所在网页的网络路径。
我们可以试着来看看。import java.net.URL; import java.awt.Graphics; import javax.swing.JApplet; public class Hello extends JApplet { public void init(){ } public void paint(Graphics g){ URL url =getDocumentBase(); System.out.println(url.toString()); g.drawString(url.toString(),50,50); } }
上面输出的结果是
file:/G:/java_test_two/jht/Hello.html
。这就是一个网络的url地址,也是我们文件在网络中的位置,那个这个东西有啥用呢?往下看。public Image getImage(URL url, String name)
这个方法可以用来得到图片,方法中第一参数就是url,没错,需要的就是图片在网络中的地址,所以使用getDocumentBase()
去获得,传到getImage
中去。import java.net.URL; import java.awt.Graphics; import java.awt.Image; import javax.swing.JApplet; public class Hello extends JApplet { public void init(){ } public void paint(Graphics g){ Image im = getImage(getDocumentBase(),"two.png"); g.drawImage(im,0,0,this); } }
下面是我的目录结构
很明显,two.png放在了和Hello.html一样的文件夹下。
9. 载入声音
public AudioClip getAudioClip(URL url, String name)
该方法返回由url和name决定的AudioClip对象。
其中:
(1) url:音频剪辑的绝对URL地址;
(2) name:相对于上面的url,为音频剪辑的相对地址,通常指名字。编写的代码
import java.awt.*; import java.applet.Applet; public class UseAudio extends Applet { public void init() { } public void start() { //播放Applet所在目录下的tiger.au声音文件 getAudioClip(getDocumentBase(),"tiger.au").play(); } };