黑马程序员技术交流社区

标题: 创建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