用Java写一个带界面的聊天程序

Java编程实践

用Java写一个带界面的网络聊天程序

基本实现思路: 首先得用Java Swing 编程写一个聊天界面,该界面需要包含以下元素

  1. 带滚轮的文本区域(显示聊天记录)
  2. 待输入的文本区域(输入聊天内容)
  3. 发送按钮

聊天界面主要的就这三大组件

实现步骤,用一个JScrollPane中间层容器来装一个文本框原子组件,该文本框设置为不可编辑,还要定义一个JPanel中间容器来装两个原子组件ButtonJTextField,就是我们的输入文本框和发送按钮,然后再给ButtonJTextField注册一个监听器,然后实现对应的响应函数,这里发生的是ActionListener,所以要实现的响应函数是actionPerformed

super(ID);
myID = ID;
this.port = port;
ta = new JTextArea();
ta.setEditable(false);
sp = new JScrollPane(ta);
this.setSize(330,400);
this.setResizable(false);
try
{
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
}
catch(Exception e)
{
    System.out.println("UI error");
}
this.getContentPane().add(sp,"Center");
p = new JPanel();
this.getContentPane().add(p,"South");
send = new JButton("发送");
tf = new JTextField(20);
tf.requestFocus();
p.add(tf);
p.add(send);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.setVisible(true);
send.addActionListener(this);
tf.addActionListener(this);

上面的代码就是实现图形界面的完整代码,看不懂的可以去看一下Java Swing编程

实现网络聊天的另一个关键步骤就是建立网络连接

网络连接中有客户端和服务器,我们需要分别实现这两个端

客户端只要构建一个socket对象,然后向目标ip地址以及对应端口号发起连接就可以了

try
{
    mySocket=new Socket(IP,port); //目标IP地址和对应的端口号
    os = new PrintWriter(mySocket.getOutputStream()); 
    //获得输出流,以便将信息发送到目标地址
    is = new BufferedReader(new
            InputStreamReader(mySocket.getInputStream()));
    //输入流,将对方发送的信息读取出来
}
catch(Exception e)
{
    System.out.println("Error:in Client Socket"+e);
}

服务器端就要定义一个ServerSocket对象,然后使用该对象的wait方法等待来自客户端的socket连接请求,得到对应的socket对象,后面就是跟客户端基本相同的操作

if(isServer)
{
    try
    {
        server=null;
        try
        {
            server=new ServerSocket(port); 
            //使用端口号port初始化一个ServerSocket对象
        }
        catch(Exception e)
        {
            System.out.println("can not listen to:"+e);
        }
        mySocket=null;
        try
        {
            mySocket=server.accept(); //等待来自客户端的socket连接请求
        }
        catch(Exception e)
        {
            System.out.println("Error:"+e);
        }
        is = new BufferedReader(new
                InputStreamReader(mySocket.getInputStream()));
        os = new PrintWriter(mySocket.getOutputStream());
        //跟客户端一样,用来接收和发送信息
    }
    catch(Exception e)
    {
        System.out.println("Error:in server client socket"+e);
    }
}

现在我们要实现的就是将接收到的信息输出到聊天区域ta中去

while(true)
{
    try
    {
        line = is.readLine(); //获得输入流中的信息
        date = new Date(); //获得日期
        SimpleDateFormat formatter = new
                SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //定义标准格式
        String currentTime = formatter.format(date); //将日期标准格式化
        s+=currentTime+""+remoteID+"说:\n"+line+"\n"; //将所有信息组合在一起
        ta.setText(s); //显示到ta文本框中
    }
    catch(Exception e)
    {
        System.out.println("Error:in receive remote information"+e);
    }
}

现在就是实现网络聊天程序的最后一步,也就是响应函数,当我们点击发送时,就要将我们输入到JTextField中的内容输出到socket对象去

