我的第一款管理软件——————拥有界面的服务器
2016-03-28 23:00
295 查看
今天下午没有课,我用下午还有晚上的时间做好了左哥布置的练习————拥有界面的服务器。
首先,第一张图是没有打开服务之前的:
下面是我的截图,界面还有eclipse的控制台:
按了启动服务,服务器就启动好了。
自动生成IP地址和端口号。
然后用系统的控制台来控制来充当用户端,连接服务器。
做为测试,我连了三个。下图为测试:
用户名、IP、登录时间都正确,而且user1、4、8所发送的对话也可以在聊天框里面看到,最后要测试的功能是发送系统消息和关闭服务器。
测试结果如下:
关闭服务器后,出现了异常:
我觉得这是正常而且无法避免的,因为用户在使用用户端连接服务器的时候,socket是打开状态,突然关闭服务器,socket必然会断开,无服务器accept()。
而且用户在使用通信时,服务器管理人员突然手动断开服务器也是不太可能的(激动的时候除外)。
总而言之,我做的这一款拥有界面的服务器基本功能已经是实现了,所有的组件都拥有其相对应的功能。有很多的小bug没有处理,以后再做,因为现在已经是十点半了,我今天写了一个下午和晚上的代码,也有点烦躁了。
下面我总结介绍我做的代码:
首先,我先做了一个MyUserModel类implements-->TableModel接口
定义一个二维字符串容器用来存储用户登录的信息:用户名、IP地址、登录时间,然后用JTable来展现TableModel里面的信息。
界面做出来后,我再一个个按钮组件、JTable、系统信息聊天框有条不紊的实现。
第一个是服务器启动按钮:
服务器启动后,就是客户端的端口接入:
接入在输出welcom!后,用TableModel里面的字符串容器来存储用户名、IP地址、登录时间,然后用JTable输出————————>>>>>这里我卡了十几分钟,因为JTable需要updata()后才可以显示Model里面的信息,长知识了,下次记住。
其中的当前时间输出我也是在百度上面摘录的。
最后的那个聊天框和系统消息就太简单了,直接就是输出就可以了。
java面向对象的思想我也在做练习的时候越来越熟练,巩固了连连看那时候没有深入了解的TableModel接口。
十一点了,下线了,明天晚上我继续去华信学习,加油。
首先,第一张图是没有打开服务之前的:
下面是我的截图,界面还有eclipse的控制台:
按了启动服务,服务器就启动好了。
自动生成IP地址和端口号。
然后用系统的控制台来控制来充当用户端,连接服务器。
做为测试,我连了三个。下图为测试:
用户名、IP、登录时间都正确,而且user1、4、8所发送的对话也可以在聊天框里面看到,最后要测试的功能是发送系统消息和关闭服务器。
测试结果如下:
关闭服务器后,出现了异常:
我觉得这是正常而且无法避免的,因为用户在使用用户端连接服务器的时候,socket是打开状态,突然关闭服务器,socket必然会断开,无服务器accept()。
而且用户在使用通信时,服务器管理人员突然手动断开服务器也是不太可能的(激动的时候除外)。
总而言之,我做的这一款拥有界面的服务器基本功能已经是实现了,所有的组件都拥有其相对应的功能。有很多的小bug没有处理,以后再做,因为现在已经是十点半了,我今天写了一个下午和晚上的代码,也有点烦躁了。
下面我总结介绍我做的代码:
首先,我先做了一个MyUserModel类implements-->TableModel接口
定义一个二维字符串容器用来存储用户登录的信息:用户名、IP地址、登录时间,然后用JTable来展现TableModel里面的信息。
public static String[][] userName = new String[11][3];//设置一个容器用来存放数据 public MyUserModel(){ userName[0][0] = "用户名"; userName[0][1] = "IP"; userName[0][2] = "登录时间"; } public void addTableModelListener(TableModelListener l) { //添加模型监听器() } public Class<?> getColumnClass(int columnIndex) { return String.class;//设置模型类型String 类 } public int getColumnCount() { return 3;//获取列数 } public String getColumnName(int columnIndex) { return "";//获取列名 } public int getRowCount() { return 11;//获取行数 } //获取模型数据 public Object getValueAt(int rowIndex, int columnIndex) { return (String)userName[rowIndex][columnIndex]; } public boolean isCellEditable(int rowIndex, int columnIndex) { return false;//设置是否可编辑 } public void removeTableModelListener(TableModelListener l) { //移除监听器 } public void setValueAt(Object aValue, int rowIndex, int columnIndex) { userName[rowIndex][columnIndex] = (String)aValue; }然后再写一个界面的方法,把服务器的控制界面做出来:
public void FrameCode(){ /************************界面代码块************************/ this.setTitle("Test"); this.setSize(700, 300); this.setLocationRelativeTo(null); this.setDefaultCloseOperation(3); BorderLayout bl = new BorderLayout(); this.setLayout(bl); //设置布局 JPanel North = new JPanel(); //创建上部面板North IPString = new JTextField(15); InferString = new JTextField(10); IPlable = new JLabel("IP地址"); openServer = new JButton("启动服务"); openServer.setActionCommand("serverOpen"); Inputlable = new JLabel("端口号"); closeServer = new JButton("关闭服务"); closeServer.setActionCommand("serverClose"); North.add(IPlable); North.add(IPString); North.add(Inputlable); North.add(InferString); North.add(openServer); North.add(closeServer); this.add(North,bl.NORTH); //把上部面板添加到界面上部 JPanel East = new JPanel(); //创建东部面板 BorderLayout ms = new BorderLayout();//创建一个版块面板,存放聊天信息和发送信息 East.setLayout(ms); Msg = new JTextArea(20,20); InputString = new JTextField(15); send = new JButton("发送"); send.setActionCommand("send"); East.add(Msg,ms.CENTER); //聊天框放在中间 JPanel Enen = new JPanel(); //在北边再设置一个流动面板,增加按钮和发送框的可视性 Enen.setLayout(new FlowLayout()); Enen.add(InputString); //发送框和发送按钮放北边 Enen.add(send); East.add(Enen, ms.SOUTH); this.add(East,bl.EAST); mm = new MyUserModel();//创建一个TestModel模型,放进JTable里面去展现 tb = new JTable(mm); tb.setRowSelectionAllowed(false);//去掉水平的选择格子 tb.setRowHeight(20); this.add(tb,bl.CENTER); this.setVisible(true); //界面可见 ma = new MyActionListener(openServer,closeServer,send, IPString ,InferString,InputString,ss,Msg); openServer.addActionListener(ma); closeServer.addActionListener(ma); send.addActionListener(ma); }其中的组件布局逻辑关系还是比较复杂的,但我在华信接近四个月的时间也不是全用来打乒乓球的,这点逻辑我还是比较容易理清的。
界面做出来后,我再一个个按钮组件、JTable、系统信息聊天框有条不紊的实现。
第一个是服务器启动按钮:
public void initFrame(){ try { //telnet localhost 9090 //创建一个服务器对象,传入一个端口号,输出建立服务完成提示 //System.out.println("服务器的地址是: "+ss.getLocalSocketAddress()); this.FrameCode(); //创建了服务器同时,设置系统消息发送线程打开 Tool.sendSystemMsg(); while(true){ ss = ma.getServer();//不停的检测服务器是否已经在动作监听器里启动 if(ss!=null){//如果启动了服务器就可以连接客户端 System.out.println("已建立服务器"); //创建要接收服务的对象,获取套接字,获取服务,阻塞代码 Socket client = ss.accept(); //输出客户端地址 System.out.println("IP地址是:"+client.getRemoteSocketAddress()); ServerThread st = new ServerThread(client,tb,Msg); //添加每一个客户端线程到socketlist容器中,方便群聊的实现 socketlist.add(st); st.start(); } } } catch (Exception e) { e.printStackTrace(); } }我用一个死循环,检测服务器是否已经启动,若是没有启动,就一直循环下去,一直到服务器启动然后到达:Socket client= ss.accept()这行阻塞代码。
服务器启动后,就是客户端的端口接入:
String str = "welcom !"; //从JFrame界面记录user登录情况 for(int i=0;i<MyUserModel.userName.length;i++){ if(MyUserModel.userName[i][0]==null){ MyUserModel.userName[i][0] = username; MyUserModel.userName[i][1] = client.getLocalAddress().toString(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//设置日期格式 MyUserModel.userName[i][2] = df.format(new Date());// new Date()为获取当前系统时间 tb.updateUI(); break; } }
接入在输出welcom!后,用TableModel里面的字符串容器来存储用户名、IP地址、登录时间,然后用JTable输出————————>>>>>这里我卡了十几分钟,因为JTable需要updata()后才可以显示Model里面的信息,长知识了,下次记住。
其中的当前时间输出我也是在百度上面摘录的。
最后的那个聊天框和系统消息就太简单了,直接就是输出就可以了。
Msg.append(username+":"+str+"\r\n");//聊天框发送当前输出信息
if(e.getActionCommand().equals("send")){ Msg.append("系统消息:"+InputString.getText()+"\r\n"); }这就是我做得服务器控制界面的练习,新增了两个类:一个是监听器,一个是模型。
java面向对象的思想我也在做练习的时候越来越熟练,巩固了连连看那时候没有深入了解的TableModel接口。
十一点了,下线了,明天晚上我继续去华信学习,加油。
相关文章推荐
- 实验二课后作业
- 由使用多态引发的一些思考
- CentOS7.2 Linux 内核版本查看简述
- Android实现自动填充验证码
- 修改Exchange2013密码修改页面
- Android无线调试(Android wireless debugging)
- Spark集群运行模式
- 剧院系统界面之管理员界面
- Linux 线程同步的三种方法
- The important thing in life is to have a great aimand the determination to attain it.
- Python学习-机器学习实战-ch04 Bayes
- Linux 虚拟机网络适配器从E1000改为VMXNET3
- web Listener
- 新浪 sae sinaapp php的设置和其他php的区别
- MediaWiki功能使用
- Java环境搭建
- ios app上架整个流程
- 作业三
- Wireshark-ARP数据包
- Interface中定义方法