【Swing 6】绝对定位—QQ登录界面
从昨天到现在,一直在研究QQ的登录界面,不知道小马先生有没有被我这种锲而不舍
精神所感动。至少从外观上是相差无几个了,当然,有几个小部件目前的我还做不出来。不
过,反正就是个界面,长得像就行了,不是嘛?
参考: 1.下拉列表框: http://blog.csdn.net/guanjungao/article/details/24875303
2. 实现JFrame的无边框: http://blog.csdn.net/qiantujava/article/details/10060847
3. 脚本之家—登录界面: http://www.jb51.net/article/48598.htm
下面先来介绍几个用得着的东西。
1. 字体设置【代码仅介绍用法, 具体的实现请看最下面的完整版本】
Swing默认的字体实在是又丑又小, 所以它提供了我们把美化的利器(Tu cao)
1 JTextField text = new JTextField(); 2 3 // 三个参数分别表示字体类型, 粗细, 大小 4 Font a = new Font("隶书", 0, 14); 5 text.setFont(a);
2. 下拉列表框
JComboBox status = new JComboBox(); status.addItem("在线"); status.addItem("离开"); status.addItem("隐身");
3. 添加背景图片和头像
【按下面的示例自行设置头像】
1 JFrame f; 2 3 public void Gui() { 4 f = new JFrame(); 5 f.setUndecorated(true); // 去掉窗口的边框(连同标题和最大、小化及关闭按钮) 6 f.setLayout(null); // 用绝对定位取代JFrame默认的边界布局 7 init(); 8 // 关闭窗口时结束javaw.exe进程, 防止打开多个窗口时且关闭时, 进程占用内存 9 f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 10 f.setSize(538, 413); 11 f.setVisible(true); 12 } 13 14 public void init() { 15 JLabel bgLabel = new JLabel(); 16 ImageIcon bgImage = new ImageIcon(“C:/Users/hasee/Desktop/我了个去/QQ背景.png”); 17 // Scale是缩放, 这一行表示将图片按指定的宽度、高度进行缩放, 记得导入java.awt.Image; 或者java.awt.*; 18 bgImage.setImage(bgImage.getImage().getScaledInstance(538, 230,Image.SCALE_DEFAULT)); 19 bgLabel.setIcon(bgImage); // 把背景图片放到标签上, 换言之, 此处标签即是容器 20 21 f.add(bgLabel); 22 }
三毛头像
QQ背景图, 动态效果大家自己PS, 我也不会
4. 窗口最小化
1 public void init() { 2 JButton minimizeButton = new JButton("—"); 3 minimizeButton.setBorder(null); // 去掉按钮的边框 4 minimizeButton.setFocusable(false); // 不让按钮获得焦点 5 minimizeButton.setBounds(203, 0, 47, 40); // 参数分别是左上角的横, 纵坐标, 按钮长和宽 6 7 // 这是注册监听事件的另一种写法 8 minimizeButton.addActionListener(new ActionListener() { 9 public void actionPerformed(ActionEvent e) { 10 f.setExtendedState(JFrame.ICONIFIED); 11 }); 12 f.add(minimizeButton); 13 }
f.setUndecorated(true);去掉下面的边框
注意,界面失去边框后,标题和最大、最小、关闭按钮都会失去,(只能自己画按钮啰)
且窗口无法移动,所以下面来解决这个问题。
5. 解决JFrame失去边框后无法移动的问题(接上面的代码)
【MouseAdapter和MouseMotionAdapter是两个抽象适配器类, 简单说,使用它们就
可以不用实现接口的全部方法!】
1 // 这两个变量在不同的方法都要用到, 所以设为全局变量 2 int xOnGui, yOnGui; 3 4 public void init() { 5 drag(); 6 } 7 8 public void drag() { 9 f.addMouseListener(new MouseAdapter() { 10 public void mousePressed(MouseEvent e) { 11 xOnGui = e.getX(); 12 yOnGui = e.getY(); 13 }); 14 15 f.addMouseMotionListener(new MouseMotionAdapter() { 16 public void mouseDragged(MousEvent e) { 17 int xOnScreen = e.getXOnScreen(); 18 int yOnScreen = e.getXOnScreen(); 19 int xx = xOnScreen - xOnGui; 20 int yy = yOnScreen - yOnGui; 21 // 这里写成f.setBounds()也可, 不过就要再加上窗口的长和宽 22 f.setLocation(xx, yy); 23 });
e.getXOnScreen();和e.getYOnScreen(); 就是分别获取屏幕上的x, y值, 把它们
放在mouseDragged()方法里面, 表示当鼠标停止拖放窗口时获取你拖的那个点的屏
幕横纵坐标, 再分别减去拖放前(即刚点击鼠标时)获取的x, y, 不就是得出当前位置窗
口左上角的横纵坐标吗?
-----------------------------------------------------------------------------------------------
完整版添加了几个监听事件:
1. 最小化按钮和关闭按钮是设置成和背景图片相似颜色的按钮(用到ActionListener接口类)
2. 当文本框获得焦点(光标)时, 内容被清空(用到FocusListener接口类)
3. 靠近关闭按钮时, 按钮变红色提醒(用到MouseListener()接口类)
问题:
一开始显示的是原来背景图片的最小化和关闭按钮, 只有在鼠标接触它们后才会变成我们弄的模样。
1 package demo; 2 3 import javax.swing.*; 4 import java.awt.*; 5 import java.awt.event.*; 6 7 public class Test extends JFrame { 8 // 用户名和密码文本框 9 private JTextField username; 10 private JTextField password; 11 // 标签 12 private JLabel signUpLabel; 13 private JLabel forgetPassLabel; 14 // 列表框 15 private JComboBox status; 16 // 复选框 17 private JCheckBox autoSignIn; 18 private JCheckBox rememberPass; 19 // 登录按钮 20 private JButton signInButton; 21 int xOnGui; 22 int yOnGui; 23 24 public static void main(String[] args) { 25 Test t = new Test(); 26 } 27 28 public Test() { 29 setUndecorated(true); 30 setTitle("绝对定位测试"); 31 setLayout(null); 32 init(); 33 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 34 setSize(538, 413); 35 setLocation(550, 200); 36 setVisible(true); 37 } 38 39 public void init() { 40 // 背景图片 41 JLabel a = new JLabel(); 42 ImageIcon bgImage = new ImageIcon("C:/Users/hasee/Desktop/我了个去/QQ背景.png"); 43 bgImage.setImage(bgImage.getImage().getScaledInstance(538, 229, Image.SCALE_DEFAULT)); 44 a.setIcon(bgImage); 45 a.setBounds(0, 0, 538, 229); 46 47 // 头像 48 JLabel b = new JLabel(); 49 ImageIcon icon = new ImageIcon("C:/Users/hasee/Desktop/我了个去/三毛.png"); 50 icon.setImage(icon.getImage().getScaledInstance(70, 76, Image.SCALE_DEFAULT)); 51 b.setIcon(icon); 52 b.setBounds(90, 242, 70, 76); 53 54 // 用户名文本框 55 username = new JTextField("QQ号码/手机/邮箱"); 56 username.setForeground(Color.gray); 57 username.addFocusListener(new UserListener()); 58 username.setBounds(170, 242, 230, 38); 59 60 // 注册帐号的标签 61 signUpLabel = new JLabel("注册帐号"); 62 signUpLabel.setForeground(new Color(0, 130, 176)); 63 signUpLabel.setBounds(410, 242, 52, 20); 64 65 // 密码文本框 66 password = new JTextField(); 67 password.setText("密码"); 68 password.setForeground(Color.gray); 69 password.addFocusListener(new PassListener()); 70 password.setBounds(170, 280, 230, 38); 71 72 // 找回密码的标签 73 forgetPassLabel = new JLabel("找回密码"); 74 forgetPassLabel.setForeground(new Color(0, 130, 176)); 75 forgetPassLabel.setBounds(410, 280, 52, 30); 76 77 // 列表框 78 status = new JComboBox(); 79 status.addItem("在线"); 80 status.addItem("离线"); 81 status.addItem("隐身"); 82 status.setBounds(110, 318, 60, 30); 83 84 // 记住密码复选框 85 rememberPass = new JCheckBox("记住密码"); 86 rememberPass.setBounds(170, 318, 80, 30); 87 rememberPass.setForeground(Color.gray); 88 89 // 自动登录复选框 90 autoSignIn = new JCheckBox("自动登录"); 91 autoSignIn.setBounds(320, 318, 80, 30); 92 autoSignIn.setForeground(Color.gray); 93 94 // 登录按钮 95 signInButton = new JButton("登录"); 96 signInButton.setBounds(170, 360, 230, 37); 97 signInButton.setForeground(Color.white); 98 signInButton.setBackground(new Color(0, 167, 226)); 99 100 // 最小化按钮 101 JButton minimizeButton = new JButton("—"); 102 minimizeButton.setFocusable(false); 103 minimizeButton.setBounds(450, 0, 50, 38); 104 minimizeButton.setForeground(Color.white); 105 minimizeButton.setBackground(new Color(0, 167, 226)); 106 minimizeButton.setBorder(null); 107 minimizeButton.addActionListener(new ActionListener() { 108 public void actionPerformed(ActionEvent e) { 109 setExtendedState(ICONIFIED); 110 } 111 }); 112 113 // 关闭按钮 114 JButton closeButton = new JButton("X"); 115 closeButton.setFocusable(false); 116 closeButton.setBounds(500, 0, 38, 38); 117 closeButton.setBackground(new Color(0, 167, 226)); 118 closeButton.setForeground(Color.white); 119 closeButton.setBorder(null); 120 closeButton.addActionListener(new ActionListener() { 121 public void actionPerformed(ActionEvent e) { 122 System.exit(0); 123 } 124 }); 125 closeButton.addMouseListener(new MouseAdapter() { 126 public void mouseEntered(MouseEvent e) { 127 closeButton.setBackground(new Color(204, 51, 0)); 128 } 129 public void mouseExited(MouseEvent e) { 130 closeButton.setBackground(new Color(0, 167, 226)); 131 } 132 }); 133 134 // 添加所有部件到JFrame容器里面 135 add(a); 136 add(b); 137 add(username); 138 add(password); 139 add(signUpLabel); 140 add(forgetPassLabel); 141 add(signInButton); 142 add(status); 143 add(rememberPass); 144 add(autoSignIn); 145 add(closeButton); 146 add(minimizeButton); 147 dragGui(); 148 } 149 // 拖动窗口 150 public void dragGui() { 151 addMouseListener(new MouseAdapter() { 152 public void mousePressed(MouseEvent e) { 153 xOnGui = e.getX(); 154 yOnGui = e.getY(); 155 } 156 }); 157 addMouseMotionListener(new MouseMotionAdapter() { 158 public void mouseDragged(MouseEvent e) { 159 int xOnScreen = e.getXOnScreen(); 160 int yOnScreen = e.getYOnScreen(); 161 int x = xOnScreen - xOnGui; 162 int y = yOnScreen - yOnGui; 163 setLocation(x, y); 164 } 165 }); 166 } 167 class UserListener implements FocusListener { 168 public void focusGained(FocusEvent e) { 169 if (username.getText().equals("QQ号码/手机/邮箱")) { 170 username.setText(""); 171 username.setForeground(Color.black); 172 } 173 } 174 public void focusLost(FocusEvent e) { 175 if (username.getText().equals("")) { 176 username.setText("QQ号码/手机/邮箱"); 177 username.setForeground(Color.gray); 178 } 179 } 180 } 181 class PassListener implements FocusListener { 182 public void focusGained(FocusEvent e) { 183 if (password.getText().equals("密码")) { 184 password.setText(""); 185 password.setForeground(Color.black); 186 } 187 } 188 public void focusLost(FocusEvent e) { 189 if (password.getText().equals("")) { 190 password.setText("密码"); 191 password.setForeground(Color.gray); 192 } 193 } 194 } 195 }