Simple_chat_Operation(Success)

//简单QQ聊天工具 基于之前发布日记基础

package Chat; 

import Q1_Window.Q1_Window;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;

public class Q1 {
public static Socket socket;
public static BufferedReader in;
public static PrintWriter os;
public static Q1_in_Listener in_l;
public static Q1_Window window = new Q1_Window() ;//实例化Q1_Window

public static void main(String args[]) throws UnknownHostException, IOException {
//监听连接
Q1_keylistener1 kl1 = new Q1_keylistener1() ;
window.tf1.addKeyListener(kl1);

}

//监听连接
static class Q1_keylistener1 implements KeyListener {
String IP;
public void keyPressed(KeyEvent e) { //默认是一个char一个char响应的
if ( e.getKeyCode() == 10 ) { //10是回车的code号

IP = window.tf1.getText();
try {
//连接
socket = new Socket(IP,5656);
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
os = new PrintWriter(socket.getOutputStream());
} catch(IOException e1){
System.out.println("连接问题");
}

//监听输入
in_l = new Q1_in_Listener();
in_l.start();

//监听发送数据
Q1_keylistener2 kl2 = new Q1_keylistener2();
window.tf2.addKeyListener(kl2);
} else{
/*...*/
}
}

public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
}

//监听输入
static class Q1_in_Listener extends Thread { //注意:同一个包下面不能用同样的类名 之前Q2用了同样的类名报错(之前分多个类时)
String text;
@SuppressWarnings("unchecked")
public void run() {
while(true) {
try {
text = in.readLine();
} catch (IOException e) {
System.out.println("输入问题");
break;
}

window.l.add(window.l.getSize(), "Q2: " + text);//在此列表的指定位置处插入指定元素。 指定位置 ,元素

}
}

}

//监听数据送出
static class Q1_keylistener2 implements KeyListener {
String text;
@SuppressWarnings("unchecked")
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 10){

text = window.tf2.getText();
//自己窗口显示要送出信息

window.l.add(window.l.getSize(), "Q1: " + text);
os.println(text);
os.flush();
} else {
/*...*/
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}

}
}


package Chat;

import Q2_Window.Q2_Window;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;

public class Q2 {
static ServerSocket server;
static Socket socket;
static BufferedReader in;
static PrintWriter os;
static Q2_in_Listener in_l;
static Q2_Window window = new Q2_Window();//实例化Q2_Window

public static void main(String args[]) throws UnknownHostException, IOException {
//缺陷连接 只能Q1主动来连接 Q2不具有主动连接功能
//改进:每个端都是Client也是Server
server = new ServerSocket(5656);
socket = server.accept();
window.l.add(0, "Q1: 连接成功!现在你们可以对话啦!");

//套接字送出 送进
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
os = new PrintWriter(socket.getOutputStream());

//通知Q1连接成功
os.println("连接成功!现在你们可以对话啦!");
os.flush();

//监听输入
in_l = new Q2_in_Listener();
in_l.start();

//监听数据发送
Q2_keylistener kl1 = new Q2_keylistener();
window.tf2.addKeyListener(kl1);

}

//监听输入
static class Q2_in_Listener extends Thread { //注意:同一个包下面不能用同样的类名 之前Q2用了同样的类名报错
String text;
public void run() {
while(true) {
try {
text = in.readLine();

} catch (IOException e) {
System.out.println("输入问题");
break;
}
window.l.add(window.l.getSize(), "Q1: " + text);
System.out.println("Q1: " + text);
}
}

}

//监听数据发送
static class Q2_keylistener implements KeyListener {
String text;
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == 10){

text = window.tf2.getText();

window.l.add(window.l.getSize(), "Q2: " + text);
os.println(text);
os.flush();
} else {
/*...*/
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}

}
}




package Q1_Window;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import java.awt.Font;
import javax.swing.JTextField;
import javax.swing.JList;
import java.util.Vector;
public class Q1_Window {

public JFrame frame;
public JTextField tf1;
public JTextField tf2;
public JScrollPane sp;
public Vector<String> v;
public JList<String> list;
@SuppressWarnings("rawtypes")
public DefaultListModel l;

public Q1_Window() {
initialize();
}

@SuppressWarnings({ "rawtypes", "unchecked" })
private void initialize() {
frame = new JFrame();

JLabel label1 = new JLabel("IP");
label1.setFont(new Font("微软雅黑", Font.PLAIN, 16));
label1.setBounds(25, 226, 29, 15);
frame.getContentPane().add(label1);

JLabel label2 = new JLabel("Text");
label2.setFont(new Font("微软雅黑", Font.PLAIN, 16));
label2.setBounds(210, 226, 42, 15);
frame.getContentPane().add(label2);

tf1 = new JTextField();
tf1.setBounds(50, 224, 144, 21);
frame.getContentPane().add(tf1);
tf1.setColumns(10);

tf2 = new JTextField();
tf2.setBounds(253, 224, 144, 21);
frame.getContentPane().add(tf2);
tf2.setColumns(10);


//DefaultListModel listModel = new DefaultListModel();
//JList list = new JList(listModel);
//v = new Vector();//实现自动增加对象数组

l = new DefaultListModel();
list = new JList(l);

//list.setFont(new Font("微软雅黑", Font.PLAIN, 12));
list.setBorder(BorderFactory.createTitledBorder("Create from liuzebin"));//有意思的边界线
list.setBounds(10, 10, 414, 198);
sp = new JScrollPane(list); //添加滚动条
sp.setBounds(10, 10, 414, 198);//注意一定要设置大小!!!!

//自动生成滚动条
sp.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sp.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

frame.getContentPane().add(sp);
frame.setTitle("Q1_Chat_Window");
frame.setBounds(100, 100, 450, 300);//前面两个参数是frame在屏幕中的显示位子,后面两个参数是大小
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
frame.setResizable(false); //不允许改变大小
frame.setVisible(true);

}
} package Q2_Window;

