java做的swing聊天器,用socket实现的,目前只能支持两个人之间聊天,局域网内或者直接连到internet的两台机器(没用router)。用到了substance.jar第三方皮肤包,请导入类路径。水印图片是skyani.jpeg,在src目录下建立一个image文件夹放进去就行了。这就是个demo,很多不足之处,还请不吝赐教!
package javaQQ;
import javax.swing.*;
import org.jvnet.substance.watermark.SubstanceImageWatermark;
import org.jvnet.substance.SubstanceLookAndFeel;
import org.jvnet.substance.api.SubstanceConstants.ImageWatermarkKind;
import org.jvnet.substance.api.SubstanceSkin;
import org.jvnet.substance.skin.OfficeBlue2007Skin;
import org.jvnet.substance.skin.SubstanceOfficeBlue2007LookAndFeel;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import java.util.concurrent.LinkedBlockingQueue;
public class ChatGUI extends JFrame
{
private static final long serialVersionUID = 1L;
private JTextField newNickName = new JTextField(6);
private JTextField friendAddress = new JTextField(9);
private JTextArea dialog = new JTextArea(15, 30);
private JTextArea input = new JTextArea(5, 40);
private JButton sendButton = new JButton("send");
private JButton changeNickName = new JButton("change");
private JButton requestChat = new JButton("invite");
private String nickName = null;
private LinkedBlockingQueue<String> sendMsgQueue = new LinkedBlockingQueue<String>();
private String inputContent;
private SendChatRequest smsg;
public ChatGUI()
{
super();
Container pane = this.getContentPane();
Font f = new Font(null, Font.PLAIN, 12);
dialog.setFont(f);
dialog.setEditable(false);
input.setFont(f);
friendAddress.setFont(f);
newNickName.setFont(f);
JPanel northPanel = new JPanel();
northPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
northPanel.add(new JLabel("new name: "));
northPanel.add(newNickName);
northPanel.add(changeNickName);
northPanel.add(new JLabel("input his/her IP:"));
northPanel.add(friendAddress);
northPanel.add(requestChat);
pane.add("North", northPanel);
ActionListener cn = new ChangeName();
changeNickName.addActionListener(cn);
ActionListener rc = new RequestChat();
requestChat.addActionListener(rc);
JPanel centerPanel = new JPanel();
centerPanel.setLayout(new GridLayout(1, 1, 10, 10));
JScrollPane jsp = new JScrollPane(dialog);
centerPanel.add(jsp);
pane.add("West", centerPanel);
JPanel southPanel = new JPanel();
JScrollPane inputJSP = new JScrollPane(input);
southPanel.add(inputJSP);
southPanel.add(sendButton);
pane.add("South", southPanel);
ActionListener al = new SendMessage();
sendButton.addActionListener(al);
sendButton.setEnabled(false);
ServerListener sl = new ServerListener();
Thread srvl = new Thread(sl);
srvl.start();
}
class SendMessage implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
inputContent = input.getText();
if(inputContent.equals(""))
{
JOptionPane.showMessageDialog(ChatGUI.this,
"Please do not send empty message", "", JOptionPane.ERROR_MESSAGE);
return;
}
input.setText("");
try
{
String displayName = null;
if(nickName == null || nickName.equals(""))
{
displayName = InetAddress.getLocalHost().getHostAddress();
}
else
{
displayName = nickName;
}
//synchronized(dialog)
{
//dialog.wait();
dialog.setText(dialog.getText() + "你:\n" + inputContent + "\n");
//dialog.notify();
}
//将inputContent放入发送队列
sendMsgQueue.add(inputContent);
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
/*catch (InterruptedException e)
{
e.printStackTrace();
}*/
}
}
class ChangeName implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
if(newNickName.getText().trim().equals(""))
{
JOptionPane.showMessageDialog(ChatGUI.this,
"Name cannot be empty", "", JOptionPane.ERROR_MESSAGE);
}
else
{
nickName = newNickName.getText();
newNickName.setText("");
//发送向对方
JOptionPane.showMessageDialog(ChatGUI.this,
"You have changed your name to " + nickName, "", JOptionPane.INFORMATION_MESSAGE);
}
}
}
class RequestChat implements ActionListener
{
public void actionPerformed(ActionEvent evt)
{
String requestIP = ChatGUI.this.friendAddress.getText();
try
{
String localIP = InetAddress.getLocalHost().getHostAddress();
if(requestIP.equals(localIP))
{
JOptionPane.showMessageDialog(ChatGUI.this,
"You cannot send invitation to yourself", "", JOptionPane.ERROR_MESSAGE);
return;
}
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
if(requestIP.equals(""))
{
JOptionPane.showMessageDialog(ChatGUI.this,
"Please input valid IP", "", JOptionPane.ERROR_MESSAGE);
}
else
{
smsg = new SendChatRequest();
Thread sm = new Thread(smsg);
sm.start();
}
}
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
public void run()
{
//JFrame.setDefaultLookAndFeelDecorated(true);
//JDialog.setDefaultLookAndFeelDecorated(true);
try
{
SubstanceImageWatermark watermark = new SubstanceImageWatermark(ChatGUI.class.getResourceAsStream("../image/skyani.jpeg"));
watermark.setKind(ImageWatermarkKind.APP_CENTER);
SubstanceSkin skin = new OfficeBlue2007Skin().withWatermark(watermark);
UIManager.setLookAndFeel(new SubstanceOfficeBlue2007LookAndFeel());
SubstanceLookAndFeel.setSkin(skin);
}
catch (UnsupportedLookAndFeelException ex)
{
ex.printStackTrace();
}
ChatGUI c = new ChatGUI();
c.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
c.pack();
EventQueue.invokeLater(new FrameShower(c));
}});
}
private static class FrameShower implements Runnable
{
private final Frame frame;
FrameShower(Frame frame)
{
this.frame = frame;
}
public void run()
{
frame.setVisible(true);
}
}
private class SendChatRequest implements Runnable
{
public void run()
{
//连接服务器
String requestIP = ChatGUI.this.friendAddress.getText();
try
{
InetAddress ia = InetAddress.getByName(requestIP);
Socket socket = new Socket(ia, 5776);
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(socket.getInputStream()));
StringBuffer sb = new StringBuffer();
String c;
try
{
c = (String)in.readObject();
sb.append(c);
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
String rstCode = sb.toString();
System.out.println(rstCode);
if(rstCode.equals("0"))
{
JOptionPane.showMessageDialog(ChatGUI.this,
requestIP + " accepted your invitation", "", JOptionPane.INFORMATION_MESSAGE);
sendButton.setEnabled(true);
}
else if(rstCode.equals("1"))
{
JOptionPane.showMessageDialog(ChatGUI.this,
requestIP + " refused your invitation", "", JOptionPane.ERROR_MESSAGE);
in.close();
socket.close();
return;
}
SendMsgThruSocket smts = new SendMsgThruSocket(out);
Thread ss = new Thread(smts);
ss.start();
ReceiveMsgFromSocket rmfs = new ReceiveMsgFromSocket(in);
Thread rs = new Thread(rmfs);
rs.start();
}
catch (UnknownHostException e1)
{
JOptionPane.showMessageDialog(ChatGUI.this,
"UnknownHostAddress", "", JOptionPane.ERROR_MESSAGE);
return;
}
catch (IOException e1)
{
JOptionPane.showMessageDialog(ChatGUI.this,
"I/O exception", "", JOptionPane.ERROR_MESSAGE);
}
}
}
private class ServerListener implements Runnable
{
public void run()
{
try
{
ServerSocket server = new ServerSocket(5776);
while(true)
{
Socket connection = server.accept();
ObjectOutputStream out = new ObjectOutputStream(connection.getOutputStream());
ObjectInputStream in = new ObjectInputStream(new BufferedInputStream(connection.getInputStream()));
String requesterIP = connection.getInetAddress().getHostAddress();
String[] options = {"accept", "refuse"};
int response = JOptionPane.showOptionDialog(ChatGUI.this, requesterIP + " sent an invitation to you...", "", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[0]);
if(response == 0)
{
out.writeObject("0");
out.flush();
sendButton.setEnabled(true);
SendMsgThruSocket smts = new SendMsgThruSocket(out);
Thread ss = new Thread(smts);
ss.start();
ReceiveMsgFromSocket rmfs = new ReceiveMsgFromSocket(in);
Thread rs = new Thread(rmfs);
rs.start();
}
else if(response == 1)
{
out.writeObject("1");
out.flush();
connection.close();
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
private class SendMsgThruSocket implements Runnable
{
ObjectOutputStream out;
SendMsgThruSocket(ObjectOutputStream out2)
{
this.out = out2;
}
public void run()
{
//等待发送消息
while (true)
{
String msgFromQueue;
try
{
msgFromQueue = (String) sendMsgQueue.take();
out.writeObject(msgFromQueue);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
}
private class ReceiveMsgFromSocket implements Runnable
{
ObjectInputStream in;
ReceiveMsgFromSocket(ObjectInputStream in)
{
this.in = in;
}
public void run()
{
while(true)
{
try
{
String rm;
while((rm = (String)in.readObject()) != null)
{
//synchronized(dialog)
{
//dialog.wait();
dialog.setText(dialog.getText() + "对方:\n" + rm + "\n");
//dialog.notify();
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
/*catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
}
}
}
}
界面展示: