话说网上真的好多啊...
创新互联公司专注为客户提供全方位的互联网综合服务,包含不限于做网站、成都网站制作、定西网络推广、小程序开发、定西网络营销、定西企业策划、定西品牌公关、搜索引擎seo、人物专访、企业宣传片、企业代运营等,从售前售中售后,我们都将竭诚为您服务,您的肯定,是我们最大的嘉奖;创新互联公司为所有大学生创业者提供定西建站搭建服务,24小时服务热线:028-86922220,官方网址:www.cdcxhl.com
package client;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ClientFrame extends JFrame{
private JTextArea allmsg;
private JTextField welcome,copyright,chatmsg;
private JButton send;
private JScrollPane js;
private boolean isConnected = true;
public DataOutputStream out;
public DataInputStream in;
public Socket s = null;
String nic; /* -- 保存用户昵称 --*/
/**
* 初始化客户端资源
* 1.获取从LoginFrame传递过来的参数
* 2.初始化界面元素
* 3.初始化通信所需要的资源 EG:输入/输出流(DataInputStream/DataOutputStream)
* */
public ClientFrame(String name,Socket socket)
{
this.setSize(310,660);
this.setLocation(290,50);
this.setTitle("聊天室客户端"+name+"");/* -- 指定窗口的标题 --*/
this.s = socket;/* -- 接收从LoginFrame中传递过来的Socket --*/
this.nic = name+" 说: ";
welcome = new JTextField(" "+name+" 欢迎您来到聊天室 ",100);
welcome.setBackground(Color.blue);
welcome.setEnabled(false);
copyright = new JTextField(" ----- all copyright @ TOP-king -----");
copyright.setEnabled(false);
allmsg = new JTextArea();
allmsg.setEditable(false);
allmsg.append(" 系统消息: 欢迎登录在线聊天室 \n");
js = new JScrollPane(allmsg);//为JTextArea添加滚动条
chatmsg = new JTextField("在此输入聊天信息");
chatmsg.addActionListener(new listen());
send = new JButton("发送");
send.addActionListener(new listen());/* -- 添加事件监听器 --*/
try {
out = new DataOutputStream(s.getOutputStream());
in = new DataInputStream(s.getInputStream());
} catch (IOException e) {JOptionPane.showMessageDialog(null, "系统异常","错误",JOptionPane.OK_CANCEL_OPTION);}
addcomponettocontainer();
/* -- 当用户关闭窗口时进行相关的处理 eg:Socket Data(Input/Output)Stream 的关闭--*/
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we)
{
sendmsg("quitlogout");/* -- 向服务器端发送关闭信息 --*/
isConnected = false;
destory();/* -- 销毁窗口资源 --*/
}
});
new Thread(new linread()).start();/* -- 启动读取信息线程 --*/
}
public void addcomponettocontainer()
{
Container c = this.getContentPane();
c.setLayout(null);
welcome.setBounds(75,10,150,20);
js.setBounds(10,50,280,500);
chatmsg.setBounds(10,560,180,30);
send.setBounds(220,560,70,30);
copyright.setBounds(10,600,280,20);
c.add(welcome);
c.add(js);
c.add(chatmsg);
c.add(send);
c.add(copyright);
this.setVisible(true);
this.setResizable(false);
}
class listen implements ActionListener
{
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
if(e.getSource()==send||e.getSource()==chatmsg)
{
String msg = chatmsg.getText().trim();
if("".equals(msg))
{
JOptionPane.showMessageDialog(null,"发送信息不能为空!","错误",JOptionPane.OK_OPTION);
}
else
{sendmsg((new Date()).toLocaleString()+"\n"+nic+msg+"\n");chatmsg.setText("");}
}
}
}
/* -- 向服务器端发送信息 --*/
public void sendmsg(String m)
{
if(isConnected)//如果socket的输出流没关闭
{
try {
out.writeUTF(m);
} catch (IOException e) {
JOptionPane.showMessageDialog(null,"发送信息失败!(系统异常)","错误",JOptionPane.OK_OPTION);
}
}
else
{
JOptionPane.showMessageDialog(null,"发送信息失败!(服务器关闭/网络故障)","错误",JOptionPane.OK_OPTION);
}
}
/* -- 读取信息线程 --*/
class linread implements Runnable
{
public void run()
{
read();
}
public void read()
{
while(isConnected)
{
try {
String msg = in.readUTF();
if("SYSTEM_CLOSED".equals(msg))
{
JOptionPane.showMessageDialog(null,"读取消息失败(服务器关闭/网络故障)!","错误",JOptionPane.OK_OPTION);
isConnected = false;
}
else
allmsg.append(msg+"\n");
} catch (IOException e) {
}
}//end while
JOptionPane.showMessageDialog(null,"读取消息失败(服务器关闭/网络故障)!","错误",JOptionPane.OK_OPTION);
}//end read()
}
public void destory()
{
try {
this.out.close();
this.in.close();
this.s.close();
} catch (IOException e) {
}
this.dispose();
}
}
======================================================
package client;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
public class LoginFrame extends JFrame{
private JTextField name;
private JTextField ip;
private JButton ok,cancle;
public Socket socket;
public LoginFrame()
{
super("登录框");
this.setSize(400,80);
this.setLocation(100,100);
name = new JTextField("昵称");
ip = new JTextField("127.0.0.1");
ok = new JButton("登录");
cancle = new JButton("取消");
ok.addActionListener(new listenEvent());
cancle.addActionListener(new listenEvent());
//建立容器
addcomponettocontainer();
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
}
/**
* 建立容器及控件
*/
public void addcomponettocontainer()
{
Container c = this.getContentPane();
c.setLayout(null);
name.setBounds(10,10,100,30);
ip.setBounds(120,10,100,30);
ok.setBounds(230,10,70,30);
cancle.setBounds(310,10,70,30);
c.add(name);
c.add(ip);
c.add(ok);
c.add(cancle);
this.setVisible(true);
this.setResizable(false);
}
public class listenEvent implements ActionListener
{
public void actionPerformed(ActionEvent event) {
// TODO Auto-generated method stub
if(event.getSource()==ok)
{
String n = name.getText().trim();
String i = ip.getText().trim();
if("".equals(n)||"".equals(i))
{
JOptionPane.showMessageDialog(null,"昵称、IP不能够为空!","错误",JOptionPane.OK_OPTION);
}
else{login(n,i);}
}
if(event.getSource()==cancle)
{
name.setText("");
ip.setText("");
}
}
}
/**
* 进行登录
* @param name
* @param ip
*/
public void login(String name,String ip)
{
try {
socket = new Socket(ip,7777);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.writeUTF(name);
out.flush();//强制输出缓存中的内容
//out.close();
new ClientFrame(name,socket);
destroywindow();
} catch (UnknownHostException e) {
JOptionPane.showMessageDialog(null,"找不到主机地址(IP错误/网络故障)!","错误",JOptionPane.OK_OPTION);
} catch (IOException e) {
}
}
public void destroywindow()
{
this.dispose();
}
public static void main(String[] args)
{
new LoginFrame();
}
}
==================================================
package server;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
public class ServerFrame extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
private JTextArea allmsg;
private JTextField currnum,totalnum,copyright,chatmsg;
private JButton send;
private JScrollPane js;
int num1,num2,port;/* -- num1:当前在线人数 num2:总上线人数 port:服务端口号 --*/
private ServerSocket ss;
ArrayListuser lists;//存放所有在线用户
public ServerFrame()
{
super("聊天室服务器端");
this.setSize(310,660);
this.setLocation(200,50);
lists = new ArrayListuser();
num1 = num2 =0;
port = 7777;
currnum = new JTextField(" 当前在线人数: "+num1);
currnum.setEnabled(false);
totalnum = new JTextField(" 上线总人数: "+num2);
totalnum.setEnabled(false);
copyright = new JTextField(" ----- all copyright @ TOP-king -----");
copyright.setEnabled(false);
allmsg = new JTextArea();
allmsg.append(" --------------- 系统消息 --------------\n");
allmsg.setEditable(false);
allmsg.setLineWrap(true); //允许自动换行
js = new JScrollPane(allmsg);//为JTextArea添加滚动条
chatmsg = new JTextField("在此输入系统信息");
chatmsg.addActionListener(new ActionListener(){
@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent arg0) {
String str = chatmsg.getText().trim();
if(!"".equals(str))
{sendmsg((new Date()).toLocaleString()+" -- 系统消息: "+str);chatmsg.setText("");}
else
JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.OK_OPTION);
chatmsg.setText("");/* -- 发送信息后,将输入栏中的信息清空 -- */
}
});
send = new JButton("发送");
send.addActionListener(new ActionListener(){
@SuppressWarnings("deprecation")
public void actionPerformed(ActionEvent arg0) {
String str = chatmsg.getText().trim();
if(!"".equals(str))
{sendmsg((new Date()).toLocaleString()+" -- 系统消息: "+str);chatmsg.setText("");}
else
JOptionPane.showMessageDialog(null, "消息不能为空","错误",JOptionPane.OK_OPTION);
chatmsg.setText("");/* -- 发送信息后,将输入栏中的信息清空 -- */
}
});
//建立容器
addcomponettocontainer();
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent we)
{
sendmsg("SYSTEM_CLOSED");/* -- 向客户端发送服务器关闭信息 -- */
destory();
}
});
start(); /* -- 启动连接服务 -- */
}
public void addcomponettocontainer()
{
//Container建立容器
Container c = this.getContentPane();
c.setLayout(null);
currnum.setBounds(20,15,130,20);
totalnum.setBounds(155,15,125,20);
js.setBounds(10,50,280,500);
chatmsg.setBounds(10,560,180,30);
send.setBounds(220,560,70,30);
copyright.setBounds(10,600,280,20);
c.add(currnum);
c.add(totalnum);
c.add(js);
c.add(chatmsg);
c.add(send);
c.add(copyright);
this.setVisible(true);
this.setResizable(false);
}
/**
* start()方法监听客户的连接
* 并且保存客户端的相关信息EG:用户昵称、用户所使用的Socket
* 用户连接到服务器成功之后,将其保存到用户列表中,并为该用户启动一个线程用于通信 */
@SuppressWarnings("deprecation")
public void start()
{
boolean isStarted = false;/* -- 用于标记服务器是否已经正常启动 -- */
try {
this.ss = new ServerSocket(port);
isStarted = true;
this.allmsg.append((new Date()).toLocaleString()+" 服务器启动 @ 端口: "+port+"\n");
while(isStarted)
{
Socket client = this.ss.accept(); /* -- 监听客户端的连接 -- */
DataInputStream in = new DataInputStream(client.getInputStream());
String name = in.readUTF();
user u = new user();
u.name = name;
u.socket = client;
lists.add(u); //将该用户加到列表中去
num1++;
num2++;
currnum.setText(" 当前在线人数: "+num1);
totalnum.setText(" 上线总人数: "+num2);
this.allmsg.append((new Date()).toLocaleString()+" : "+u.name+" 登录 \n");
new Thread(new ClientThread(u)).start();/* -- 为该用户启动一个通信线程 -- */
}
} catch (IOException e) {
System.out.println("服务器已经启动......");
System.exit(0);
}
}
/**
* 通信线程主要功能包括:
* 1.监听客户端输入的信息
* 2.将接收到的信息转发给其他用户 */
class ClientThread implements Runnable
{
user user = null;
boolean isConnected = true;
DataInputStream dis = null;
DataOutputStream dos = null;
public ClientThread(user u)
{
this.user = u;
try {
this.dis = new DataInputStream(this.user.socket.getInputStream());
this.dos = new DataOutputStream(this.user.socket.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void run()
{
readmsg();
}
/* -- 读取客户的聊天信息 -- */
@SuppressWarnings("deprecation")
public void readmsg()
{
while(isConnected)
{
try {
String msg = dis.readUTF();
if("quitlogout".equals(msg))//当用户关闭客户端窗口时,发送quit字符串 表示用户已经退出
{
num1--;
try{
this.dis.close();
this.dos.close();
this.user.socket.close();
this.isConnected = false;
}catch(IOException ioe)
{
ioe.printStackTrace();
}finally{
this.isConnected = false;
if(dis!=null) this.dis.close();
if(dos!=null) this.dos.close();
if(this.user.socket!=null) this.user.socket.close();
}
lists.remove(this.user);//从列表中删除该用户
currnum.setText(" 当前在线人数: "+num1);
allmsg.append((new Date()).toLocaleString()+" : "+this.user.name+" 退出\n");
}
else
sendmsg(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/* -- 将信息进行转发 -- */
public void sendmsg(String msg)
{
user us = new user();
DataOutputStream os = null;
if(lists.size()0)
{
for(int i=0;ilists.size();i++)
{
us = lists.get(i);
try {
os = new DataOutputStream(us.socket.getOutputStream());
os.writeUTF(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
else
JOptionPane.showMessageDialog(null, "当前无用户在线。发送消息失败","失败",JOptionPane.OK_OPTION);
}
public void destory()
{
try {
this.ss.close();
} catch (IOException e) {
e.printStackTrace();
}
this.dispose();
}
public static void main(String[] args)
{
new ServerFrame();
}
}
=================================================
package server;
import java.net.*;
public class user {
String name;
Socket socket;
}
一: 首先弄清题目的意思
A.需要的主要组件列表:
1. 创建一个窗口,窗口标题叫Information
2. 3个标签, 用于显示文字 Name Number Class
3. 3个文本框, 用于填写信息
4. 1个按钮, 文字是确认
5. 1个文本域
B.业务逻辑
1. 当点击按钮确认的时候, 把 文本框的信息显示到文本域
C.设计的主要技术
JLabel , JButton, JTextField ...等, 都是swing的组件 , 所以应该使用swing进行创建
二: 确定使用的布局
swing虽然重写了大部分的组件, 但是布局, 依旧沿袭awt技术
分析图片上的布局:
至少有2种方法可以实现,
方法一: 绝对布局 , 优点: 配合可视化GUI拖曳, 可以完美的实现图上的组件的位置
但是缺点也是致命的, 不同的操作系统平台下, 可能会出现位置的移动,
只适合开发平台, 移植效果差 . 所以不推荐使用
方法二: 灵活的表格布局, 配合流式布局 , 所有操作系统下,显示效果都比较统一.
三: 效果图
四: 参考代码
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class FrameDemo extends JFrame {
//申明需要的组件
private final JTextField jtf1,jtf2,jtf3;
private final JTextArea jta;
public FrameDemo() {
setTitle("Information");//设置窗口标题
setSize(320, 360);//设置窗口大小
setLocationRelativeTo(null);//设置窗口居中
setDefaultCloseOperation(EXIT_ON_CLOSE);//设置关闭时退出虚拟机
getContentPane().setLayout(new FlowLayout());//设置窗口布局为流式布局
JPanel jp = new JPanel(new GridLayout(4, 2));//设置jp面板为表格布局4行2列
//第一行
JPanel jp01 = new JPanel();
JLabel jl1 = new JLabel("Name:");
jp01.add(jl1);
JPanel jp1 = new JPanel();
jtf1 = new JTextField(8);
jp1.add(jtf1);
//第二行
JPanel jp02 = new JPanel();
JLabel jl2 = new JLabel("Number:");
jp02.add(jl2);
JPanel jp2 = new JPanel();
jtf2 = new JTextField(8);
jp2.add(jtf2);
//第三行
JPanel jp03 = new JPanel();
JLabel jl3 = new JLabel("Class:");
jp03.add(jl3);
JPanel jp3 = new JPanel();
jtf3 = new JTextField(8);
jp3.add(jtf3);
//第四行
JPanel jp04 = new JPanel();
JLabel jl4 = new JLabel("");
jp04.add(jl4);
JPanel jp4 = new JPanel();
JButton jb = new JButton("确认");
jp4.add(jb);
jp.add(jp01);
jp.add(jp1);
jp.add(jp02);
jp.add(jp2);
jp.add(jp03);
jp.add(jp3);
jp.add(jp04);
jp.add(jp4);
getContentPane().add(jp);
jta = new JTextArea();
jta.setColumns(20);//设置文本域的大小
jta.setEditable(false);//设置文本域不可编辑
jta.setBackground(jp.getBackground());//设置文本域的背景色和面板一样
getContentPane().add(jta);
jb.addActionListener(new ActionListener() {//给按钮添加事件
public void actionPerformed(ActionEvent e) {//点击按钮,显示信息到文本域
String name = jtf1.getText();
String number = jtf2.getText();
String clazz = jtf3.getText();
jta.setText("You name is "+name+" number is "+number+" class is "+clazz);
}
});
}
public static void main(String[] args) {
new FrameDemo().setVisible(true);//创建窗口,被设置为可见
}
}
五: 拓展
虽然图形界面的实现方法是多样的, 我们一定要根据具体情况, 选择一个比较优化的 合理的, 符合业务逻辑的实现方法
public static void process() {
try {
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
while (portList.hasMoreElements())
{
CommPortIdentifier portId = (CommPortIdentifier) portList.nextElement();
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL)//如果端口类型是串口则判断名称
{
if(portId.getName().equals("COM1")){//如果是COM1端口则退出循环
break;
}else{
portId=null;
}
}
}
SerialPort serialPort = (SerialPort)portId.open("Serial_Communication", 1000);//打开串口的超时时间为1000ms
serialPort.setSerialPortParams(9600,SerialPort.DATABITS_8,SerialPort.STOPBITS_1,SerialPort.PARITY_NONE);//设置串口速率为9600,数据位8位,停止位1们,奇偶校验无
InputStream in = serialPort.getInputStream();//得到输入流
OutputStream out = serialPort.getOutputStream();//得到输出流
//进行输入输出操作
//操作结束后
in.close();
out.close();
serialPort.close();//关闭串口
} catch (PortInUseException e) {
e.printStackTrace();
} catch (UnsupportedCommOperationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}