精华帖 (5) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2013-07-16
最后修改:2013-08-01
通过本人一段时间的研究,终于使用Swing写出一个山寨版的QQ,目前还有很多功能都还在处于开发中,先发个已经开发好的界面供Swing爱好者,指点一二。 如有喜爱Swing的朋友且愿意与大家一起交流探讨,可以加本人的Q、Q 、群:【263198218】,一起交流。现上传部分界面效果图 服务器目前使用网上一个较有名的软件做为服务器端。客户端: 启动界面 ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2013-07-16
最后修改:2013-07-16
package client.login; import java.awt.EventQueue; import java.awt.Image; import java.awt.SplashScreen; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.FilenameFilter; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Random; import java.util.TreeMap; import javax.swing.ImageIcon; import javax.swing.Timer; import javax.swing.ToolTipManager; import org.jivesoftware.smack.Roster; import org.jivesoftware.smack.XMPPConnection; import org.jivesoftware.smack.XMPPException; import org.jivesoftware.smack.packet.Presence; import org.jivesoftware.smackx.packet.VCard; import swingx.crazy.componentx.JADialog; import swingx.crazy.componentx.JAFrame; import swingx.crazy.componentx.JAMessageBox; import swingx.crazy.security.Checker; import swingx.crazy.systeminfo.OSUtils; import swingx.crazy.util.Config; import swingx.crazy.util.UIUtil; import swingx.crazy.util.Util; import client.SystemTrayIcon; import client.beans.user.User; import client.data.LocalDataConnection; import client.resources.Resources; import client.skin.Skin; import client.util.ClientConfig; import client.util.ClientUtil; import com.sun.awt.AWTUtilities; public class StartRunning { private XMPPConnection connection; private static String USER_IM_HOME; //参数 public static String ARGUMENTS; //资源文件目录 private static File RESOURCE_DIRECTORY; //bin(二进制)文件目录 private static File BIN_DIRECTORY; //日志文件目录 private static File LOG_DIRECTORY; //客户端文件目录 private static File USER_DIRECTORY; //plugin(接口)文件目录 private static File PLUGIN_DIRECTORY; //xtra文件目录 private static File XTRA_DIRECTORY; //config文件目录 private static File CONFIG_DIRECTORY; //skin文件目录 private static File SKIN_DIRECTORY; //客户端程序配置、登录配置 private Config config, loginConfig; //登录窗口 private LoginFrame loginFrame; public ImageIcon sysIcon = new ImageIcon(ClientConfig.IMAGE_DIR + ClientConfig.FILE_SEP + "tray"+ClientConfig.FILE_SEP+"online.png"); //正在登录窗口 private LoadingFrame loadingFrame; //客户端主界面 private MainFrame mainFrame; //存放界面皮肤的集合 private Map<String, Skin> skinMap; //当前系统的皮肤和当前预览的皮肤 private Skin currentSkin, currentPreviewSkin; //垃圾回收定时器 private Timer gcTimer; //登录历史记录列表 private List<String> loginHistory; //当前登录的用户 private User currentUser; //登录界面Banner private String bannerName; private Roster userRoster; private VCard vcard; public StartRunning() { super(); System.setProperty("java.awt.im.style", "no-spot"); //读取初始化配置 this.config = new Config(ClientConfig.CONFIG_PATH); this.loginConfig = new Config(ClientConfig.LOGIN_CONFIG_PATH); this.loginHistory = new ArrayList<String>(ClientConfig.MAX_HISTORY_USER_COUNT); initDirectory(); initBannerName(); //连接服务器 ModelUtils.connServer(); connection = ModelUtils.getConnection(); if(!isRunning()) { //DBConnectionManager.getInstance(); load(); } else { System.exit(0); } } /** * 确保目录的存在,不存在则重新生成 */ private void initDirectory() { USER_IM_HOME = ClientConfig.USER_DIR + "/"; BIN_DIRECTORY = initializeDirectory("bin"); LOG_DIRECTORY = initializeDirectory("logs"); USER_DIRECTORY = initializeDirectory("users"); SKIN_DIRECTORY = initializeDirectory("skin"); CONFIG_DIRECTORY = initializeDirectory("config"); PLUGIN_DIRECTORY = initializeDirectory("plugin"); RESOURCE_DIRECTORY = initializeDirectory("resources"); XTRA_DIRECTORY = initializeDirectory("resources/xtra"); } /** * 跟踪用户配置目录。 * * @return 根据操作系统的目录名。 */ public static String getUserConf() { if (OSUtils.isLinux()) { return null; } else if(OSUtils.isMacOSX()) { return null; } else { return ClientConfig.USER_DIR; } } /** * 验证当前同一台机器上已经运行的客户端数量 * @return */ private boolean isRunning(){ String info = null; //具体代码暂未实现 return info != null; } /** * 加载系统的所有皮肤 */ public void loadAllSkin(){ //所有皮肤的集合 skinMap = new TreeMap<String, Skin>(); Skin defaultSkin = new Skin(ClientConfig.DEFAULT_SKIN_NAME); skinMap.put(defaultSkin.getName().toUpperCase(), defaultSkin); File skinRoot = new File(ClientConfig.SKIN_DIR); if (skinRoot.exists() && skinRoot.isDirectory()){ File[] skinDirs = skinRoot.listFiles(); String name, path; File file; int count = 0; for (File skinDir: skinDirs){ if (skinDir.isDirectory()){ name = skinDir.getName(); path = skinDir.getPath(); file = new File(path + ClientConfig.FILE_SEP + ClientConfig.SKIN_NORMAL_FILE_NAME); if (!file.exists() || !file.isFile()){ continue; } file = new File(path + ClientConfig.FILE_SEP + ClientConfig.SKIN_BLUR_FILE_NAME); if (!file.exists() || !file.isFile()){ continue; } file = new File(path + ClientConfig.FILE_SEP + ClientConfig.SKIN_PREVIEW_FILE_NAME); if (!file.exists() || !file.isFile()){ continue; } skinMap.put(name.toUpperCase(), new Skin(name)); count++; if (count >= ClientConfig.MAX_SKIN_COUNT - 1){ break; } } } } } /** * 更改系统皮肤 */ public void changeSkin(Skin newSkin, boolean save){ boolean currentShow = (currentPreviewSkin == newSkin); if((!save && currentShow) || (save && currentSkin == newSkin)){ return; } if(newSkin == null){ newSkin = skinMap.get(ClientConfig.DEFAULT_SKIN_NAME.toUpperCase()); } if(!currentShow){ Image image = newSkin.getImage(); Image blurImage = newSkin.getBlurImage(); BufferedImage bufferedBlurImage = blurImage == null? null: UIUtil.toBufferedImage(blurImage, null); for (Window win: Window.getWindows()){ if(win.isDisplayable()){ if(win instanceof JAFrame){ ((JAFrame)win).setBackgroundImage(image, bufferedBlurImage); } else if(win instanceof JADialog){ ((JADialog)win).setBackgroundImage(image, bufferedBlurImage); } } } currentPreviewSkin = newSkin; image = null; blurImage = null; } if( save){ for (Skin skin: skinMap.values()){ skin.setSelected(skin == newSkin); } currentSkin = newSkin; config.savePropertie(ClientConfig.SKIN_NAME, currentSkin.getName()); } } /** * 回收垃圾内存 */ public void startGC() { int delay = Integer.parseInt(config.getProperty(ClientConfig.GC_PERIOD, "5000")); //初始化定时器 gcTimer = new Timer(delay, new ActionListener(){ public void actionPerformed(ActionEvent e){ System.gc(); } }); gcTimer.start(); } /** * 初始化窗口中Banner名字 */ private void initBannerName() { //读取当前文件夹里所有文件 String[] fileNames = new File(ClientConfig.BANNER_DIR).list(new BannerFilter()); int count = fileNames.length; if(count > 0){ int index = new Random().nextInt(count); bannerName = fileNames[index]; } } public SystemTrayIcon getTray() { if (this.loginFrame != null) { return this.loginFrame.getTrayIcon(); } return null; } /** * 取得当前皮肤 * @return */ public Skin getCurrentSkin() { if (currentSkin != null) { return currentSkin; } else { this.loadAllSkin(); return currentSkin = skinMap.get(ClientConfig.DEFAULT_SKIN_NAME.toUpperCase()); } } /** * 取得皮肤 * @param name - 皮肤的名称 * @return */ public Skin getSkin(String skinName){ return skinMap.get(skinName.toUpperCase()); } /** * 取得所有皮肤的返回Map集合类型数据 * @return */ public Map<String, Skin> getAllSkins(){ return skinMap; } /** * 取得Banner文件名 * @return */ public String getBannerName(){ return this.bannerName; } /** * 返回当前用户对象 * @return */ public User getCurrentUser(){ return currentUser; } /** * 返回历史登录列表 * @return */ public List<String> getLoginHistory(){ return loginHistory; } /** * 返回系统配置 * @return */ public Config getConfig(){ return config; } /** * 返回登录配置 * @return */ public Config getLoginConfig(){ return loginConfig; } public LoadingFrame getLoadingFrame(){ return this.loadingFrame; } /** * 取得登录的主窗口对象 * @return */ public MainFrame getMainFrame(){ return mainFrame; } public void setMainFrame(MainFrame mainFrame) { this.mainFrame = mainFrame; } public void setLoadingFrame(LoadingFrame loadingFrame) { this.loadingFrame = loadingFrame; } /** * 进行密码加密 * @param savedPassword * @return */ public String getPasswordTextWhenSaved(String savedPassword){ return Long.toHexString(Checker.compute(savedPassword, "CRC-32")); } public XMPPConnection getConnection() { return connection; } /** * 返回历史用户账号 * @return */ public String getHistoryUserString() { return loginHistory.toString().replaceAll("\\[|\\]| ", ""); } /** * 删除历史用户 * @param name */ public void removeHistoryUser(String username){ loginHistory.remove(username); loginConfig.remove(username + ClientConfig.PASSWORD_KEY); loginConfig.remove(username + ClientConfig.AUTO_LOGIN_KEY); loginConfig.setPropertie(ClientConfig.LOGIN_HISTORY, getHistoryUserString()); loginConfig.saveConfig(); } /** * 输出错误提示信息 * @param title * @param message * @param isError */ public void showMessageBeforeLogin(String title, String message, boolean isError){ JAMessageBox messageBox ; if (isError) { messageBox = JAMessageBox.createErrorMessageBox(this.loginFrame, title, message); }else { messageBox = JAMessageBox.createInformationMessageBox(this.loginFrame, title, message); } Image image = new ImageIcon(ClientConfig.BANNER_DIR + ClientConfig.FILE_SEP + this.bannerName).getImage(); messageBox.setIconImage(ClientUtil.getImage("Icon18x18.png")); messageBox.setBackgroundImage(image); messageBox.open(); } private void load(){ String history = loginConfig.getProperty(ClientConfig.LOGIN_HISTORY); String[] historyList; int count = 0; boolean isAuto = false; String autoerrorMsg = null; if(history != null && (historyList = history.split(ClientConfig.USER_LIST_SEP)).length > 0){ for(String name: historyList){ if(User.isAllowedName(name)){ loginHistory.add(name); count++; } if(count >= ClientConfig.MAX_HISTORY_USER_COUNT){ break; } } } if(!loginHistory.isEmpty()){ String first = loginHistory.get(0); isAuto = Boolean.parseBoolean(loginConfig.getProperty(first + ClientConfig.AUTO_LOGIN_KEY, "false")); if(isAuto){ String savedPassword = loginConfig.getProperty(first + ClientConfig.PASSWORD_KEY); if(savedPassword == null){ isAuto = false; }else{ try { this.connection.login(first, savedPassword, "my_pc_client"); //取得当前用户相关的好友 userRoster=connection.getRoster(); userRoster.setSubscriptionMode(Roster.SubscriptionMode.manual); vcard = new VCard(); vcard.load(connection, "1234@sh-711701-00039/my_pc_client"); } catch (Exception e) { if ("Not connected to server.".equalsIgnoreCase(e.getMessage())) { showMessageBeforeLogin(Resources.getString("title.error"), Resources.getString("message.server.unavailable"), true); } else if ("not-authorized(401)".equalsIgnoreCase(e.getMessage())) { showMessageBeforeLogin(Resources.getString("title.error"), Resources.getString("message.loging.failed"), true); } System.out.println("e.getMessage()" + e.getMessage());; } return; } } } if(isAuto) { afterLoginSuccess(); } else{ loginFrame = new LoginFrame(this); if(autoerrorMsg != null) { if(currentUser == null) { loginFrame.requestUser(); } else { loginFrame.requestPassword(true); } showMessageBeforeLogin("\u767B\u9646", autoerrorMsg, true); } } } /** * 登录验证 * @param name - 登录账号 * @param password - 登录密码 */ public void login(String name , String password){ String errorMsg = null; if (!User.isAllowedName(name)) { errorMsg = Resources.getString("message.username.error"); this.loginFrame.requestUser(); }else if (!User.isAllowedPassword(password.trim())) { errorMsg = Resources.getString("message.password.error"); this.loginFrame.requestPassword(true); }else if (!User.isPasswordLength(password)) { errorMsg = User.PASSWORD_LENGTH_ERROR; this.loginFrame.requestPassword(true); }else { //系统保存的密码 String savedPassword = loginConfig.getProperty(name + ClientConfig.PASSWORD_KEY); boolean userInput = false; //判断 if (savedPassword != null && password.equals(getPasswordTextWhenSaved(savedPassword))) { userInput = true; } else { savedPassword = password; userInput = true; } if(userInput){ try { this.connection.login(name, savedPassword, "my_pc_client"); //修改验证方式 userRoster=connection.getRoster(); userRoster.setSubscriptionMode(Roster.SubscriptionMode.manual); } catch (Exception e) { if ("Not connected to server.".equalsIgnoreCase(e.getMessage())) { showMessageBeforeLogin(Resources.getString("title.error"), Resources.getString("message.server.unavailable"), true); } else if ("not-authorized(401)".equalsIgnoreCase(e.getMessage())) { showMessageBeforeLogin(Resources.getString("title.error"), Resources.getString("message.loging.failed"), true); } return; } } } if(errorMsg != null) { currentUser = null; showMessageBeforeLogin(Resources.getString("title.error"), errorMsg, true); } else { loadingFrame = new LoadingFrame(loginFrame, StartRunning.this); //currentUser.setAutoLogin(loginFrame.isAutoLogin()); //currentUser.setSavePassword(loginFrame.isSavePassword()); loginHistory.remove(name); loginHistory.add(0, name); loginConfig.remove(name + ClientConfig.AUTO_LOGIN_KEY); loginConfig.remove(name + ClientConfig.PASSWORD_KEY); if(loginHistory.size() > ClientConfig.MAX_HISTORY_USER_COUNT) { loginHistory = loginHistory.subList(0, ClientConfig.MAX_HISTORY_USER_COUNT); } loginConfig.setPropertie(ClientConfig.LOGIN_HISTORY, getHistoryUserString()); loginConfig.saveConfig(); //加载本地个人数据数据库 LocalDataConnection.getInstance(name); afterLoginSuccess(); } //为了测试所把上面一行加到此处 //afterLoginSuccess(); } /** * 登录成功则初始化相关的数据 */ private void afterLoginSuccess(){ //当前窗口对象不为空时 if (loginFrame != null) { //关闭当前登录界面 loginFrame.dispose(); //loginFrame = null; } //加载所有皮肤 loadAllSkin(); // if (loadingFrame != null) { //关闭当前登录界面 loadingFrame.dispose(); } mainFrame = new MainFrame(this); changeSkin(this.getSkin(config.getProperty(ClientConfig.SKIN_NAME, ClientConfig.DEFAULT_SKIN_NAME)), true); if (this.vcard != null) { //this.mainFrame.setUserVCard(vcard); } //发送在线请求 Presence presence = new Presence(Presence.Type.available,"",1,Presence.Mode.available); getConnection().sendPacket(presence); vcard = new VCard(); try { vcard.load(connection, "1236@sh-711701-00039"); //this.mainFrame.setUserVCard(vcard); } catch (XMPPException e) { e.printStackTrace(); } //changeSkin(getSkin(config.getProperty(ClientConfig.SKIN_NAME, ClientConfig.DEFAULT_SKIN_NAME)), true); //回收垃圾 startGC(); } /** * 关闭闪屏 */ private void closeSplash(){ SplashScreen splash = SplashScreen.getSplashScreen(); if(splash != null){ splash.close(); } } /** * 退出系统 */ public void exit(){ if(gcTimer != null){ gcTimer.stop(); } if(mainFrame != null){ config.setPropertie(ClientConfig.TITLE_OPAQUE, String.valueOf(mainFrame.isTitleOpaque())); config.setPropertie(ClientConfig.SKIN_ALPHA, String.valueOf(mainFrame.getImageAlpha())); config.setPropertie(ClientConfig.SKIN_MODE, String.valueOf(mainFrame.getImageDisplayMode())); config.setPropertie(ClientConfig.SKIN_NAME, currentSkin == null? ClientConfig.DEFAULT_SKIN_NAME : currentSkin.getName()); //config.setPropertie(ClientConfig.TABS_FOREGROUND, mainFrame.getTabForegroundDes()); //config.setPropertie(ClientConfig.STATUS_FOREGROUND, mainFrame.getStatusForegroundDes()); boolean maximized = (mainFrame.getExtendedState() & JAFrame.MAXIMIZED_BOTH) != 0; config.setPropertie(ClientConfig.WINDOW_MAXIMIZED, String.valueOf(maximized)); if(UIUtil.isTranslucencySupported()) { config.setPropertie(ClientConfig.WINDOW_ALPHA, String.valueOf(AWTUtilities.getWindowOpacity(mainFrame))); } if(!maximized) { config.setPropertie(ClientConfig.WINDOW_SIZE, ClientUtil.sizeToString(mainFrame.getSize())); } } config.saveConfig(); System.exit(0); } public Roster getUserRoster() { return this.userRoster; } public ImageIcon getSysIcon() { return this.sysIcon; } /** * 返回的IM目录为当前用户(user.home)。 * user.home是所有用户特定的文件被放置在一个多用户系统中运行IM。 * * @return */ public static String getIMUserHome() { return USER_IM_HOME; } /** * 初始化相关目录,如果不存在创建相关的目录 * @param directoryHome - IM目录 * @param directoryName - 目录名称 * @return 返回相关的File对象 */ private static synchronized File initializeDirectory(File directoryHome, String directoryName){ File targetDir = new File(directoryHome, directoryName).getAbsoluteFile(); if(!targetDir.exists()){ targetDir.mkdirs(); } return targetDir; } /** * 初始化相关目录,如果不存在创建相关的目录 * * @param directoryName - 目录名称 * @return 返回相关的File对象 */ private static synchronized File initializeDirectory(String directoryName){ return initializeDirectory(new File(USER_IM_HOME), directoryName); } /** * 返回IM安装的Bin目录 , bin目录包含着启动IM的所需脚本 * @return */ public static File getBinDirectory() { if (BIN_DIRECTORY == null ) { BIN_DIRECTORY = initializeDirectory("bin"); } return BIN_DIRECTORY; } /** * 返回IM安装的资源目录。 * 资源目录包含了所有本地库运行所需的操作系统特定的操作,如托盘支持。 * 您可以将其他本地在这个目录库,如果你想拥有它们放置到system.library.path。 * @return */ public static File getResourceDirectory() { if (RESOURCE_DIRECTORY == null ) { RESOURCE_DIRECTORY = initializeDirectory("resources"); } return RESOURCE_DIRECTORY; } /** * 返回日志目录中。日志目录包含所有IM的调试和错误文件。 * * @return 日志目录 */ public static File getLogDirectory() { if (LOG_DIRECTORY == null ) { LOG_DIRECTORY = initializeDirectory("logs"); } return LOG_DIRECTORY; } /** * 返回皮肤目录。皮肤目录包含所有IM的皮肤。 * * @return 皮肤目录 */ public static File getSkinDirectory() { if (SKIN_DIRECTORY == null ){ SKIN_DIRECTORY = initializeDirectory("skin"); } return SKIN_DIRECTORY; } /** * 返回配置目录。配置目录包含所有IM的相关配置文件。 * * @return 配置目录 */ public static File getConfigDirectory() { if (CONFIG_DIRECTORY == null ) { CONFIG_DIRECTORY = initializeDirectory("config"); } return CONFIG_DIRECTORY; } /** * Banner文件过滤流 * @author 东泽 2012-06-19 * */ private class BannerFilter implements FilenameFilter{ public boolean accept(File dir, String name){ return name.toLowerCase().endsWith(ClientConfig.DOT_PNG); } } /** * @param args */ public static void main(String[] args) { System.setProperty("sun.java2d.noddraw", "true"); ToolTipManager.sharedInstance().setInitialDelay(200); UIUtil.setPopupMenuConsumeEventOnClose(false); if(Util.isWindows()){ UIUtil.initToolTipForSystemStyle(); } UIUtil.hideInputRect(); EventQueue.invokeLater(new Runnable(){ public void run(){ //SplashProcess.start(); new StartRunning(); } }); } } |
|
返回顶楼 | |
发表时间:2013-07-16
效果不错,不过用swing还不如用swt |
|
返回顶楼 | |
发表时间:2013-07-16
小te 写道 效果不错,不过用swing还不如用swt 呵呵,主要是本人喜欢Swing业余时间无聊时就研究研究。。其实Swing和SWT都差不多 |
|
返回顶楼 | |
发表时间:2013-07-17
最后修改:2013-07-17
非常不错啊
|
|
返回顶楼 | |
发表时间:2013-07-17
看着挺不错的
|
|
返回顶楼 | |
发表时间:2013-07-17
非常漂亮。,
|
|
返回顶楼 | |
发表时间:2013-07-17
能提供代码学习一下就好了。
一直做web,都没做过GUI的东西呢。 |
|
返回顶楼 | |
发表时间:2013-07-17
很好看,看来我们误解了swing了
|
|
返回顶楼 | |
发表时间:2013-07-18
如果不是高仿QQ,我觉得这个更棒,更吸引眼球,说回来,楼主很棒~
|
|
返回顶楼 | |