仿QQ聊天軟體及原始碼java版
一直以來,很多java的同志們都沒有一個完整資料來參考。把原始碼貼出來,大家共享!
import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dialog; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.GridLayout; import java.awt.Image; import java.awt.Insets; import java.awt.MenuItem; import java.awt.PopupMenu; import java.awt.Rectangle; import java.awt.SystemTray; import java.awt.Toolkit; import java.awt.TrayIcon; import java.awt.TrayIcon.MessageType; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; 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.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; import java.net.SocketException; import java.net.UnknownHostException; import java.util.Date; import java.util.Scanner; import java.util.Stack; import java.util.prefs.Preferences; import javax.swing.BoxLayout; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JDialog; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JMenuItem; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JPopupMenu; import javax.swing.JProgressBar; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.JToggleButton; import javax.swing.ScrollPaneConstants; import javax.swing.SwingConstants; import javax.swing.UIManager; import javax.swing.border.BevelBorder; import javax.swing.border.Border; import javax.swing.border.EmptyBorder; import javax.swing.border.TitledBorder; import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreePath; public class EQ extends JDialog{ private JTextField ipEndTField; private JTextField ipStartTField; private JTextField userNameTField;//使用者框 private JPasswordField passwordTField;//密碼框 private JTextField placardPathTField;//placard:公告 private JTextField updatePathTField;//更新路徑 private JTextField pubPathTField; public static EQ frame = null; private ChatTree chatTree; private JPopupMenu popupMenu;//右鍵選單 private JTabbedPane tabbedPane;//分頁面板 private JToggleButton searchUserButton;//搜尋使用者按鈕 private JProgressBar progressBar;//滾動條 private JList faceList; private JButton selectInterfaceOKButton; private DatagramSocket ss;//資料報插座 private final JLabel stateLabel; private static String user_dir; private static File localFile; private static File netFile; private String netFilePath; private JButton messageAlertButton; private Stack<String> messageStack;////Stack 類表示後進先出(LIFO)的物件堆疊。 private ImageIcon messageAlertIcon; private ImageIcon messageAlertNullIcon; private Rectangle location; public static TrayIcon trayicon; private Dao dao; //Preferences.systeRoot:返回系統的根首選項節點 Preferences:引數選擇 public final static Preferences preferences = Preferences.systemRoot(); private JButton userInfoButton; //---------------------------------------------------------------------------------- public static void main(String[] args){ try{ String laf = preferences.get("lookAndFeel", "java預設"); if(laf.indexOf("當前系統") > -1){ UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } EQ frame = new EQ(); frame.setVisible(true); frame.SystemTrayInitial();// 初始化系統欄 frame.server(); frame.checkPlacard(); }catch(Exception e){ e.printStackTrace(); } } //---------------------------------------------------------------------------------- public EQ(){ super(new JFrame()); frame = this; dao = Dao.getDao(); location = dao.getLocation(); setTitle("EQ聊天"); setBounds(location); progressBar = new JProgressBar(); //BevelBorder:該類實現簡單的雙線斜面邊框。Bevel:斜面 lowered:凹入斜面型別。 progressBar.setBorder(new BevelBorder(BevelBorder.LOWERED)); tabbedPane = new JTabbedPane(); popupMenu = new JPopupMenu(); chatTree = new ChatTree(this); user_dir = System.getProperty("user.dir");// 程式執行路徑用於系統更新 localFile = new File(user_dir + File.separator + "EQ.jar");// 本地EQ檔案 stateLabel = new JLabel();// 狀態列標籤 this.addWindowListener(new FrameWindowListener());// 新增窗體監視器 this.addComponentListener(new ComponentAdapter(){ public void componentResized(final ComponentEvent e){ saveLocation(); } public void componentMoved(final ComponentEvent e){ saveLocation(); } }); try{// 啟動通訊服務埠 ss = new DatagramSocket(1111); }catch(SocketException e2){ if(e2.getMessage().startsWith("Address already in use")){ showMessageDialog("服務埠被佔用,或者本軟體已經執行。"); } System.exit(0); } {// 初始化公共資訊按鈕 messageAlertIcon = new ImageIcon(EQ.class.getResource("/image/messageAlert.gif")); messageAlertNullIcon = new ImageIcon(EQ.class.getResource("/image/messageAlertNull20.gif")); messageStack = new Stack<String>(); messageAlertButton = new JButton(); messageAlertButton.setHorizontalAlignment(SwingConstants.RIGHT); messageAlertButton.setContentAreaFilled(false);//不填充內容區域 final JPanel BannerPanel = new JPanel(); BannerPanel.setLayout(new BorderLayout()); this.add(BannerPanel,BorderLayout.NORTH); userInfoButton = new JButton(); BannerPanel.add(userInfoButton,BorderLayout.WEST); userInfoButton.setMargin(new Insets(0,0,0,10));//Margin:邊距 insets:插入 initUserInfoButton();// 初始化本地使用者頭像按鈕 BannerPanel.add(messageAlertButton,BorderLayout.CENTER); messageAlertButton.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { if(!messageStack.empty()){ showMessageDialog(messageStack.pop());//堆疊頂部的物件(Vector 物件中的最後一項)。 } } }); messageAlertButton.setIcon(messageAlertIcon); showMessageBar(); } this.add(tabbedPane,BorderLayout.CENTER); tabbedPane.setTabPlacement(SwingConstants.LEFT);//設定此選項卡窗格的選項卡布局 ImageIcon userTicon = new ImageIcon(EQ.class.getResource("/image/tabIcon/tabLeft.PNG")); tabbedPane.addTab(null,userTicon,createUserList(),"使用者列表"); ImageIcon sysOTicon = new ImageIcon(EQ.class.getResource("/image/tabIcon/tabLeft2.PNG")); tabbedPane.addTab(null, sysOTicon, createSysToolPanel(), "系統操作"); ImageIcon sysSTicon = new ImageIcon(EQ.class.getResource("/image/tabIcon/tabLeft3.png")); tabbedPane.addTab(null, sysSTicon, createSysSetPanel(), "系統設定"); this.setAlwaysOnTop(true);//總在頂部 } //---------------------------------------------------------------------------------- private JScrollPane createSysSetPanel(){//系統設定面板 final JPanel sysSetPanel = new JPanel(); JScrollPane scrollPane = new JScrollPane(sysSetPanel); sysSetPanel.setLayout(new BoxLayout(sysSetPanel,BoxLayout.Y_AXIS)); scrollPane.setBorder(new EmptyBorder(0,0,0,0)); final JPanel sysPathPanel = new JPanel(); sysPathPanel.setMaximumSize(new Dimension(600,200)); sysPathPanel.setBorder(new TitledBorder("系統路徑"));//title - 邊框應顯示的標題 sysPathPanel.setLayout(new GridLayout(0,1)); sysSetPanel.add(sysPathPanel); sysPathPanel.add(new JLabel("程序升級路徑")); updatePathTField = new JTextField(preferences.get("updatePath", "請輸入路徑")); sysPathPanel.add(updatePathTField); sysPathPanel.add(new JLabel("系統公告路徑:")); placardPathTField = new JTextField(preferences.get("placardPath","請輸入路徑")); sysPathPanel.add(placardPathTField); sysPathPanel.add(new JLabel("公共程式路徑:")); pubPathTField = new JTextField(preferences.get("pubPath", "請輸入路徑")); sysPathPanel.add(pubPathTField); final JButton pathOKButton = new JButton("確定"); pathOKButton.setActionCommand("sysOK"); pathOKButton.addActionListener(new SysSetPanelOKListener()); sysSetPanel.add(pathOKButton); final JPanel loginPanel = new JPanel(); loginPanel.setMaximumSize(new Dimension(600, 90)); loginPanel.setBorder(new TitledBorder("登入升級伺服器")); final GridLayout gridLayout_1 = new GridLayout(0, 1); gridLayout_1.setVgap(5); loginPanel.setLayout(gridLayout_1); sysSetPanel.add(loginPanel); final JPanel panel_7 = new JPanel(); panel_7.setLayout(new BoxLayout(panel_7, BoxLayout.X_AXIS)); loginPanel.add(panel_7); panel_7.add(new JLabel("使用者名稱:")); userNameTField = new JTextField(preferences.get("username", "請輸入使用者名稱")); panel_7.add(userNameTField); final JPanel panel_8 = new JPanel(); panel_8.setLayout(new BoxLayout(panel_8, BoxLayout.X_AXIS)); loginPanel.add(panel_8); panel_8.add(new JLabel("密 碼:")); passwordTField = new JPasswordField("*****"); panel_8.add(passwordTField); final JButton loginOKButton = new JButton("確定"); sysSetPanel.add(loginOKButton); loginOKButton.setActionCommand("loginOK"); loginOKButton.addActionListener(new SysSetPanelOKListener()); final JPanel ipPanel = new JPanel(); final GridLayout gridLayout_2 = new GridLayout(0, 1); gridLayout_2.setVgap(5); ipPanel.setLayout(gridLayout_2); ipPanel.setMaximumSize(new Dimension(600, 90)); ipPanel.setBorder(new TitledBorder("IP搜尋範圍")); sysSetPanel.add(ipPanel); final JPanel panel_5 = new JPanel(); panel_5.setLayout(new BoxLayout(panel_5, BoxLayout.X_AXIS)); ipPanel.add(panel_5); panel_5.add(new JLabel("起始IP:")); ipStartTField = new JTextField(preferences.get("ipStart", "192.168.0.1")); panel_5.add(ipStartTField); final JPanel panel_6 = new JPanel(); panel_6.setLayout(new BoxLayout(panel_6, BoxLayout.X_AXIS)); ipPanel.add(panel_6); panel_6.add(new JLabel("終止IP:")); ipEndTField = new JTextField(preferences.get("ipEnd", "192.168.1.255")); panel_6.add(ipEndTField); final JButton ipOKButton = new JButton("確定"); ipOKButton.setActionCommand("ipOK"); ipOKButton.addActionListener(new SysSetPanelOKListener()); sysSetPanel.add(ipOKButton); return scrollPane; } //---------------------------------------------------------------------------------- private JScrollPane createUserList(){// 使用者列表面板 JScrollPane scrollPane = new JScrollPane(); scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); addUserPopup(chatTree,getPopupMenu());// 為使用者新增彈出選單 scrollPane.setViewportView(chatTree); scrollPane.setBorder(new EmptyBorder(0,0,0,0)); chatTree.addMouseListener(new ChatTreeMouseListener()); return scrollPane; } //---------------------------------------------------------------------------------- private JScrollPane createSysToolPanel() {// 系統工具面板 JPanel sysToolPanel = new JPanel(); // 系統工具面板 sysToolPanel.setLayout(new BorderLayout()); JScrollPane sysToolScrollPanel = new JScrollPane(); sysToolScrollPanel .setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); sysToolScrollPanel.setBorder(new EmptyBorder(0, 0, 0, 0)); sysToolScrollPanel.setViewportView(sysToolPanel); sysToolPanel.setBorder(new BevelBorder(BevelBorder.LOWERED)); JPanel interfacePanel = new JPanel(); sysToolPanel.add(interfacePanel, BorderLayout.NORTH); interfacePanel.setLayout(new BorderLayout()); interfacePanel.setBorder(new TitledBorder("介面選擇-再次啟動生效")); faceList = new JList(new String[]{"當前系統", "java預設"}); interfacePanel.add(faceList); faceList.setBorder(new BevelBorder(BevelBorder.LOWERED)); final JPanel interfaceSubPanel = new JPanel(); interfaceSubPanel.setLayout(new FlowLayout()); interfacePanel.add(interfaceSubPanel, BorderLayout.SOUTH); selectInterfaceOKButton = new JButton("確定"); selectInterfaceOKButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { preferences.put("lookAndFeel", faceList.getSelectedValue().toString()); JOptionPane.showMessageDialog(EQ.this, "重新執行本軟體後生效"); } }); interfaceSubPanel.add(selectInterfaceOKButton); JPanel searchUserPanel = new JPanel(); // 使用者搜尋面板 sysToolPanel.add(searchUserPanel); searchUserPanel.setLayout(new BorderLayout()); final JPanel searchControlPanel = new JPanel(); searchControlPanel.setLayout(new GridLayout(0, 1)); searchUserPanel.add(searchControlPanel, BorderLayout.SOUTH); final JList searchUserList = new JList(new String[]{"檢測使用者列表"});// 新新增使用者列表 final JScrollPane scrollPane_2 = new JScrollPane(searchUserList); scrollPane_2.setDoubleBuffered(true); searchUserPanel.add(scrollPane_2); searchUserList.setBorder(new BevelBorder(BevelBorder.LOWERED)); searchUserButton = new JToggleButton(); searchUserButton.setText("搜尋新使用者"); searchUserButton.addActionListener(new SearchUserActionListener(searchUserList)); searchControlPanel.add(progressBar); searchControlPanel.add(searchUserButton); searchUserPanel.setBorder(new TitledBorder("搜尋使用者")); final JPanel sysUpdatePanel = new JPanel(); sysUpdatePanel.setOpaque(false); sysUpdatePanel.setLayout(new GridBagLayout()); sysUpdatePanel.setBorder(new TitledBorder("系統操作")); sysToolPanel.add(sysUpdatePanel, BorderLayout.SOUTH); final JButton sysUpdateButton = new JButton("系統更新"); final GridBagConstraints gridBagConstraints_1 = new GridBagConstraints(); gridBagConstraints_1.gridx = 0; gridBagConstraints_1.gridy = 0; sysUpdatePanel.add(sysUpdateButton, gridBagConstraints_1); sysUpdateButton.addActionListener(new SysUpdateListener());// 新增系統更新事件 final JLabel updateLabel = new JLabel("最近更新:"); final GridBagConstraints updateLabelLayout = new GridBagConstraints(); updateLabelLayout.gridy = 1; updateLabelLayout.gridx = 0; sysUpdatePanel.add(updateLabel, updateLabelLayout); final JLabel updateDateLabel = new JLabel();// 程式更新日期標籤 Date date = new Date(localFile.lastModified()); String dateStr = String.format("%tF %<tr", date); updateDateLabel.setText(dateStr); final GridBagConstraints updateDateLayout = new GridBagConstraints(); updateDateLayout.gridy = 2; updateDateLayout.gridx = 0; sysUpdatePanel.add(updateDateLabel, updateDateLayout); final JLabel updateStaticLabel = new JLabel("更新狀態:"); final GridBagConstraints updateStaticLayout = new GridBagConstraints(); updateStaticLayout.gridy = 3; updateStaticLayout.gridx = 0; sysUpdatePanel.add(updateStaticLabel, updateStaticLayout); final JLabel updateInfoLabel = new JLabel();// 版本資訊標籤 checkSysInfo(updateInfoLabel);// 呼叫檢測版本更新的方法 final GridBagConstraints gridBagConstraints_5 = new GridBagConstraints(); gridBagConstraints_5.gridy = 4; gridBagConstraints_5.gridx = 0; sysUpdatePanel.add(updateInfoLabel, gridBagConstraints_5); JPanel statePanel = new JPanel(); add(statePanel, BorderLayout.SOUTH); statePanel.setLayout(new BorderLayout()); statePanel.add(stateLabel); stateLabel.setText("總人數:" + chatTree.getRowCount()); return sysToolScrollPanel; } //---------------------------------------------------------------------------------- private void initUserInfoButton(){ try{ String ip = InetAddress.getLocalHost().getHostAddress(); User user = dao.getUser(ip); userInfoButton.setIcon(user.getIconImg()); userInfoButton.setText(user.getName()); userInfoButton.setIconTextGap(JLabel.RIGHT); userInfoButton.setToolTipText(user.getTipText()); userInfoButton.getParent().doLayout(); }catch(UnknownHostException e1){ e1.printStackTrace(); } } //---------------------------------------------------------------------------------- private void showMessageBar(){// 顯示公告資訊按鈕的執行緒 new Thread(new Runnable() { public void run() { while (true) { if (!messageStack.empty()) { try { messageAlertButton.setIcon(messageAlertNullIcon); messageAlertButton.setPreferredSize(new Dimension(20, 20)); Thread.sleep(500); messageAlertButton.setIcon(messageAlertIcon); Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } } else { try { Thread.sleep(3000); } catch (InterruptedException e) { e.printStackTrace(); } } } } }).start(); } //---------------------------------------------------------------------------------- private void checkSysInfo(final JLabel updateInfo){ new Thread(new Runnable(){ public void run(){ String info = ""; while(true){ try{ netFilePath = preferences.get("updatePath", "EQ.jar"); if(netFilePath.equals("EQ.jar")){ info = "<html><center><font color=red><b>無法登入</b><br>未設定升級路徑</font></center></html>"; updateInfo.setText(info); continue; } netFile = new File(netFilePath); if(netFile.exists()){ Date netDate = new Date(netFile.lastModified()); if(!localFile.exists()){ info = "<html><font color=blue>本地程式位置出錯!</font></html>"; }else{ Date localDate = new Date(localFile.lastModified()); if(netDate.after(localDate)){ info = "<html><font color=blue>網路上有最新程式!</font></html>"; pushMessage(info); }else{ info = "<html><font color=green>現在是最新程式!</font></html>"; } } }else{ info = "<html><center><font color=red><b>無法訪問</b><br>升級路徑</font></center></html>"; } updateInfo.setText(info); Thread.sleep(5*1000); }catch(InterruptedException e){ e.printStackTrace(); } } } }).start(); } //---------------------------------------------------------------------------------- class SearchUserActionListener implements ActionListener{ private final JList list; SearchUserActionListener(JList list){ this.list = list; } @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub if(searchUserButton.isSelected()){ searchUserButton.setText("停止搜尋"); new Thread(new Runnable(){ public void run(){ Resource.searchUsers(chatTree, progressBar,list, searchUserButton); } }).start(); }else{ searchUserButton.setText("搜尋新使用者"); } } } //---------------------------------------------------------------------------------- class SysSetPanelOKListener implements ActionListener{ @Override public void actionPerformed(ActionEvent e) { // TODO Auto-generated method stub String command = e.getActionCommand(); if(command.equals("sysOK")){ String updatePath = updatePathTField.getText(); String placardPath = placardPathTField.getText(); String pubPath = pubPathTField.getText(); preferences.put("updatePath", updatePath); // 設定系統升級路徑 preferences.put("placardPath", placardPath);// 設定系統公告路徑 preferences.put("pubPath", pubPath); // 設定公共程式路徑 JOptionPane.showMessageDialog(EQ.this, "系統設定儲存完畢"); } if (command.equals("loginOK")) { String username = userNameTField.getText(); String password = new String(passwordTField.getPassword()); preferences.put("username", username); // 設定系統升級路徑 preferences.put("password", password);// 設定系統公告路徑 JOptionPane.showMessageDialog(EQ.this, "登入設定儲存完畢"); } if (command.equals("ipOK")) { String ipStart = ipStartTField.getText(); String ipEnd = ipEndTField.getText(); try { InetAddress.getByName(ipStart); InetAddress.getByName(ipEnd); } catch (UnknownHostException e1) { JOptionPane.showMessageDialog(EQ.this, "IP地址格式錯誤"); return; } preferences.put("ipStart", ipStart); // 設定系統升級路徑 preferences.put("ipEnd", ipEnd);// 設定系統公告路徑 JOptionPane.showMessageDialog(EQ.this, "IP設定儲存完畢"); } } } //---------------------------------------------------------------------------------- private final class SysUpdateListener implements ActionListener{// 系統更新事件 @Override public void actionPerformed(final ActionEvent e) { // TODO Auto-generated method stub String username = preferences.get("username", null); String password = preferences.get("password", null); if(username == null || password == null){ pushMessage("未設定登入升級伺服器的使用者名稱或密碼"); return; } Resource.loginPublic(username, password); updateProject(); } } //---------------------------------------------------------------------------------- private class ChatTreeMouseListener extends MouseAdapter{// 使用者列表的監聽器 public void mouseClicked(final MouseEvent e){ if (e.getClickCount() == 2) { TreePath path = chatTree.getSelectionPath(); if (path == null) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) path .getLastPathComponent(); User user = (User) node.getUserObject(); try { TelFrame.getInstance(ss, new DatagramPacket(new byte[0], 0, InetAddress.getByName(user.getIp()), 1111), chatTree); } catch (IOException e1) { e1.printStackTrace(); } } } } //---------------------------------------------------------------------------------- private void server(){// 伺服器啟動方法 new Thread(new Runnable(){ public void run(){ while(true){ if(ss != null){ byte[] buf = new byte[4096]; DatagramPacket dp = new DatagramPacket(buf,buf.length); try{ ss.receive(dp); }catch(IOException e){ e.printStackTrace(); } TelFrame.getInstance(ss,dp,chatTree); } } } }).start(); } //---------------------------------------------------------------------------------- private void addUserPopup(Component component, final JPopupMenu popup){// 新增使用者彈出選單 component.addMouseListener(new MouseAdapter(){ public void mousePressed(MouseEvent e){ if(e.isPopupTrigger()){ showMenu(e); } } public void mouseReleased(MouseEvent e) { if (e.isPopupTrigger()) showMenu(e); } private void showMenu(MouseEvent e){ if(chatTree.getSelectionPaths() == null){ popupMenu.getComponent(0).setEnabled(false); popupMenu.getComponent(2).setEnabled(false); popupMenu.getComponent(3).setEnabled(false); popupMenu.getComponent(4).setEnabled(false); popupMenu.getComponent(5).setEnabled(false); }else{ if(chatTree.getSelectionPaths().length < 2){ popupMenu.getComponent(3).setEnabled(false); }else { popupMenu.getComponent(3).setEnabled(true); } popupMenu.getComponent(0).setEnabled(true); popupMenu.getComponent(2).setEnabled(true); popupMenu.getComponent(4).setEnabled(true); popupMenu.getComponent(5).setEnabled(true); } popup.show(e.getComponent(), e.getX(), e.getY()); } }); } //---------------------------------------------------------------------------------- private void saveLocation(){// 儲存主窗體位置的方法 location = getBounds(); dao.updateLocation(location); } //---------------------------------------------------------------------------------- protected JPopupMenu getPopupMenu(){// 建立使用者彈出選單 if (popupMenu == null) { popupMenu = new JPopupMenu(); popupMenu.setOpaque(false); } final JMenuItem rename = new JMenuItem(); popupMenu.add(rename); rename.addActionListener(new RenameActionListener()); rename.setText("更名"); final JMenuItem addUser = new JMenuItem(); addUser.addActionListener(new AddUserActionListener()); popupMenu.add(addUser); addUser.setText("新增使用者"); final JMenuItem delUser = new JMenuItem(); delUser.addActionListener(new delUserActionListener()); popupMenu.add(delUser); delUser.setText("刪除使用者"); final JMenuItem messagerGroupSend = new JMenuItem(); messagerGroupSend .addActionListener(new messagerGroupSendActionListener()); messagerGroupSend.setText("信使群發"); popupMenu.add(messagerGroupSend); final JMenuItem accessComputerFolder = new JMenuItem("訪問主機資源"); accessComputerFolder.setActionCommand("computer"); popupMenu.add(accessComputerFolder); accessComputerFolder .addActionListener(new accessFolderActionListener()); final JMenuItem accessPublicFolder = new JMenuItem(); popupMenu.add(accessPublicFolder); accessPublicFolder.setOpaque(false); accessPublicFolder.setText("訪問公共程式"); accessPublicFolder.setActionCommand("public"); accessPublicFolder.addActionListener(new accessFolderActionListener()); return popupMenu; } //---------------------------------------------------------------------------------- private void updateProject(){// 程式更新方法 netFilePath = preferences.get("updatePath", "EQ.jar"); if(netFilePath.equals("EQ.jar")){ pushMessage("未設定升級路徑"); return; } netFile = new File(netFilePath); localFile = new File(user_dir + File.separator + "EQ.jar"); if (localFile != null && netFile != null && netFile.exists() && localFile.exists()) { Date netDate = new Date(netFile.lastModified()); Date localDate = new Date(localFile.lastModified()); if (netDate.after(localDate)) { new Thread(new Runnable() { public void run() { try { Dialog frameUpdate = new UpdateFrame(); frameUpdate.setVisible(true); Thread.sleep(2000); FileInputStream fis = new FileInputStream(netFile); FileOutputStream fout = new FileOutputStream( localFile); int len = fis.available(); if (len > 0) { byte[] data = new byte[len]; if (fis.read(data) > 0) { fout.write(data); } } fis.close(); fout.close(); frameUpdate.setVisible(false); frameUpdate = null; showMessageDialog("更新完畢,請重新啟動程式。"); } catch (Exception e) { e.printStackTrace(); } } }).start(); } else { showMessageDialog("已經是最新的程式了。"); } } } //---------------------------------------------------------------------------------- private void checkPlacard() { // 檢測公告資訊方法 String placardDir = preferences.get("placardPath", null); if (placardDir == null) { pushMessage("未設定公告路徑"); return; } File placard = new File(placardDir); try { if (placard.exists() && placard.isFile()) { StringBuilder placardStr = new StringBuilder(); Scanner sc = new Scanner(new FileInputStream(placard)); while (sc.hasNextLine()) { placardStr.append(sc.nextLine()); } pushMessage(placardStr.toString()); } } catch (FileNotFoundException e) { pushMessage("公告路徑錯誤,或公告檔案不存在"); } } //---------------------------------------------------------------------------------- public void setStatic(String str){// 設定狀態列資訊 if(stateLabel != null){ stateLabel.setText(str); } } public void pushMessage(String info){// 堆壓資訊 if(!messageStack.contains(info)){ messageStack.push(info); } } private void showMessageDialog(String message){ JOptionPane.showMessageDialog(this, message); } //---------------------------------------------------------------------------------- private String showInputDialog(String str){// 顯示輸入對話方塊 String newName = JOptionPane.showInputDialog(this, "<html>輸入<font color=red>" + str + "</font>的新名字</html>"); return newName; } private class accessFolderActionListener implements ActionListener {// 訪問資源 public void actionPerformed(final ActionEvent e) { TreePath path = chatTree.getSelectionPath(); if (path == null) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) path .getLastPathComponent(); User user = (User) node.getUserObject(); String ip = "\\\\"+user.getIp(); String command = e.getActionCommand(); if (command.equals("computer")) { Resource.startFolder(ip); } if (command.equals("public")) { String serverPaeh = preferences.get("pubPath", null); if (serverPaeh == null) { pushMessage("未設定公共程式路徑"); return; } Resource.startFolder(serverPaeh); } } } private class RenameActionListener implements ActionListener {// 更名 public void actionPerformed(final ActionEvent e) { TreePath path = chatTree.getSelectionPath(); if (path == null) return; DefaultMutableTreeNode node = (DefaultMutableTreeNode) path .getLastPathComponent(); User user = (User) node.getUserObject(); String newName = showInputDialog(user.getName()); if (newName != null && !newName.isEmpty()) { user.setName(newName); dao.updateUser(user); DefaultTreeModel model = (DefaultTreeModel) chatTree.getModel(); model.reload(); chatTree.setSelectionPath(path); initUserInfoButton(); } } } private class FrameWindowListener extends WindowAdapter { public void windowClosing(final WindowEvent e) {// 系統關閉事件 setVisible(false); } } private class AddUserActionListener implements ActionListener { public void actionPerformed(final ActionEvent e) {// 新增使用者 String ip = JOptionPane.showInputDialog(EQ.this, "輸入新使用者IP地址"); if (ip != null) chatTree.addUser(ip, "add"); } } private class delUserActionListener implements ActionListener { public void actionPerformed(final ActionEvent e) {// 刪除使用者 chatTree.delUser(); } } private class messagerGroupSendActionListener implements ActionListener {// 信使群發 public void actionPerformed(final ActionEvent e) { String message = JOptionPane.showInputDialog(EQ.this, "請輸入群發信息", "信使群發", JOptionPane.INFORMATION_MESSAGE); if (message != null && !message.equals("")) { TreePath[] selectionPaths = chatTree.getSelectionPaths(); Resource.sendGroupMessenger(selectionPaths, message); } else if (message != null && message.isEmpty()) { JOptionPane.showMessageDialog(EQ.this, "不能傳送空資訊!"); } } } private void SystemTrayInitial() { // 系統欄初始化 if (!SystemTray.isSupported()) // 判斷當前系統是否支援系統欄 return; try { String title = "TT"; String company = "成都市同道科技有限公司"; SystemTray sysTray = SystemTray.getSystemTray(); Image image = Toolkit.getDefaultToolkit().getImage( EQ.class.getResource("/icons/sysTray.png"));// 系統欄圖示 trayicon = new TrayIcon(image, title + "\n" + company, createMenu()); trayicon.setImageAutoSize(true); trayicon.addActionListener(new SysTrayActionListener()); sysTray.add(trayicon); trayicon.displayMessage(title, company, MessageType.INFO); } catch (Exception e) { e.printStackTrace(); } } private PopupMenu createMenu() { // 建立系統欄選單的方法 PopupMenu menu = new PopupMenu(); MenuItem exitItem = new MenuItem("退出"); exitItem.addActionListener(new ActionListener() { // 系統欄退出事件 public void actionPerformed(ActionEvent e) { System.exit(0); } }); MenuItem openItem = new MenuItem("開啟"); openItem.addActionListener(new ActionListener() {// 系統欄開啟選單項事件 public void actionPerformed(ActionEvent e) { if (!isVisible()) { setVisible(true); toFront(); } else toFront(); } }); // 系統欄的訪問伺服器選單項事件 MenuItem publicItem = new MenuItem("訪問伺服器"); publicItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String serverPaeh = preferences.get("pubPath", null); if (serverPaeh == null) { pushMessage("未設定公共程式路徑"); return; } Resource.startFolder(serverPaeh); } }); menu.add(publicItem); menu.add(openItem); menu.addSeparator(); menu.add(exitItem); return menu; } class SysTrayActionListener implements ActionListener {// 系統欄雙擊事件 public void actionPerformed(ActionEvent e) { setVisible(true); toFront(); } } }
相關推薦
仿QQ聊天軟體及原始碼java版
一直以來,很多java的同志們都沒有一個完整資料來參考。把原始碼貼出來,大家共享! import java.awt.BorderLayout; import java.awt.Component; import java.awt.Dialog; import java.a
仿QQ聊天軟體2.0版
仿QQ聊天軟體2.0版 轉載請標明出處:牟尼的專欄 http://blog.csdn.net/u012027907 上次課設做了Java版的仿QQ聊天程式。這次軟體實訓,我們繼續完好了仿QQ聊天程式,將上次未完畢及不完好的地方
仿QQ聊天軟體java實現(一)
之前學java通訊的時候寫過簡單的通訊程式,但比較簡陋,於是重新寫了一個仿照QQ的聊天軟體,主要在介面上做了優化,增加了一些功能。實現的功能有註冊、登入、好友列表、分組、黑名單、新增好友、群列表、建立群、新增群、聊天氣泡、傳送文字、圖片、檔案、表情。 好了先上圖看下效果:
仿QQ聊天軟件2.0版
字段 col 12px ava 字體設置 pic 清華大學 環境 總結 版權聲明:本文為博主原創文章,未經博主允許不得轉載。 https://blog.csdn.net/u012027907/article/details/369528
網路程式設計(三)---- MFC 仿QQ聊天軟體
今天來八一八,MFC的SOCKET 程式設計,利用CSocket實現一個基於TCP實現一個QQ聊天程式。你會發現,MFC要比WIN32 簡單的多。但是如果你不理解具體API socket基礎知識,你可能會覺得有一點費解。 所以在開始之前 我還是請大家先看看http://bl
JAVA仿QQ聊天系統4.0(擴充套件韓順平的程式的功能及介面)附原始碼
下載連結 http://download.csdn.net/detail/qq245034548/8391381連結:https://pan.baidu.com/s/1btDApLQuHvLk44EtWKQygw 密碼:3ezf4 詳細設計4.1 系統程式流程如下
[原始碼和報告分享]基於java 的仿QQ聊天工具
概要設計 在客戶端:當用戶登入後,生成唯一的socket, 存放在Client實體類中,在整個客戶端就一個Client類和一個socket。有一個視窗控制器——ChatUIList,用來記錄使用者和好友聊天框是否開啟,當收到訊息後,首先在ChatUIList中查詢是否有好友的視窗,如果沒有則新建聊天框彈出並
仿QQ聊天程式(java)
仿QQ聊天程式 一、設計內容及要求 1.1綜述 A.系統概述 我們要做的就是類似QQ這樣的面向企業內部的聊天軟體,基本功能和QQ類似。首先,系統分為兩大部分,第一部分是客戶端,是使用者使用的部分,第二部分就是伺服器,所有的客戶端都是通過伺服器來進行使用者身份驗證
JAVA 仿QQ聊天程式
一、設計內容及要求 1.1綜述 A.系統概述 我們要做的就是類似QQ這樣的面向企業內部的聊天軟體,基本功能和QQ類似。首先,系統分為兩大部分,第一部分是客戶端,是使用者使用的部分,第二部分就是伺服器,所有的客戶端都是通過伺服器來進行使用者身份驗證及聊天
Socket實現仿QQ聊天(可部署於廣域網)附原始碼(2)-伺服器搭建
1.前言 這是本系列的第二篇文章,第一篇文章得到了很多朋友們的支援,在這裡表示非常的感謝。對於這一系列文章需要補充的是這只是一篇入門級別的Socket通訊文章,對於專業人員來說完全可以跳過。本文只介紹一些基本TCP通訊技術並使用該技術實現聊天功能。本篇文章實現聊
Java通訊-仿QQ聊天專案
前後歷時一個多月的Java實現聊天通訊專案-仿QQ聊天室基本告一段落,期間面對了很多問題,也有不同的解決方案,重寫了幾次核心程式碼,等等問題。現在在專案的結束之時,給自己做一個總結,算是一個回顧,算是一次提升,也是一次新的開始。 Github連結
仿QQ聊天工具(JAVA實現)專案總結
一、遇到的異常及解決辦法 1. org.hibernate.HibernateException:Could not parse configuration: /hibernate.cfg.xml ..省略 Caused by: org.dom4j.Docu
Netty 仿QQ聊天室 (實戰二)
Netty 聊天器(百萬級流量實戰二):仿QQ客戶端 瘋狂創客圈 Java 分散式聊天室【 億級流量】實戰系列之15 【部落格園 總入口 】 原始碼IDEA工程獲取連結:Java 聊天室 實戰 原始碼 寫在前面 大家好,我是作者尼恩。 今天是百萬級流量 Netty 聊天器 打造的系列文章的第二篇,
GFF高仿QQ客戶端及伺服器
一、GFF簡介 GFF是仿QQ介面,通訊基於SAEA.MessageSocket、SAEA.Http、SAEA.MVC實現包含客戶端和伺服器的程式,原始碼完全公開,專案原始碼地址:https://github.com/yswenli/GFF ,大家可以去我的github瞭解,歡迎follow,st
GFF高仿QQ客戶端及服務器
col ide {0} sed ogr ini 交流 包含 tor 一、GFF簡介 GFF是仿QQ界面,通信基於SAEA.MessageSocket、SAEA.Http、SAEA.MVC實現包含客戶端和服務器的程序,源碼完全公開,項目源碼地址:https://github
iOS感測器集錦、飛機大戰、開發除錯工具、強制更新、Swift仿QQ空間頭部等原始碼
iOS精選原始碼 飛機大作戰 iOS優質部落格 Apple於北京時間9月17日晚在官網釋出了Xcode 10正式版,QiShare團隊成員於9月18日中午統一升級以對現有專案做適配。期間,作者發現某專案使用Xcode 10編譯
python 實戰之模仿開發QQ聊天軟體(三)TCP/IP伺服器與客戶端建設
無論是p2p還是c/s還是b/s,只要用到通訊,必然是要用到今天寫的這個。 TCP/IP是網路軟體最核心的部分,缺少這個你只能當做單機遊戲玩。 TCP/IP,只需要搞清楚udp和tcp這兩個就可以了。 兩者的區別在於 udp每次傳送資訊都需要傳送ip和埠號,可以比
Netty 仿QQ聊天室(實戰二)
Netty 聊天器(百萬級流量實戰二):仿QQ客戶端 瘋狂創客圈 Java 分散式聊天室【 億級流量】實戰系列之15 【部落格園 總入口 】 寫在前面 大家好,我是作者尼恩。 今天是百萬級流量 Netty 聊天器 打造的系列文章的第二篇, 設計一個
WPF仿QQ聊天框表情文字混排實現
二話不說。先上圖 圖中分別有檔案、文字+表情、純文字的展示,對於同一個list不同的展示形式,很明顯,應該用多個DataTemplate,那麼也就需要DataTemplateSelector了: class MessageDataTemplateSe
Android仿qq聊天記錄待定與刪除功能效果
模仿手機qq,歷史聊天記錄長按會彈出待定和刪除按鈕的效果。qq效果圖 程式碼實現的效果圖 首先,看到這個效果,想一下實現的思路:彈出的待辦和刪除按鈕,是通過dialog實現的。那麼這個dialog就要能完成幾個效果,第一:自定義介面,第二:控制dialog的顯示位置,第三