文章目录

  • 绘制登录界面
  • 绘制好友列表界面
  • 绘制对话界面

这次我们准备做一个仿QQ的通信项目,首先要做的是把一些图形界面先准备好,那么我们开始第一步吧

绘制登录界面

我们不妨先看一眼QQ真实的登录界面长啥样

当然由于能力问题,而且Java的GUI确实很一般,所以我们做个简易版本的就好。把功能大概地抽象一下

  1. 首先画一个窗口,分两个子窗口,上面画成蓝色背景,下面的用于绘制组件

  2. 下面的窗口要有提示文本提醒你输入账户和密码,且设置一个文本框一个密码框用于获取账号和密码

  3. 设置两个按钮,注册和登录,并对它们添加监听器

  4. 如果登录成功,打印登录信息,如果登录失败,在原界面显示失败信息,这里我们设置随机数让登录成功的可能性为50%

    代码如下

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;public class LoginUI extends JFrame {private JTextField jtf1;private JPasswordField jtf2;private JPanel north;public static void main(String[] args) {LoginUI ui = new LoginUI("登录界面");ui.draw();}public LoginUI(String title) {super(title);}public void draw() {//窗体设置setDefaultCloseOperation(EXIT_ON_CLOSE);setSize(400, 400);setLocation(800, 400);//Panel设置north = new JPanel();north.setBackground(new Color(59, 122, 199));//north设置颜色north.setPreferredSize(new Dimension(0, 200));JPanel south = new JPanel();south.setPreferredSize(new Dimension(0, 200));add(north, BorderLayout.NORTH);add(south, BorderLayout.SOUTH);//south处理JLabel user = new JLabel("用户名");JLabel password = new JLabel("密码");jtf1 = new JTextField(20);jtf2 = new JPasswordField(20);JButton jb1 = new JButton("登录");JButton jb2 = new JButton("注册");jtf1.setEditable(true);jtf2.setEditable(true);//设置绝对位置user.setBounds(70, 60, 40, 40);password.setBounds(70, 90, 40, 40);jtf1.setBounds(150, 70, 150, 20);jtf2.setBounds(150, 100, 150, 20);jb1.setBounds(240, 130, 60, 20);jb2.setBounds(150, 130, 60, 20);//将组件添加进southsouth.setLayout(null);south.add(user);south.add(jtf1);south.add(password);south.add(jtf2);south.add(jb1);south.add(jb2);//可视化setVisible(true);//添加监听器LoginUIListener ll = new LoginUIListener(this);jb1.addActionListener(ll);jb2.addActionListener(ll);}public void drawfault() {JLabel label = new JLabel("账号或密码错误,请重新输入!");label.setBounds(40, 140, 40, 40);north.add(label);setVisible(true);}private class LoginUIListener implements ActionListener {LoginUI ui;public LoginUIListener(LoginUI ui) {this.ui = ui;}@Overridepublic void actionPerformed(ActionEvent e) {if (e.getActionCommand().equals("注册")) {String name = jtf1.getText();String password = String.valueOf(jtf2.getPassword());System.out.println("新用户注册成功!\n用户名:\t" + name + "\n密码:\t" + password);//todo:UserData.allusers.put(name, password);}if (e.getActionCommand().equals("登录")) {//todo:检查是否能够登录??在UserData里面查询该用户if (Math.random() > 0.5) {String name = jtf1.getText();String password = String.valueOf(jtf2.getPassword());System.out.println("用户登录成功!\n用户名:\t" + name + "\n密码:\t" + password);dispose();Client client = new Client(name);client.start();} else {ui.drawfault();}}}}
    }

    来看看我们模拟的效果

上面输入123,下面输入456

或者

那么我们第一部分完工了,下面第二部分,绘制QQ好友列表界面

绘制好友列表界面

同样的,我们先看看QQ是咋做的

  1. 一个高瘦的界面,分两个部分上面是个人信息,下面是好友列表
  2. 个人信息有背景,有头像、用户名和个性签名
  3. 每一个好友的信息,包括头像、用户名、个性签名
  4. 好友列表中有若干个好友,由于好友数量较多时屏幕画不下,因此采用要加滚动条
  5. 双击好友可以开启与他的聊天界面

这里我们仍然分两个部分,上面个人信息下面的好友列表各一个panel,下面由于要装滑动条,采用JScrollPane,好友列表中采用JList实现,而由于每一个好友在屏幕中的显示有图片和文字,因此我们重写Jlist的单元渲染器(ListCellRenderer)。

关于检测双击,一般我们用e.getClickCount检测,我们可以在MouseAdapter中的mouseClicked检测这一行为。

关于如何重写单元渲染器,javax.swing.ListCellRenderer中有一个官方示范,截取部分如下

照着这个抄就行,至于单元渲染器的介绍,这里三篇博客讲的挺详细的,贴在这里自取

https://blog.csdn.net/yanhanhui1/article/details/104983677

https://blog.csdn.net/weixin_36571185/article/details/71616952

https://www.cnblogs.com/hesi/p/6242699.html

该说的说完了直接上代码吧,这次我们先写一个Client类,用户列表界面作为其子类,并且我们修改在上一部分代码里面增加一点内容,使得登录成功后登录页面关闭,并且启动一个客户端,关于Clinet类的通信有关内容我们下期再讲,本期主要解决GUI相关问题。

接下来开始写登录界面的主要代码

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;public class Client {private final String userID;public Client(String userID){this.userID=userID;}public void start(){ListUI lui = new ListUI("好友列表",this.userID);lui.draw();}private class ListUI extends JFrame {private JPanel lnorth;private JScrollPane lsouth;private String userID;public ListUI(String title,String userID) {super(title);this.userID=userID;}public void draw() {//窗体设置setDefaultCloseOperation(EXIT_ON_CLOSE);setSize(400, 700);setLocation(200, 100);//Panel设置lnorth = new JPanel();lnorth.setBackground(new Color(59, 122, 199));//north设置颜色lnorth.setPreferredSize(new Dimension(0, 150));lsouth = new JScrollPane();lsouth.setBackground(new Color(7, 11, 14));//north设置颜色lsouth.setPreferredSize(new Dimension(0, 515));add(lnorth, BorderLayout.NORTH);add(lsouth, BorderLayout.SOUTH);//lnorth的处理:加上个人信息JLabel userName = new JLabel(this.userID);//todo:从UserData数据库里面取头像ImageIcon headimage = (new ImageIcon("img/QQicon.png"));headimage.setImage(headimage.getImage().getScaledInstance(100,100,Image.SCALE_DEFAULT));JLabel head = new JLabel(headimage);//todo:从UserData数据库里面取个人签名JLabel signature = new JLabel("I am so vegetable qwq");//将组件设置位置加入lnorthuserName.setBounds(150,20,200,20);head.setBounds(20,20,100,100);signature.setBounds(150,40,200,100);lnorth.setLayout(null);lnorth.add(userName);lnorth.add(head);lnorth.add(signature);//lsouth处理//首先我们重写JList的单元渲染器类@SuppressWarnings({ "rawtypes", "serial" })class MyCellRenderer  extends JLabel implements ListCellRenderer {public MyCellRenderer() {setOpaque(true);}@Overridepublic Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected,boolean cellHasFocus) {Color background;Color foreground;// check if this cell represents the current DnD drop locationJList.DropLocation dropLocation = list.getDropLocation();if (dropLocation != null&& !dropLocation.isInsert()&& dropLocation.getIndex() == index) {background = Color.RED;foreground = Color.WHITE;// check if this cell is selected}else if (isSelected) {background = Color.BLUE;foreground = Color.WHITE;// unselected, and not the DnD drop location} else {background = Color.WHITE;foreground = Color.BLACK;};/*******设置JLable的文字******/String text="<html>姓名<br/>个性签名 <html/>";setText(text);//设置JLable的文字/*******设置JLable的图片*****/// 得到此图标的 Image,然后创建此图像的缩放版本。ImageIcon headimage = (new ImageIcon("img/QQicon.png"));headimage.setImage(headimage.getImage().getScaledInstance(50,50,Image.SCALE_DEFAULT));setIcon(headimage);setIconTextGap(30);//设置JLable的图片与文字之间的距离setBackground(background);setForeground(foreground);return this;}}//todo:从Userdata中找出用户的每一个好友,并取他们的头像和用户名和个人标签JPanel[] jl = new JPanel[50];for(int i=0;i<50;i++){JPanel jf = new JPanel();jf.setLayout(null);jf.setPreferredSize(new Dimension(200,200));jl[i]=jf;}ListModel<JPanel> jListModel =  new DefaultComboBoxModel<JPanel>(jl);  //数据模型JList<JPanel> myJlist = new JList<JPanel>();myJlist.setModel(jListModel);myJlist.setCellRenderer(new MyCellRenderer());myJlist.setFont(new Font(Font.SERIF, Font.PLAIN, 18));//加滚动条lsouth.setViewportView(myJlist);//加监听器myJlist.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {if(e.getClickCount() == 2){System.out.println("双击");JList myList = (JList) e.getSource();int index = myList.getSelectedIndex();    //已选项的下标Object obj = myList.getModel().getElementAt(index);  //取出数据System.out.println(obj.toString());DialogUI du = new DialogUI("111");du.draw();}}});setVisible(true);}}
}

我们来看看效果咋样

效果还是可以的,图中的蓝色是因为该元素被选中了,这个背景色你可以自己调,在JList的单元渲染器里面可以设置,beselected为true时的颜色。我们再看看双击后java控制台的输出

也是很符合预期的,那么这部分基本上就完成了。

绘制对话界面

接下来我们完成第三部分,对话界面。

同样的,首先我们来看看QQ正版的对话界面长啥样吧,这部分应该是最简单的

观察一下我们发现屏幕大致分3块,右边是图像,这里我们给个背景色好了,左边分三块,上面是对话界面,下面的发送界面是一个文本框加一个发送按钮,中间界面里面有截屏、表情、文件、发送等按钮。

基本没啥难度,直接放代码吧

package Clinet;import javax.swing.*;
import java.awt.*;public class DialogUI extends JFrame {private String friendName;public DialogUI(String friendName){super("与"+friendName+"的对话");this.friendName=friendName;}public void draw(){//窗体设置setDefaultCloseOperation(EXIT_ON_CLOSE);setSize(800, 800);setLocation(100, 100);//Panel设置JPanel east = new JPanel();JPanel west = new JPanel();JPanel north = new JPanel();JPanel south = new JPanel();JPanel center = new JPanel();add(east,BorderLayout.EAST);add(west,BorderLayout.WEST);west.setLayout(new BorderLayout());west.add(north, BorderLayout.NORTH);west.add(south, BorderLayout.SOUTH);west.add(center,BorderLayout.CENTER);east.setBackground(new Color(0x4D62C1));//east设置颜色north.setBackground(new Color(0xE07456));//north设置颜色north.setVisible(true);east.setPreferredSize(new Dimension(200, 0));west.setPreferredSize(new Dimension(600, 0));north.setPreferredSize(new Dimension(0, 500));south.setPreferredSize(new Dimension(0, 200));//south处理JButton send = new JButton("发送");JButton file = new JButton("文件");JButton emoji = new JButton("表情");JButton catchScreen = new JButton("截屏");JTextArea sender = new JTextArea();sender.setText("在这里输入文字");//设置绝对位置send.setBounds(0,0,100,100);file.setBounds(150,0,100,100);emoji.setBounds(300,0,100,100);catchScreen.setBounds(450,0,100,100);sender.setBounds(50,50,500,200);center.add(send);center.add(file);center.add(emoji);center.add(catchScreen);south.add(sender);//可视化setVisible(true);}
}

看看效果咋样

不错,完工,我们下一期再介绍服务器的代码,下下期介绍客户端服务器通信的代码。

仿QQ通信(一)绘制客户端界面相关推荐

  1. 仿QQ聊天软件(登录界面、好友界面、聊天界面)-Java(Swing、Socket)

    文章目录 一.项目结构 二.项目功能 三.制作界面 (一).登录界面的制作 (二).好友列表界面 (三).聊天界面 四.制作服务器 五.设计通信协议 六.项目缺点 学习了socket通信后,就想来制作 ...

  2. Android仿QQ,网易邮箱客户端收件人控件

    效果图 实现思路 这个功能首先想到的是安卓原生控件AutoCompleteTextView和MultiAutoCompleteTextView 前者用的还是比较多的,比如字符联想,最近搜索记录等用的都 ...

  3. android跳转到qq页面显示,安卓仿QQ登录及登录成功界面跳转

    [实例简介] 和QQ登录及其相似的一款代码开发,和QQ登录及其相似的一款代码开发,和QQ登录及其相似的一款代码开发!! [实例截图] [核心代码] 5d386b11-34e3-4f85-b050-16 ...

  4. 高仿it之家新闻客户端源码

    仿it之家新闻客户端界面,数据为本地假数据.仅实现了新闻模块的功能. 源码下载:http://code.662p.com/list/11_1.html 详细说明:http://android.662p ...

  5. 仿qq左滑删除listview_Java基于Swing和Netty仿QQ界面聊天小项目

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:硬刚一周,3W字总结,一年的经验告诉你如何准备校招! 个人原创100W+访问量博客:点击前往,查看更多 来源:b ...

  6. WPF编程;上位机编程;C#编程;仿QQ基础实现(一)之界面预览

    简介 一.摘要 1.描述 2.关键字 二.什么是WPF 三.为什么选择WPF 四.仿QQ的登录界面 五.仿QQ联系人界面 六.源码下载 七.其他 八.参考 一.摘要 1.描述 本文主要描述的是如何通过 ...

  7. java实现仿qq界面及功能、网路编程、实现抽象工厂模式、线程池代码与测试

    java实现仿qq界面及功能 用Swing 代码在百度网盘:http://pan.baidu.com/s/1pJjxI4b 具体见https://www.iteye.com/topic/1137293 ...

  8. Java仿QQ客户端(用JTree实现好友列表)

    仿QQ客户端 当前效果 登录界面 好友列表界面 当前效果 登录界面 首先,为了达到美观的目的,需要添加一张背景图片,我采用的方法是将图片添加到JLabel上,再将JLabel添加到界面上,但这样会面临 ...

  9. java qq通信,Java通信-仿QQ聊天项目

    前后历时一个多月的Java实现聊天通信项目-仿QQ聊天室基本告一段落,期间面对了很多问题,也有不同的解决方案,重写了几次核心代码,等等问题.现在在项目的结束之时,给自己做一个总结,算是一个回顾,算是一 ...

最新文章

  1. k8s集群配置使用coredns代替kube-dns
  2. Dumpzilla工具第615行bug的解决办法
  3. 杂项-Log:NLog
  4. python复制多个文件_python 之 复制多个模板文件
  5. CSS控制表格的方法
  6. apache启动报错记录
  7. twisted mysql_在Twisted下用MySQLadbapi获取自增id
  8. Win8.1 JAVA环境配置全过程
  9. java 文件url地址_简单的解析文件,取URL地址,并根据地址抓下页面
  10. O - Muddy Fields
  11. LINUX上,2080/1080卡不要混插
  12. GD32f103介绍第一章
  13. 五子棋等级考试软件的开发(五)
  14. 西北工业大学网络空间安全考研经验分享
  15. 用c语言编程,统计大写字母,小写字母,数字,其他字符的个数,用C语言:输入一行字符,不超过50个,统计出其中英文大写字母,小写字母,数字,空格以及其他字符个数...
  16. 黑灰对比可以为高大上网站风格代言
  17. Front Immunol 复现 | 1. GEO数据下载及sva批次校正(PCA可视化)
  18. 【转载】CDS view自学系列
  19. SWOT、KPI 和 360 度考核,绩效评估中的哪个更适用?
  20. Android-vold源码分析之连接电脑OTG(11)

热门文章

  1. 格雷欣法则(Gresham's Law,亦称之为劣币驱逐良币规律)
  2. 大神的ACM训练计划(详细)
  3. LeetCode 二叉树路径问题 Path SUM(①②③)总结
  4. 主机模拟i2c检测设备时出现错误死循环_西部数码使用指南:网站打不开数据库错误等常见问题解决方法...
  5. 天津市卓越软件实验班线上测试,天津卓越软件工程师试验班实施方案.pdf
  6. LeetCode 1. 两数之和【哈希表】
  7. 其境遇与文章中描写的现实恰恰相反科技的
  8. Android 错误: 程序包android.support.annotation不存在
  9. 02讲 | STM32单片机实现LED灯反转
  10. c#产生随机字符串的两种方法