花径不曾缘客扫 蓬门今始为君开|

java程序设计 - 第二次实验

【实验目的】

继续熟悉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方法来调用它。

【实验后的练习】

  1. 程序中的主类如果不用public修饰,编译能通过吗?
    删除主类的public命名为新文件TestA.java,可以通过编译。

  2. 程序中的主类如果不用public修饰,程序能正确运行吗?
    不可以运行,运行报错!
    运行报错:加载: AppletFont.class不是公共的, 或者没有公共构造器。
    如果一个源文件中含有public修饰的类,那么这个文件名必须与类名一致,如果没有public类,则文件可以随意命名。一个文件中,public的类可以有零个或一个,非public的类可以有零个或多个。普通的Java程序是从一个public类的main函数开始执行的,就像C程序是从main()函数开始执行一样。要求只能有一个public类,是为了给类装载器提供方便。
    一个public类只能定义在以它的类名为文件名的文件(严格区分大小写),每一个源文件都只有一个public类,因为每个编译单元都只能有一个公共接口,用public类来表现。该接口可以按照要求包含众多的支持包访问权限的类。如果有一个以上的public类,编译器就会报错。(另一种可能会报错的情况)
    当程序主类不是public类时,Java虚拟机就根本找不到运行的人口,无法正确运行。

  3. 程序将paint方法误写成Paint,编译能通过么?
    更改paint为Paint命名为新文件TestB.java,可以正常通过编译。

  4. 程序将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);
		}
	}
 */
  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();
				}
			}

		}
		
	}
}
  1. 利用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真是其乐无穷啊。
此外,善用开发者文档,以及引用他山之石,择其所长避己之短,能更加顺利地完成程序的编写运行,虽然耗时耗力,但真的大有所获。

本文作者:MemoryOfXiaoZheng

本文链接:https://www.cnblogs.com/XiaoZhenglld/p/18044426

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   小郑唠唠叨  阅读(79)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 Alice in 冷凍庫 Orangestar,IA
Alice in 冷凍庫 - Orangestar,IA
00:00 / 00:00
An audio error has occurred.

作词 : Orangestar

作曲 : Orangestar

それは時の果てる 劇場世界のプロローグ

アライ A lie? 君は誰? どことなく物憂げに

裸足のままで 張りつく夜に遊ぶように

彷徨う僕は何故か 君を探しているのだ

だぁ だぁ

あの日のいつかまでの 星座のソラは闇のように

閉ざされた小景に 意味もなく吐き捨てる

あぁ 僕は何故 僕をどこまで連れてくの

開けたその先に いつか見た扉

合図で るらったったった

繰り返して 回ったったった

君が居そうな氷漬けの夢

迷走 昏いステップ るらったったった

寂しくて 笑ったったった

踏み出すままに汚せ

今は凍えぬように

言葉よ意味を成せ 冷やかな世界 病みの曜日

消え行くあてもなく 独り舞台に泣き崩れる

あぁ もう嫌だ 全て0からやり直して

回り切ったその先に いつか見た扉

荒んだ夜 眠れないレイニー

自称冷静な世界と side alley – C O O

見据えたナンセンス 必然の解離

僕ら また出逢えるように

あぁ

朝靄を空に裂いた 君のその柔い手が

白銀製の帳を たやすく浚ってゆく

知らぬまま 大人になるほど 懐かしさは残るけど

それも全部かき混ぜて 廻り出す今日は綺麗だ

時間が音をたてながら 崩れてゆく最後を

君は何故か悲しそうに 笑ながら踊る Wonderland

またあの日と 同じようなさ 星空に呑まれては

紡ぎ出した言葉通りの 想い熱を放て