当前位置:编程学习 > JAVA >>

将不定期开放“人人都说Swing丑,唯我独爱它—Swing高仿QQ” 源码


从今天开始将会在CSDN上开放Swing高仿QQ的源码。
所有信息第一时间在群里公布

一起探讨java方面的问题。
本群位置有限先来先得
所以加群时请注名信息来源地


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();
    }
Swing QQ java --------------------编程问答--------------------


/**
 * 初始化窗口中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();
            }
        });
}

}
--------------------编程问答-------------------- 支持一个 Swing现在实际用处不多啊 --------------------编程问答--------------------
引用 3 楼 lovnie1 的回复:
支持一个 Swing现在实际用处不多啊

人人都说Swing丑,唯我独爱它—Swing高仿QQ
这个东西只能说一种爱好与兴趣吧!或是用来研究java里面一些如一些MVC模型、适配器模式等等还是不错的。 --------------------编程问答--------------------
引用 4 楼 ycb1689 的回复:
Quote: 引用 3 楼 lovnie1 的回复:

支持一个 Swing现在实际用处不多啊

人人都说Swing丑,唯我独爱它—Swing高仿QQ
这个东西只能说一种爱好与兴趣吧!或是用来研究java里面一些如一些MVC模型、适配器模式等等还是不错的。

qq这个还是很不错的 能学到很多东西  发个截图看看 --------------------编程问答--------------------
引用 5 楼 lovnie1 的回复:
Quote: 引用 4 楼 ycb1689 的回复:

Quote: 引用 3 楼 lovnie1 的回复:

支持一个 Swing现在实际用处不多啊

人人都说Swing丑,唯我独爱它—Swing高仿QQ
这个东西只能说一种爱好与兴趣吧!或是用来研究java里面一些如一些MVC模型、适配器模式等等还是不错的。

qq这个还是很不错的 能学到很多东西  发个截图看看

请点击下面文字

人人都说Swing丑,唯我独爱它—Swing高仿QQ

--------------------编程问答-------------------- 挺好的东西不能错过! --------------------编程问答-------------------- 楼主牛逼!!!! --------------------编程问答-------------------- 牛掰的楼主,支持一个!! --------------------编程问答-------------------- 楼主 求源码? 给我好吗 我拿来完成设计。邮箱510456018@qq.com --------------------编程问答-------------------- 关键还是图片效果做得好。 --------------------编程问答-------------------- 顶
补充:Java ,  Java SE
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,