GUI
GUI:图形用户界面
用图形的方式,来显示计算机操作的界面,这样更方便,更直观
java为GUI提供的对象都存在java.awt和javaX.swing两个包中
Awt和Swing
1、java.awt:抽象窗口工具包,需要调用本地系统方法实现功能,属于重量级控件(与系统的耦合性强)
2、javaX.swing:在awt基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由java实现,增强了移植性,属于轻量机控件
建立一个简单的窗体
//1,创建一个窗体。Frame
Frame f = new Frame("my frame");
//2, 对窗体进行基本设置。
f.setSize(500, 400);
f.setLocation(400, 200);
//设置布局。
f.setLayout(new FlowLayout());
//给窗体添加组件。
Button but = new Button("my button");
//加入一个文本框组件。
TextField tf = new TextField(40);
//将组件添加到窗体中。
f.add(tf);
f.add(but);
事件监听机制
组成部分:
事件源(组件)
事件(Event)
监听器(Listener)
事件处理(引发事件后处理方式)
练习:
/*
* 需求:想要点击按钮有效果,比如打印一句话。
* 思路:
* 1,确定事件源。按钮。
* 2,确定监听器。按钮添加监听器,按钮对象最清楚。到按钮对象中查找。
* 3,定义处理方式。
*
* 定义的规范:XXXLinstener:XXX监听器。 --对应的XXXEvent事件。
*/
//1,在按钮上添加所需的监听器。
but.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// System.out.println("按钮被触发了....."+e);
// System.exit(0);
/*
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 5; j++) {
System.out.print("*");
}
System.out.println();
}*/
}
});
/*
* 需求:想要实现点击窗体X就可以实现窗体的关闭。
* 思路:
* 1,事件源:窗体。
* 2,监听器。通过窗口对象去查。
* 3,事件处理。
*
* 到底哪些监听接口有适配器类?
* 只要监听接口的中的方法在2个以内,都没有适配器类。适配器的出现只为方便创建监听器对象。
* 但是一般监听接口都有适配器。
*
*/
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.out.println("window closing");
System.exit(0);
}
@Override
public void windowOpened(WindowEvent e) {
System.out.println("孔雀开屏!window open");
}
});
/*
* 演示鼠标监听。
*
* 按钮事件源。
* 鼠标监听器注册到按钮上。
*
*
* 组件.addXXXListener(new XXXAdapter()
* {
* public void methodName(XXXEvent e){}
* }));
*
*/
but.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
/*
* 想要对鼠标双击进行处理。应该找鼠标事件对象。因为事件对象一产生,内部必然封装事件源以及事件相关内容。
* 要查MouseEvent对象。
*/
if(e.getClickCount() == 2){
System.out.println("mouse double click");
}
}
});
/*
* 需求:文本框中只能输入数字。
* 事件源:文本框。
* 文本框注册键盘监听。
* 事件处理
*/
tf.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
//1,如何获取录入的内容。通过键盘事件对象获取。
// char key = e.getKeyChar();
// int code = e.getKeyCode();
// System.out.println(code+"...."+KeyEvent.getKeyText(code));
// int code = e.getKeyCode();
// if(!(code>=KeyEvent.VK_0 && code<=KeyEvent.VK_9)){
// System.out.println("必须是0-9数字");
// e.consume();//直接取消默认处理方式。
// }
if(e.isControlDown() && e.getKeyCode()==KeyEvent.VK_ENTER){
System.out.println("ctrl+enter run");
}
}
});
//3,让窗体显示。
f.setVisible(true);
System.out.println("over");
}
小结:
确定事件源(容器或组件)
通过事件源对象的addXXXListener()方法将侦听器注册到该事件源上。
该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
一般用匿名内部类来表示。
在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。
事件触发后会把事件打包成对象传递给该变量。(其中包括事件源对象。通过getSource()或者,getComponent()获取。
网络编程
网络模型
OSI(开放系统互联参考模型)
TCP/IP参考模型
网络通讯的要素:IP地址、端口号、传输协议
UDP
将数据及源和目的封装成数据包,不需要建立连接,每个数据包大小限制在64K内,因为无连接,是不可靠协议,不需建立连接,速度快。
简记:面向无连接,不可靠,速度快,将数据封装成包传输,最大64K
TCP
建立连接,形成传输数据的通道,在连接中进行大数据传输,通过三次握手完成连接,是可靠协议,必须建立连接,效率稍低
简记:面向连接,安全可靠,效率稍低,通过三次握手确保连接 的建立,
Socket
端口,就是为网络服务提供的一种机制
通信的两端都有Socket
网络通信其实就是Socket间的通信
数据在两个Socket间通过IO流传输
UDP传输
DatagramSocket和DatagramPacket
建立发送端,接收端
建立数据包
调用Socket的发送接收方法
关闭Socket
发送端与接收端是两个独立的运行程序
在发送端,要在数据包对象中明确目的地IP及端口
/*
* 案例一:通过udp实现群聊程序。
* 思路: 这个程序中既有收又有发,需要同时执行,需要使用多线程技术。
* 一个线程负责发,一个线程负责收。需要两个任务。
*/
public static void main(String[] args) throws IOException {
//发送端的socket 接收端的socket
DatagramSocket sendSocket = new DatagramSocket();
DatagramSocket receSocket = new DatagramSocket(10002);
//创建任务对象。
Send send = new Send(sendSocket);
Rece rece = new Rece(receSocket);
//创建线程并开启。
Thread t1 = new Thread(send);
Thread t2 = new Thread(rece);
t1.start();
t2.start();
}
}
// 发送任务
class Send implements Runnable {
private DatagramSocket ds;
public Send(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
try {
BufferedReader bufr = new BufferedReader(new InputStreamReader(
System.in));
String line = null;
while ((line = bufr.readLine()) != null) {
byte[] buf = line.getBytes();// 将数据转成字节数组。
DatagramPacket dp = new DatagramPacket(buf, buf.length,
InetAddress.getByName("192.168.1.223"), 10002);
ds.send(dp);
if ("886".equals(line)) {
break;
}
}
// 4,关闭资源。
ds.close();
} catch (IOException e) {
}
}
}
// 接收任务。
class Rece implements Runnable {
private DatagramSocket ds;
public Rece(DatagramSocket ds) {
super();
this.ds = ds;
}
@Override
public void run() {
while (true) {
try {
byte[] buf = new byte[1024];
DatagramPacket dp = new DatagramPacket(buf, buf.length);
ds.receive(dp);// 阻塞
String ip = dp.getAddress().getHostAddress();
int port = dp.getPort();
String text = new String(dp.getData(), 0, dp.getLength());
System.out.println(ip + ":" + port + ":" + text);
if(text.equals("886")){
System.out.println(ip+"....离开聊天室");
}
} catch (IOException e) {
}
}
}
IP
ip地址对象。InetAddress
获取本地主机地址对象。
InetAddress ip = InetAddress.getLocalHost();
获取其他主机的地址对象。
InetAddress ip = InetAddress.getByName(“www.sina.com.cn”);
TCP传输
=====
需求:通过TCP传输将数据发送给服务器
基本思路
客户端:
1、客户端需要明确服务器的IP地址以及端口,这样才可以去试着建立连接,如果连接失败,会出现异常
2、连接成功,说明客户端与服务端建立了通道,那么通过IO流,就可以进行数据的传输,而Socket对象已经提供了输入流和输出流对象,通过getInputStream();getOutputStream();获取即可
3、与服务端通讯结束后,关闭Socket
服务端:
1、服务端需要明确它要处理的数据时从哪个端口进入的
2、当有客户端访问时,要明确哪个客户端可通过accept()获取已连接的客户端对象,并通过该对象与客户端通过IO流进行数据传输
3、当客户端访问结束,并关闭该客户端
案例二:实现客户端和服务端的收发过程。
public static void main(String[] args) throws UnknownHostException, IOException {
// 创建客户端socket对象。明确服务端地址和端口。
Socket s = new Socket(“192.168.1.223”, 10004);
// 发送数据,通过socket输出流完成。
OutputStream out = s.getOutputStream();
out.write(“服务端,我来了”.getBytes());
// 读取服务端返回的数据,通过socket输入流
InputStream in = s.getInputStream();
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf,0,len);
System.out.println(text);
// 关闭资源。
s.close();
}
}
public static void main(String[] args) throws IOException {
System.out.println(“服务端开启…”);
* 需求:获取客户端的数据并显示在屏幕上。 思路: 1,创建服务端的socket。明确端口,监听一个端口。
* 2,服务端只要获取到连接过来的客户端就可以和指定的客户端通信了。 3,通过获取客户端的读取流对象读取客户端发来的数据。 4,并显示屏幕上。
// 1,创建服务端的socket。明确端口,监听一个端口。
ServerSocket ss = new ServerSocket(10003);
while (true) {
// 2,服务端只要获取到连接过来的客户端就可以和指定的客户端通信了。
Socket s = ss.accept();
String ip = s.getInetAddress().getHostAddress();
System.out.println(ip + ".....connected");
// 3,通过获取客户端的读取流对象读取客户端发来的数据。
InputStream in = s.getInputStream();
// 4,并显示屏幕上。
byte[] buf = new byte[1024];
int len = in.read(buf);
String text = new String(buf, 0, len);
System.out.println(text);
// 5,关闭资源。
s.close();
}
// ss.close();
}
}
TCP传输最容易出现的问题
1、客户端连接上服务端,两端都在等待,没有任何数据传输
2、通过例程分析:
因为read方法或readline方法是阻塞式的
3、解决办法
自定义结束标记
使用shutdowmInput、shutdowmOutput方法
最常见的客户端和服务端
客户端:浏览器
服务端:Tomcat
访问方式:
浏览器中输入 http://192.168.1.2239(IP):8000/自己的应用程序名/具体资源名
URL:
用于解析URL地址
URLConnection:获取URL的连接
HTTP1.0和HTTP1.1的区别
HTTP1.0:一次连接一次请求
HTTP1.1:一次连接多次请求
常见的网络架构
-------
C/S:Client/Server
特点:
1、程序员需要开发客户端和服务端
2、维护较为麻烦
3、将一部分运算转移到客户端来完成,减轻服务器端压力
B/S:browser/Server
特点:
1、程序员只需开发服务端,客户端使用系统已有的浏览器即可
2、维护很简单,只需要维护服务端
3、所有的运算都在服务端
目前常用的的B/S网络架构