先引入包:import java.io.*;
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
//给出提示
System.out.println("请输入第一个数");
//从控制台读取一行数据
String a1=br.readLine();
float num1=Float.parseFloat(a1);
//定义类
Class Cat{
int age; 成员变量/属性
String name; 成员变量/属性
}
//创建对象
Cat cat1=new Cat();
//访问对象属性
cat1.age=3;
cat1.name=”小白”;
创建成员方法(成员函数)
public 返回数据类型 方法名(参数列表){
函数主体;
} //返回数据类型是输出;参数列表是输入。void表示没有输出值
Class Person{
int age;
String name;
//人可以说话
public void speak(){
System.out.println(“我会说话,我是一个好人”)
}
//人可以计算两个数的和(有输入也有输出)
public int add(int num1,int num2){
int result=0;
return num1+num2; //把表达式返回的值给主调函数
}
}
//成员方法的调用
Person p1=new Person();
p1.speak(); //输出“我会说话,我是好人”
System.out.println(“两个数的和是:”+p1.add(10,20)) //输出30
特点:方法名和类名相同、没有返回值、在创建一个类的新对象时,系统会自动的调用该类的构造方法完成对新对象的初始化。
class Person{
int age;
String name;
public Person(int age,String name){
System.out.println("我是构造函数");
this.age=age;
this.name=name;
}
}
Person p1=new Person(12,"小白");
-------输出“我是构造函数”
this是属于一个对象,不属于类的。java虚拟机会给每个对象分配this。代表当前对象。
this不能在类定义的外部使用,只能在类定义的方法中使用
类变量是该类的所有对象共享的变量,任何一个该类的对象去访问它时,取到的都是相同的值,同样任何一个该类的对象去修改它时,修改的也是同一个变量。
定义类变量:
访问修饰符(public、protected、默认、private) static 数据类型 变量名
访问类变量:
类名.类变量名(推荐) 对象名.类变量名
static{
函数主体
} //静态区域块只被执行一次
static int i=1; //表示1为全局变量
定义类方法:
访问修饰符(public、protected、默认、private) static 数据类型 方法名(){}
访问类方法:
类名.类方法名(推荐) 对象名.类方法名
static int totalfee;
public static int gettotalfee(){
return totalfee;
} //类变量原则上用类方法去访问或操作
***类方法可以访问类变量;不可以访问非类变量;
非静态方法可以访问类变量;也可以访问非静态变量。
java提供4种访问控制修饰符号控制方法和变量的访问权限。
包的三大作用:
***打包命令一般放在文件开始处,命名用小写字母
***引入一个包的目的就是要使用该包下的类
class Clerk{
String name;
private float salary;
public float getsalary(){
return salary;
} //通过一个成员方法去控制和访问私有的属性
}
语法:class 子类 extends 父类
***父类的private修饰符的属性和方法不能被子类继承
子类最多只能继承一个父类(指直接继承);
java所有的类都是Object的子类
比方说按下 F1 键这个动作,如果当前在 Flash 界面下弹出的就是 AS 3 的帮助文档;如果当前在 Word 下弹出的就是Word 帮助;在 Windows 下弹出的就是 Windows 帮助和支持。同一个事件发生在不同的对象上会产生不同的结果。
Java中多态的实现方式:接口实现,继承父类进行方法重写,同一个类中进行方法重载。
//调用
//非多态演示
Cat cat1=new Cat();
cat1.cry();
cat1.eat();
Dog dog1=new Dog();
dog1.cry();
dog1.eat();
//多态演示
Animal an=new Cat();
an.cry();
an.eat();
an=new Dog();
an.cry();
an.eat();
//多重多态演示
Master master1=new Master();
master1.feed(new Cat(),new Fish());
System.out.println(); //打出一个空行
master1.feed(new Dog(),new Bone());
}
}
class Master{
//给动物喂食物,使用多态,只要写一个方法
public void feed(Animal an,Food f){
an.eat();
f.showname();
}
}
//食物父类
class Food{
String name;
public void showname(){
System.out.println("食物");
}
}
//食物鱼子类
class Fish extends Food{
public void showname(){
System.out.println("鱼");
}
}
//食物骨头子类
class Bone extends Food{
public void showname(){
System.out.println("骨头");
}
}
//动物Animal父类
class Animal{
String name;
int age;
public void cry(){
System.out.println("动物不知道怎么叫");
}
public void eat(){
System.out.println("不知道怎么吃");
}
}
//Dog子类
class Dog extends Animal{
public void cry(){
System.out.println("汪汪叫");
}
public void eat(){
System.out.println("狗爱吃骨头");
}
}
//猫子类
class Cat extends Animal{
public void cry(){
System.out.println("猫猫叫");
}
public void eat(){
System.out.println("猫爱吃鱼");
}
}
10.方法重载(overload)
方法重载是指在一个类中定义多个同名的方法,但要求每个方法具有不同的参数的类型或参数的个数。调用重载方法时,Java编译器能通过检查调用的方法的参数类型和个数选择一个恰当的方法。方法重载通常用于创建完成一组任务相似但参数的类型或参数的个数不同的方法。
***方法的参数类型,个数,顺序至少有一项不同
只是返回类型不一样,不能构成重载;
只是控制访问修饰符号不同,不能构成重载
11.方法覆盖(override)
方法覆盖就是子类有一个方法,和父类的某个方法的方法名、返回类型、参数一样,那么我们就说子类的这个方法覆盖了父类的那个方法。
***子类的方法的返回类型、参数、方法名、要和父类的返回类型、参数、方法名完全一样,否则编译出错。
***子类方法不能缩小父类方法的访问权限。
12.set()和get()
set是设置的意思,而get是获取的意思,顾名思义,这两个方法是对数据进行设置和获取用的。而且,在类中使用set和get方法时,都是在set和get后面跟上一些特定的词来形成特定意思的方法名,比如setage()和getage(),表示设置年龄和获取年龄。
然后我们来了解一下JAVA面向对象编程中的封闭性和安全性。封闭性即对类中的域变量进行封闭操作,即用private来修饰他们,如此一来其他类则不能对该变量访问。这样我们就将这些变量封闭在了类内部,这样就提高了数据的安全性,当我们想要操作这些域变量怎么办呢?我们可以通过两种方法,
第一种:即通过public方式的构造器(或称构造函数),对象一实例化就对该变量赋值。第二种:就是通过上面提到的set和get方法,
这里我举一个特定的例子,我定义一个Person类,该类中有name、age这两个私有域变量,然后我定义setname()、getname()、setage()、getage()这四个方法,通过这四个方法来实现对name和age的操作。这样一来,我不用直接对Person类中的域变量操作,而是通过set和get方法间接地操作这些变量,这样就能提高域变量的安全性,同时又保证了域变量的封装型。
最后说说set和get方法的使用场景,一般来说set和get方法都是对私有域变量进行操作的,所以大多数都是使用在包含特定属性的类实体中。
13.java虚拟机的分区
Java的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)
堆区:
1.存储的全部是对象,每个对象都包含一个与之对应的class的信息。(class的目的是得到操作指令)
2.jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对 象本身.
3.一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。
栈区:
1.每个线程包含一个栈区,栈中只保存基础数据类型的对象和自定义对象的引用(不是对象),对象都存放在堆区中
2.每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
3.栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。
4.由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.
静态区/方法区:
1.方法区又叫静态区,跟堆一样,被所有的线程共享。方法区包含所有的class和static变量。
2.方法区中包含的都是在整个程序中永远唯一的元素,如class,static变量。
3.全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。
14.抽象类、抽象方法(abstract)
***抽象类不能被实例化。(抽象类无法实例化,无法创建对象。现实生活中也有抽象类的类子,比如说人类是一个抽象类,无法创建一个叫人类的对象,人继承人类来创建对象。况且抽象类中的抽象方法只有声明,没有主体(没有{}),如果实例化了,又如何去实现调用呢?)
Animal an=new Animal(); //如果Animal类是抽象类,则是错误的
Animal an=new Cat(); //通过继承创建对象
ep:abstract class Animal{
int age;
String name;
abstract public void cry(); //抽象类中可以没有abstract抽象方法
public void sx(){
System.out.println("实现方法"); //抽象类中可以有实现方法
}
}
***abstract类中的abstract方法是不允许在抽象类中实现的,只能在子类中实现。
***当一个子类继承的父类是抽象类的话,需要程序员把抽象类的抽象方法全部实现。
***一旦类包含了抽象方法,则这个类必须声明为abstract抽象类。
15.接口
接口就是给出没有内容的方法,封装到一起,到某个类要使用的时候,再根据具体情况把这些方法写出来。
建立接口: interface 接口名{方法;}
实现接口: class 类名 implements 接口{
变量;
方法;
}
接口是更加抽象的抽象类,抽象类里可以有方法体,接口里的所有方法都没有方法体。
接口体现了程序设计的多态和高内聚低耦合的设计思想。
访问形式:接口名.变量名
ep:
//调用
//创建Computer
Computer computer=new Computer();
Camera camera=new Camera();
Phone phone=new Phone();
computer.usbUsb(camera);
computer.usbUsb(phone);
}
}
//定义一个Usb接口
interface Usb{
public void start(); //接口开始工作
public void stop(); //接口停止工作
}
//相机类,实现usb接口
class Camera implements Usb{
public void start(){
System.out.println("我是相机,我要开始工作了");
}
public void stop(){
System.out.println("我是相机,我要停止工作了");
}
}
//手机类,实现usb接口
class Phone implements Usb{
public void start(){
System.out.println("我是手机,我要开始工作了");
}
public void stop(){
System.out.println("我是手机,我要停止工作了");
}
}
//计算机
class Computer{
public void usbUsb(Usb usb){ //开始使用Usb接口
usb.start();
usb.stop();
}
}
16.实现接口与继承类
java的继承是单继承,也就是说一个类最多只能有一个父类,继承是层级式的,不太灵活。修改某个类就会打破继承的平衡,而接口就没有这个麻烦,因为它只针对实现接口的类才起作用。
***实现接口可以看做是对继承的一种补充。
实现接口可在不打破继承关系的前提下,对某个类功能扩展,非常灵活。
ep:小猴子继承了父类猴子的跳的方法,通过接口还可以实现鱼游的方法,鸟飞的方法。
//调用
Littermonkey li=new Littermonkey();
li.jump();
li.swimming();
li.fly();
}
}
interface Fish{
public void swimming();
}
interface Bird{
public void fly();
}
class Monkey{
public void jump(){
System.out.println("跳");
}
}
class Littermonkey extends Monkey implements Fish,Bird{
public void swimming(){
System.out.println("游");
}
public void fly(){
System.out.println("飞");
}
}
17.用接口实现多态
package third;
public class maiche {
public static void main(String[] args) {
// TODO Auto-generated method stub
//调用
Carshop cs=new Carshop();
cs.sellcar(new BMW());
cs.sellcar(new Benchi());
System.out.println("总收入是:"+cs.totalmoney());
}
}
//汽车接口
interface Car{
String getname(); //默认的级别 方法
int getprice();
}
//BMW类实现Car接口
class BMW implements Car{
public String getname(){
return "BMW";
}
public int getprice(){
return 300000;
}
}
//benchi类实现Car接口
class Benchi implements Car{
public String getname(){
return "Benchi";
}
public int getprice(){
return 400000;
}
}
//汽车出售店
class Carshop{
int money=0;
//开始卖车
public void sellcar(Car car){
System.out.println("车型:"+car.getname()+"\t"+"价格是:"+car.getprice()); //只是记录卖出的车型和价格,可以不写
money+=car.getprice();
}
public int totalmoney(){
return money; //用一个成员方法返回售车总收入
}
}
***继承是多态得以实现的基础。
在上面例子中,多态就是一种类型(都是Car类型),表现出多种状态,(不同的车有不同的名字和价格)
多态给我们带来的好处是:消除了类之间的耦合关系,使程序更容易扩展。比如在上例中,新增加一种类型汽车的销售。只需要让新定义的类实现Car类并实现它的所有的方法,而无需对原代码做任何修改,Carshop类的sellcar方法就能处理新的车型了。
18.绑定
绑定:指的是一个方法的调用与方法所在的类(方法主体)关联起来。
前期绑定:在程序执行前方法已经被绑定,此时由编译器或其它连接程序实现。例如:C。
后期绑定:在运行时根据具体对象的类型进行绑定。
在Java中,几乎所有的方法都是后期绑定的,在运行时动态绑定方法属于子类还是基类。但是也有特殊,针对static方法和final方法由于不能被继承,因此在编译时就可以确定他们的值,他们是属于前期绑定的。特别说明的一点是,private声明的方法和成员变量不能被子类继承,所有的private方法都被隐式的指定为final的(由此我们也可以知道:将方法声明为final类型的一是为了防止方法被覆盖,二是为了有效的关闭java中的动态绑定)。java中的后期绑定是有JVM来实现的,我们不用去显式的声明它,而C++则不同,必须明确的声明某个方法具备后期绑定。
19.final(最后的,最终的)
final可以修饰变量和方法。
***final修饰的变量又叫常量,一般用XX-XX-XX来命名(带下划线)
final修饰的变量在定义时,必须赋值,并且以后不能再赋值
20.数组
数组定义: 数据类型 数组名[]=new 数据类型[数组大小]
int a []=new int[5] //从a[0]开始
数组的引用: 数组名[2] //数组的第3个数
声明数组: int a[];
创建数组: a=new int[10];
初始化数组: int a[]={2,5,4}
数组大小: 数组名.length
ep://定义数组并赋值
float arr[]={3,5,1,3.4f};
//计算总体重---遍历数组
float all=0;
for(int i=0;i<=3;i++){
all+=arr[i];
}
System.out.println("总体重是:"+all);
}
}
ep:
编写一个程序,可以计算4条狗的平均体重,可以找出体重最大和最小的狗的名字,可以通过输入狗的名字,查找它的体重。
//定义一个可以存放四只狗的对象数组
Dog dogs[]=new Dog[4];
//从控制台输入各个狗的信息
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
for(int i=0;i<4;i++){
dogs[i]=new Dog(); //对象数组使用的时候一定先new一个,分配内存
System.out.println("请输入第"+(i+1)+"狗名");
//从控制台读取狗名
String name=br.readLine();
//将狗名使用set方法传入Dog类中
dogs[i].setName(name);
System.out.println("请输入第"+(i+1)+"狗的体重");
//从控制台读取狗的体重
String s_weigt=br.readLine();
float weigt=Float.parseFloat(s_weigt); //Alt+“/”是帮助输入的提示的快捷键
dogs[i].setWeigt(weigt);
}
//计算总体重
float allweigt=0;
for(int i=0;i<4;i++){
allweigt+=dogs[i].getWeigt();
}
//计算平均体重
float avgweigt=0;
avgweigt=allweigt/dogs.length;
System.out.println("总体重:"+allweigt+"平均体重:"+avgweigt);
//找出体重最大的狗
float maxweigt=dogs[0].getWeigt(); //假设第一只狗的体重最大
int maxindex=0; //定义用于比较体重的下标
for(int i=1;i<4;i++){
if(maxweigt
maxweigt=dogs[i].getWeigt();
maxindex=i;
}
}
//找出体重最小的狗
float minweigt=dogs[0].getWeigt(); //假设第一只狗的体重最小
int minindex=0; //定义用于比较体重的下标
for(int j=1;j<4;j++){
if(maxweigt
maxweigt=dogs[j].getWeigt();
maxindex=j;
}
}
System.out.println("最大体重的狗是第"+(maxindex+1)+"狗"+"\t"+"名字叫"+dogs[maxindex].getName()+"\t"+"体重是"+maxweigt);
System.out.println("最小体重的狗是第"+(minindex+1)+"狗"+"\t"+"名字叫"+dogs[minindex].getName()+"\t"+"体重是"+minweigt);
//输入狗的名字查找狗的体重
System.out.println("请输入狗的名字");
String cname=br.readLine();
int cindex=0;
for(int k=0;k<4;k++){
if(cname.equals(dogs[k].getName())){ //变量名.equals()方法用于字符串比较内容是否一致
System.out.println("你要找的狗名"+dogs[cindex].getName()+"\t"+"体重是"+dogs[cindex].getWeigt());
}
}
}
}
class Dog{
private String name;
private float weigt;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getWeigt() {
return weigt;
}
public void setWeigt(float weigt) {
this.weigt = weigt;
}
}
21.排序(将一群数据,依照指定的顺序进行排列的过程)
简单的说,排序就是把一组记录(元素)按照某个域的值的递增或递减的次序重新排列的过程。
ep:冒泡排序法
int arr[]={1,4,400,8,-7};
int temp=0;
//排序
//外层循环,可以决定一共走几趟
for(int i=0;i
//内层循环,开始逐个比较,如果发现前一个数比后一个数大则交换
for(int j=0;j
if(arr[j]>arr[j+1]){
//换位
temp=arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
}
}
}
//输出最后结果
for(int i=0;i
System.out.println(arr[i]+"\t");
}
}
}
22.查找
23.递归
递归算法是一种直接或者间接的调用自身的算法。其算法的流程走向必须形成封闭。
特点:
24.多维数组
定义: 类型 数组名[][]=new 类型[大小][大小]
25.二进制、位运算
移位运算符:
位运算:
***1个字节=8位bit bit的最高位为符号位
0代表正数,1代表负数
二进制---原码、反码、补码
26.集合框架
集合类的用处: 因为你在处理数据的时候,可能事先不知道数据的大小,需要运行的时候才能知道,所以集合类就可以装在你事先不知道大小的数据。(存放动态变化的数据)
java.util包:实用工具类库。在这个包中,Java提供了一些实用的方法和数据结构。本章介绍Java的实用工具类库java.util包。在这个包中,Java提供了一些实用的方法和数据结构。例如,Java提供日期(Data)类、日历(Calendar)类来产生和获取日期及时间,提供随机数(Random)类产生各种类型的随机数,还提供了堆栈(Stack)、向量(Vector) 、位集合(Bitset)以及哈希表(Hashtable)等类来表示相应的数据结构。
java集合类主要有:
是否是
如何选用集合类?
***在同一个包中的类,可以同包中的其他class文件直接访问或调用
ep:vector
//调用
Vector vv=new Vector();
//创建职员
Aemp emp1=new Aemp("1", "aa", 1000);
Aemp emp2=new Aemp("2", "bb", 2000);
Aemp emp3=new Aemp("3", "cc", 3000);
//将职员放入vv集合类中
vv.add(emp1);
vv.add(emp2);
vv.add(emp3);
//遍历vv中所有的对象(数据)
for(int i=0;i
Aemp emp=(Aemp)vv.get(i);
System.out.println(emp.getName());
}
}
}
//创建职员类
class Aemp{
private String empNo;
private String name;
private float sal;
//构造方法初始化变量
public Aemp(String empNo,String name,float sal){
this.empNo=empNo;
this.name=name;
this.sal=sal;
}
//使用set和get方法进行数据传递
public String getEmpNo() {
return empNo;
}
public void setEmpNo(String empNo) {
this.empNo = empNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public float getSal() {
return sal;
}
public void setSal(float sal) {
this.sal = sal;
}
}
27.泛型
泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类(包括集合类)、接口、和方法的创建中,分别称为泛型类、泛型接口、泛型方法。泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
ep://调用
//创建两个存放数据的集合类al和bl
ArrayList
ArrayList bl=new ArrayList();
//创建一只狗
Dog dog=new Dog();
//放入到集合中
al.add(dog);
//创建一只猫
Cat cat=new Cat();
//放入到集合中
bl.add(cat);
//取出
Dog temp=al.get(0); //引用泛型后即不用强制转换,
Cat temp1=(Cat)bl.get(0); //强制将Object转化为Cat类
}
}
class Cat{
private String color;
private int age;
//传递数据
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Dog{
private String name;
private int age;
//传递数据
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
28.异常处理
2种处理方法:在发生异常的地方直接处理
将异常抛给调用者,让调用者处理。
3种异常:检查性异常。java.lang.Exception
运行期异常。java.lang.RuntimeException
错误。java.lang.Error
方法一:try……….catch
程序运行产生异常时,将从异常发生点中断程序并向外抛出异常信息。
方法二:finally
如果把finally块置try….catch语句后,finally块一般都会得到执行,它相当于一个万能的保险,即使前面的try块发生异常,而又没有对应异常的catch块,finally将马上执行。
以下情形,finally块将不会被执行:
方法三:将异常抛给调用者,让调用者处理异常throws Exception
***对异常的处理,默认规则:向上抛出-----被调用类在运行过程中对遇到的异常一概不作处理,而是直接向上抛出,一直到最上层的调用类。
29.图形开发
GUI(Graphics User Interface)(又叫goo-e)。
IDE(integrated development environment)集成开发环境,用于提供程序开发环境(ep:eclipse、jcreator等)
***JFrame是Frame的子类,是一个顶层容器,可以添加其他swing组件的类。
开发图形要引入的包:java.awt.*;
javax.swing.*;
ep:JButton
package tuxingkaifa;
import java.awt.*;
import javax.swing.*;
public class jbutton extends JFrame{
//把需要的swing组件定义在这里
JButton jb1=null;
public static void main(String[] args) {
// TODO Auto-generated method stub
//调用
jbutton jj=new jbutton(); //****容易忘
}
public jbutton(){
//创建一个button按钮
jb1=new JButton();
//添加JButton组件
this.add(jb1);
//给窗体设置标题
this.setTitle("JButton的应用");
//设置窗体大小,按像素设置大小
this.setSize(500,150);
//设置窗体初始位置
this.setLocation(500,150);
//设置当关闭窗口时,保证JVM也退出
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//显示窗体
this.setVisible(true);
}
}
30.三大常用布局管理器
组件在容器(比如JFrame)中的位置和大小是由布局管理器来决定的。所有的容器都会使用一个布局管理器,通过它来自动进行组件的布局管理。
边界布局:将容器简单的划分为东南西北中5个区域,中间区域最大。
不是五个部分都必须添加,中部组件会自动调节大小
边界布局JFrame和JDialog对话框组件默认布局方法。
步骤:
ep:边界布局
package tuxingkaifa;
import java.awt.*;
import javax.swing.*;
public class bujuguanliqi extends JFrame {
//定义需要的各个组件
JButton jb1,jb2,jb3,jb4,jb5;
public static void main(String[] args) {
// TODO Auto-generated method stub
bujuguanliqi bjgl=new bujuguanliqi(); //***容易忘
}
public bujuguanliqi(){
//创建组件
jb1=new JButton("中部");
jb2=new JButton("北部");
jb3=new JButton("东部");
jb4=new JButton("西部");
jb5=new JButton("南部");
this.add(jb1,BorderLayout.CENTER); //添加到东南西北中
this.add(jb2,BorderLayout.NORTH);
this.add(jb3,BorderLayout.EAST);
this.add(jb4,BorderLayout.WEST);
this.add(jb5,BorderLayout.SOUTH);
//设置窗体属性
this.setTitle("边界布局演示");
this.setSize(300,200);
this.setLocation(200,200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//显示窗体
this.setVisible(true);
}
}
流式布局(FlowLayout):按照组件的添加次序将组件从左到右放置在容器中。当到达容器的边界时,组件将放置到下一行中,也是居中、左对齐、右对齐的方式排列组件。
***当窗体改变大小时,组件的位置可能改变,但是大小不变,
默认组件是居中对齐,可以通过FlowLayout(intalign)函数来指定对齐方式。
……………和上面的一样
……………
this.add(jb1); //添加到东南西北中
this.add(jb2);
this.add(jb3);
this.add(jb4);
this.add(jb5);
//设置窗体属性
this.setLayout(new FlowLayout(FlowLayout.LEFT));
//禁止用户改变窗体大小
this.setResizable(false);
……………
……………
网格布局(GridLayout):它将容器分割成多行多列,组件被填充到各个网格中,添加到容器中的组件首先放置在左上角的网格中,然后从左到右放置其他的组件,当占满该行的所有网格后,接着继续在下一行从左到右放置组件。
***组件的相对位置不随容器的缩放而变化,但大小会变化
所有的组件的大小相同
可以通过GridLayout(int rows,int cols,int hgap,int vgap)来指定网格的行/列,水平间隙/垂直间隙。
ep:网格布局
package cuowu;
import java.awt.*;
import javax.swing.*;
public class cuowu1 extends JFrame{
//定义组件
int size=9;
JButton jbs[]=new JButton[size]; //对象数组
public static void main(String[] args) {
// TODO Auto-generated method stub
cuowu1 cw=new cuowu1();
}
public cuowu1(){
//创建组件
for(int i=0;i<size;i++){
jbs[i]=new JButton(String.valueOf(i)); //对象数组使用之前必须先new
}
//添加组件
for(int i=0;i<size;i++){
this.add(jbs[i]);
}
//设置网格布局管理器
this.setLayout(new GridLayout(3,3,10,10));//行数、列数、垂直间隙、水平间隙
this.setTitle("边界布局演示");
this.setSize(300,200);
this.setLocation(200,200);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//显示窗体
this.setVisible(true);
}
}
31.Swing组件---面板组件
JPanel:非顶层容器,一个界面只可以有一个JFrame窗体组件,但可以有多个JPanel面板组件,而JPanel上也可以使用FlowLayout、BorderLayout、GridLayout等各种布局管理器,这样可以组合使用达到较为复杂的布局效果。
***JPanel是JComponent的子类;
属于容器类组件,可以加入别的组件
默认布局管理器是流式布局(FlowLayout)
package tuxingkaifa;
import java.awt.*;
import javax.swing.*;
public class mianban extends JFrame{
//定义组件
JPanel jp1,jp2;
JButton jb1,jb2,jb3,jb4,jb5,jb6;
public static void main(String[] args) {
// TODO Auto-generated method stub
mianban mn=new mianban();
}
//创建组件
public mianban(){
jp1=new JPanel();
jp2=new JPanel();
jb1=new JButton("西瓜");
jb2=new JButton("苹果");
jb3=new JButton("荔枝");
jb4=new JButton("葡萄");
jb5=new JButton("桔子");
jb6=new JButton("香蕉");
//设置布局管理器-------(JPanel默认流式布局)
//添加JPanel
jp1.add(jb1);
jp1.add(jb2);
jp2.add(jb3);
jp2.add(jb4);
jp2.add(jb5);
//把panel加入JFrame
this.add(jp1,BorderLayout.NORTH);
this.add(jb6,BorderLayout.CENTER);
this.add(jp2,BorderLayout.SOUTH);
this.setSize(300,200);
this.setLocation(200,200);
this.setResizable(false);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//显示窗体
this.setVisible(true);
}
}
32.文本框---JTextField
密码框---JPasswordField
标签----JLable
复选框组件----JCheckBox
单选框组件----JRadioButton
***同一组单选按钮必须先创建ButtonGroup,然后把单选框组件放入到ButtonGroup中
下拉框组件----JComboBox
列表框组件----JList
滚动窗格组件----JScrollPane
***一般来说,列表框组件+滚动窗格组件是组合使用的。目的是让列表框中的选项可以有滚动条支持。
拆分窗格----JSplitPane(容器类组件)
多行文本框----JTextArea
页签组件----JTabbedPane选项卡窗格
菜单组件:
JMenuBar 菜单条组件 树干
JMenu 菜单组件 树枝
JMenuItem 菜单项组件 树叶
二级菜单制作
JMenu里面可以嵌套JMenu
工具条组件----JToolBar
ep:qq登录界面
package cuowu;
import java.awt.*;
import javax.swing.*;
public class yeqianzujian extends JFrame {
//定义组件
//JPanel1组件
//北部区域,上面就放一张图片
JLabel jl1; //标签
//南部区域
JButton jb1,jb2,jb3; //按钮
JPanel jp1;
//中部区域
JTabbedPane jtp1; //选项卡窗格
JPanel jp2,jp3,jp4;
JLabel jl2,jl3,jl4,jl5; //qq号码、qq密码、忘记密码、申请密码保护
JTextField jtf; //号码文本框
JPasswordField jpf; //密码框
JButton jb4; //清除号码
JCheckBox jcb1,jcb2; //复选框
//JPanel2组件
JLabel jl6,jl7; //手机号码、密码
JTextField jtf1; //号码文本框
JPasswordField jpf1; //密码框
//JPanel3组件
JLabel jl8,jl9; //手机号码、密码
JTextField jtf2; //号码文本框
JPasswordField jpf2; //密码框
public static void main(String[] args) {
// TODO Auto-generated method stub
//调用
yeqianzujian yqzj=new yeqianzujian();
}
public yeqianzujian(){
//创建JFrame北部JLabel1组件
jl1=new JLabel(new ImageIcon("images/qqdl.jpg"));
//创建JFrame北部JLabel2组件
jl2=new JLabel("qq号码",JLabel.CENTER);
jl3=new JLabel("qq密码",JLabel.CENTER);
jl4=new JLabel("忘记密码",JLabel.CENTER);
jl4.setFont(new Font("宋体",Font.PLAIN,16)); //设置字体,字号
jl4.setForeground(Color.blue); //设置字体颜色
jl5.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));//鼠标移动到jl5后会变成手指图标
jtf=new JTextField();
jpf=new JPasswordField();
jb4=new JButton("清除号码"); //JButton上可以放图片。new JButton(new ImageIcon"图片路径")
jcb1=new JCheckBox("隐身登录");
jcb2=new JCheckBox("记住密码");
jtp1=new JTabbedPane();
jp2=new JPanel();
jp3=new JPanel();
jp3.setBackground(Color.RED); //给面板设置背景色
jp4=new JPanel();
//创建JFrame中部JTabbedPane选项卡JPanel3组件
jl6=new JLabel("手机号码",JLabel.CENTER);
jl7=new JLabel("号码",JLabel.CENTER);
jtf1=new JTextField(20);
jpf1=new JPasswordField(20);
//创建JFrame中部JTabbledPane选项卡JPanel4组件
jl8=new JLabel("电子邮箱",JLabel.CENTER);
jl9=new JLabel("密码",JLabel.CENTER);
jtf2=new JTextField(20);
jpf2=new JPasswordField(20);
//创建JFrame南部JPanel组件
jp1=new JPanel();
jb1=new JButton("登 录");
jb2=new JButton("取消");
jb3=new JButton("注册向导");
//设置布局管理器
jp2.setLayout(new GridLayout(3,3));
// jp3.setLayout(new GridLayout(2,2));
// jp4.setLayout(new GridLayout(2,2));
//加入组件
//将组件添加到JPanel2中
jp2.add(jl2);
jp2.add(jtf);
jp2.add(jb4);
jp2.add(jl3);
jp2.add(jpf);
jp2.add(jl4);
jp2.add(jcb1);
jp2.add(jcb2);
jp2.add(jl5);
//将组件添加到JPanel3中
jp3.add(jl6);
jp3.add(jtf1);
jp3.add(jl7);
jp3.add(jpf1);
//将组件添加到JPanel4中
jp4.add(jl8);
jp4.add(jtf2);
jp4.add(jl9);
jp4.add(jpf2);
//添加到JPanel1中
jp1.add(jb1);
jp1.add(jb2);
jp1.add(jb3);
//将面板添加到选项卡窗格上
jtp1.add("qq号码",jp2); // 第一个参数代表选项卡名称,第二个参数代表对应的面板
jtp1.add("手机号码",jp3);
jtp1.add("电子邮箱",jp4);
//将JLabel添加到Frame北部
this.add(jl1,BorderLayout.NORTH);
//将JPanel2添加到Frame中部
this.add(jtp1,BorderLayout.NORTH);
//将JPanel1添加到Frame南部
this.add(jp1,BorderLayout.SOUTH);
//窗体设置
this.setTitle("qq登录界面");
this.setIconImage((new ImageIcon("images/qe.jpg")).getImage());
this.setSize(350,300);
this.setLocationRelativeTo(null);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setResizable(false);
}
}
33.java绘图体系
paint(Graphics g)绘制组件的外观
repaint()刷新组件的外观
画直线----drawLine
矩形边框---drawRect
椭圆边框----drawOval
填充矩形----fillRect
填充椭圆--- fillOval
画图片---drawImage
画字符串---drawString
设置画笔的字体---setFont(Font font)
设置画笔的颜色---setColor(Color c)
34.事件处理机制
委派事件模型:指当事件发生时,产生事件的对象(即事件源),会把此“信息”传递给“事件的监听者”处理的一种方式。这里所说的“信息”实际上就是java.awt.event事件类库里某个类所创建的对象。
事件源产生一个时间,可以传送给事件监听者处理。
常用的事件类:
ep:方向键控制小球移动
package cuowu;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
public class shijianjianting extends JFrame {
//设定组件
MyPanels mp=null;
public static void main(String[] args) {
// TODO Auto-generated method stub
//调用
shijianjianting sjjt=new shijianjianting();
}
public shijianjianting(){
//构建组件
mp=new MyPanels();
//监听
this.addKeyListener(mp);
//加入组件
this.add(mp);
//设置窗体
this.setTitle("键盘事件监听");
this.setSize(400,300);
this.setLocationRelativeTo(null);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
//定义自己的面板
class MyPanels extends JPanel implements KeyListener{
int x=10,y=10;
public void paint(Graphics g){
super.paint(g);
g.fillOval(x, y, 10, 10);
}
public void keyPressed(KeyEvent e){
System.out.println("被按下"+((char)e.getKeyCode()));
if(e.getKeyCode()==KeyEvent.VK_DOWN){
System.out.println("向下");
y++;
}
else if(e.getKeyCode()==KeyEvent.VK_UP){
System.out.println("向上");
y--;
}
else if(e.getKeyCode()==KeyEvent.VK_LEFT){
System.out.println("向左");
x--;
}
else if(e.getKeyCode()==KeyEvent.VK_RIGHT){
System.out.println("向右");
x++;
}
this.repaint();
}
public void KeyReleased(KeyEvent e){}
}
事件监听者实际上就是一个类,该类实现了某个事件监听器接口,比如上面的MyPanel就是一个类,该类实现了ActionListener接口,它就可以作为一个事件监听者,对接受到的事件进行处理。
事件监听器接口有多种,不同的事件监听器接口可以监听不同的事件,一个类可以实现一个事件监听接口,也可以实现多个监听接口。
步骤:
35.线程
进程和线程的主要差别在于它们是不同的操作系统资源管理方式。进程有独立的地址空间,一个进程崩溃后,在保护模式下不会对其它进程产生影响,而线程只是一个进程中的不同执行路径。线程有自己的堆栈和局部变量,但线程之间没有单独的地址空间,一个线程死掉就等于整个进程死掉,所以多进程的程序要比多线程的程序健壮,但在进程切换时,耗费资源较大,效率要差一些。但对于一些要求同时进行并且又要共享某些变量的并发操作,只能用线程,不能用进程。
操作系统的设计,因此可以归结为三点:
(1)以多进程形式,允许多个任务同时运行;(进程就好比工厂的车间,它代表CPU所能处理的单个任务)
(2)以多线程形式,允许单个任务分成不同的部分运行;(线程就好比车间里的工人。一个进程可以包括多个线程)(车间的空间是工人们共享的,比如许多房间是每个工人都可以进出的。这象征一个进程的内存空间是共享的,每个线程都可以使用这些共享内存。可是,每间房间的大小不同,有些房间最多只能容纳一个人,比如厕所。里面有人的时候,其他人就不能进去了。这代表一个线程使用某些共享内存时,其他线程必须等它结束,才能使用这一块内存。)
(3)提供协调机制,一方面防止进程之间和线程之间产生冲突,另一方面允许进程之间和线程之间共享资源。
***线程是轻量级的进程
线程没有独立的地址空间(内存空间)
线程是由进程创建的(寄生在进程)
一个进程可以拥有多个线程----多线程编程
线程的状态:新建状态(new)、就绪状态(Runnable)、运行状态(Running)、阻塞状态(Blocked)、死亡状态(Dead)
在java中一个类要当做线程来使用有两种方法:
继承Thread类,并重写run函数
实现Runnable接口,并重写run函数
ep:多线程Runnable使用:
package third1;
public class duoxiancheng {
public static void main(String[] args) {
// TODO Auto-generated method stub
Pig pig=new Pig(10);
Bird bird=new Bird(10);
//建立线程
Thread t1=new Thread(pig);
Thread t2=new Thread(bird);
//启动线程
t1.start();
t2.start();
}
}
//一个线程每隔1秒输出一次helloworld
class Pig implements Runnable{
int n=0;
int times=0;
public Pig(int n){
this.n=n;
}
//重写run函数
public void run(){
while(true){
try {
Thread.sleep(1000); //1000表示休眠1000毫秒
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
times++;
System.out.println("我是一个线程,正在输出"+times+"个helloWord!");
if(times==n){
break;
}
}
}
}
//一个线程通过接收n来执行1+.....n的和
class Bird implements Runnable{ //多线程时应使用implements接口来实现,不要使用extends继承。
int n=0;
int res=0;
int times=0;
public Bird(int n){
this.n=n;
}
//重写run函数
public void run(){
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
res+=(++times);
System.out.println("当前结果是:"+res);
if(times==n){
System.out.println("最后的结果是:"+res);
break;
}
}
}
}
ep:继承Thread来开发线程
package third1;
public class danjicheng {
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建一个Cat对象
Cat cat=new Cat();
//启动线程
cat.start(); //.start()会导致run函数运行
}
}
class Cat extends Thread{
int times=0;
//重写run函数
public void run(){
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
times++;
System.out.println("我是一个线程,正在输出"+times+"个helloWord!");
if(times==10){
break;
}
}
}
}
***a+=(++b)------b=b+1,a=a+b
a+=(b++)-------a=a+b,b=b+1
总结:
Thread类本身就实现了Runnable接口
尽可能使用实现Runnable接口的方式来创建线程
两种方式,他们的一个对象只能启动(即:.start())一次,否则就会有异常抛出。
36.java线程的同步---解决问题
解决问题的关键就是要保证容易出问题的代码的原子性,所谓原子性就是指:当a线程在执行某段代码的时候,别的线程必须等到a线程执行完后,它才能执行这段代码。
只需要在需要同步的代码段,用:
线程并发同步锁----synchronized(Object){你要同步的代码}
ep:3个站点同时卖10张票
package third1;
public class shouqian {
public static void main(String[] args) {
// TODO Auto-generated method stub
Ticketwindows tw=new Ticketwindows();
Thread t1=new Thread(tw);
Thread t2=new Thread(tw);
Thread t3=new Thread(tw);
t1.start();
t2.start();
t3.start();
}
}
class Ticketwindows implements Runnable{
//共有10张票
private int nums=10;
private Dog mydog=new Dog(); //?????
public void run(){
while(true){
//出票速度是1秒出一张
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (mydog) {
if(nums>0){
System.out.println(Thread.currentThread()+"正在售出第"+nums+"张票");
nums--;
}
else{
//售票结束
break;
}
}
}
}
}
class Dog{}
37.文件流
文件在程序中是以流的形式来操作的。
流:数据在数据源(文件)和程序(内存)之间经历的路径
输入流:数据从数据源到内存的路径
输出流:数据从内存到文件的路径
java流分为两种:字节流:可以用于读写二进制文件及任何类型文件byte
字符流:可以读写文本文件,不能操作二进制文件
字节流 字符流
输入 InputStream Reader
输出 OutPutStream Writer
ep:字节流
package third1;
import java.io.*;
public class tupiankaobei {
public static void main(String[] args) {
// TODO Auto-generated method stub
//先将图片读入到内存,再将内存中的图片写入到某个文件,因为二进制文件只能使用字节流来处理
//声明流
//输入流
FileInputStream fis=null;
//输出流
FileOutputStream fos=null;
//新建流
try {
fis=new FileInputStream("E:\\1.jpg");
fos=new FileOutputStream("D:\\1.jpg");
//新建字节数组
byte buf[]=new byte[1024];
int n=0; //记录实际读取到的字节数
//循环读取照片
while((fis.read(buf))!=-1){ //读取的字节数,如果已达到流的末尾,则返回-1
//输出到指定文件
fos.write(buf);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
//一定要关闭打开的文件流
try {
fis.close();
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
ep:字符流(一次读取两个字节)
package third1;
import java.io.*;
public class zifuliu {
public static void main(String[] args) {
// TODO Auto-generated method stub
FileReader fr=null;
FileWriter fw=null;
try {
//建立输入流
fr=new FileReader("E:\\1.txt");
//建立输出流
fw=new FileWriter("D:\\1.txt");
//创建字符数组
char c[]=new char[1024];
//记录实际读取到的字符数
int n=0;
while((n=fr.read(c))!=-1){
//输出Txt文件内容
fw.write(c);
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
fr.close();
fw.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
***字节流直接操作byte;字符流直接操作char(一次读取两个字节);缓冲字符流直接操作string(一个读取一行)
***操作文件肯定会有异常,所以要用try…catch语句块
ep:缓冲字符流
package third1;
import java.io.*;
public class huanchongzifuliu {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
BufferedReader br=null;
BufferedWriter bw=null;
try {
//创建FileReader对象,先用FileReader找到文件,再传给BufferedReader
FileReader fr=new FileReader("E:\\1.txt");
br=new BufferedReader(fr);
//创建FileWrite对象
FileWriter fw=new FileWriter("D:\\1.txt");
bw=new BufferedWriter(fw);
//循环读取
String s=""; //定义字符串s
while((s=br.readLine())!=null){
//输出到磁盘
bw.write(s+"\r\n");
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
try {
br.close();
bw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
ep:记事本(界面+功能)
package third1;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import java.io.*;
import java.util.*;
public class jishiben extends JFrame implements ActionListener{
//定义组件
JTextArea jta=null; //定义一个文本框
JMenuBar jmb=null; //定义一个菜单条
JMenu jm=null; //定义一个菜单
JMenuItem jmi1=null; //定义菜单选项
JMenuItem jmi2=null;
JMenuItem jmi3=null;
public static void main(String[] args) {
// TODO Auto-generated method stub
//定义一个主函数对象
jishiben jsb=new jishiben();
}
public jishiben(){
jta=new JTextArea(); //创建一个文本框组件
jmb=new JMenuBar(); //创建菜单条
jm=new JMenu("文件"); //菜单
jm.setMnemonic('F'); //设置助记符
jmi1=new JMenuItem("打开",new ImageIcon("1.jpg")); //菜单项目
jmi1.setMnemonic('O');
//open打开注册监听
jmi1.addActionListener(this);
jmi1.setActionCommand("open");
jmi2=new JMenuItem("保存");
jm.setMnemonic('S');
//save保存注册监听
jmi2.addActionListener(this);
jmi2.setActionCommand("save");
jmi3=new JMenuItem("退出");
jm.setMnemonic('E');
//exit退出注册监听
jmi3.addActionListener(this);
jmi3.setActionCommand("exit");
//添加
this.add(jta); //把文本框添加到JFrame
this.setJMenuBar(jmb); //把菜单条放进JFrame中
jmb.add(jm);
jm.add(jmi1);
jm.add(jmi2);
jm.add(jmi3);
//JFrame默认布局是border布局,不用设置
//设置布局方式
this.setLocation(300,200);
this.setSize(400,300);
this.setVisible(true);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
//判断哪个菜单被选中
if(e.getActionCommand().equals("open")){
//创建一个文件选择组件
JFileChooser jfc=new JFileChooser();
//设置名字
jfc.setDialogTitle("请选择要打开的文件....");
//设置默认方式打开
jfc.showOpenDialog(null);
jfc.setVisible(true);
//得到用户选择的文件的全(绝对)路径
String filename=jfc.getSelectedFile().getAbsolutePath();
//声明流
FileReader fr=null;
BufferedReader br=null;
try {
//新建流
fr=new FileReader(filename);
br=new BufferedReader(fr);
//从文件中读取信息
String s="";
String allCon="";
while((s=br.readLine())!=null){
allCon+=s+"\r\n";
}
//将信息放置到jta
jta.setText(allCon);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
finally{
try {
fr.close();
br.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
//保存功能
else if(e.getActionCommand().equals("save")){
JFileChooser jfc=new JFileChooser(); //创建一个保存对话框
jfc.setDialogTitle("将文件保存为..."); //设置名字
jfc.showSaveDialog(null); //设置默认方式保存
jfc.setVisible(true);
String file=jfc.getSelectedFile().getAbsolutePath(); //得到用户要保存的全(绝对)路径
//准备写入到指定文件
FileWriter fw=null;
BufferedWriter bw=null;
try {
fw=new FileWriter(file);
bw=new BufferedWriter(fw);
bw.write(this.jta.getText().replaceAll("n", "\r\n")); //将JTextArea中的内容输出到指定的文件中
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
finally{
try {
// fw.close(); //一定不能关闭
bw.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
else if(e.getActionCommand().equals("exit")){
System.exit(0);
}
}
}