📄 clients.java
字号:
package chatSystem;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import java.awt.event.*;
import java.io.IOException;
import java.net.*;
import java.util.*;;
/**
* 这个类是客户的主程序,也是所有的类都是在这个类内实现的
* 调用了登录和注册类,还提供了与所有在线用户群聊的功能
* 还能显示所有在线用户
* @author 黄祖光
*
*/
public class Clients extends JFrame implements ActionListener
{
JScrollPane scrollpanel=null;
String name,clientname,singleChatInf;
JPanel bp,myPanel;
MainPanel mainpanel;
GroupChat groudchat=null;
int mx,my,h=350,w=90,myport;
JLabel me;
String information;
LoginDialog login=null;
ArrayList list=new ArrayList();//用来存放在线用户的资料
SingleServer sise=null;
public static String serverport="192.168.1.100";
Clients()
{
login =new LoginDialog(this,"登录",true,this);//这个是登录线程,如果是合法用户则继续执行下面的程序,否则不执行.
name=login.getName();//得到用户名
setTitle(name);
myPanel=new JPanel();
myPanel.setBackground(Color.orange);
me=new JLabel("迷你QQ",new ImageIcon("image\\dh.gif"),SwingConstants.CENTER);//标题栏
myPanel.add(me);
add(myPanel,BorderLayout.NORTH);
mainpanel=new MainPanel(name);
mainpanel.setSize(w, h);
scrollpanel=new JScrollPane(mainpanel);
scrollpanel.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
scrollpanel.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED );
add(scrollpanel,BorderLayout.CENTER);
bp=new JPanel();
JButton gb=new JButton("群聊");
gb.addActionListener(this);
bp.add(gb);
add(bp,BorderLayout.SOUTH);
setBounds(500,100,270,600);
setVisible(true);
groudchat=new GroupChat();//启动群聊的线程
addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent we)
{
if(login.QuitChat())//当关闭整个程序时先要关掉一些SOCKET这样才不会引起异常
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent ae)
{
if (ae.getActionCommand()=="群聊")
{
groudchat.frame.setVisible(true);//显示群聊的对话框
}
}
/**
* 这个方法是用来提示用户有人想与他单聊,并让想与他单聊的用户的按钮显为另一种颜色
* @param str
*/
public void chatSign(String str)
{
for(int i=0;i<list.size();i++)
{
Friends f=(Friends)list.get(i);
if(str.equals(f.getName()))
{
f.button.setBackground(Color.yellow);
f.chated=true;
System.out.println(f.getName()+" chatSign: this is the color changed");
break;
}
}
}
/**
* 用来保存上线用户,把在线用户添加到列表中
* @param info
*/
public void addFriend(String info)
{
StringTokenizer st=new StringTokenizer(info,"#");
String s=st.nextToken();
myport=Integer.parseInt(s);//取得用户的帐号
System.out.println("myport:"+myport);
while(st.hasMoreTokens())
{
s=st.nextToken();
Friends friend=new Friends(s,false);
list.add(friend);
}
}
/**
* 这个类用来把在线好友封装在一个类中,以保存其帐号和IP地址等信息
* 用以来为单聊做准备
* @author 黄祖光
*
*/
private class Friends
{
String acountip,ip,clientName;
int aount;
JButton button;
boolean chated=false;//这个变量是用来标注当请求单聊还是被请求的
Friends(String acount,boolean chated)
{
this.chated=chated;
this.acountip=acount;
StringTokenizer st=new StringTokenizer(acountip,",");
aount=Integer.parseInt(st.nextToken());
ip=st.nextToken();
clientName=st.nextToken();//取得用户名
ImageIcon icon=new ImageIcon("image\\cs001.gif");
button=new JButton(aount+"",icon);
}
/**
* 取得用户的帐号
* @return
*/
public int getAcount()
{
return aount;
}
/**
* 取得用户的IP地址
* @return
*/
public String getIP()
{
ip=ip.substring(1,ip.length());
return ip;
}
/**
* 取得用户名
* @return
*/
public String getName()
{
return clientName;
}
/**
* 使代表用户显示在按钮消失来表示用户下线
*/
public void remove()
{
button.setVisible(false);
}
}
/**这个方法用来判断新登录的好友是不是在此用户下线前再次上线的,
*如果是的话就直接让button再次显示就行了.不用再生成一个Friends对象了
*/
public boolean isExist( int num)
{
boolean exist=false;
for(int i=0;i<list.size();i++)
{
Friends f=(Friends)list.get(i);
if(f.aount==num)
{
f.button.setVisible(true);
exist=true;
}
}
return exist;
}
/**
* 这个类是用户的主界面,用来显示在线的用户和显示功能按钮
* @author 黄祖光
*
*/
private class MainPanel extends JPanel implements ActionListener
{
String outname;
ImageIcon icon=null;
JPopupMenu popup;
int clientNum=1,port;
MainPanel(String name)
{
outname=name;
setBackground(Color.white);
Border etched=BorderFactory.createLoweredBevelBorder();
Border titled=BorderFactory.createTitledBorder(etched);
setBorder(etched);
popup=new JPopupMenu();
JMenuItem chanam=new JMenuItem("改名");
chanam.addActionListener(this);
popup.add(chanam);
JMenuItem open=new JMenuItem("打开");
open.addActionListener(this);
popup.add(open);
name=login.getName();//取得用户名
information=login.getInformation();//取得用户信息
addFriend(information);
setLayout(new GridLayout(list.size()+5,2));
for(int i=0;i<list.size();i++)//向列表中添加好友信息
{
Friends friend=(Friends)list.get(i);
int acount=friend.getAcount();
addClient(friend);
}
sise=new SingleServer(myport,outname);//实例化和启动单聊主程序
sise.start();
}
/**
* 往主界面上添加好友,并用一个按钮代表一个用户,并添加事件,用以来实现用户单聊的功能
* @param friend
*/
public void addClient(final Friends friend)
{
JPanel panel=new JPanel();
panel.setBackground(Color.white);
JButton button=friend.button;
button.setBackground(Color.white);
button.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent ae)
{
InetAddress address=null;
try
{
address=InetAddress.getByName(friend.ip.substring(1,friend.ip.length()));
}
catch (UnknownHostException e)
{
e.printStackTrace();
}
if(!friend.chated)//如果chated为假的,说明是用户请求单聊的,否则是用户被请求
{
singleChatInf=friend.getName();
groudchat.sendmessage.sendClientInf(singleChatInf);//向被请求用户发送信息
//生成单聊的对话框线程
ChatFra cf=new ChatFra(Color.cyan,friend.aount,friend.ip.substring(1,friend.ip.length()),name,friend.getName());
}
else
{
friend.button.setBackground(Color.white);//使按钮恢复原来的颜色
friend.chated=false;
}
}
});
panel.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent me)
{
if((me.getModifiersEx()&InputEvent.BUTTON3_DOWN_MASK)!=0)
{
popup.show(me.getComponent(),me.getX(),me.getY());
mx=me.getX();my=me.getY();
}
}
});
JLabel clientsname=new JLabel(friend.clientName);//name是用来存放用户名的,num是用来存入端口号的,这个得以后改数据库了再改正吧
panel.add(clientsname);
panel.add(button);
add(panel);
}
/**
* 好友下线时在界面上删除代表好友的按钮,从而显示其下线
* @param a
*/
public void removeCliends(String a)
{
int aount=Integer.parseInt(a);
for(int i=0;i<list.size();i++)
{
Friends f=(Friends)list.get(i);
if(aount==f.getAcount())
{
f.remove();
}
}
}
public void actionPerformed(ActionEvent ae)
{
if(ae.getActionCommand()=="打开")
{
//new ChatFrame("chat to client",Color.yellow,name).setVisible(true);
}
else if(ae.getActionCommand()=="改名")
{
new ChangeName("修改名字",mx+500,my+100);
}
}
}
/**
* 这个类是用来修改各个好友的名的,但现在还不能改名,因为触发好友的按钮不是全局变量,且改好后不知道怎么刷新,让新名显现出来...
* 因为时间的关系,这个类没有在程序中实现,以后会实现的
* @author 55
*
*/
private class ChangeName extends JDialog implements ActionListener
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -