Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
CS 602 Sample Project Cover Sheet Name: Wentao LI ID: 31335692 Class: CS 602 Semester: Fall 2014 Date :Dec 15th, 2014 SourceCode: http://web.njit.edu/~wl256/ChatRoom.tar Email: [email protected] Description: My project is a C/S online chatroom. It is simple to use, just login and enjoy unicast / broadcast, emoji, drawing save/load received images and text & emojis ~ PS: Current the entry class for sever is chatroom.sever.SeverEngine !!! The entry class for client is chatroom.client.ClientEntry !!! Brief Explanation to my source code: ClientSide: chatroom.client.* chatroom.client.defaultemojis.* chatroom.msg.* (shared) SeverSide: chatroom.server.* chatroom.msg.* (shared) /////////////////////////////////////////////client/////////////////////////////////////////////////////////////////////////// package chatroom.client; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Font; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import javax.swing.BorderFactory; import javax.swing.Box; import javax.swing.JButton; import javax.swing.JColorChooser; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ScrollPaneConstants; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.border.BevelBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.FontUIResource; import chatroom.msg.*; public class FrameDemo extends JFrame implements MouseListener { /** * */ private static final long serialVersionUID = 1L; String username; ObjectInputStream objectin = null; ObjectOutputStream objectout =null; Lock outlock=null; ClientMsgReceiver myclientmsgreceiver; ArrayList<DataObject> texts= new ArrayList<DataObject>(); ArrayList<DataObject> lines= new ArrayList<DataObject>(); public final int FRAMEWIDTH = 800; public final int FRAMEHEIGHT = 580; private static final Color TIP_COLOR = new Color(255, 255, 225); protected JLabel left= new JLabel(); protected UpperTextPane uptextpane; protected LowerTextPane lwtextpane; protected JScrollPane jspuptextpane; protected JScrollPane jsplwtextpane; protected JButton btnsend; protected JButton btnemoji, btnloadtext,btnsavetext, btnloaddrawing,btnsavedrawing,btncolor, btnrefreshlist, btnremoveupper, btnreset; protected JComboBox<String> msgtype; protected JLabel right = new JLabel(); protected DrawPanel drawpanel; protected ListDemo listpanel; protected PicsJWindow picWindow; protected CoolToolTip error_tip; private class ImmediateColorListener implements ActionListener { private JDialog dialog; private JColorChooser chooser; public ImmediateColorListener() { chooser = new JColorChooser(); chooser.getSelectionModel().addChangeListener(new ChangeListener() { public void stateChanged(ChangeEvent event) { setBackground(chooser.getColor()); // FrameDemo.this.drawpanel.currentcolor=chooser.getColor(); } }); dialog = new JDialog((Frame) null, false /* not modal */); dialog.add(chooser); dialog.pack(); } public void actionPerformed(ActionEvent event) { chooser.setColor(FrameDemo.this.drawpanel.currentcolor); dialog.setVisible(true); } } @Override public void mouseClicked(MouseEvent arg0) {} @Override public void mouseEntered(MouseEvent arg0) { error_tip.setVisible(false); } @Override public void mouseExited(MouseEvent arg0) {} @Override public void mousePressed(MouseEvent e) { picWindow.setVisible(false); } @Override public void mouseReleased(MouseEvent e) { if (getY() <= 0) { setLocation(getX(), 0); } if (e.getButton() != 1) return;/*not left mouse key*/ JComponent source = (JComponent) e.getSource(); /*react to the event the mouse is released*/ if (e.getX() >= 0 && e.getX() <= source.getWidth() && e.getY() >= 0 && e.getY() <= source.getHeight()) { if (source == btnsend){ String message = lwtextpane.getText(); if (message.length() == 0) { error_tip.setText("PLEASE ENTER SOME TEXT"); error_tip.setVisible(true); }else if(message.length()>100){ error_tip.setText("100 CHARACTERS AT MOST ONE TIME AND U HAVE "+message.length() + "CHARACTERS"); error_tip.setVisible(true); }else{ this.sendtext(message); lwtextpane.setText(""); lwtextpane.revalidate(); } }else if (source == this.btnemoji){ picWindow.setVisible(true); } else if (source == this.btnremoveupper){ uptextpane.setText(""); uptextpane.revalidate(); }else if (source == this.btnreset){ lwtextpane.setText(""); lwtextpane.revalidate(); }else if (source == this.btnrefreshlist){ this.sendrequireuserlist(); }else if (source == this.btnsavetext){ File dir= new File(this.username+".text"); ObjectOutputStream tempout; try{ if (!dir.exists()){ dir.createNewFile(); } tempout = new ObjectOutputStream(new FileOutputStream(dir)); tempout.writeObject(texts); tempout.close(); } catch(Exception e1){ } }else if (source == this.btnloadtext){ File dir= new File(this.username+".text"); ObjectInputStream tempin; try{ if (dir.exists()){ tempin= new ObjectInputStream(new FileInputStream(dir)); texts= (ArrayList<DataObject>) tempin.readObject(); if (!texts.isEmpty()){ Iterator<DataObject> it = texts.iterator(); while (it.hasNext()){ DataObject tempdo = it.next(); if (tempdo instanceof TextObject){ this.receivetext((TextObject) tempdo); }else if (tempdo instanceof ImageObject){ this.receiveimage((ImageObject) tempdo); } } } } } catch(Exception e1){ } }else if (source == this.btnsavedrawing){ File dir= new File(this.username+".drawing"); ObjectOutputStream tempout; try{ if (!dir.exists()){ dir.createNewFile(); } tempout = new ObjectOutputStream(new FileOutputStream(dir)); tempout.writeObject(lines); lines= new ArrayList<DataObject>(); tempout.close(); } catch(Exception e1){ } }else if (source == this.btnloaddrawing){ File dir= new File(this.username+".drawing"); ObjectInputStream tempin; try{ if (dir.exists()){ tempin= new ObjectInputStream(new FileInputStream(dir)); texts= (ArrayList<DataObject>) tempin.readObject(); if (!texts.isEmpty()){ Iterator<DataObject> it = texts.iterator(); while (it.hasNext()){ DataObject tempdo = it.next(); if (tempdo instanceof LinesObject){ this.receivelines((LinesObject) tempdo); } } } } } catch(Exception e1){ } } } } public FrameDemo(String username,ObjectInputStream in, ObjectOutputStream out){ this.username=username; this.objectin=in; this.objectout=out; this.outlock=new ReentrantLock(); this.setTitle(this.username); // setLayout(new BorderLayout()); setSize(FRAMEWIDTH,FRAMEHEIGHT); setResizable(false); setLocationRelativeTo(null); setAlwaysOnTop(true); this.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { ////////////////////////////send a quit DataObject///////////////////////////// DataObject mydataobject = new DataObject("superman90|logout"); ClientMsgSender mymsgsender= new ClientMsgSender(mydataobject ,FrameDemo.this.objectout,FrameDemo.this.outlock); mymsgsender.start(); try { Thread.sleep(100); } catch (InterruptedException e1) { // TODO Auto-generated catch block System.out.println("framedemo existing exception : "+e1); } try { FrameDemo.this.objectin.close(); FrameDemo.this.objectout.close(); } catch (IOException e1) { // TODO Auto-generated catch block System.out.println("framedemo existing's closing exception : "+e1); } System.exit(1); } }); this.addComponentListener(new ComponentAdapter(){ @Override public void componentResized(ComponentEvent e) { FrameDemo.this.picWindow.dispose(); } @Override public void componentMoved(ComponentEvent e) { FrameDemo.this.picWindow.dispose(); } @Override public void componentHidden(ComponentEvent e) { FrameDemo.this.picWindow.dispose(); } }); uptextpane=new UpperTextPane(this.username); uptextpane.addMouseListener(this); jspuptextpane=new JScrollPane(uptextpane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); lwtextpane=new LowerTextPane(this.username); lwtextpane.addMouseListener(this); jsplwtextpane=new JScrollPane(lwtextpane, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED); error_tip = new CoolToolTip(this, jsplwtextpane, TIP_COLOR, 3, 10); btnemoji = new JButton("Emoji"); btnemoji.setFocusable(false); btnemoji.addMouseListener(this); btnloadtext = new JButton("LoadText"); btnloadtext.setFocusable(false); btnloadtext.addMouseListener(this); btnsavetext = new JButton("SaveText"); btnsavetext.setFocusable(false); btnsavetext.addMouseListener(this); btnloaddrawing = new JButton("LoadDrawing"); btnloaddrawing.setFocusable(false); btnloaddrawing.addMouseListener(this); btnsavedrawing = new JButton("SaveDrawing"); btnsavedrawing.setFocusable(false); btnsavedrawing.addMouseListener(this); btncolor =new JButton("DrawingColor"); btncolor.setFocusable(false); btncolor.addActionListener(new ImmediateColorListener()); btnremoveupper = new JButton("Clean"); btnremoveupper.setFocusable(false); btnremoveupper.addMouseListener(this); picWindow = new PicsJWindow(this); // // Box upbox = Box.createHorizontalBox(); upbox.add(btnemoji); upbox.add(Box.createHorizontalStrut(6)); upbox.add(btnloadtext); upbox.add(Box.createHorizontalStrut(3)); upbox.add(btnsavetext); upbox.add(Box.createHorizontalStrut(6)); upbox.add(btncolor); upbox.add(btnloaddrawing); upbox.add(Box.createHorizontalStrut(3)); upbox.add(btnsavedrawing); upbox.add(Box.createHorizontalStrut(9)); upbox.add(btnremoveupper); btnrefreshlist=new JButton("RefreshList"); btnrefreshlist.setFocusable(false); btnrefreshlist.addMouseListener(this); btnsend = new JButton("Send"); btnsend.setFocusable(false); btnsend.addMouseListener(this); btnreset = new JButton("Reset"); btnreset.setFocusable(false); btnreset.addMouseListener(this); String[] str_msg_type= {"Broadcast","Unicast"}; msgtype = new JComboBox<String>(str_msg_type); Box lwbox=Box.createHorizontalBox(); lwbox.setBorder(BorderFactory.createEmptyBorder(8,8,8,8)); lwbox.add(Box.createHorizontalStrut(13)); lwbox.add(new JLabel("Message Type: ")); lwbox.add(msgtype); lwbox.add(Box.createHorizontalStrut(10)); lwbox.add(btnrefreshlist); lwbox.add(Box.createHorizontalStrut(3)); lwbox.add(btnreset); lwbox.add(btnsend); JPanel paneLeftSouth = new JPanel(); paneLeftSouth.setLayout(new BorderLayout()); paneLeftSouth.add(upbox, BorderLayout.NORTH); paneLeftSouth.add(jsplwtextpane,BorderLayout.CENTER); paneLeftSouth.add(lwbox,BorderLayout.SOUTH); left.setLayout(new BorderLayout()); left.setOpaque(false); paneLeftSouth.setBackground(Color.CYAN); left.add(jspuptextpane,BorderLayout.CENTER); left.add(paneLeftSouth,BorderLayout.SOUTH); // drawpanel= new DrawPanel(this); drawpanel.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED) ); listpanel= new ListDemo(this); right.setLayout(new BorderLayout()); right.setPreferredSize(new Dimension(250,580)); right.setOpaque(false); right.add(drawpanel,BorderLayout.NORTH); right.add(listpanel, BorderLayout.CENTER); add(left, BorderLayout.CENTER); add(right,BorderLayout.EAST); EventQueue.invokeLater(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub FrameDemo.this.myclientmsgreceiver =new ClientMsgReceiver(FrameDemo.this, FrameDemo.this.objectin); FrameDemo.this.myclientmsgreceiver.start(); } }); } protected void sendtext(String text){ boolean unicast=true; TextObject mytextobject; String msgtype_s=(String)msgtype.getSelectedItem(); if (msgtype_s.equalsIgnoreCase("Broadcast")){ unicast=false; } uptextpane.addsenttitle(unicast, this.username); uptextpane.addsenttext(text); if (unicast){ mytextobject= new TextObject(this.username,this.listpanel.getselectedname(),text); }else{ mytextobject= new TextObject(this.username,text); } ClientMsgSender mymsgsender= new ClientMsgSender(mytextobject,this.objectout,this.outlock); mymsgsender.start(); } protected void sendimage(int imagenum){ boolean unicast=true; ImageObject myimageobject; String msgtype_s=(String)msgtype.getSelectedItem(); if (msgtype_s.equalsIgnoreCase("Broadcast")){ unicast=false; } uptextpane.addimageicon(true, this.username, imagenum, unicast); if (unicast){ myimageobject= new ImageObject(this.username,this.listpanel.getselectedname(),imagenum); }else{ myimageobject= new ImageObject(this.username,imagenum); } ClientMsgSender mymsgsender= new ClientMsgSender(myimageobject,this.objectout,this.outlock); mymsgsender.start(); } protected void sendlines(ArrayList<Line> lines){ boolean unicast=true; LinesObject mylinesobject; String msgtype_s=(String)msgtype.getSelectedItem(); if (msgtype_s.equalsIgnoreCase("Broadcast")){ unicast=false; } if (unicast){ mylinesobject= new LinesObject(this.username,this.listpanel.getselectedname(),lines); }else{ mylinesobject= new LinesObject(this.username,lines); } ClientMsgSender mymsgsender= new ClientMsgSender(mylinesobject,this.objectout,this.outlock); mymsgsender.start(); } protected void sendrequireuserlist(){ UserListObject myuserlistobject=new UserListObject(this.username); ClientMsgSender mymsgsender= new ClientMsgSender(myuserlistobject,this.objectout,this.outlock); mymsgsender.start(); } protected void receivetext(final TextObject textobject){ EventQueue.invokeLater(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub String[] header = textobject.getMessage().split("[|]"); if (header[2].equalsIgnoreCase("broadcast")){ uptextpane.addreceivedtitle(false, header[3]); uptextpane.addreceivedtext(textobject.getText()); }else{ uptextpane.addreceivedtitle(true, header[3]); uptextpane.addreceivedtext(textobject.getText()); } } }); } protected void receiveimage(final ImageObject imageobject){ EventQueue.invokeLater(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub String[] header = imageobject.getMessage().split("[|]"); if (header[2].equalsIgnoreCase("broadcast")){ uptextpane.addimageicon(false, header[3], imageobject.getImagenum(), false); }else{ uptextpane.addimageicon(false, header[3], imageobject.getImagenum(), true); } } }); } protected void receivelines(final LinesObject linesobject){ EventQueue.invokeLater(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub if (linesobject.getLines()!=null){ drawpanel.linelist.addAll(linesobject.getLines()); drawpanel.repaint(); } } }); } protected void receiveuserlist(final UserListObject userlistobject){ EventQueue.invokeLater(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub if (userlistobject.isHasnewlyregistered()){ uptextpane.addmiddletext(userlistobject.getNewlyregistered()+"has just registered"); } if (userlistobject.isHasnewlylogouted()){ uptextpane.addmiddletext(userlistobject.getNewlylogouted()+"has just logouted"); } listpanel.setcontents(userlistobject.getUserlist()); } }); } public void localtest(){ // // // // // // // // ArrayList<String> tempstring=new ArrayList<String>(); for (int i=0;i<20;i++){ Integer ti=new Integer(i); tempstring.add(ti.toString()); } listpanel.setcontents(tempstring); this.uptextpane.addmiddletext(this.listpanel.getselectedname()); } public static void setUIFont(FontUIResource f) { /* sets the default font for all Swing components. ex.setUIFont (new javax.swing.plaf.FontUIResource("Serif",Font.ITALIC,12));*/ Enumeration<Object> keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()) { Object key = keys.nextElement(); Object value = UIManager.get(key); if (value instanceof FontUIResource) UIManager.put(key, f); } } // public static void main(String[] args)throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException { // // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // // setUIFont(new FontUIResource("SansSerif", Font.PLAIN, 15)); // FrameDemo mydemo=new FrameDemo("tempusername",null,null); // mydemo.setVisible(true); // //// mydemo.localtest(); // } } package chatroom.client; import java.util.*; import java.awt.EventQueue; import java.awt.Font; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.Socket; import javax.swing.JOptionPane; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.plaf.FontUIResource; import chatroom.msg.*; public class ClientEntry { static Socket clientsocket; static ObjectInputStream myobjectin = null; static ObjectOutputStream myobjectout =null; static String anonymousname= null; static String username=null; public static void setUIFont(FontUIResource f) { /* sets the default font for all Swing components. ex.setUIFont (new javax.swing.plaf.FontUIResource("Serif",Font.ITALIC,12));*/ Enumeration<Object> keys = UIManager.getDefaults().keys(); while (keys.hasMoreElements()) { Object key = keys.nextElement(); Object value = UIManager.get(key); if (value instanceof FontUIResource) UIManager.put(key, f); } } public static void main(String[] args){ boolean breaknow=false; try{ System.out.println("Should connect now . . . "); clientsocket = new Socket("127.0.0.1", 20000); myobjectout = new ObjectOutputStream(clientsocket.getOutputStream()); myobjectin = new ObjectInputStream(clientsocket.getInputStream()); try{ breaknow=false; while (!breaknow){ System.out.println("Try to get anoymous name . . . "); myobjectout.writeObject(new DataObject("superman90|"+"requirename")); myobjectout.reset(); DataObject anonymousData=(DataObject) myobjectin.readObject(); String[] temp =anonymousData.getMessage().split("[|]"); if (temp.length>0 && temp[2]!=null){ anonymousname=temp[2]; breaknow=true; System.out.println("got anoymous name . . . "); break; } } }catch(IOException | ClassNotFoundException e){ System.out.println("ClientEntry getAnoymousName: "+e.getMessage()); } try { System.out.println("Try to get valid user name . . . "); breaknow=false; boolean again = false; while (!breaknow){ if (again){ username =JOptionPane.showInputDialog(null, "Sorry it is regitered and please reenter name to register as or use "+anonymousname, "Register", JOptionPane.QUESTION_MESSAGE); } else { username =JOptionPane.showInputDialog(null, "Please enter name to register as or use "+anonymousname, "Register", JOptionPane.QUESTION_MESSAGE); } System.out.println("The username is "+username); myobjectout.writeObject(new DataObject("superman90|"+"register|"+username)); myobjectout.reset(); DataObject anonymousData=(DataObject) myobjectin.readObject(); String[] temp =anonymousData.getMessage().split("[|]"); if (temp.length>0 && temp[1].equalsIgnoreCase("reregister") && temp[2].equalsIgnoreCase("success")){ username=temp[3]; breaknow=true; System.out.println("got valid user name . . . "); break; } again =true; } }catch(IOException | ClassNotFoundException e){ System.out.println("ClientEntry getUserName: "+e.getMessage()); } // // // // // // // System.out.println(username); Scanner in = new Scanner(System.in); in.nextLine(); myobjectin.close(); myobjectout.close(); clientsocket.close(); }catch(IOException e){ System.out.println("ClientEntry getUserName"+e.getMessage()); } try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (UnsupportedLookAndFeelException e) { // TODO Auto-generated catch block e.printStackTrace(); } setUIFont(new FontUIResource("SansSerif", Font.PLAIN, 15)); EventQueue.invokeLater(new Runnable(){ @Override public void run() { // TODO Auto-generated method stub FrameDemo mydemo=new FrameDemo(ClientEntry.this.username,myobjectin,myobjectout); mydemo.setVisible(true); } }); } } package chatroom.client; import java.io.IOException; import java.io.ObjectInputStream; import chatroom.msg.*; /** * long time used * @author superman90 * */ public class ClientMsgReceiver extends Thread { FrameDemo owner; ObjectInputStream in; public ClientMsgReceiver(FrameDemo owner, ObjectInputStream in){ this.owner=owner; this.in= in; } public void clientmsgdistributor(DataObject mydataobject){ String[] header= mydataobject.getMessage().split("[|]"); if ((header.length>0)&&(header[0].equalsIgnoreCase("superman90"))){ if (header[1].equalsIgnoreCase("text")){ owner.receivetext((TextObject)mydataobject); owner.texts.add(mydataobject); }else if (header[1].equalsIgnoreCase("image")){ owner.receiveimage((ImageObject)mydataobject); owner.texts.add(mydataobject); }else if (header[1].equalsIgnoreCase("lines")){ owner.receivelines((LinesObject) mydataobject); owner.lines.add(mydataobject); }else if (header[1].equalsIgnoreCase("userlist")){ owner.receiveuserlist((UserListObject) mydataobject); } } } @Override public void run() { try { while (!Thread.currentThread().isInterrupted()){ DataObject mydataobject=null; mydataobject = (DataObject) in.readObject(); if (mydataobject!=null){ System.out.println("a ClientMsgReceiver is processing a message: "+mydataobject.getMessage()); clientmsgdistributor(mydataobject); } } } catch (ClassNotFoundException | IOException e) { // TODO Auto-generated catch block System.out.println("a ClientMsgReceiver "+e); } } } package chatroom.client; import java.io.IOException; import java.io.ObjectOutputStream; import java.util.concurrent.locks.Lock; import chatroom.msg.*; /** * one time thing * @author superman90 * */ public class ClientMsgSender extends Thread { DataObject dataobject; ObjectOutputStream out; Lock outputlock; public ClientMsgSender(DataObject dataobject, ObjectOutputStream out, Lock outputlock ){ this.dataobject=dataobject; this.out=out; this.outputlock=outputlock; } @Override public void run() { outputlock.lock(); try{ try{ out.writeObject(dataobject); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }finally{ outputlock.unlock(); } } } package chatroom.client; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Font; import java.awt.Point; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import javax.swing.Icon; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JLayeredPane; import javax.swing.JPanel; import javax.swing.border.EmptyBorder; /** * cool tip panel */ public class CoolToolTip extends JPanel { private static final long serialVersionUID = 1L; private JLabel label = new JLabel(); private boolean haveShowPlace; private Component attachedCom; // component needed private Component parentWindow; // component shown within public CoolToolTip(Component parent,Component attachedComponent, Color fillColor,int borderWidth, int offset) { this.parentWindow = parent; this.attachedCom = attachedComponent; label.setBorder(new EmptyBorder(borderWidth, borderWidth, borderWidth,borderWidth)); label.setBackground(fillColor); label.setOpaque(true); label.setFont(new Font("system", 0, 14)); setOpaque(false); // this.setBorder(new BalloonBorder(fillColor, offset)); this.setLayout(new BorderLayout()); add(label); setVisible(false); // 当气泡显示时组件移动,气泡也跟着移动 this.attachedCom.addComponentListener(new ComponentAdapter() { @Override public void componentMoved(ComponentEvent e) { if (isShowing()) {//悬浮提示 显示了的,重新设置位置 determineAndSetLocation(); } } }); } private void determineAndSetLocation() { if(!attachedCom.isShowing()){ return; } Point loc = attachedCom.getLocationOnScreen(); Point paPoint = parentWindow.getLocationOnScreen(); //System.out.println(attachedComponent.getLocationOnScreen()); setBounds(loc.x-paPoint.x, loc.y -paPoint.y - getPreferredSize().height, getPreferredSize().width, getPreferredSize().height); } public void setText(String text) { label.setText(text); } public void setIcon(Icon icon) { label.setIcon(icon); } public void setIconTextGap(int iconTextGap) { label.setIconTextGap(iconTextGap); } @Override public void setVisible(boolean show) { if (show) { determineAndSetLocation(); findShowPlace(); } super.setVisible(show); } private void findShowPlace() { if (haveShowPlace) { return; } // we use the popup layer of the top level container (frame or // dialog) to show the balloon tip // first we need to determine the top level container JLayeredPane layeredPane = null; if(parentWindow instanceof JDialog){ layeredPane = ((JDialog)parentWindow).getLayeredPane(); }else if(parentWindow instanceof JFrame){ layeredPane = ((JFrame)parentWindow).getLayeredPane(); } /*Container parent = attachedCom.getParent(); while (true) { if (parent instanceof JFrame) { layeredPane = ((JFrame) parent).getLayeredPane(); break; } else if (parent instanceof JDialog) { layeredPane = ((JDialog) parent).getLayeredPane(); break; } parent = parent.getParent(); }*/ if(layeredPane!=null){ layeredPane.add(this, JLayeredPane.POPUP_LAYER); haveShowPlace = true; } } public Component getAttachedComponent() { return attachedCom; } public void setAttachedComponent(Component attachedComponent) { this.attachedCom = attachedComponent; } } package chatroom.client; import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; import chatroom.msg.*; public class DrawPanel extends JPanel implements MouseMotionListener, MouseListener{ ArrayList<Line> linelist; ArrayList<Line> newline; int lastX, lastY; FrameDemo container; Color currentcolor; public DrawPanel(){} public DrawPanel(FrameDemo container){ setBackground(Color.WHITE); currentcolor=Color.BLUE; linelist = new ArrayList<Line>(); newline = new ArrayList<Line>(); addMouseMotionListener(this); addMouseListener(this); this.container = container; } public void mouseMoved(MouseEvent me){ } public void mouseDragged(MouseEvent me){ int endX = me.getX(); int endY = me.getY(); Line line = new Line(lastX, lastY, endX, endY , currentcolor); linelist.add(line); newline.add(line); lastX = endX; lastY = endY; repaint(); } public void mouseEntered(MouseEvent me){} public void mouseExited(MouseEvent me){} public void mousePressed(MouseEvent me){ lastX = me.getX(); lastY = me.getY(); newline=new ArrayList<Line>(); } public void mouseReleased(MouseEvent me){ //////////////////////////sending new line/////////////////////////// // container.uptextpane.addmiddletext(newline.toString()); container.sendlines(newline); // } public void mouseClicked(MouseEvent me){} public void paintComponent(Graphics g){ super.paintComponent(g); Iterator<Line> it = linelist.iterator(); while(it.hasNext()){ Line current = it.next(); Color oldcolor = g.getColor(); g.setColor(current.getColor()); g.drawLine(current.getStartX(), current.getStartY(), current.getEndX(), current.getEndY()); g.setColor(oldcolor); // } //LineMessage lm = new LineMessage(); //lm.setMessage(linelist); //container.sendMessage(lm); g.drawString("Painted on JPanel",100,100); } public Dimension getPreferredSize(){ return new Dimension(250,250); } public Dimension getMinimumSize(){ return new Dimension(250,250); } } package chatroom.client; import java.net.URL; import javax.swing.ImageIcon; public class ImageIconwithNum extends ImageIcon{ private static final long serialVersionUID = 1L; int imagenum; public int getIm() { return imagenum; } public void setIm(int imagenum) { this.imagenum = imagenum; } public ImageIconwithNum(URL url,int imagenum){ super(url); this.imagenum = imagenum; } } package chatroom.client; import java.awt.*; import java.util.ArrayList; import javax.swing.*; import javax.swing.event.*; /* ListDemo.java requires no other files. */ public class ListDemo extends JPanel implements ListSelectionListener { /** * */ private static final long serialVersionUID = 1L; private JList<String> list; private DefaultListModel<String> listModel; private FrameDemo owner; public ListDemo(FrameDemo owner) { super(new BorderLayout()); this.owner=owner; // // listModel = new DefaultListModel<String>(); listModel.addElement(owner.username); listModel.addElement("Jane Doe"); listModel.addElement("John Smith"); // listModel.addElement("Kathy Green"); //Create the list and put it in a scroll pane. list = new JList<String>(listModel); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setSelectedIndex(0); list.addListSelectionListener(this); list.setVisibleRowCount(10); JScrollPane listScrollPane = new JScrollPane(list); add(listScrollPane, BorderLayout.CENTER); } public void setcontents(ArrayList<String> names){ listModel = new DefaultListModel<String>(); for (int i=0;i<names.size();i++){ listModel.addElement(names.get(i)); } list.setModel(listModel); list.setSelectedIndex(0); } public String getselectedname(){ return listModel.getElementAt(list.getSelectedIndex()).toString(); } //This method is required by ListSelectionListener. public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting() == false) { if (list.getSelectedIndex() == -1) { //No selection, disable fire button. owner.uptextpane.addmiddletext("~Currenttly unicast receiver list is refleshed~"); } else { //Selection, enable the fire button. owner.uptextpane.addmiddletext("~"+this.getselectedname()+" is selected as unicast receiver~"); } } } } package chatroom.client; import java.awt.Dimension; import javax.swing.JTextPane; import javax.swing.text.StyledDocument; import chatroom.msg.*; public class LowerTextPane extends JTextPane{ StyledDocument doc; String username; // public LowerTextPane(String username){ doc=this.getStyledDocument(); this.setSize(500, 100); this.setPreferredSize(new Dimension(500, 100)); this.setMinimumSize(new Dimension(500, 100)); this.username=username; } public TextObject generateTextObject(){ return null; } } package chatroom.client; import java.awt.*; import javax.swing.*; import java.awt.event.*; /** * <p> Title: pictures</p> * * <p> Description: </p> * * <p> Copyright: Copyright (c) 2011 </p> * * <p> Company: </p> * * @author not attributable * @version 1.0 */ public class PicsJWindow extends JWindow { private static final long serialVersionUID = 1L; private final int H_ELEMENT_NUM=3; private final int V_ELEMENT_NUM=6; private GridLayout gridLayout1 = new GridLayout(this.H_ELEMENT_NUM,this.V_ELEMENT_NUM); private JLabel[] ico=new JLabel[this.H_ELEMENT_NUM*this.V_ELEMENT_NUM]; /*放表情*/ private int i; private FrameDemo owner; public PicsJWindow(FrameDemo owner) { super(owner); this.owner=owner; try { init(); this.setAlwaysOnTop(true); } catch (Exception exception) { exception.printStackTrace(); } } private void init() throws Exception { this.setPreferredSize(new Dimension(30*V_ELEMENT_NUM,30*H_ELEMENT_NUM)); JPanel p = new JPanel(); p.setOpaque(true); this.setContentPane(p); p.setLayout(gridLayout1); p.setBackground(SystemColor.text); String fileName = ""; for(i=0;i <ico.length;i++){ fileName= "defaultemojis/"+i+".gif";/*修改图片路径*/ ico[i] =new JLabel(new ImageIconwithNum(PicsJWindow.class.getResource(fileName),i),SwingConstants.CEN TER); ico[i].setSize(28,28); ico[i].setBorder(BorderFactory.createLineBorder(new Color(225,225,225), 1)); ico[i].setToolTipText(i+""); ico[i].addMouseListener(new MouseAdapter(){ public void mouseClicked(MouseEvent e){ if(e.getButton()==1){ JLabel cubl = (JLabel)(e.getSource()); ImageIconwithNum cupic = (ImageIconwithNum)(cubl.getIcon()); ////////////////////////////////send image//////////////////////////////////////////////////////////////////// // owner.uptextpane.addimageicon(true, owner.username, cupic.imagenum, true); owner.sendimage(cupic.imagenum); cubl.setBorder(BorderFactory.createLineBorder(new Color(225,225,225), 1)); getObj().dispose(); } } @Override public void mouseEntered(MouseEvent e) { ((JLabel)e.getSource()).setBorder(BorderFactory.createLineBorder(Color.BLUE)); } @Override public void mouseExited(MouseEvent e) { ((JLabel)e.getSource()).setBorder(BorderFactory.createLineBorder(new Color(225,225,225), 1)); } }); p.add(ico[i]); } p.addMouseListener(new MouseAdapter(){ @Override public void mouseExited(MouseEvent e) { getObj().dispose(); } }); } @Override public void setVisible(boolean show) { if (show) { determineAndSetLocation(); } super.setVisible(show); } private void determineAndSetLocation() { Point loc = owner.btnemoji.getLocationOnScreen();/*控件相对于屏幕的位置*/ setBounds(loc.x-getPreferredSize().width/3, loc.ygetPreferredSize().height, getPreferredSize().width, getPreferredSize().height); } private JWindow getObj(){ return this; } } package chatroom.client; import java.awt.Color; import java.awt.EventQueue; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; import chatroom.msg.*; public class UpperTextPane extends JTextPane { /** * */ private static final long serialVersionUID = 1L; StyledDocument doc; SimpleDateFormat sf; String username; public UpperTextPane(String username) { this.doc=this.getStyledDocument(); this.sf = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss"); this.username=username; this.setEditable(false); this.setSize(500, 300); } protected void addsenttitle(boolean unicast, String sender){ SimpleAttributeSet attrSet=new SimpleAttributeSet(); String mystring= sender + "-" + sf.format(new Date())+"\n"; int posstart=doc.getLength(); StyleConstants.setFontFamily(attrSet, "SansSerif"); StyleConstants.setBold(attrSet, false); StyleConstants.setItalic(attrSet, false); StyleConstants.setFontSize(attrSet, 12); if (unicast){ StyleConstants.setForeground(attrSet, Color.RED); }else{ StyleConstants.setForeground(attrSet, Color.BLUE); } StyleConstants.setAlignment(attrSet, StyleConstants.ALIGN_RIGHT); try { doc.insertString(doc.getLength(), mystring, attrSet); doc.setParagraphAttributes(posstart, mystring.length(), attrSet, true); } catch (BadLocationException e) { // TODO Auto-generated catch block System.out.println(e); } this.setCaretPosition(doc.getLength()); } protected void addsenttext(String text){ SimpleAttributeSet attrSet=new SimpleAttributeSet(); String mystring= text+"\n"; int posstart=doc.getLength(); // StyleConstants.setFontFamily(attrSet, "Serif"); StyleConstants.setBold(attrSet, false); StyleConstants.setItalic(attrSet, false); StyleConstants.setFontSize(attrSet, 14); StyleConstants.setForeground(attrSet, Color.BLACK); StyleConstants.setForeground(attrSet, Color.BLUE); StyleConstants.setAlignment(attrSet, StyleConstants.ALIGN_RIGHT); try { doc.insertString(doc.getLength(), mystring, attrSet); doc.setParagraphAttributes(posstart, mystring.length(), attrSet, true); } catch (BadLocationException e) { // TODO Auto-generated catch block System.out.println(e); } this.setCaretPosition(doc.getLength()); } protected void addreceivedtitle(boolean unicast, String sender){ SimpleAttributeSet attrSet=new SimpleAttributeSet(); String mystring= sender + "-" + sf.format(new Date())+"\n"; int posstart=doc.getLength(); StyleConstants.setFontFamily(attrSet, "SansSerif"); StyleConstants.setBold(attrSet, false); StyleConstants.setItalic(attrSet, false); StyleConstants.setFontSize(attrSet, 12); if (unicast){ StyleConstants.setForeground(attrSet, Color.RED); }else{ StyleConstants.setForeground(attrSet, Color.BLUE); } StyleConstants.setAlignment(attrSet, StyleConstants.ALIGN_LEFT); try { doc.insertString(doc.getLength(), mystring, attrSet); doc.setParagraphAttributes(posstart, mystring.length(), attrSet, true); } catch (BadLocationException e) { // TODO Auto-generated catch block System.out.println(e); } this.setCaretPosition(doc.getLength()); } protected void addreceivedtext(String text){ SimpleAttributeSet attrSet=new SimpleAttributeSet(); String mystring= text+"\n"; int posstart=doc.getLength(); // StyleConstants.setFontFamily(attrSet, "Serif"); StyleConstants.setBold(attrSet, false); StyleConstants.setItalic(attrSet, false); StyleConstants.setFontSize(attrSet, 14); StyleConstants.setForeground(attrSet, Color.BLACK); StyleConstants.setForeground(attrSet, Color.BLUE); StyleConstants.setAlignment(attrSet, StyleConstants.ALIGN_LEFT); try { doc.insertString(doc.getLength(), mystring, attrSet); doc.setParagraphAttributes(posstart, mystring.length(), attrSet, true); } catch (BadLocationException e) { // TODO Auto-generated catch block System.out.println(e); } this.setCaretPosition(doc.getLength()); } protected void addmiddletext(String text){ SimpleAttributeSet attrSet=new SimpleAttributeSet(); String mystring= text+"\n"; int posstart=doc.getLength(); // StyleConstants.setFontFamily(attrSet, "Monospaced"); StyleConstants.setBold(attrSet, false); StyleConstants.setItalic(attrSet, false); StyleConstants.setFontSize(attrSet, 14); StyleConstants.setForeground(attrSet, Color.GRAY); StyleConstants.setForeground(attrSet, Color.BLUE); StyleConstants.setAlignment(attrSet, StyleConstants.ALIGN_CENTER); try { doc.insertString(doc.getLength(), mystring, attrSet); doc.setParagraphAttributes(posstart, mystring.length(), attrSet, true); } catch (BadLocationException e) { // TODO Auto-generated catch block System.out.println(e); } this.setCaretPosition(doc.getLength()); } protected void addimageicon(boolean selfsent,String printedname,int imagenum,boolean unicast){ String fileName= "defaultemojis/"+imagenum+".gif"; if (selfsent){ this.addsenttitle(unicast, printedname); this.addsenttext("\n"); }else { this.addreceivedtitle(unicast, printedname); this.addreceivedtext("\n"); } this.setCaretPosition(doc.getLength()-1); this.insertIcon(new ImageIcon(this.getClass().getResource(fileName))); this.setCaretPosition(doc.getLength()); } public void upperselftest(){ this.addsenttitle(true, "unicast"); this.addsenttext("unicast sample text"); this.addsenttitle(false, "broadcast"); this.addsenttext("broadcast sample text"); this.addreceivedtitle(true, "unicastsender"); this.addreceivedtext("unicast sample text"); this.addimageicon(false, "imagetestuser", 48, true); this.addreceivedtitle(false, "broadcastsender"); this.addreceivedtext("broadcast sample text"); this.addmiddletext("some body have just log in"); this.addimageicon(true, "imagetestuser", 1, true); } // public void HandleTextObject(TextObject to){ String msg = uname + " " + sf.format(new Date()); } } /////////////////////////////////////////////////msg//////////////////////////////////////////////////////////// package chatroom.msg; import java.io.Serializable; public class DataObject implements Serializable{ private String message; public DataObject(){} public DataObject(String message){ setMessage(message); } public void setMessage(String message){ this.message = message; } public String getMessage(){ return message; } } package chatroom.msg; import java.io.Serializable; public class ImageObject extends DataObject implements Serializable { /** * */ private static final long serialVersionUID = 1L; private int imagenum; public int getImagenum() { return imagenum; } public void setImagenum(int imagenum) { this.imagenum = imagenum; } public ImageObject(String Sender, String Reciever, int imagenum){ this.setMessage("superman90|image|unicast|"+Sender+"|"+Reciever); this.setImagenum(imagenum); } public ImageObject(String Sender, int imagenum){ this.setMessage("superman90|image|broadcast|"+Sender); this.setImagenum(imagenum); } } package chatroom.msg; public class ImagePositionandNum { private int num; private int pos; public ImagePositionandNum(int pos, int num){ this.setPos(pos); this.setNum(num); } public int getNum() { return num; } public void setNum(int num) { this.num = num; } public int getPos() { return pos; } public void setPos(int pos) { this.pos = pos; } } package chatroom.msg; import java.awt.Color; import java.io.Serializable; public class Line implements Serializable{ /** * */ private static final long serialVersionUID = 1L; int startx, starty, endx, endy; Color color = null; public Color getColor() { return color; } public void setColor(Color color) { this.color = color; } public Line(){} public Line(int sx, int sy, int ex, int ey, Color color){ setStartX(sx); setStartY(sy); setEndX(ex); setEndY(ey); setColor(color); } public void setStartX(int sx){ startx = sx; } public void setStartY(int sy){ starty = sy; } public void setEndX(int ex){ endx = ex; } public void setEndY(int ey){ endy = ey; } public int getStartX(){ return startx; } public int getStartY(){ return starty; } public int getEndX(){ return endx; } public int getEndY(){ return endy; } } package chatroom.msg; import java.io.Serializable; import java.util.ArrayList; public class LinesObject extends DataObject implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private ArrayList<Line> lines; public LinesObject(String Sender, String Reciever, ArrayList<Line> lines){ this.setMessage("superman90|lines|unicast|"+Sender+"|"+Reciever); this.setLines(lines); } public LinesObject(String Sender, ArrayList<Line> lines){ this.setMessage("superman90|lines|broadcast|"+Sender); this.setLines(lines); } public ArrayList<Line> getLines() { return lines; } public void setLines(ArrayList<Line> lines) { this.lines = lines; } } package chatroom.msg; import java.io.Serializable; import java.util.ArrayList; public class TextObject extends DataObject implements Serializable { /** * */ private static final long serialVersionUID = 1L; private String text; public TextObject(String Sender, String Reciever, String text){ this.setMessage("superman90|text|unicast|"+Sender+"|"+Reciever); this.setText(text); } public TextObject(String Sender, String text){ this.setMessage("superman90|text|broadcast|"+Sender); this.setText(text); } // private ArrayList<ImagePositionandNum> images; // public TextObject(String Sender, String Reciever, String text, ArrayList<ImagePositionandNum> images){ // this.setMessage("superman90|text|unicast|"+Sender+"|"+Reciever); // this.setText(text); // this.setImages(images); // } // // public TextObject(String Sender, String text, ArrayList<ImagePositionandNum> images){ // this.setMessage("superman90|text|broadcast|"+Sender); // this.setText(text); // this.setImages(images); // } public String getText() { return text; } public void setText(String text) { this.text = text; } // // // // // // // public ArrayList<ImagePositionandNum> getImages() { return images; } public void setImages(ArrayList<ImagePositionandNum> images) { this.images = images; } } package chatroom.msg; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; public class UserListObject extends DataObject implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private Date senttime; private ArrayList<String> userlist; private boolean hasnewlyregistered=false; private boolean hasnewlylogouted=false; String newlyregistered=null; String newlylogouted=null; /** * client constructor * construct a msg to be sent to server to require current user list * @param Sender who require the userlist */ public UserListObject(String Sender){ this.setMessage("superman90|requireuserlist|"+Sender); this.setSenttime(new Date()); this.setUserlist(null); } /** * server constructor * construct a msg to be sent to client containning current user list * @param the current userlist to be sent */ public UserListObject(ArrayList<String> userlist){ this.setMessage("superman90|userlist"); this.setSenttime(new Date()); this.setUserlist(userlist); } /** * server constructor * construct a msg to be sent to client containning current user list * @param the current userlist to be sent and hasnewlyregistered newlyregistered hasnewlylogouted newlylogouted */ public UserListObject(ArrayList<String> userlist, boolean hasnewlyregistered, String newlyregistered, boolean hasnewlylogouted, String newlylogouted){ this.setMessage("superman90|userlist"); this.setSenttime(new Date()); this.setUserlist(userlist); this.setHasnewlyregistered(hasnewlyregistered); this.setNewlyregistered(newlyregistered); this.setHasnewlylogouted(hasnewlylogouted); this.setNewlylogouted(newlylogouted); } public Date getSenttime() { return senttime; } public void setSenttime(Date senttime) { this.senttime = senttime; } public ArrayList<String> getUserlist() { return userlist; } public void setUserlist(ArrayList<String> userlist) { this.userlist = userlist; } public boolean isHasnewlyregistered() { return hasnewlyregistered; } public void setHasnewlyregistered(boolean hasnewlyregistered) { this.hasnewlyregistered = hasnewlyregistered; } public boolean isHasnewlylogouted() { return hasnewlylogouted; } public void setHasnewlylogouted(boolean hasnewlylogouted) { this.hasnewlylogouted = hasnewlylogouted; } public String getNewlyregistered() { return newlyregistered; } public void setNewlyregistered(String newlyregistered) { this.newlyregistered = newlyregistered; } public String getNewlylogouted() { return newlylogouted; } public void setNewlylogouted(String newlylogouted) { this.newlylogouted = newlylogouted; } } ////////////////////////////////////////////////////////////server//////////////////////////////////////////////////// /** * */ package chatroom.server; /** * * @author superman90 * */ import java.io.ObjectOutputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.HashMap; import java.util.Scanner; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class ServerEngine extends Thread{ private HashMap<String,ObjectOutputStream> serverhashmap = new HashMap<>(); private Lock hashmaplock =new ReentrantLock(); private ServerSocket serversocket=null; private int serverport= 20000; private int totaluser=0; // // public ServerEngine() { super(); init(); } public ServerEngine(int serverport) { super(); this.serverport = serverport; init(); } private void init(){ } @Override public void run() { System.out.println("ServerEngine is running, port: "+serverport); try{ try{ serversocket = new ServerSocket(serverport); while (!Thread.currentThread().isInterrupted()){ Socket incoming = serversocket.accept( ); System.out.println("ServerEngine"+serverport+" : a new socket is created"); new SocketHandler(serverhashmap,hashmaplock,incoming,++totaluser).start(); } } finally{ System.out.println("ServerEngine is closing, port: "+serverport); if (serversocket!= null){ serversocket.close(); } } } catch (Exception e){ System.out.println("ServerEngine: "+e); } System.out.println("ServerEngine"+serverport+" existing! "); } public static void main(String[] args) { Thread oneserver = new ServerEngine(); oneserver.start(); Scanner in=new Scanner(System.in); String inputline; boolean running=true; while (running){ inputline=in.nextLine(); if (inputline.equalsIgnoreCase("q")){ oneserver.interrupt(); running =false; break; } } System.exit(-1); } } /** * */ package chatroom.server; import java.util.*; /** * @author superman90 * */ public class SeverEntry { enum Status { RUNNING("RUNNING"),STOP("STOPPED"); private String text; private Status(String s){this.text=s;} public String toString(){return text;} }; public static void echo(Object o){ System.out.println(o); } /** * @param args */ public static void main(String[] args) { boolean running=true; Status status=Status.STOP; Scanner in=new Scanner(System.in); try { String inputline; while (running) { inputline = in.nextLine(); if (inputline.equalsIgnoreCase("q")) { if (status.equals(Status.RUNNING)){ status=Status.STOP; } echo("CURRENT STATUS: "+status+ "and existing~"); running = false; break; }else if (inputline.equalsIgnoreCase("info")) { echo("SERVER STATUS INFO: "+status); int n = Thread.activeCount(); Thread[] mythreads= new Thread[n]; Thread.enumerate(mythreads); echo(n); for (int i=0;i<n;i++){ echo(mythreads[i].getName()); echo(mythreads[i]); } }else if (inputline.equalsIgnoreCase("start")){ // status=Status.RUNNING; echo("CURRENT STATUS: "+status); }else if (inputline.equalsIgnoreCase("stop")){ status=Status.STOP; echo("CURRENT STATUS: "+status); } else { echo("Don't understand: " + inputline); } } } finally{ in.close(); } } } /** * */ package chatroom.server; import java.io.*; import java.net.*; import java.util.ArrayList; import java.util.Iterator; import java.util.HashMap; import chatroom.msg.*; import java.util.concurrent.locks.Lock; /** * @author superman90 * */ public class SocketHandler extends Thread { HashMap<String,ObjectOutputStream> serverhashmap= null; Lock hashmaplock=null; Socket mysocket = null; //sequence number for anonymous user int myseqnumber; String username; boolean registered=false; ObjectInputStream myobjectin = null; ObjectOutputStream myobjectout =null; DataObject mydataobject= null; public SocketHandler( HashMap<String, ObjectOutputStream> serverhashmap, Lock thehashmaplock, Socket mysocket, int num) { super(); this.serverhashmap = serverhashmap; this.mysocket = mysocket; this.hashmaplock=thehashmaplock; this.myseqnumber=num; this.username="AnonymousUser"+myseqnumber; } ////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////LOCKED FUNCTION//////////////////////////////////////////// private void broadcast(DataObject obj){ this.hashmaplock.lock(); try{ Iterator<ObjectOutputStream> it = serverhashmap.values().iterator(); while(it.hasNext()){ ObjectOutputStream currentoutput = it.next(); if (!currentoutput.equals(this.myobjectout)){ try{ currentoutput.writeObject(obj); currentoutput.reset(); }catch(IOException e){ System.out.println("SocketHandler broadcast: "+e.getMessage()); } } } }finally{ this.hashmaplock.unlock(); } } private void unicast(DataObject obj, String name){ this.hashmaplock.lock(); try{ if (this.serverhashmap.containsKey(name)){ ObjectOutputStream theobjectout=this.serverhashmap.get(name); try{ theobjectout.writeObject(obj); theobjectout.reset(); }catch(IOException e){ System.out.println("SocketHandler unicast: "+e.getMessage()); } } }finally{ this.hashmaplock.unlock(); } } private void unicast_self(DataObject obj){ this.hashmaplock.lock(); try{ try{ this.myobjectout.writeObject(obj); this.myobjectout.reset(); }catch(IOException e){ System.out.println("SocketHandler unicast_self: "+e.getMessage()); } }finally{ this.hashmaplock.unlock(); } } private boolean register_a_user(){ this.hashmaplock.lock(); try{ if (serverhashmap.putIfAbsent(this.username, this.myobjectout)==null){ System.out.println(username+" registered"+serverhashmap.containsKey(this.username)); return true; }else{ return false; } }finally{ this.hashmaplock.unlock(); } } private void unicast_userlist(String receiver){ this.hashmaplock.lock(); try{ try{ ArrayList<String> myuserlist=new ArrayList<String>(this.serverhashmap.keySet()); UserListObject userlistobject; ObjectOutputStream theobjectout; userlistobject=new UserListObject(myuserlist); theobjectout=this.serverhashmap.get(receiver); theobjectout.writeObject(userlistobject); theobjectout.reset(); }catch(IOException e){ System.out.println("SocketHandler unicast_userlist: "+e.getMessage()); } }finally{ this.hashmaplock.unlock(); } } private void broadcast_userlist( boolean hasnewlyregistered, String newlyregistered, boolean hasnewlylogouted, String newlylogouted){ this.hashmaplock.lock(); try{ ArrayList<String> myuserlist=new ArrayList<String>(this.serverhashmap.keySet()); UserListObject userlistobject; userlistobject=new UserListObject(myuserlist,hasnewlyregistered,newlyregistered,hasnewlylogouted,newlylo gouted); Iterator<ObjectOutputStream> it = serverhashmap.values().iterator(); while(it.hasNext()){ ObjectOutputStream currentoutput = it.next(); if (!currentoutput.equals(this.myobjectout)){ try{ currentoutput.writeObject(userlistobject); currentoutput.reset(); }catch(IOException e){ System.out.println("SocketHandler broadcast_userlist: "+e.getMessage()); } } } }finally{ this.hashmaplock.unlock(); } } ////////////////////////////END OF LOCKED FUNCTION//////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////// private void msgparser(){ String[] header=this.mydataobject.getMessage().split("[|]"); if ((header.length>0)&&(header[0].equalsIgnoreCase("superman90"))){ //register handler if (header[1].equalsIgnoreCase("register")&&(!this.registered)){ if (header[2]!=null){ this.username=header[2]; } if (register_a_user()){ this.registered=true; this.unicast_self(new DataObject("superman90|"+"reregister|"+"success|"+this.username)); this.broadcast_userlist(true, this.username, false, null); }else{ this.username="AnonymousUser"+myseqnumber; this.unicast_self(new DataObject("superman90|"+"reregister|"+"fail|"+this.username)); } //require anonymous name }else if (header[1].equalsIgnoreCase("requirename")&&(!this.registered)){ this.unicast_self(new DataObject("superman90|"+"rerequirename|"+this.username)); //logout handler }else if (this.registered && header[1].equalsIgnoreCase("logout")){ this.unicast_self(new DataObject("superman90|"+"relogout|"+this.username)); Thread.currentThread().interrupt(); //answer to requireuserlist }else if (this.registered && header[1].equalsIgnoreCase("requireuserlist")){ if (header[2]!=null){ this.unicast_userlist(header[2]); } }else if (this.registered && ( (header[1].equalsIgnoreCase("text"))|| (header[1].equalsIgnoreCase("image"))|| (header[1].equalsIgnoreCase("lines")) )){ if (header[2].equals("broadcast")){ this.broadcast(mydataobject); }else{ this.unicast(mydataobject, header[4]); } } } } @Override public void run() { try{ myobjectin = new ObjectInputStream(mysocket.getInputStream()); myobjectout = new ObjectOutputStream(mysocket.getOutputStream()); while (!Thread.currentThread().isInterrupted()){ mydataobject = (DataObject) myobjectin.readObject(); if (mydataobject!=null){ System.out.println("a ServerHandler is processing a message: "+mydataobject.getMessage()); msgparser(); } } }catch (Exception e){ System.out.println(e); }finally{ if (this.registered){ this.hashmaplock.lock(); try{ serverhashmap.remove(this.username); }finally { this.hashmaplock.unlock(); } } try{ this.broadcast_userlist(false, null,true, this.username); myobjectin.close(); myobjectout.close(); mysocket.close(); }catch(IOException e){ System.out.println(e.getMessage()); } } } }