黑马程序员技术交流社区
标题:
创建GUI窗口并实现聊天
[打印本页]
作者:
巴塞罗那的凌晨
时间:
2015-4-19 21:24
标题:
创建GUI窗口并实现聊天
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class GuiChat extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final int DEFAULT_PORT = 8899;
// 把主窗口分为NORTH、CEMTER和SOUTH三个部分
private JLabel stateLB;
private JTextArea centerTextArea;
private JPanel souJPanel;
private JTextArea inputTextArea;
private JPanel bottomPanel;
private JTextField ipTextField;
private JTextField remotePortTF;
private JButton sendBT;
private JButton clearBT;
private DatagramSocket datagramSocket;
private void setUpUI() {
// 初始化窗口
setTitle("GUI 聊天");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(400, 400);
setResizable(false);
setLocationRelativeTo(null);
// 窗口的NORTH部分
stateLB = new JLabel("当前还未启动监听");
stateLB.setHorizontalAlignment(JLabel.RIGHT);
// 窗口的CENTER部分
centerTextArea = new JTextArea();
centerTextArea.setEditable(false);
centerTextArea.setBackground(new Color(211, 211, 211));
// 窗口的SOTH部分
souJPanel = new JPanel(new BorderLayout());
inputTextArea = new JTextArea(5, 20);// 内容输入区
bottomPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 5));
ipTextField = new JTextField("127.0.0.1", 8);
remotePortTF = new JTextField(String.valueOf(DEFAULT_PORT), 3);
sendBT = new JButton("发送");
clearBT = new JButton("清屏");
bottomPanel.add(ipTextField);
bottomPanel.add(remotePortTF);
bottomPanel.add(sendBT);
bottomPanel.add(clearBT);
souJPanel.add(new JScrollPane(inputTextArea), BorderLayout.CENTER);
souJPanel.add(bottomPanel, BorderLayout.SOUTH);
// 添加窗口NORTH、CENTER、SOUTH部分的组件
add(stateLB, BorderLayout.NORTH);
add(new JScrollPane(centerTextArea), BorderLayout.CENTER);
add(souJPanel, BorderLayout.SOUTH);
setVisible(true);
}
private void setListener() {
sendBT.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 获取发送的目标IP地址和端口号
final String ipAddress = ipTextField.getText();
final String remotePort = remotePortTF.getText();
// 判断IP地址和端口号是否为空
if (ipAddress == null || ipAddress.trim().equals("")
|| remotePort == null || remotePort.trim().equals("")) {
JOptionPane.showMessageDialog(GuiChat.this, "请输入IP地址和端口号");
return;
}
if (datagramSocket == null || datagramSocket.isClosed()) {
JOptionPane.showMessageDialog(GuiChat.this, "监听不成功");
return;
}
// 获得需要发送的内容
String sendContent = inputTextArea.getText();
byte[] buf = sendContent.getBytes();
try {
// 将发送的内容显示在自己的聊天记录中
centerTextArea.append("我对" + ipAddress + ":" + remotePort
+ "说:\n" + inputTextArea.getText() + "\n\n");
// 添加内容后 ,使滚动条自动滚动到最低端
centerTextArea.setCaretPosition(centerTextArea.getText()
.length());
datagramSocket.send(new DatagramPacket(buf, buf.length,
InetAddress.getByName(ipAddress), Integer
.parseInt(remotePort)));
inputTextArea.setText("");
} catch (IOException e1) {
JOptionPane.showMessageDialog(GuiChat.this, "出错了,发送不成功!");
e1.printStackTrace();
}
};
});
// 为clearBT按钮添加事件监听器
clearBT.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
centerTextArea.setText("");// 清空聊天记录的内容
}
});
}
private void initSokett() {
int port = DEFAULT_PORT;
while (true) {
try {
if (datagramSocket != null && !datagramSocket.isClosed()) {
datagramSocket.close();
}
try {// 判断端口号是否在1~65535之间
port = Integer.parseInt(JOptionPane.showInputDialog(this,
"请输入端口号", "端口号", JOptionPane.QUESTION_MESSAGE));
if (port < 1 || port > 65535) {
throw new RuntimeException("端口号超出范围");
}
} catch (Exception e) {
JOptionPane.showMessageDialog(null,
"你输入的端口不正确,请输入1~65535之间的数");
continue;
}
// 启动DatagramSocket
datagramSocket = new DatagramSocket(port);
startListen();// 调用startListen方法
// 在stateLB中显示程序监听的端口号
stateLB.setText("已在" + port + "端口监听");
break;
} catch (SocketException e) {// 端口号被占用重新填写
JOptionPane.showMessageDialog(this, "端口已被占用,请重新设置端口");
stateLB.setText("当前还未监听");
}
}
}
private void startListen() {
new Thread(){
private DatagramPacket p;
public void run(){
byte[] buf = new byte[1024];
//创建DatagramSocket
p = new DatagramPacket(buf,buf.length);
while(!datagramSocket.isClosed()){
try{
datagramSocket.receive(p);//接收聊天消息
//添加到聊天记录框
centerTextArea.append(p.getAddress().getHostAddress()+":"+((InetSocketAddress)p.getSocketAddress()).getPort()+"对我说:\n"+new String(p.getData(),0,p.getLength())+"\n\n");
//使滚动条自动滚到最底端
centerTextArea.setCaretPosition(centerTextArea.getText().length());
}catch(IOException e){
e.printStackTrace();
}
}
}
}.start();
}
public GuiChat() {
setUpUI();
initSokett();
setListener();
}
public static void main(String[] args) {
new GuiChat();
}
}
作者:
小龟
时间:
2015-4-19 23:18
顶一下~~@
作者:
俊勇
时间:
2015-4-20 23:11
不错哦,学习新东西了~~~
作者:
巴塞罗那的凌晨
时间:
2015-4-20 23:37
不错!灰常好!有潜质,好好努力,看好你!
作者:
ShadowDancer
时间:
2015-4-21 08:46
受教了!!!
作者:
q8387811
时间:
2015-4-21 09:09
学习学习!!!!
作者:
乱了夏末蓝了海
时间:
2015-4-21 22:53
写得好。。。
作者:
乱了夏末蓝了海
时间:
2015-4-21 22:55
搬砖的走了。。。不用谢
作者:
赵晗
时间:
2016-7-16 22:28
学习学习
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2