读书人

完善QQ登陆界面模仿

发布时间: 2013-08-01 15:23:18 作者: rapoo

完美QQ登陆界面模仿

?当然,很明显,这是一个玩笑。虽然我可以想像在屏幕前的你一定觉得这不好笑。实际上我们要的是这样的笑果(效果?)
完善QQ登陆界面模仿
?任务目标:较为完善的模仿QQ登陆界面。
实现的功能:

1.QQ登陆界面的外观模仿。2.实现了窗体组件的布局管理。

3.实现了去除窗体边框后的最小化,拖动,关闭。

4.实现了鼠标移动到各组件的动画切换效果。

5.实现了弹出菜单的建立。

6.因为每个组件都是单独建立的所以还可以实现图片的快速切换。

个人收获:

1.会熟练运用了BrideLayout 和 FlowLayout 布局管理器

2.熟练掌握了各基本组件的用法。

3.熟练掌握了鼠标监听器的使用方法,并会用构造器传值。

4.了解如何去利用绘图工具去得到一些自己想要图片。

5.基本掌握简单界面的开发过程,并提高了我自主学习,交流的能力,磨练了心智与毅力。

?

其实,现在回想起来实现一个QQ登陆界面也不难,因为它不可以改变大小,所以开发起来还是很容易的。

下面是重头戏,我的主程序代码。

