我们先对普通的界面进行布局。创建两个类,一个Receiver,一个Sender。然后编写界面:
package Chat;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTextArea;
public class Receiver {
public String info;
private JFrame frame;
private JPanel pane_buttom;
private JSplitPane pane_center;
// 显示内容的文本框,输入内容的文本框,发送内容按钮
private JScrollPane pane_showWindow;
private JScrollPane pane_inputWindow;
private JTextArea area_showWindow;
private JTextArea area_inputWindow;
private JButton btn_send;
private Dimension dimension;// 用于设置area_showWindow可拖拉的大小
public Receiver() {
frame = new JFrame();
pane_buttom = new JPanel();
pane_showWindow = new JScrollPane();
pane_inputWindow = new JScrollPane();
area_showWindow = new JTextArea();
area_inputWindow = new JTextArea();
pane_center = new JSplitPane(JSplitPane.VERTICAL_SPLIT, false, pane_showWindow, pane_inputWindow);
btn_send = new JButton("send");
dimension = new Dimension(50, 300);
}
public void showFrame() throws UnsupportedFlavorException, IOException {
initFrame();
initChatTextArea();
initButton();
btn_send();
readfile();
}
public void readfile() throws UnsupportedFlavorException, IOException {
Transferable t = Toolkit.getDefaultToolkit().getSystemClipboard()
.getContents(null);
if (t != null && t.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {
// 因为原系的剪贴板里有多种信息, 如文字, 图片, 文件等
// 先判断开始取得的可传输的数据是不是文字, 如果是, 取得这些文字
List<File> s = (List) t.getTransferData(DataFlavor.javaFileListFlavor);
// 同样, 因为Transferable中的DataFlavor是多种类型的,
// 所以传入DataFlavor这个参数, 指定要取得哪种类型的Data.
for(File f:s)
System.out.println(f.getAbsolutePath());
}
}
public void initFrame() {
frame.setTitle("receiver");
int width = (int) Toolkit.getDefaultToolkit().getScreenSize().getWidth();
int height = (int) Toolkit.getDefaultToolkit().getScreenSize().getHeight();
frame.setBounds(width / 2, height / 2, 400, 450);
frame.setVisible(true);
}
// 内容显示文本框和输入内容文本框
private void initChatTextArea() {
// 取得视图焦点
pane_showWindow.getViewport().add(area_showWindow);
pane_inputWindow.getViewport().add(area_inputWindow);
// 将显示文本域设置为不可编辑
area_showWindow.setEditable(false);
// 设置显示文本域可拖拉的大小
pane_showWindow.setMinimumSize(dimension);
frame.add(pane_center, BorderLayout.CENTER);
}
// 发送文件,发送内容按钮
public void initButton() {
pane_buttom.add(btn_send);
frame.add(pane_buttom, BorderLayout.SOUTH);
}
private void btn_send() {
aaa(); //这是一个鼠标点击事件,当点击时可发送信息,这里我们需要将点击事件放在线程中,
//不然会导致无限循环,函数aaa()在下面文章
}
public static void main(String[] args) throws UnsupportedFlavorException, IOException {
Receiver chat = new Receiver();
ReadFile r=new ReadFile();
chat.showFrame();
}
}
因为两个界面的布局一模一样,所以就不都贴上去了。接下来我们继续编写关于双发通信的代码,因为是基于UDP协议,所以,我们无需进行连接,只需写好端口号,直接一个程序发送,一个程序接收就可以。
下面的代码是Receiver类中的aaa()函数接收信息的代码:只需给出端口再将接收的信息显示在界面上:
private void aaa() {
try {
// jie
DatagramSocket socketre = new DatagramSocket(8014);
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b, b.length);
while (true) {
socketre.receive(dp);
area_showWindow.append("sender:" + new String(dp.getData(), 0, dp.getLength()) + "\r\n");
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
sender类中的发送端口如下,这里我们需要用到线程,将发送信息的send方法写到线程中,并且把按钮的点击事件也写到这里。注意:由于发送方像接收方一样,未接收到就一直等待的方法,我们需要进行一个判断,如果输入框为空,我们就不进行传送信息。。。否则会无限给接收方发送空数据。
private void aaa() {
try {
DatagramSocket socket = new DatagramSocket(8015);
new Thread(new Runnable() {
@Override
public void run() {
btn_send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
info = area_inputWindow.getText();
area_showWindow.append("sender: " + info + "\r\n");
// pw.println(info);
area_inputWindow.setText("");
if (info != null) { //判断是否为空
byte[] b = info.getBytes();
DatagramPacket dp;
try {
dp = new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 8014);
socket.send(dp);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
}
}).start();
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
这样我们就做完了一端收,另一端发的代码。。接下来只要把代码互相复制一下。将端口改成不同的,即可完成互相收发的功能。receiver类aaa()函数代码如下:
private void aaa() {
try {
DatagramSocket socket = new DatagramSocket(8015);
new Thread(new Runnable() {
@Override
public void run() {
btn_send.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
info = area_inputWindow.getText();
area_showWindow.append("sender: " + info + "\r\n");
// pw.println(info);
area_inputWindow.setText("");
if (info != null) {
byte[] b = info.getBytes();
DatagramPacket dp;
try {
dp = new DatagramPacket(b, b.length, InetAddress.getByName("127.0.0.1"), 8014);
socket.send(dp);
} catch (UnknownHostException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
}
});
}
}).start();
................................................上述代码
} catch (SocketException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
sender类aaa()函数代码如下:
private void aaa() {
.......................................上述代码
try {
// jie
DatagramSocket socketse = new DatagramSocket(8016);
byte[] b = new byte[1024];
DatagramPacket dp = new DatagramPacket(b, b.length);
while(true) {
socketse.receive(dp);
area_showWindow.append("receiver:" + new String(dp.getData(), 0, dp.getLength()) + "\r\n");
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
.......................................上述代码
}
编写完后运行效果: