【实验目的】
继续熟悉Eclipse的使用并尝试编写一个简单的Applet程序
【实验过程】
编写一个Java Applet程序,并正在Java Applet中写两行文字:“这是一个Java Applet程序”和“我改变了字体”。
import java.applet.*;
import java.awt.*;
public class JavaApplet extends Applet{
public void paint(Graphics g) {
g.setColor(Color.blue);
//绘制一行文字:“这是一个JavaApplet程序”
g.drawString("这是一个JavaApplet程序",20,10);
g.setColor(Color.red);
g.setFont(new Font("宋体",Font.BOLD,36));
//绘制一行文字:“我改变了字体”
g.drawString("我改变了字体",20,50);
}
}
import java.applet.*;
import java.awt.*;
public class AppletFont extends Applet{
public void paint(Graphics g) {
g.setColor(Color.blue);
//绘制一行文字:“这是一个JavaApplet程序”
g.drawString("这是一个JavaApplet程序",20,10);
g.setColor(Color.red);
g.setFont(new Font("宋体",Font.BOLD,36));
//绘制一行文字:“我改变了字体”
g.drawString("我改变了字体",20,50);
}
}
搜集资料发现,所调用的paint方法下的Graphics类,起到了小应用程序中图像绘制的作用。Graphics类是所有图形上下文的抽象基类,允许应用程序绘制到在各种设备上实现的组件以及屏幕外图像。
实际生活中需要绘图,要准备画纸、画笔和颜料。程序中绘图亦是如此,Applet本身的显示区域可作为画纸,使用Graphics画笔,再选定样式颜色诸如此类,就要用到Graphics类下面的方法。
可见,paint方法的运行是逐步进行的,在绘制完第一行文字后,程序会先执行setColor(Color.red)切换字体颜色,再进行后续操作,绘制出第二行文字,并不影响已绘制完的第一行文字。
【实验心得】
Applet是Java的一种程序,编写一个简单的Applet程序时,首先应调用Applet类,使用import语句。
import java.applet.*;
import java.awt.*;
没有这些import语句,Java编译器就识别不了Applet和Graphics类。
注意到Applet类是没有定义main()方法的,查找资料发现它是运用“init、start、destroy、paint”四种方法,外加一种自动调用的“stop”方法。
可以通过调整句子首字符起点的坐标,使得绘制效果更完整。java的坐标系统规定在屏幕左上角为原点(0,0),正x值向右,正y值向下。
Java Applet与普通的Java应用执行的机制并不相同,它没有main(),通过查找资料发现。main方法只是一个程序入口,Applet是通过init()来初始化的,嵌入到浏览器中运行,于是就不需要用main方法来调用它。
【实验后的练习】
-
程序中的主类如果不用public修饰,编译能通过吗?
删除主类的public命名为新文件TestA.java,可以通过编译。 -
程序中的主类如果不用public修饰,程序能正确运行吗?
不可以运行,运行报错!
运行报错:加载: AppletFont.class不是公共的, 或者没有公共构造器。
如果一个源文件中含有public修饰的类,那么这个文件名必须与类名一致,如果没有public类,则文件可以随意命名。一个文件中,public的类可以有零个或一个,非public的类可以有零个或多个。普通的Java程序是从一个public类的main函数开始执行的,就像C程序是从main()函数开始执行一样。要求只能有一个public类,是为了给类装载器提供方便。
一个public类只能定义在以它的类名为文件名的文件(严格区分大小写),每一个源文件都只有一个public类,因为每个编译单元都只能有一个公共接口,用public类来表现。该接口可以按照要求包含众多的支持包访问权限的类。如果有一个以上的public类,编译器就会报错。(另一种可能会报错的情况)
当程序主类不是public类时,Java虚拟机就根本找不到运行的人口,无法正确运行。 -
程序将paint方法误写成Paint,编译能通过么?
更改paint为Paint命名为新文件TestB.java,可以正常通过编译。 -
程序将paint方法误写成Paint,运行时能看到有关的输出信息吗?
不能看到有关的输出信息!会得到一个空白的窗口,好像还关不掉(捂脸)。
这涉及到继承问题:子类JavaApplet继承了父类Applet里面的paint方法,之后在子类重写paint方法,以达到绘制输出信息的效果。但如果子类用的是Paint,就根无法定位继承父类Applet里面的paint方法,绘制的目的便无法达成。
【实验过程】
在Eclipse平台中实现下列简单的程序:
1、编写控制台程序输出1--200之间的所有素数。
所谓素数,便是其只含有1与它本身两个因子。除了1以外,一个非素数含有的最小因子是2,理所应当的,理论存在非素数的最大因子不超过它的一半大小。所以,我们只要给出任意一个自然数,再用2到这个自然数一般大小的数进行相除,倘若有一次运算结果余数为零,这个自然是便不再是素数。如此步骤反复进行,便可找到1--200所有的素数。程序流程图如下:
2. 嵌套循环(for + while)实现1!+2!+3!+ ... 9!即阶乘之和。(如果能采用递归算法实现阶乘,再调用此函数实现求和,更妙)
public class FactorialAccumulation {
public static void main (String[] args) {
int summation = 0;
for(int i = 1;i < 10;i += 1) {
summation += multiplication(i);
}
System.out.println("1!+2!+...+9!="+summation);
}
public static int multiplication(int j) {
int n = 1;
for(int k = 1;k <= j;k += 1) {
n = n * k;
}
return j = n;
}
}
/*
另一种阶乘循环的写法:
if(j == 1) {
return 1;
}
else {
return j*multiplication(j - 1);
}
}
*/
- 尝试用applet编写程序实现摄氏温度和华氏温度的转换。
import java.applet.Applet;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class TemperatureConversion extends Applet implements ActionListener{
private static final long serialVersionUID = 1L;
TextField temperature1,temperature2;
Label lab1,lab2,lab3,lab4;
Button button1;
String text1,text2;
// “按钮”方法
public void init() {
lab1 = new Label("摄氏温度");
lab2 = new Label("华氏温度");
lab3 = new Label("°C");
lab4 = new Label("°F");
temperature1 = new TextField(10);
temperature2 = new TextField(10);
// 按钮,加上监听器
button1 = new Button("转换");
button1.addActionListener(this);
button1.setActionCommand("a");
// 摄氏温度
add(lab1);
add(temperature1);
add(lab3);
// 华氏温度
add(lab2);
add(temperature2);
add(lab4);
// 转换按钮
add(button1, BorderLayout.PAGE_END);
// 给两个输入框加上监听器
temperature1.addActionListener(this);
temperature2.addActionListener(this);
}
@Override
// “转换”方法
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getActionCommand().equals("a")) {
// 判断摄氏温度是否为空,或者摄氏温度是否有被修改;若满足以上条件其中之一,做华氏度转摄氏度转换
// 情况一:如果摄氏温度和华氏温度都为空,不进行任何操作;若是不满足以皆空,才会进行系列操作,因此可以用非运算符简化程序
if(!(temperature1.getText().equals("") && temperature2.getText().equals(""))) {
// 情况二:华氏温度为空或未被修改,且摄氏温度已被修改,执行摄氏度转换华氏度的操作
if(temperature2.getText().equals("") || temperature2.getText().equals(text2)) {
String celsius = temperature1.getText();
Double celsius1 = Double.valueOf(celsius).doubleValue();
Double fahrenheit2 = 1.8*celsius1 + 32;
float fahrenheit3 = (float)(Math.round(fahrenheit2 * 100))/100;
temperature2.setText(fahrenheit3+"");
text1 =temperature1.getText();
text2 =temperature2.getText();
}
// 情况三:摄氏温度为空或未被修改,且华氏温度已被修改,执行华氏度转换摄氏度的操作
else if(temperature1.getText().equals("") || temperature1.getText().equals(text1)) {
String fahrenheit = temperature2.getText();
Double fahrenheit1 = Double.valueOf(fahrenheit).doubleValue();
Double celsius2 = (fahrenheit1 - 32) / 1.8;
float celsius3 = (float)(Math.round(celsius2 * 100))/100;
temperature1.setText(celsius3+"");
text1 =temperature1.getText();
text2 =temperature2.getText();
}
// 情况四:当摄氏温度和华氏温度同时被修改,默认执行摄氏度转华氏度的操作
else if((!(temperature1.getText().equals(text1))) && (!(temperature2.getText().equals(text2)))) {
String celsius = temperature1.getText();
Double celsius1 = Double.valueOf(celsius).doubleValue();
Double fahrenheit2 = 1.8*celsius1 + 32;
float fahrenheit3 = (float)(Math.round(fahrenheit2 * 100))/100;
temperature2.setText(fahrenheit3+"");
text1 =temperature1.getText();
text2 =temperature2.getText();
}
}
}
}
}
- 利用if语句实现阶梯电费的问题:用电量240度以下(包含240度)每度电0.55元,用电量在240-540度之间,超出240度电的部分按0.70元计算,用电量超过540度电,超出540度电的部分按照0.95元计算。(仅保留小数点后两位)
import javax.swing.JOptionPane;
public class Electricity {
public static void main(String[] args) {
String electricity = JOptionPane.showInputDialog(null,"请输入总用电量(度):","电费输入",JOptionPane.QUESTION_MESSAGE);
int i = Integer.parseInt(electricity);
float charge = culculation(i);
String result = String.format("%.2f", charge);
// 这一个对话框需要点击后再显示弹出
JOptionPane.showMessageDialog(null,"你的电费为:"+result+" 元","电费总金额",JOptionPane.PLAIN_MESSAGE);
}
// 计算电费方法
private static float culculation(int i) {
float j = 0;
if(i <=240) {
j += i * 0.55;
}
else if(i > 240 && i <=540){
j += 240 * 0.55 + (i-240) * 0.7;
}
else if(i > 540) {
j += 240 * 0.55 + 300 * 0.7 + (i - 540) * 0.95;
}
return j;
}
}
【实验心得】
花了很长时间终于实现了效果,结果还是很满意的。在不断尝试的过程中往往会碰上数不胜数,猝不及防的bug。比如摄氏度华氏度转换的空白报错,必须得要清空摄氏度输入框才能进行华氏度转摄氏度等等。程序勉强能正常使用是及格线,如何设计并优化逻辑,使其更符合人操作的直觉,更具人性化,报错更少,才越能体现程序的价值和功力。debug真是其乐无穷啊。
此外,善用开发者文档,以及引用他山之石,择其所长避己之短,能更加顺利地完成程序的编写运行,虽然耗时耗力,但真的大有所获。