package awtSwing130709;import java.awt.BorderLayout;import java.awt.Dimension;import java.awt.FlowLayout;import java.awt.Graphics;import java.awt.Image;import java.awt.Point;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import java.awt.image.ImageObserver;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JCheckBox;import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JPasswordField;public class QQ130710 extends JPanel{//定义一个全局变量的监听器类LoginListener0716 lo;JFrame qqf;JButton j1;JButton j3;JButton j5;JButton j4;JPanel jpin;Image ii;JButton jb1;/** * 主程序入口 *///犯了个大错误不能在主函数写太多   TATpublic static void main(String[] args) {// 实例化一个对象QQ130710 qq = new QQ130710();qq.Frame();}// 定义一个获得下方面板的方法public JPanel getSouth() {// 实例化一个新面板JPanel jp = new JPanel();//加入两个按钮两个透明的标签jp.setLayout(new FlowLayout(FlowLayout.LEFT,0,0));ImageIcon i1=new ImageIcon("images/8.png");ImageIcon i2=new ImageIcon("images/9.png");//多账号登陆 j1=new JButton(i1);//二维码按钮JButton j2=new JButton(i2);JLabel jl1=new JLabel();JLabel jl2=new JLabel();jl1.setPreferredSize(new Dimension(65,1));jl2.setPreferredSize(new Dimension(70,1));j1.setPreferredSize(new Dimension(52,45));j2.setPreferredSize(new Dimension(24,25));j1.setOpaque(false);j2.setOpaque(false);//去除按钮边框j1.setBorderPainted(false);//给多账号登陆加一个监听器,实现其切换图片效果(内部类)MouseAdapter qb8=new MouseAdapter(){public void mouseEntered(MouseEvent e) {j1.setIcon(new ImageIcon("images/8(1).png"));}public void mouseExited(MouseEvent e) {j1.setIcon(new ImageIcon("images/8.png"));}};j1.addMouseListener(qb8);//实例化一个按钮对象JButton jb=new JButton("登         陆");jb.setActionCommand("login");//设置按钮的属性jb.setPreferredSize(new Dimension(150,33));//jb.setBorderPainted(false);//设置按钮的位置jp.setLocation(118, 247);//给按钮加上监听器jb.addActionListener(lo);//添加按钮到画板上jp.add(j1);jp.add(jl1);jp.add(jb);jp.add(jl2);jp.add(j2);//因为是面板所以直接将其设为透明jp.setOpaque(false);return jp;}// 定义一个获得中间面板的方法public JPanel getCenter() {// 实例化一个新面板JPanel jp = new JPanel();//设置面板内的流体布局从左对齐jp.setLayout(new FlowLayout(FlowLayout.LEFT));//实例化一个下拉框JComboBox co=new JComboBox();co.setEditable(true);   //选择添加内容co.addItem("540767457");//用于获得下拉框的String// String l1=co.getSelectedItem().toString();//  System.out.println(l1);//设置下拉框属性co.setPreferredSize(new Dimension(187,25));JLabel jl1=new JLabel("注册账号");JLabel jl2=new JLabel("找回密码");//实例化一个密码输入框JPasswordField jp1=new JPasswordField();//实例化一个图片ImageIcon ii = new ImageIcon("images/14.png");//实例化一个按钮JButton jb3=new JButton(ii);jb3.setPreferredSize(new Dimension(22,20));//去除按钮边框jb3.setBorderPainted(false);//设置密码框属性jp1.setPreferredSize(new Dimension(187,25));jp1.setLayout(new FlowLayout(FlowLayout.RIGHT,0,0));//把按钮加入密码输入框jp1.add(jb3);//实例化一个监听器用于传递用户名和密码lo=new LoginListener0716(jp1,co,qqf);//实例化两个复选框JCheckBox jc1=new JCheckBox("记住密码");//复选框 变为透明jc1.setOpaque(false);JCheckBox jc2=new JCheckBox("自动登录");//复选框 变为透明jc2.setOpaque(false);//添加组件到面板上面jp.add(co);jp.add(jl1);jp.add(jp1);jp.add(jl2);//添加复选框jp.add(jc1);jp.add(jc2);//因为是面板所以直接将其设为透明jp.setOpaque(false);return jp;}// 定义一个获得左边面板的方法public JPanel getWest() {// 实例化一个新面板JPanel jp = new JPanel();//设置面板内的流体布局从右对齐jp.setLayout(new FlowLayout(FlowLayout.RIGHT));//新建一个面板对象用于存放图片//用了重绘的方法 jpin = new JPanel(){ public void paint(Graphics g){ g.drawImage(ii, 0, 0, null); } }; jpin.setLayout(null );// 设置面板的属性jp.setPreferredSize(new Dimension(100, 0));// 实例化一个图形对象ImageIcon i = new ImageIcon("images/1.png");System.out.println("1");//得到一个image对象 ii=i.getImage();//因为图形必须依托标签或者按钮才能显示//创建标签对象并把图片传入JLabel jl2=new JLabel(i);/** * 不能在这取啊 * 不能在这取啊 * 不能在这取啊 * 不能在这取啊 * 是因为画布要在面板可见后取 *///在画板上加一个图片jpin.setPreferredSize(new Dimension(81,81));//创建一个切换在线状态的按钮 jb1=new JButton(new ImageIcon("images/15.png"));jb1.setPreferredSize(new Dimension(15,15));jb1.setBorderPainted(false);    jb1.setBounds(66, 66, 15, 15);          //给最小化加一个监听器,实现其切换图片效果MouseAdapter lala=new MouseAdapter(){public void mouseEntered(MouseEvent e) {jb1.setIcon(new ImageIcon("images/15.png"));}public void mouseExited(MouseEvent e) {jb1.setIcon(new ImageIcon("images/15(1).png"));}};jb1.addMouseListener(lala);    //创建一个状态监听器,实现其弹出窗口效果    stateListener st=new stateListener(jb1);    jb1.addMouseListener(st);//删除图像下的面板//jl.setOpaque(false);//因为是面板所以直接将其设为透明//把图形加到面板上去jpin.add(jb1);jp.add(jpin);//因为是面板所以直接将其设为透明jp.setOpaque(false);//jpin.setOpaque(false);//jp.add(jl2);return jp;}// 定义一个获得上方面板的方法public JPanel getNorth() {// 实例化一个新面板JPanel jp = new JPanel();// 设置面板的属性jp.setPreferredSize(new Dimension(0, 130));jp.setLayout(new FlowLayout(FlowLayout.RIGHT,0,0));// 实例化一个图形对象ImageIcon ii3 = new ImageIcon("images/3.png");    //设置 j3=new JButton(ii3); //给设置加一个监听器,实现其切换图片效果MouseAdapter qb3=new MouseAdapter(){public void mouseEntered(MouseEvent e) {j3.setIcon(new ImageIcon("images/3(1).png"));}public void mouseExited(MouseEvent e) {j3.setIcon(new ImageIcon("images/3.png"));}};j3.addMouseListener(qb3);ImageIcon ii4 = new ImageIcon("images/4.png");//最小化j4=new JButton(ii4);//用内部类定义一个最小化的按钮ActionListener q1=new ActionListener(){@Overridepublic void actionPerformed(ActionEvent e) {qqf.setExtendedState(qqf.ICONIFIED); //最小化}};j4.addActionListener(q1);//给最小化加一个监听器,实现其切换图片效果MouseAdapter qb4=new MouseAdapter(){public void mouseEntered(MouseEvent e) {j4.setIcon(new ImageIcon("images/4(1).png"));}public void mouseExited(MouseEvent e) {j4.setIcon(new ImageIcon("images/4.png"));}};j4.addMouseListener(qb4);ImageIcon ii5 = new ImageIcon("images/5.png");//关闭j5=new JButton(ii5);//设置命令为closej5.setActionCommand("close");//在这里我们新定义了一个监听器//虽然我还不知道为什么如果不新定义一个监听器LoginListener0716 ll = new LoginListener0716(null, null, qqf);//给关闭加一个监听器j5.addActionListener(ll);//给关闭加一个监听器,实现其切换图片效果MouseAdapter qb=new MouseAdapter(){public void mouseEntered(MouseEvent e) {j5.setIcon(new ImageIcon("images/5(1).png"));}public void mouseExited(MouseEvent e) {j5.setIcon(new ImageIcon("images/5.png"));}};j5.addMouseListener(qb);//因为是面板所以直接将其设为透明jp.setOpaque(false);jp.add(j3);jp.add(j4);jp.add(j5);//将按钮置于右上方//j5.setBounds(343, 0, 37, 15);//j5.setOpaque(true);j3.setPreferredSize(new Dimension(28,15));j4.setPreferredSize(new Dimension(28,15));j5.setPreferredSize(new Dimension(35,15));//去除按钮边框j3.setBorderPainted(false);j4.setBorderPainted(false);j5.setBorderPainted(false);return jp;}// 定义一个初始化QQ窗体的方法public void  Frame() {// 创建一个新的窗体对象 qqf = new JFrame();// 设置对象的各个属性 qqf.setTitle("QQ"); qqf.setSize(378, 290);// qqf.setLocation(500, 250); qqf.setLocation(new Point(500,200)); qqf.setResizable(false); qqf.setDefaultCloseOperation(2);//JFrame 的默认布局是边框布局// 设置它的边框布局管理器//BorderLayout BO = new BorderLayout();//jf.setLayout(BO);// 把上方的面板加到QQ窗体上qqf.add(getNorth(), BorderLayout.NORTH);// 把左边的面板加到QQ窗体上JPanel qqfw=getWest();qqf.add(qqfw, BorderLayout.WEST);// 把中间的面板加到QQ窗体上qqf.add(getCenter(), BorderLayout.CENTER);// 把下方的面板加到QQ窗体上qqf.add(getSouth(), BorderLayout.SOUTH);/** * 因为JFrame上有一个图层 * 一个图层又分为好多层 * 然后有些图层是不透明的 * 所以我们的思路就是 * 把BackgrounPicture置于JFrame最底层 * 然后再将面板一一设为透明的即可 *///给QQ窗体加入背景ImageIcon im=new ImageIcon("images/13.png");//转换为一个标签对象JLabel JP=new JLabel(im);//设置填充区域JP.setBounds(0, 0, im.getIconWidth(),im.getIconHeight());//将图片置于JLayeredPane面板的最底层qqf.getLayeredPane().add(JP,new Integer(Integer.MIN_VALUE));//获取ContentPane面板(就是那个不透明的家伙)JPanel opacity=(JPanel) qqf.getContentPane();//把它设为透明的opacity.setOpaque(false);//为了模仿的更像 去除掉它的边框吧qqf.setUndecorated(true);//对界面加入监听器,使其能拖动qqf.addMouseMotionListener(lo);//实现不同的方法应该加入不同的监听器qqf.addMouseListener(lo);qqf.setVisible(true);Graphics g=jpin.getGraphics();//g.drawImage(ii, 15, 15, null);}//public void paint(Graphics g){//System.out.println("111");//super.paint(g);//调用父类的重绘方法//repaint(g);//}/** * 这里主要是用于绘制用户图标的方法 */private void repaint(Graphics g){//得到面板的画布对象,用于画图片System.out.println("222");}}

?

?首先,先申明一下,我这样写是不对的,一个类里面不能实现太多功能,否则你很难去找出错误。由于我前面写过QQ登陆界面的开发,我在这就挑重点讲一下。如何实现了鼠标移动到各组件的动画切换效果,在这里由于只是完成了切换效果,所以我并没有创建新的类去实现,直接用的匿名内部类(这个只在代码较少的情况下使用),事实上这个还是很方便的,还在一定程度上避免了传值市的空指针问题。另外,一定要记住取画布时一定要在窗体可见以后,否则就会出现空指针的问题。

另外,如何给QQ登陆界面加一个状态切换按钮,这个问题你是否想过呢?当想到这时,我头疼了一阵子
完善QQ登陆界面模仿
?就是那个小黄点,这时候你肯定不能在西边的面板加,这时候熊哥给我了一个很好的建议,把图像直接画在面板的画布上,再把小黄点用绝对布局加在面板右下角上。在面板的画布上直接绘制图形真的是一个好方法,希望大家能够熟练掌握。

下面是实现最小化,拖动,关闭的两个监听器对象。其实一个监听器对象可以实现多个功能。

package awtSwing130709;/** * JRadioButton 单选按钮 */import java.awt.Point;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JOptionPane;import javax.swing.JPasswordField;/** * 适配器就是抽象类 * MouseAdapter重写了mouselistener中的所有方法,所以你不用全部实现 * 你只需要重写你所需要的方法 * @author Administrator * */public class LoginListener0716 extends MouseAdapter implements ActionListener{private String pass,name;private JPasswordField jp1;private JComboBox co;private JFrame qqf;//private JButton j5;         Point P;         Point orgin=new Point();       //得到关闭按钮的位置 //    Point pj=j5.getLocation();//重写她的构造方法,用于传递登陆界面的用户名和密码的值public LoginListener0716(JPasswordField jp1,JComboBox co,JFrame qqf){this.jp1=jp1;this.co=co;this.qqf=qqf;//this.j5=j5;}@Overridepublic void actionPerformed(ActionEvent e) {//判断动作执行的对象是否是JButton的实例化的一个对象if(e.getSource() instanceof JButton){//System.out.println("fffffffff");//打印出按钮的命令System.out.println(e.getActionCommand());//判断按钮的命令作用if(e.getActionCommand().equals("close")){System.out.println("dfd");System.exit(0);}//如果得到的是登陆命令if(e.getActionCommand().equals("login")){//得到用户名和密码name=co.getSelectedItem().toString();pass=jp1.getText();//如果用户名和密码匹配if(pass.equals("123456")&&name.equals("540767457")){//实现一个登陆成功的界面JFrame jf=new JFrame();jf.setSize(200,150);jf.setLocation(200,150);jf.setTitle("Welcome");jf.setDefaultCloseOperation(3);JLabel jl=new JLabel("登陆成功");jf.add(jl);jf.setVisible(true);    qqf.setVisible(false);}else{//弹出界面第一个参数如果是null就会出现在屏幕中间,如果其他就是在面板中间JOptionPane.showMessageDialog(qqf, "请填写正确的用户名和密码");}}     }}//得到最原始的坐标public void mousePressed(MouseEvent e) {orgin.x=e.getX();orgin.y=e.getY();//System.out.print(orgin.x);System.out.println(orgin.y);}//设置一个拖动事件public void mouseDragged(MouseEvent e){    //获取绝对位置 Point P1=qqf.getLocation();//重新设置面板位置qqf.setLocation(P1.x+e.getX()-orgin.x,P1.y+e.getY()-orgin.y);//qqf.setLocation(e.getX(),e.getY());}}

?

package awtSwing130709;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.awt.event.MouseAdapter;import javax.swing.JFrame;public class QQbutton extends MouseAdapter implements ActionListener{JFrame qqf;public QQbutton(JFrame qqf){this.qqf=qqf;}//最小化public void actionPerformed(ActionEvent e) {qqf.setExtendedState(qqf.ICONIFIED);}}

?

接下啦是实现弹出窗体的方法,在这里我先说一下,现在的我无论用什么方法都去除不了JPopupMenu上JMenuItem上的左边的空白问题,就是左边那个红色的区域(不信大家可以把jp.setUI(new PopupMenuUI(){注释掉)
完善QQ登陆界面模仿

这时,龙哥告诉了我可以在弹出菜单上的画布上直接画一个这样弹出菜单样式,他的背景色就可以和右边的合二为一了。最终我们就得到了QQ的完美界面。

下面是弹出菜单的代码

package awtSwing130709;import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics;import java.awt.Insets;import java.awt.event.MouseAdapter;import java.awt.event.MouseEvent;import javax.swing.ImageIcon;import javax.swing.JButton;import javax.swing.JComponent;import javax.swing.JMenuItem;import javax.swing.JPopupMenu;import javax.swing.plaf.PopupMenuUI;public class stateListener extends MouseAdapter{private JButton jb1;public stateListener(JButton jb1) {this.jb1=jb1;}public void mousePressed(MouseEvent e) {//System.out.println("456");JPopupMenu jp=new JPopupMenu();final ImageIcon im16=new ImageIcon("images/55.png");//jp.setUI(new PopupMenuUI(){//public void paint(Graphics g, JComponent c){//g.drawImage(im16.getImage(), 0, 0,101,142, null);////}//});//JLabel jl16=new JLabel(im16);JMenuItem jm=new JMenuItem(im16);jm.setBackground(Color.RED);//其默认的Layout是在调试中发现的javax.swing.plaf.basic.DefaultMenuLayout,//是一个专属的布局Layout继承自BoxLayoutjm.setMargin(new Insets(-10,-20,0,0));jm.setBorder(null);jp.setBorder(null);jp.setPreferredSize(new Dimension(101,142));jm.setPreferredSize(new Dimension(101,142));//jm.setIcon(im16);jp.setLayout(null);jm.setLayout(null);//jm.setBounds(-5, -5, 100, 100);//jp.add(jm);jp.insert(jm, 0);//jp.setPopupSize(new Dimension(101,142));//jp.setPreferredSize(new Dimension(110,149));jp.setOpaque(false);jp.setBackground(Color.WHITE);jp.setBorderPainted(false);jp.setVisible(true);jp.show(jb1, 0, 15);}}

?
完善QQ登陆界面模仿
?后记:其实,“完美”QQ登陆界面并不完美,登陆按钮其实可以用贴图,还有QQ登陆窗体上的圆角,

以及标签,键盘的切换效果,还有弹出菜单我只加了一个ITEM也就是一张图,偷了下懒。这是我的第一篇产品总结,希望有大神能指点一二,我先在此谢过了。
?

点赞

读书人网 >编程

热点推荐