201871010115 十二周作业
项目 |
内容 |
这个作业属于哪个课程 |
https://www.cnblogs.com/nwnu-daizh/ |
这个作业的要求在哪里 |
https://www.cnblogs.com/nwnu-daizh/p/11867214.html |
作业学习目标 |
(1) 掌握Vetor、Stack、Hashtable三个类的用途及常用API; (2) 掌握ArrayList、LinkList两个类的用途及常用API; (3) 了解java集合框架体系组成; (4) 掌握Java GUI中框架创建及属性设置中常用类的API; (5) 了解Java GUI中2D图形绘制常用类的API; |
随笔博文正文内容包括:
第一部分:总结第九章、第十章理论知识(40分)
第九章 集合
9.1.1将集合的接口与实现分离
1.集合框架实现了对基本数据结构的封装。集合是一种包含多个元素,并提供对所包含元素,操作方法的类,其包含的元素可以由同一类型的,对象组成,也可以由不同类型的对象组成。
2.集合类的使用:
Java的集合类包含在java.util包中。import java.util.*;
3.队列(queue)接口:“先进先出”。
4.队列通常有两种实现方式:
- 使用循环数组;循环数组比链表更高效。循环数组是一个有界集合,即容量有限。如果程序 中要收集的对象数量没有上限,就最好使用链表来实现。
- 使用链表
9.1.2 Collection接口
iterator方法用于返回一个实现了Iterator接口的对象。可以使用这个迭代器对象一次访问结合中的元素。
9.1.3迭代器
1. Iterator 通过反复调用next方法,可以逐个访问集合中的每个元素。 调用next之前调用hasNext。
2. 当调用next时,迭代器就越过下个元素,并返回刚刚越过的那个元素的引用。
3.remove方法将会删除上次调用next方法时返回的元素。
Iterator< String> it = c.iterator(); it.next();//skip over the first slement it.remove();//now remove it 注意:remove之前没有调用next是不合法的。
4.编译器简单地将"for each"循环翻译为带有迭代器的循环。"for each"循环可以与任何实现了Iterable接口的对象一起工作,这个接口只包含了一个抽象方法。
public interface Iterable< E>{ Iterable< E> iterator(); }
Collection接口扩展了Iterable接口。因此,对于标准库中的任何集合都可以使用"for each"循环。
9.1.4泛型实用方法
1 . java.util.Collection< E> retainAll(Collection<?> other)
从这个集合中删除所有与other集合中不同的元素。如果由于这个调用改变了集合,则返回true。
< T> toArray(T [] arrayToFill)
返回这个集合的对象数组。如果arrayToFill足够大,就将集合中的元素填入这个数组中,剩余空间填null;
2 . retain 英[rɪˈteɪn] 美[rɪˈteɪn]
v. 保持; 持有; 保留; 继续拥有; 继续容纳; 聘请(律师等);否则,分配一个新数组,其成员类型与arrayToFill的成员类型相同,其长度等于集合的大小,并填充集合元素。
9.1.5集合框架中的接口
1.集合框架两个基本接口:Collection和Map。
4.Set接口等同于Collection接口,不过其方法行为更加有更严谨的定义。集(Set)的add方法不允许增加重复的元素。要适当的定义集的equals方法:只要两个集合包含同样的元素就认为是相等的,而不要求这些元素有相同的顺序。hashCode方法的定义要保证包含相同元素的两个集会得到相同的散列码。
Map接口映射唯一关键字到值。关键字(key)是以后用于检索值的对象。给定一个关键字和一个值,可以存储这个值到一个Map对象中。当这个值被存储以后,就可以使用它的关键字来检索它Map循环使用两个基本操作:get( )和put()。使用put( )方法可以将一个指定了”关键字和值”的值加入映射。为了得到值,可以通过将关键字作为参数来调用get()方法。调用返回该值。
9.2.1链表
数组和数组列表都有一个重大缺陷:从数组中间删除一个元素要付出很大代价,其原因是数组中处于被删除元素之后的所有元素都要向数组的前端移动。在数组的中间插入一个元素也是如此。
数组再连续的存储位置上存放对象引用,但链表却将每个对象存放在独立的结点总。每个节点还存放着序列中下一个结点的引用。
在Java程序设计语言中,所有链表实际上都是双向链接的(double linked)–即每个结点还存放着指向前驱结点的引用。
链表是一个有序集合,每个对象的位置十分重要。LinkedList.add方法将对象添加到链表的尾部。
只有对自然有序的集合使用迭代器添加元素才有实际意义。
如果迭代器发现它的集合被另外一个迭代器修改了,或者是被该集合自身的方法修改了,就会抛出一个异常。
链表不支持快速地随机访问。如果要查看链表中第n个元素,就必须从头开始,越过n-1个元素。LinkedList对象根本不做任何缓存位置信息的操作;
9.2.3散列集(hash set)
散列表为每个对象计算一个整数,称为散列码(hash code)。散列码是由对象的实例域产生的一个整数。
在Java中,散列表用链表数组实现。每个列表被称为桶(bucket)。要想查找列表中对象的位置,就首先计算它的散列码,然后与桶的总数取余,所得到的结果就是保存这个元素的桶的索引。
当桶被占满的时候,这种现象称为散列冲突(hash collision)。这时,需要用新对象与桶中的所有对象进行比较,查看这个对象是否已经存在。
9.2.4树集
TreeSet(红黑树)类与散列集十分类似,不过它比散列集有所改进。树集是一个有序集合。每次将一个元素添加到树中时,都被放置在正确的排序位置上。因此,迭代器总是以排好序的顺序访问每个元素。
从Java SE 6起,TreeSet类实现了NavigableSet接口。这个接口增加了几个便于定位元素以及反向遍历的方法。
java.util.NavigableSet< E>
E higer(E value)
E lower(E value)
返回大于value的最小元素或小于value的最大元素,没有则返回null。
ceiling(E value)
floor(E value)
返回大于等于value的最小元素或小于等于value的最大元素,没有则返回null。
E pollFirst()
E pollLast
删除并返回集合中的最大或最小元素,集合为空时返回null。
Iterator< E> descendingIterator()
返回一个按照递减顺序遍历集中元素的迭代器。
9.2.5队列与双端队列
队列可以在头尾部插入元素,有两个端头的队列,即双端队列,不支持在队列中间添加元素。在Java SE6中引入了Deque接口,并由ArrayDeque和LinkedList类实现。
java.util.Queue< E>
boolean add(E elment);//报错
boolean offer(E e);//false
E remove()//删除并返回头部元素,如果空,则报错
E poll()//如果空,则为null;
E element()//返回头部,如空,报错
E peek()//返回null
9.2.6 优先级队列
优先级队列(priority queue)中的元素可以按照任意的顺序插人,却总是按照排序的顺序进行检索。也就是说,无论何时调用remove方法,总会获得当前优先级队列中最小的元素。然而,优先级队列并没有对所有的元素进行排序。如果用迭代的方式处理这些元素,并不需要对它们进行排序。优先级队列使用了-一个优雅且高效的数据结构,称为堆(heap)。 堆是一个可以自我调整的二叉树,对树执行添加(add)和删除( remore2) 操作,可以让最小的元素移动到根,而不必花费时间对元素进行排序。
与est样,一个优先级队列既可以保存实现了Copamla接口的类对象也可以保存在构造器中提供的Comparator对象。
使用优先级 队列的典型示例是任务调度。每一个任务有一个优先级,任务以随机顺序添级最高的任务从队列中删除(由于习惯上加到队列中。每当启动一个新的任务时,都将优先级最高的任务从从队列中删除(由于习惯上将1设为“最高”优先级,所以会将最小的元素删除)。
并不是按照元素的排列顺序访问的。将最程序清单9-5显示了一个正在运行的优先级而删除却总是删掉剩余元素中优先级数级队列。与Tes中的选代不同。这里的选代数最小的那个元素。
9.5 算法
9.5.1排序与混排
1.Collections类中的sort方法可以对实现了List接口的集合进行排序。
a>如果想按照降序对列表进行排序,可以使用一种非常方便的静态方法Collections.reverseOrder()。这个方法将返回一个比较器,比较器返回b.compareTo(a)。
例如:Collections.sort(staff,Collections.reverseOrder());
或者
Collections.sort(staff,Collections.reverseOrder(itemCompartor));
2.Collections类有一个算法shuffle,其功能与排序正好相反,即随机地混排列表中元素的顺序。
a>如果列表没有实现RandomAccess接口,shuffle方法将元素复制到数组中,然后打乱数组元素的顺序,最后在将打乱顺序后的元素复制会列表。
9.5.2二分查找
Collections类的binarySearch方法实现了这个算法。注意,集合必须是排好序的,否则将返回错误的答案。
注:只有采用随机访问,二分查找才有意义。如果必须利用迭代方式一次次地遍历链表的一半元素来找到中间位置的元素,二分查找就完全失去了优势。因此,如果为binarySearch算法提供一个链表,它将自动地变为线性查找。
9.5.6编写自己的代码
a>在编写自己的算法时(实际上,是以集合为参数的任何方法),应该尽可能使用接口,而不是使用具体的实现。
例如:void fillMenu(ArrayList<String> items); 应该写成 void fillMenu(Collection<String> items);
注:那么为什么在Java类库不更多地使用呢,因为Java类库中许多的类库在集合类库之前创建的。
b>通过使用集合视图来优化算法
9.6 遗留的集合
9.6.1Hastable类
Hashtable类与HashMap类的作用一样,实际上,它们拥有相同的接口。与Vector类的方法一样。Hashtable的方法也是同步的。如果对于同步性或遗留代码的兼容性没有任何要求,就应该使用HashMap。
9.6.2枚举
遗留集合使用Enumeration接口对元素序列进行遍历,与Iterator接口类似。
9.6.3属性映射
1.属性映射表(property map)是一个类型非常特殊的映射表结构。它有下面3个特性:
(1)a>键与值都是字符串。
(2)b>表可以保存到一个文件中,也可以从文件中加载。
(3)c>使用一个默认的辅助表。
2.实现属性映射表的Java平台类称为Properties。属性映射表通常用于程序的特殊配置选项。
9.6.4栈
从1.0开始,标准类库中就包含了Stack类,其中包含push方法和pop方法。但是Stack类扩展为Vector类,从理论角度看,Vector类并不太令人满意,它可以让栈使用不属于栈的insert和remove方法。
9.6.5位基
Java平台的BitSet类用于存放一个位序列。如果需要高效地存放位序列就可以使用位集。由于位集将位包装在字节里,所以,使用位集要比使用Boolean对象的ArrayList更加高效。
第十章 图形程序设计
10.1Swing概述
10.1.1 AWT
1.Java的抽象窗口工具箱(Abstract Window Toolkit, AWT)包含在java.awt包中,它提供了许多用来设计GUI的组件类和容器类。
2. AWT库处理用户界面元素的方法:把图形元素的创建和行为委托给本地GUI工具箱进行处理。
3. AWT库使用缺陷。菜单、滚动条和文本域等用户界面元素,在不同的平台上,操作行为上存在一些微妙的差异。
10.1.2swing
1.Swing库具有更丰富且方便的用户界面元素集合。
2. Swing对底层平台的依赖很少,因此与平台相关的bug很少。
3.Swing会带来交叉平台上的统一视觉体验。
4.Swing类库被放在javax.swing包里。
10.1.3swing与AWT的关系
1.大部分AWT组件都有其Swing的等价组件。
2.Swing组件的名字一般是在AWT组件名前面添加一个字母“J”,如:JButton,JFrame,JPanel等。
10.2创建框架
1.组件
构成图形用户界面的元素,拿来即用 用图形表示(能在屏幕上显示,能和用户进行交互)Button、Checkbox、Scrollbar、Choice、Frame通常把由Component类的子类或间接子类创建的对象称为一组件
2.容器 容器是Java中能容纳和排列组件的组件。 常用的容器是框架(Frame,JFrame)
3.添加组件 Container类提供了一个方法add(),用来在容器类组件对象中添加其他组件。容器本身也是一个组件,可以把一个容器添加到另一个容器里,
4.框架(Frame) 在Java中,常采用框架(Frame)创建初始界面,即GUI的顶层窗口
5.在组件中显示信息
(1)Jframe的结构,它由根面板、层级面板、玻璃面板和 内容面板 (content pane)四层面板构成。Swing程序员最关心的是内容面板,也称为内容窗格。
(2)在AWT中可调用add()方法把组件直接添加到AWT Frame中,在Swing中组件则添加到内容窗格里。
改变框架:
1、Component类:setVisible(boolean bool)设置窗口是否显示;set||getSize(int w,int h||Dimension d)设置/获取大小;
set||getLocation(int x,int y)设置获取位置,setBounds(int x,int y,int w,int h)设置位置和大小。
2、windows类:toBack()将窗口移动到桌面窗口栈的后面 ;toFront()将窗口移动到桌面的前面;setLocationByPlatfrom(boolean bool)由平台选择一个合适的位置显示窗口。
3、Frame类: isResizable(boolean bool)是否可以让用户改变大小;setTitle(String str)设置标题;setIconImage(Image img)设置框架的图标。
setUndecorate(boolean bool)框架显示中的标题栏以及关闭按钮这些是否显示;setExtendedState(int state)设置窗口的状态,如Frame.ICONIFIED可以让窗口最小化。
4、Toolkit类:getDefaultToolkit()返回一个默认的工具箱;Dimension getScreen()返回用户屏幕的尺寸; Image getImage(String filename)加载得到一个指定的图像对象。
10.3框架定位
1.框架定位与框架属性
定位:常用Component类的setLocation和setBounds方法
常用属性 Title:框架标题 IconImage:框架图标
2.定框架大小
通过调用Toolkit类的方法来得到屏幕尺寸信息。
Toolkit kit = Toolkit.getDefaultToolkit(); //生成Toolkit对象
Dimension screenSize = kit.getScreenSize();//返回Dimension对象的屏幕大小
int screenWidth = screenSize.width;//获得Dimension对象屏幕的宽度
int screenHeight=screenSize.height; ;//获得Dimension对象屏幕的高度
10.4在组件中显示信息
1.Jframe的结构:有根面板、层级面板、玻璃面板和内容面板(content pane)四层面板。
Swing程序员关心的是内容面板(内容窗格)。
在AWT中可调用add()方法把组件直接添加到AWT
Frame中,在Swing中组件则添加到内容窗格里。
代码如下:
Container contentPane = getContentPane();
Component c=…;
contentPane.add(c);
2.用户也可以自行创建一个组件类,此时需要重载
paintComponent()。
用户的自建组件也可添加到内容窗格里。
paintComponent(Graphics g)定义在JComponent类中,该方法在窗口需要重新绘图时(如扩大窗口或极小化窗口),被系统自动调用.paintComponent()方法被调用时,系统就自动产生一个Graphics类型的参数,传递给paintComponent方法中的参数g。
10.5处理2D图形
Point2D类:用于描述一个点的抽象类,包含了2个内部静态类(也是其子类):Double,Float分别用给定的双精度浮点数和浮点数位置去构造一个点。point类继承point2D类,并
且是用整型数去构造一个点。
(1)2D库
2D库提供了一个非常强大的图形操作库集。2D库的类是Graphics类的子类,2D类对象通常可
用Graphics对象转换而来。例:
public void paintComponent(Graphics g)
(
graphics2D g2=(graphics 2D)g;
(2)2D图形类使用浮点数坐标系。存在的问题:
Retangle2D r=······;
float f=r.getWidth();//Error
getWidth()返回double值, 应进行转换:
float f=(float)r.getWidth();
10.6使用颜色
每次绘制前都可以用Graphics2D的对象去调用setPaint,指定一种颜色去绘制图形,在后面的draw绘制图形时都是用指定的颜色,也可以用fill去用这种颜色填充图形。Color类里面有常量表示一些常用的颜色,也可以new Color(int r,int p,int g)构造一个颜色,SystemColor里面也有很多表示系统颜色的常量。
Graphics2D类的setPaint方法(Graphics类为setColor方法)用来设置颜色。
例:g2.setPaint(Color.RED); g2.drawString(“Set Color”,100,100);
(1)Color类中定义的13种标准颜色
BLACK、BLUE、CYAN、DARK_GRAY、GRAY、 GREEN、LIGHT_GRAY、MAGENTA、ORANGE、PINK、RED、WHITE、YELLOW
(2)复合色
通过指定红绿蓝三色比例,用Color类对象来复合成一种新的颜色。
Color构造器如下:
Color(int redness,int greenness,int blueness) 其中参数取值为0--255 例: g.setPaint(new Color(0,128,128));
10.7文本使用特殊字体
(1)AWT的五种逻辑字体名SanaSerif Serif Monospaced Dialog DialogInput 这些逻辑字体在不同语言和操作系统上映射为不同的物理字体。
(2)字体风格
Font.PLAIN Font.BOLD Fond.ITALIC Fond.BOLD + Font.ITALIC
(3)设置字体 Font serif=new Font(“Serif”,Font.BOLD,14);
g2.setFont(serif);
10.8图形显示
可以用ImageIO类里的静态方法read去读取图像,参数可以是File对象也可以是URL对象。
Graphics类:绘制图像用drawImage(Image,int x,int y,ImageObserver observer)参数是:要绘制的对象,左上角的X坐标,左上角的Y坐标,绘制进程中以通告为目的的对象。
第二部分:实验部分
实验1:测试程序1(6分)
示例1代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
package nine; //示例程序1 import java.util.Vector; class Cat { private int catNumber; Cat( int i) { catNumber = i; } void print() { System. out .println( "Cat #" + catNumber); } } public class Cats{ public static void main(String[] args){ Vector<Cat> cats= new Vector<Cat>(); for ( int i=0; i<7; i++) cats.addElement( new Cat(i)); for ( int i=0; i<cats.size(); i++) (cats.elementAt(i)).print(); } } |
运行结果:
Vector类类似长度可变的数组。 Vector类的关键方法:
Vector中只能存放对象。 void addElement(Object obj)
Vector的元素通过下标进行访问。 void add(int index, Object element)
Vector类关键属性: Object elementAt(int index)
- capacity表示集合最多能容纳的元素个数。 一 void insertElementAt(Object obj, int index)
capacitylncrement表示每次增加多少容量。
/ size表示集合当前元素个数。
示例2代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
package nine; //示例程序2 import java.util.*; public class Stacks { static String[] months={ "金" , "银" , "铜" , "铁" }; public static void main(String[] args){ Stack<String> stk = new Stack<String> (); for ( int i=0; i<months.length; i++) stk.push(months[i]); //for循环将i压入栈顶 System. out .println(stk); System. out .println( "element 2=" + stk.elementAt(2)); while (!stk.empty()) System. out .println(stk.pop()); //Stack类方法中pop是移除栈顶对象并作为此函数的值返回该对象 } } |
结果如下
Stack类是Vector的子类。Stack类描述堆栈数据结构,即FILO。
Stack类的关键方法:public void push(Object item) 一 public Object pop() 一 public Object peek() public boolean empty()
示例3代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
package nine; //示例程序3 import java.util.*; class Counter { int i = 1; public String toString() { return Integer.toString(i); } } public class Statistics { public static void main(String[] args) { Hashtable ht = new Hashtable(); for ( int i = 0; i < 10000; i++) { //通过Math.random()的随机性查看随机生成的10000个数在0-20 之间的分布 Integer r = new Integer(( int ) (Math.random() * 20)); if (ht.containsKey(r)) ((Counter)ht. get (r)).i++; else ht.put(r, new Counter()); } System. out .println(ht); } } |
结果如下:
Hashtable通过键来查找元素。
Hashtable用散列码(hashcode)来确定键。所有对象都有一个散列码,可以通过Object类的hashCode()方法获得。
实验1:测试程序2(6分)
(1)ArrayListDemo代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
package nine; import java.util.*; public class ArrayListDemo { public static void main(String[] argv) { ArrayList al = new ArrayList(); // Add lots of elements to the ArrayList... 向ArrayList中添加元素 al.add( new Integer(11)); al.add( new Integer(12)); al.add( new Integer(13)); al.add( new String( "hello" )); // First print them out using a for loop. 使用for循环进行打印 System. out .println( "Retrieving by index:" ); for ( int i = 0; i < al.size(); i++) { System. out .println( "Element " + i + " = " + al. get (i)); } } } |
结果如下:
(2)LinkedListDemo代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
package nine; import java.util.*; public class LinkedListDemo { public static void main(String[] argv) { LinkedList l = new LinkedList(); l.add( new Object()); l.add( "Hello" ); l.add( "zhangsan" ); //添加元素 ListIterator li = l.listIterator(0); while (li.hasNext()) System. out .println(li.next()); if (l.indexOf( "Hello" ) < 0) System.err.println( "Lookup does not work" ); else System.err.println( "Lookup works" ); } } |
结果如下:
实验1:测试程序3(6分)
9-1代码如下
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
package linkedList; import java.util.*; /** * This program demonstrates operations on linked lists. * @version 1.12 2018-04-10 * @author Cay Horstmann */ public class LinkedListTest { public static void main(String[] args) { var a = new LinkedList<String>(); a.add( "Amy" ); a.add( "Carl" ); a.add( "Erica" ); var b = new LinkedList<String>(); b.add( "Bob" ); b.add( "Doug" ); b.add( "Frances" ); b.add( "Gloria" ); //在a和b中添加元素 // merge the words from b into a 将b和a进行合并 ListIterator<String> aIter = a.listIterator(); Iterator<String> bIter = b.iterator(); while (bIter.hasNext()) { if (aIter.hasNext()) aIter.next(); aIter.add(bIter.next()); } System. out .println(a); // remove every second word from b 删除b中的每两个单词 bIter = b.iterator(); while (bIter.hasNext()) { bIter.next(); // skip one element 跳过一个元素 if (bIter.hasNext()) { bIter.next(); // skip next element 跳过下一个元素 bIter.remove(); // remove that element 删除该元素 } } System. out .println(b); // bulk operation: remove all words in b from a //批量操作:从a中删除b中的所有单词 a.removeAll(b); System. out .println(a); } } |
结果如下:
ArrayList:可以将其看作是能够自动增长容量的数组。利用ArrayList的toArray()返回一个数组。Arrays.asList()返回一个列表。
LinkedList是采用双向循环链表实现的。利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-endedqueue)。
LinkedList的底层数据采用双向链表(double-linked list)类内除了数据本身外,还有两个引用,分别指向前一个元素和后一个元素。
如果经常在List中进行插入和删除操作,应该使用LinkedList,否则,使用ArrayList将更加快速。
实验2:测试程序1(6分)
示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
|
package ten; import javax.swing.*; public class SimpleFrameTest { public static void main(String[] args) { JFrame frame = new JFrame(); frame.setBounds(0, 0,300, 200); // 设置组建的位置 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible( true ); //显示框架 } } |
运行结果:
10-1代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
package simpleFrame; import java.awt.*; import javax.swing.*; /** * @version 1.34 2018-04-10 * @author Cay Horstmann */ public class SimpleFrameTest { public static void main(String[] args) { EventQueue.invokeLater(() -> //事件分配线程中 { var frame = new SimpleFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //定义一个用户关闭框架时的响应动作 frame.setVisible( true ); //为了显示框架,main方法需要调用框架的setVisible方法 }); } } class SimpleFrame extends JFrame { private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; public SimpleFrame() { setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); } } |
运行结果
JFrame.setVisible(true)方法可以让框架可见,JFrame.show()可以让框架可见并且置于其他窗口的前面。JFrame.setDefaultCloseOperation(int i)可以定义关闭这个框架时候的响应动作,让程序退出的常量是JFrame.EXIT_ON_CLOSE。
在操作系统中,一个独立的正在运行的程序称为进程,通常一个程序又被分为称作任务的小块,任务又可以进一步分为称作线程的更小的块。如果一个程序多于一个线程同时执行,就可以称为多线程并行。一个线程被定义为一个单一的连续控制流,线程也可以成为执行环境或者轻量级程序。当一个程序发起之后,会首先生成一个缺省的线程,这个线程被称作主线程,就是由main方法引导进入的线程,main方法调用的方法结构会在这个主线程中顺序执行。
GUI创建:
- java.awt:Abstract Window ToolKit (抽象窗口工具包),需要调用本地系统方法实现功能。属重量级控件。
- javax.swing:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由Java实现。增强了移植性,属轻量级控件。
实验2:测试程序2(6分)
10-2代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
package sizedFrame; import java.awt.*; import javax.swing.*; /** * @version 1.35 2018-04-10 * @author Cay Horstmann */ public class SizedFrameTest { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new SizedFrame(); frame.setTitle( "SizedFrame" ); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //定义一个用户关闭框架时的响应动作 frame.setVisible( true ); }); } } class SizedFrame extends JFrame { public SizedFrame() { // get screen dimensions 获取屏幕的尺寸 Toolkit kit = Toolkit.getDefaultToolkit(); Dimension screenSize = kit.getScreenSize(); int screenHeight = screenSize.height; int screenWidth = screenSize.width; // set frame width, height and let platform pick screen location //设置画面宽度,高度,让平台选择画面位置 setSize(screenWidth / 2, screenHeight / 2); setLocationByPlatform( true ); // set frame icon 设置框架图标 Image img = new ImageIcon( "icon.gif" ).getImage(); setIconImage(img); } } |
运行结果:
框架:没有包含在其他窗口中的窗口被称为框架(frame),在AWT中有一个Frame类,是用来描述框架的,这个类在Swing版本中是JFrame(绝大数的Swing组件都有J开头),它
是极少数几个不绘制在画布上的Swing组件之一,它的修饰部件(如按钮,标题栏,图标等)由用户的窗口系统绘制,而不是由Swing绘制,Swing用来绘制框架里的内容。
框架定位与框架属性
定位:常用Component类的setLocation和setBounds方法 常用属性 Title:框架标题 IconImage:框架图标
实验2:测试程序3(6分)
10-3代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
package notHelloWorld; import javax.swing.*; import java.awt.*; /** * @version 1.34 2018-04-10 * @author Cay Horstmann */ public class NotHelloWorld { public static void main(String[] args) { EventQueue.invokeLater(() -> { var frame = new NotHelloWorldFrame(); frame.setTitle( "NotHelloWorld" ); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //定义一个用户关闭框架时的响应动作 frame.setVisible( true ); }); } } /** * A frame that contains a message panel.包含信息面板的框架 */ class NotHelloWorldFrame extends JFrame { public NotHelloWorldFrame() { add( new NotHelloWorldComponent()); pack(); } } /** * A component that displays a message.显示消息的组件 */ class NotHelloWorldComponent extends JComponent //创建一个能够进行绘制的组件 { public static final int MESSAGE_X = 75; //字符串中的第一个字符位于从左至右75像素 public static final int MESSAGE_Y = 100; //第一个字符位于从上到下100个像素 private static final int DEFAULT_WIDTH = 300; private static final int DEFAULT_HEIGHT = 200; public void paintComponent(Graphics g) { g.drawString( "Not a Hello, World program" , MESSAGE_X, MESSAGE_Y); } //调用Graphics类中的drawString方法显示文本 public Dimension getPreferredSize() //覆盖getPreferredSize方法,返回一个有首选宽度和高度的Dimension类对象 { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); } } |
运行结果:
添加组件 Container类提供了一个方法add(),用来在容器类组件对象中添加其他组件。容器本身也是一个组件,可以把一个容器添加到另一个容器里
用户自行创建一个组件类,此时需要重载 paintComponent()。
用户的自建组件也可添加到内容窗格里。
paintComponent(Graphics g)定义在JComponent类中,该方法在窗口需要重新绘图时(如扩大窗口或极小化窗口),被系统自动调用.paintComponent()方法被调用时,系统就自动产生一个Graphics类型的参数,传递给paintComponent方法中的参数g。
实验总结:(19分)
此课程在本学期学习中,前期问题教多,作为计算机专业学生,前提课程Java程序设计必不可少,没有良好的编程能力作为基础,此课程进行中,困难重重。但是在后期,不管我们每个人学习情况如何,我们基本对这些问题解决掉了,取长补短,达到了平衡状态。实践是解决任何理论问题的最好方法,理论必不可少,加强实践能力,理论才能融会贯通。