public void actionPerformed(ActionEvent e)
{
	date=new Date(); //获得日期
	SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
	String currentTime = formatter.format(date);
	s+=currentTime+""+myID+"说:\n"+tf.getText()+"\n";
	ta.setText(s); //将我们要发送的信息输出到ta文本框
	os.println(tf.getText()); //将要发送的信息发送出去
	os.flush(); //上面是发送到缓冲区,这一步确保信息被发送出去
	tf.setText(""); //将我们的输入框置为空
	tf.requestFocus();
}

完整代码:

package net;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.text.SimpleDateFormat;
import java.util.Date;

import javax.swing.*;

public class ChatFrame extends JFrame implements ActionListener{

	JTextField tf;
	JTextArea ta;
	JScrollPane sp;
	JButton send;
	JPanel p;
	int port;
	String s="";
	String myID;
	Date date;
	ServerSocket server;
	Socket mySocket;
	BufferedReader is;
	PrintWriter os;
	String line;
	
	public ChatFrame(String ID, String remoteID, String IP, int port, boolean isServer)
	{
		super(ID);
		myID = ID;
		this.port = port;
		ta = new JTextArea();
		ta.setEditable(false);
		sp = new JScrollPane(ta);
		this.setSize(330,400);
		this.setResizable(false);
		try
		{
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		}
		catch(Exception e)
		{
			System.out.println("UI error");
		}
		this.getContentPane().add(sp,"Center");
		p = new JPanel();
		this.getContentPane().add(p,"South");
		send = new JButton("发送");
		tf = new JTextField(20);
		tf.requestFocus();
		p.add(tf);
		p.add(send);
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setVisible(true);
		send.addActionListener(this);
		tf.addActionListener(this);
		if(isServer)
		{
			try
			{
				server=null;
				try
				{
					server=new ServerSocket(port);
				}
				catch(Exception e)
				{
					System.out.println("can not listen to:"+e);
				}
				mySocket=null;
				try
				{
					mySocket=server.accept();
				}
				catch(Exception e)
				{
					System.out.println("Error:"+e);
				}
				is = new BufferedReader(new
						InputStreamReader(mySocket.getInputStream()));
				os = new PrintWriter(mySocket.getOutputStream());
			}
			catch(Exception e)
			{
				System.out.println("Error:in server client socket"+e);
			}
		}
		else
		{
			try
			{
				mySocket=new Socket(IP,port);
				os = new PrintWriter(mySocket.getOutputStream());
				is = new BufferedReader(new
						InputStreamReader(mySocket.getInputStream()));
			}
			catch(Exception e)
			{
				System.out.println("Error:in Client Socket"+e);
			}
		}
		while(true)
		{
			try
			{
				line = is.readLine();
				date = new Date();
				SimpleDateFormat formatter = new
						SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				String currentTime = formatter.format(date);
				s+=currentTime+""+remoteID+"说:\n"+line+"\n";
				ta.setText(s);
			}
			catch(Exception e)
			{
				System.out.println("Error:in receive remote information"+e);
			}
		}
	}
	public void actionPerformed(ActionEvent e)
	{
		date=new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String currentTime = formatter.format(date);
		s+=currentTime+""+myID+"说:\n"+tf.getText()+"\n";
		ta.setText(s);
		os.println(tf.getText());
		os.flush();
		tf.setText("");
		tf.requestFocus();
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
	}
}

我们可以定义两个对象来测试一下

客户端

package net;

public class ChatClientFrame {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ChatFrame client = new
                ChatFrame("dog","cat","127.0.0.1",2009,false);
    }

}

服务器端

package net;

public class ChatServerFrame {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ChatFrame cserver = new
                ChatFrame("cat","dog","127.0.0.1",2009,true);
    }
}

补充一点:如果要在两个电脑上运行,需要给出服务器端的ip地址,可以使用ipconfig/all查看电脑的ip地址

效果图

用Java写一个带界面的聊天程序_第1张图片
参考:

清华大学Java教程

你可能感兴趣的:(网络,java,socket,gui)