import javax.swing.BorderFactory;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import java.awt.Font;
import javax.swing.JTextField;
import javax.swing.JList;
import java.util.Vector;
public class Q2_Window {

public JFrame frame;
public JTextField tf1;
public JTextField tf2;
public JScrollPane sp;
public Vector<String> v;
public JList<String> list;
public DefaultListModel<String> l;

public Q2_Window() {
initialize();
}

@SuppressWarnings({ "rawtypes", "unchecked" })
private void initialize() {
frame = new JFrame();

JLabel label1 = new JLabel("IP");
label1.setFont(new Font("微软雅黑", Font.PLAIN, 16));
label1.setBounds(25, 226, 29, 15);
frame.getContentPane().add(label1);

JLabel label2 = new JLabel("Text");
label2.setFont(new Font("微软雅黑", Font.PLAIN, 16));
label2.setBounds(210, 226, 42, 15);
frame.getContentPane().add(label2);

tf1 = new JTextField();
tf1.setBounds(50, 224, 144, 21);
frame.getContentPane().add(tf1);
tf1.setColumns(10);

tf2 = new JTextField();
tf2.setBounds(253, 224, 144, 21);
frame.getContentPane().add(tf2);
tf2.setColumns(10);

//v = new Vector();//实现自动增加对象数组
l = new DefaultListModel();
list = new JList(l);

//list.setFont(new Font("微软雅黑", Font.PLAIN, 12));
list.setBorder(BorderFactory.createTitledBorder("Create from liuzebin"));
list.setBounds(10, 10, 414, 198);
sp = new JScrollPane(list); //添加滚动条
sp.setBounds(10, 10, 414, 198);

//自动生成滚动条
sp.setHorizontalScrollBarPolicy(
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
sp.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

frame.getContentPane().add(sp);
frame.setTitle("Q2_Chat_Window");
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
frame.setResizable(false); //锁定窗口大小
frame.setVisible(true); //之前自己一个类 ,没有此语句,也可执行 出现界面???到Q2引时无法显示
}

/*界面:

*/

/*笔记:

1、实现全局引用变量:

一个主类(其他类在主类里面):

static变量,只要实例化一次,可以在主类下面其他类引用变量,无需传递参数。

如:static BufferedReader in;

In = new BufferedReader();

In可以在其他类中直接引用

多个类:

方法一:

如果不在一个主类下面,那么需要传递参数来实现全局引用变量

如:class A{

BufferedReader in = new BufferedReader();

B b = new B(in);

}

Class B{

BufferedReader in;

B(BufferedReader in){

This.in = in

}

//下面引用in

}

方法二:

class A{

BufferedReader in = new BufferedReader();

}

Class B{

A a = new A();

//下面引用in

a.in = …

}

2、全局变量问题

如:

class A{

C c = new C();

}

Class B{

C c = new C();

}

Class C {

//…

}

注意,这样在类A、B中实例的c不是同一个,是全局变量。

3、类的问题

如果类是一个一个分开,那么Q1端和Q2端的类是不能重名的

4、键盘监听器问题

详见日记java keylistener,主要注意如果没有加if语句,默认是一个char输入一个char响应。就不能是每句话的响应了。

要掌握e.getKeyCode(); e.getKeyChar();使用方法

5、list的显示问题

之前用的是

Class Window(){

//主函数 界面省略

Public Vector v = newVector();

Jlist list = new Jlist(v);

v.add(“啦啦啦”);

}

这样就实现添加了。

当没有主函数的只是界面类的时候,在另一个类中实例化这个类,调用v.add(“啦啦啦”);不能实现添加问题。

如:

Class Q1{

Window window = new Window();

window.v.add(“啦啦啦”);

}

理论可以,事实证明失败,主要原因是:list无法动态更新,和tf.setText(“啦啦啦”);有很大差距。

public DefaultListModel l;使用,实现动态更新;

l = new DefaultListModel();

list = new JList(l);

添加:

window.l.add(window.l.getSize(), "Q2: " + text);

6、滚动条实现

JList list = new List();

JScrolPane sp = new JScrolPane(list);

sp.setBound(…);//一定一定要设置大小 和list一样大 不然无法显示

具体情况以及,下拉选项参考使用JAVA SWING 实现列表以及列表的滚动条

*/ /*改进:

1.每个端各自都是Client和Server

2.滚动条实现自动下拉

3.每次输入Text后回车输出清除tf2中的内容 */

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值