【案例11-1】 简易记事本
【案例介绍】
1.案例描述
本案例要求利用Java Swing 图形组件开发一个图形化简易记事本。记事本功能包括文本编辑、保存文本到指定路径、打开指定路径下的文本、退出等。
2.运行结果
【案例目标】
-
学会分析“简易计算器”程序实现的逻辑思路。
-
能够独立完成“简易计算器”程序的源代码编写、编译及运行。
-
掌握Java Swing界面编程的应用。
【案例分析】
(1)记事本界面整体可以看做是一个容器窗口。
(2)从运行结果中的记事本界面的布局效果显示内容可以看出,该图形化界面有最小化、放大缩小以及关闭按钮,以及菜单栏、菜单、文本域。菜单栏可以使用JMenuBar实现,文本域可以使用JTextArea来实现,菜单可以使用JMenu来实现,菜单项可以使用JMenuItem来实现。
(3)为了使窗口可以最小化、放大缩小、关闭还必须为这些按钮注册监听器,进行相应的事件处理。
(4)定义一个程序入口,用于启动Swing案例程序。
【案例实现】
MyMenu.java
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.*;
class MyNotePad extends JFrame implements ActionListener {
private JTextArea jta = null;
private JMenuBar jmb = null;
private JMenu jm = null;
private JMenuItem jmiOpen = null;
private JMenuItem jmiSave = null;
private JMenuItem jmiExit = null;
private JFileChooser jfc = null;
public MyNotePad() {
jta = new JTextArea();
this.setLayout(new BorderLayout());
this.add(jta);
jmb = new JMenuBar();
jm = new JMenu("文件");
jmiOpen = new JMenuItem("打开");
jmiOpen.addActionListener(this);
jmiOpen.setActionCommand("打开");
jmiSave = new JMenuItem("保存");
jmiSave.addActionListener(this);
jmiSave.setActionCommand("保存");
jmiExit = new JMenuItem("退出");
jmiExit.addActionListener(this);
jmiExit.setActionCommand("退出");
jm.add(jmiOpen);
jm.add(jmiSave);
jm.add(jmiExit);
jmb.add(jm);
this.setJMenuBar(jmb);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setSize(400, 300);
this.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
String str = e.getActionCommand();
if (str.equals("打开")) {
System.out.println("打开");
jfc = new JFileChooser();
jfc.setDialogTitle("请选择文件!");
jfc.showOpenDialog(null);
jfc.setVisible(true);
File file = jfc.getSelectedFile();
BufferedReader br = null;
try {
FileReader fReader = new FileReader(file);
br = new BufferedReader(fReader);
String readStr = "";
String allCode = "";
while ((readStr = br.readLine()) != null) {
allCode += readStr + "\r\n";
}
jta.setText(allCode);
} catch (Exception e2) {
e2.printStackTrace();
// TODO: handle exception
} finally {
try {
br.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} else if (str.equals("保存")) {
JFileChooser jfc = new JFileChooser();
jfc.setDialogTitle("已保存");
jfc.showSaveDialog(null);
File file = jfc.getSelectedFile();
BufferedWriter bw = null;
try {
FileWriter fw = new FileWriter(file);
bw = new BufferedWriter(fw);
String jtaStr = jta.getText();
bw.write(jtaStr);
} catch (Exception e2) {
// TODO: handle exception
e2.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
} else if (str.equals("退出")) {
System.exit(0);
}
}
}
public class MyMenu {
public static void main(String[] str) {
MyNotePad notePad = new MyNotePad();
}
}
上述代码中,第7-13行代码,声明了文本域、菜单栏、菜单、菜单项、打开、保存、退出以及选择文件等对象。MyNotePad()方法中,对文本域、菜单栏、菜单、菜单项、打开、保存、退出等对象进行实例化,并将打开、保存、退出放入菜单容器,将菜单容器放入菜单栏容器,将菜单栏放入窗口容器。并设置了窗口容器的大小。actionPerformed()方法中,编写了打开文件、保存、以及退出的逻辑。最后,在main()方法中对容器对象进行实例化,用于启动Swing案例程序。
【案例11-2】 简易计算器
【案例介绍】
1.案例描述
本案例要求利用Java Swing 图形组件开发一个可以进行简单的四则运算的图形化计算器。
2.运行结果
运
【案例目标】
-
学会分析“简易计算器”程序实现的逻辑思路。
-
能够独立完成“简易计算器”程序的源代码编写、编译及运行。
-
掌握Java Swing界面编程的应用。
-
了解计算器逻辑运算实现。
【案例分析】
要制作一个计算器,首先要知道它由哪些部分组成,如下图所示:
一个简单的图形化界面计算器,需要由界面组件、组件的时间监听器和具体的事件处理逻辑组成。
实现一个简易图形化界面计算器可分以下几个步骤:
-
UI组件创建和初始化:包括窗体的创建,显示计算结果文本框、清除按钮、数字按钮、运算符等按钮的初始化。
-
在窗体中添加UI组件:包括放置数字键及运算符面板、放置清除框面板。
-
布局结束之后,就是计算器的难点:编写事件处理程序。
-
按键的响应实现。
-
计算逻辑的实现。
-
注册监听器
【案例实现】
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Vector;
import java.math.BigDecimal;
public class Calculator {
// 操作数1,为了程序的安全,初值一定设置,这里我们设置为0。
String str1 = "0";
// 操作数2
String str2 = "0";
// 运算符
String signal = "+";
// 运算结果
String result = "";
// 以下k1至k5为状态开关
// 开关1用于选择输入方向,将要写入str1或str2
// 为 1 时写入 str1,为 2 时写入 str2
int k1 = 1;
// 开关 2 用于记录符号键的次数
// 如果 k2>1 说明进行的是 2+3-9+8 这样的多符号运算
int k2 = 1;
// 开关3用于标识 str1 是否可以被清 0
// 等于 1 时可以,不等于1时不能被清0
int k3 = 1;
// 开关4用于标识 str2 是否可以被清 0
// 等于 1 时可以,不等于1时不能被清0
int k4 = 1;
// 开关5用于控制小数点可否被录入
// 等于1时可以,不为1时,输入的小数点被丢掉
int k5 = 1;
// store的作用类似于寄存器,用于记录是否连续按下符号键
JButton store;
//vt 存储之前输入的运算符。
@SuppressWarnings("rawtypes")
Vector vt = new Vector(20, 10);
// 创建一个 JFrame 对象并初始化。JFrame 可以理解为程序的主窗体。
JFrame frame = new JFrame("Calculator");
//创建一个JTextField对象并初始化。JTextField用于显示操作和计算结果的文本框。
// 参数 20 表明可以显示 20 列的文本内容
JTextField result_TextField = new JTextField(result, 20);
// 清除按钮
JButton clear_Button = new JButton("Clear");
// 数字键0到9
JButton button0 = new JButton("0");
JButton button1 = new JButton("1");
JButton button2 = new JButton("2");
JButton button3 = new JButton("3");
JButton button4 = new JButton("4");
JButton button5 = new JButton("5");
JButton button6 = new JButton("6");
JButton button7 = new JButton("7");
JButton button8 = new JButton("8");
JButton button9 = new JButton("9");
// 计算命令按钮,加减乘除以及小数点等
JButton button_Dian = new JButton(".");
JButton button_jia = new JButton("+");
JButton button_jian = new JButton("-");
JButton button_cheng = new JButton("*");
JButton button_chu = new JButton("/");
JButton button_dy = new JButton("=");
public Calculator() {
button0.setMnemonic(KeyEvent.VK_0);
result_TextField.setHorizontalAlignment(JTextField.RIGHT);
// 创建一个 Jpanel 对象并初始化
JPanel pan = new JPanel();
// 设置该容器的布局为四行四列,边距为5像素
pan.setLayout(new GridLayout(4, 4, 5, 5));
// 将用于计算的按钮添加到容器内
pan.add(button7);
pan.add(button8);
pan.add(button9);
pan.add(button_chu);
pan.add(button4);
pan.add(button5);
pan.add(button6);
pan.add(button_cheng);
pan.add(button1);
pan.add(button2);
pan.add(button3);
pan.add(button_jian);
pan.add(button0);
pan.add(button_Dian);
pan.add(button_dy);
pan.add(button_jia);
// 设置 pan 对象的边距
pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// 按照同样的方式设置第二个JPanel
JPanel pan2 = new JPanel();
pan2.setLayout(new BorderLayout());
pan2.add(result_TextField, BorderLayout.WEST);
pan2.add(clear_Button, BorderLayout.EAST);
// 设置主窗口出现在屏幕上的位置
frame.setLocation(300, 200);
// 设置窗体可以调大小
frame.setResizable(true);
//窗体中可以放置 JPanel,这里我们将面板pan和面板pan2让如窗体
frame.getContentPane().setLayout(new BorderLayout());
frame.getContentPane().add(pan2, BorderLayout.NORTH);
frame.getContentPane().add(pan, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
//Listener类中编写的是数字键的响应逻辑。
class Listener implements ActionListener {
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
String ss = ((JButton) e.getSource()).getText();
store = (JButton) e.getSource();
vt.add(store);
if (k1 == 1) {
if (k3 == 1) {
str1 = "";
k5 = 1;
}
str1 = str1 + ss;
k3 = k3 + 1;
result_TextField.setText(str1);
} else if (k1 == 2) {
if (k4 == 1) {
str2 = "";
k5 = 1;
}
str2 = str2 + ss;
k4 = k4 + 1;
result_TextField.setText(str2);
}
}
}
//Listener_signal类中编写了运算符号键的响应逻辑
class Listener_signal implements ActionListener {
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
String ss2 = ((JButton) e.getSource()).getText();
store = (JButton) e.getSource();
vt.add(store);
if (k2 == 1) {
k1 = 2;
k5 = 1;
signal = ss2;
k2 = k2 + 1;
} else {
int a = vt.size();
JButton c = (JButton) vt.get(a - 2);
if (!(c.getText().equals("+"))
&& !(c.getText().equals("-"))
&& !(c.getText().equals("*"))
&& !(c.getText().equals("/")))
{
cal();
str1 = result;
k1 = 2;
k5 = 1;
k4 = 1;
signal = ss2;
}
k2 = k2 + 1;
}
}
}
//Listener_clear类中编写了清除键的响应逻辑
class Listener_clear implements ActionListener {
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
store = (JButton) e.getSource();
vt.add(store);
k5 = 1;
k2 = 1;
k1 = 1;
k3 = 1;
k4 = 1;
str1 = "0";
str2 = "0";
signal = "";
result = "";
result_TextField.setText(result);
vt.clear();
}
}
//Listener_dy类中编写的是等于号键的响应逻辑
class Listener_dy implements ActionListener {
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
store = (JButton) e.getSource();
vt.add(store);
cal();
k1 = 1;
k2 = 1;
k3 = 1;
k4 = 1;
str1 = result;
}
}
//Listener_xiaos类中编写的是小数点键的相应逻辑
class Listener_xiaos implements ActionListener {
@SuppressWarnings("unchecked")
public void actionPerformed(ActionEvent e) {
store = (JButton) e.getSource();
vt.add(store);
if (k5 == 1) {
String ss2 = ((JButton) e.getSource()).getText();
if (k1 == 1) {
if (k3 == 1) {
str1 = "";
k5 = 1;
}
str1 = str1 + ss2;
k3 = k3 + 1;
result_TextField.setText(str1);
} else if (k1 == 2) {
if (k4 == 1) {
str2 = "";
k5 = 1;
}
str2 = str2 + ss2;
k4 = k4 + 1;
result_TextField.setText(str2);
}
}
k5 = k5 + 1;
}
}
// 监听等于键
Listener_dy jt_dy = new Listener_dy();
// 监听数字键
Listener jt = new Listener();
// 监听符号键
Listener_signal jt_signal = new Listener_signal();
// 监听清除键
Listener_clear jt_c = new Listener_clear();
// 监听小数点键
Listener_xiaos jt_xs = new Listener_xiaos();
button7.addActionListener(jt);
button8.addActionListener(jt);
button9.addActionListener(jt);
button_chu.addActionListener(jt_signal);
button4.addActionListener(jt);
button5.addActionListener(jt);
button6.addActionListener(jt);
button_cheng.addActionListener(jt_signal);
button1.addActionListener(jt);
button2.addActionListener(jt);
button3.addActionListener(jt);
button_jian.addActionListener(jt_signal);
button0.addActionListener(jt);
button_Dian.addActionListener(jt_xs);
button_dy.addActionListener(jt_dy);
button_jia.addActionListener(jt_signal);
clear_Button.addActionListener(jt_c);
// 窗体关闭事件的响应程序
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
}
// calc()方法中编写了计算逻辑的实现。
public void cal() {
double a2;
double b2;
String c = signal;
double result2 = 0;
if (c.equals("")) {
result_TextField.setText("Please input operator");
} else {
if (str1.equals("."))
str1 = "0.0";
if (str2.equals("."))
str2 = "0.0";
a2 = Double.valueOf(str1).doubleValue();
b2 = Double.valueOf(str2).doubleValue();
if (c.equals("+")) {
result2 = a2 + b2;
}
if (c.equals("-")) {
result2 = a2 - b2;
}
if (c.equals("*")) {
BigDecimal m1 = new BigDecimal(Double.toString(a2));
BigDecimal m2 = new
BigDecimal(Double.toString(b2));
result2 = m1.multiply(m2).doubleValue();
}
if (c.equals("/")) {
if (b2 == 0) {
result2 = 0;
} else {
result2 = a2 / b2;
}
}
result = ((new Double(result2)).toString());
result_TextField.setText(result);
}
}
@SuppressWarnings("unused")
public static void main(String[] args) {
try {
//通过 UIManager 来设置窗体的 UI 风格
UIManager.setLookAndFeel("javax.swing.plaf.metal.MetalLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}
Calculator cal = new Calculator();
}
}
上述代码中,第7-32行代码,定义了一些成员变量,方便响应的逻辑实现。第34-35行代码,创建了一个Vector对象,存储之前输入的运算符。第37行代码,创建了一个 JFrame 对象并初始化。JFrame 可以理解为程序的主窗体。第40行代码,创建了一个JTextField对象并初始化。JTextField用于显示操作和计算结果的文本框。参数 20 表明可以显示 20 列的文本内容。
第42行代码,创建了一个清除按钮对象。第44-53行,创建数字键0-9按钮对象。第55-60行,创建计算命令按钮,加减乘除以及小数点等按钮对象。第65-101行代码,是对计算器进行布局。
Listener类中编写的是数字键的响应逻辑。Listener_xiaos类中编写的是小数点键的相应逻辑。Listener_signal类中编写了运算符号键的响应逻辑。Listener_dy类中编写的是等于号键的响应逻辑。Listener_clear类中编写了清除键的响应逻辑。
calc()方法中编写了计算逻辑的实现。第222-247行代码,创建监听对象,斌对各个按键进行监听。第249-253行代码,为窗体关闭事件的响应程序。第297行代码,通过 UIManager 来设置窗体的 UI 风格。
【案例11-3】 模拟QQ登录
【案例介绍】
1.案例描述
QQ是现实生活中常用的聊天工具,QQ登录界面看似小巧、简单,但其中涉及的内容却很多,对于初学者练习Java Swing工具的使用非常合适。本案例要求使用所学的Java Swing知识,模拟实现一个QQ登录界面。
2.运行结果
【案例目标】
-
学会分析“模拟QQ登录”程序实现的逻辑思路。
-
能够独立完成“模拟QQ登录”程序的源代码编写、编译及运行。
-
掌握Java Swing界面编程的应用。
【案例分析】
(1)首先,需要定义一些成员变量,如最小化、关闭、账号、密码、头像等,方便响应的逻辑实现。
(2)由于需要对账号、密码、头像等进行布局,故需要先对这些对象进行实例化。
(3)在对需要用到的文本框、图片等对象进行实例化过后,可以使用对象.setBounds()设置文本框、图片等组件的位置。
(4)接下来,对最小化、关闭、账号、密码、头像等添加监听事件。同时,对窗体也添加窗体拖动监听事件。
(5)最后,为最小化、关闭等编写点击时的执行逻辑。为账号、密码等设置点击、悬停等执行逻辑。
【案例实现】
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Font;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class Login extends JFrame implements MouseListener
{
JLabel bacgrangd, jan, bi, QQ, qq, tu; //gif,最小化,关闭,logo,QQ,头像
JLabel an1, an2, lie1, lie2;// 暗色块|线
JTextField user;// 账号
JPasswordField pass;// 密码
JPanel bgcolor;// 白
JLabel su1, mi1, ku1, ku2, gou1, gou2;// 缩略图
JLabel text1, text2, text3, text4, text5;//自动登录,记住密码,找回密码,注册账号,登录
static Point origin = new Point();// 变量,用于可拖动窗体
int a = 0, b = 0, c = 0, d = 0;// 控制线
int f = 0, g = 0, h = 0, j = 0;// 控制√
JLabel submit, ma;// 背景
public Login()
{
//实例化
bacgrangd = new JLabel(new ImageIcon("images/1.gif"));
jan = new JLabel(new ImageIcon("images/最小化.png"));
bi = new JLabel(new ImageIcon("images/关闭.png"));
QQ = new JLabel(new ImageIcon("imagesqq.png"));
qq = new JLabel("QQ");
an1 = new JLabel();
an2 = new JLabel();// 暗调
tu = new JLabel(new ImageIcon("images/头像.png"));
user = new JTextField();
pass = new JPasswordField();
su1 = new JLabel(new ImageIcon("images/qq (1).png"));
mi1 = new JLabel(new ImageIcon("images/密码.png"));
lie1 = new JLabel(new ImageIcon("images/直线2.png"));
lie2 = new JLabel(new ImageIcon("images/直线2.png"));
bgcolor = new JPanel();
ku1 = new JLabel(new ImageIcon("images/框框.png"));
ku2 = new JLabel(new ImageIcon("images/框框.png"));
gou1 = new JLabel(new ImageIcon("images/对勾.png"));
gou2 = new JLabel(new ImageIcon("images/对勾.png"));
text1 = new JLabel("自动登录");
text2 = new JLabel("记住密码");
text3 = new JLabel("找回密码");
text4 = new JLabel("注册账号");
text5 = new JLabel("登录");
submit = new JLabel();
ma = new JLabel(new ImageIcon("images/二维码.png"));
//位置
bacgrangd.setBounds(-35, -123, 500, 250);
jan.setBounds(364, 2, 32, 32);
bi.setBounds(396, 3, 32, 32);
QQ.setBounds(10, 10, 32, 32);
qq.setBounds(50, 5, 45, 45);
an1.setBounds(361, 0, 35, 35);
an2.setBounds(395, 0, 35, 35);
tu.setBounds(170, 80, 90, 85);
user.setBounds(130, 160, 180, 40);
pass.setBounds(130, 200, 180, 40);
su1.setBounds(100, 170, 20, 20);
mi1.setBounds(100, 210, 20, 20);
lie1.setBounds(100, 190, 240, 10);
lie2.setBounds(100, 230, 240, 10);
bgcolor.setBounds(0, 125, 500, 300);
ku1.setBounds(100, 250, 20, 20);
ku2.setBounds(190, 250, 20, 20);
gou1.setBounds(106, 255, 10, 10);
gou2.setBounds(196, 255, 10, 10);
text1.setBounds(125, 250, 80, 20);
text2.setBounds(215, 250, 80, 20);
text3.setBounds(288, 250, 80, 20);
text4.setBounds(15, 300, 80, 20);
text5.setBounds(206, 285, 80, 20);
submit.setBounds(100, 280, 242, 35);
ma.setBounds(385, 290, 30, 30);
//属性
qq.setFont(new Font("微软雅黑", 1, 25));
qq.setForeground(Color.white);
an1.setBackground(new Color(0, 0, 0, 0.3f));
an2.setBackground(new Color(0, 0, 0, 0.3f));
bgcolor.setBackground(new Color(255, 255, 255));
user.setForeground(Color.gray);
user.setText("QQ号码/手机/邮箱");
user.setOpaque(false);// 透明背景
user.setBorder(null);// 去掉边框
// 框内文字样式
user.setFont(new Font("微软雅黑", Font.PLAIN, 16));
// 框内文字样式
pass.setFont(new Font("微软雅黑", Font.PLAIN, 16));
pass.setBorder(null);// 去掉边框
pass.setOpaque(false);// 透明背景
pass.setForeground(Color.gray);
pass.setText("密码");
pass.setEchoChar((char) 0);// 让密码显示出来
text1.setFont(new Font("微软雅黑", 0, 12));
text2.setFont(new Font("微软雅黑", 0, 12));
text3.setFont(new Font("微软雅黑", 0, 12));
text4.setFont(new Font("微软雅黑", 0, 12));
text5.setFont(new Font("微软雅黑", 0, 15));
text1.setForeground(new Color(170, 170, 170));
text2.setForeground(new Color(170, 170, 170));
text3.setForeground(new Color(170, 170, 170));
text4.setForeground(new Color(170, 170, 170));
text5.setForeground(Color.white);
gou1.setVisible(false);
gou2.setVisible(false);
submit.setBackground(new Color(5, 186, 251));
submit.setOpaque(true);
text3.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
text4.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
//事件区域
jan.addMouseListener(this);
bi.addMouseListener(this);
user.addMouseListener(this);
pass.addMouseListener(this);
text1.addMouseListener(this);
text2.addMouseListener(this);
text3.addMouseListener(this);
text4.addMouseListener(this);
ku1.addMouseListener(this);
ku2.addMouseListener(this);
submit.addMouseListener(this);
ma.addMouseListener(this);
this.addMouseListener(this);
// 窗体拖动事件
this.addMouseMotionListener(new MouseMotionListener()
{
public void mouseMoved(MouseEvent e)
{
}
public void mouseDragged(MouseEvent e)
{
Point p = getLocation();
setLocation(p.x + e.getX() - origin.x, p.y + e.getY() - origin.y);
}
});
user.addFocusListener(new FocusListener()
{
public void focusLost(FocusEvent e) // 失去焦点
{
su1.setIcon(new javax.swing.ImageIcon("images/qq (1).png"));
lie1.setIcon(new javax.swing.ImageIcon("images/直线2.png"));
c = 0;
// 判断是否为空(为了设置默认提示语)
if (user.getText().isEmpty())
{
user.setForeground(Color.gray);
user.setText("QQ号码/手机/邮箱");
}
}
// 得到焦点
public void focusGained(FocusEvent e)
{
user.setForeground(Color.black);
lie1.setIcon(new javax.swing.ImageIcon("images/直线3.png"));
a = 1;
c = 1;
b = 0;
su1.setIcon(new javax.swing.ImageIcon("images/qq(2).png"));
if (user.getText().equals("QQ号码/手机/邮箱"))
{
user.setText("");
}
else
{
user.setText(user.getText());
user.selectAll();
}
}
});
pass.addFocusListener(new FocusListener()
{
// 失去焦点
public void focusLost(FocusEvent e)
{
// 失去焦点换图片
lie2.setIcon(new javax.swing.ImageIcon("images/直2.png"));
mi1.setIcon(new javax.swing.ImageIcon("images/密码.png"));
d = 0;
if (pass.getText().isEmpty())
{
pass.setForeground(Color.gray);
pass.setText("密码");
pass.setEchoChar((char) 0);// 让密码显示出来
}
}
public void focusGained(FocusEvent e) // 得到焦点
{
mi1.setIcon(new javax.swing.ImageIcon("images/密码(1).png"));
lie2.setIcon(new javax.swing.ImageIcon("images/直线3.png"));
b = 1;
a = 0;
d = 1;
pass.setForeground(Color.black);
pass.setEchoChar('*');// 让用户输入看不见
if (pass.getText().equals("密码"))
{
pass.setText("");
}
else
{
pass.setText(pass.getText());
}
}
});
this.setLayout(null);// 布局
this.add(jan);
this.add(bi);
this.add(qq);
this.add(QQ);
this.add(an1);
this.add(an2);
this.add(tu);
this.add(lie1);
this.add(lie2);
this.add(user);
this.add(pass);
this.add(su1);
this.add(mi1);
this.add(gou1);
this.add(gou2);
this.add(ku1);
this.add(ku2);
this.add(text1);
this.add(text2);
this.add(text3);
this.add(text4);
this.add(text5);
this.add(submit);
this.add(ma);
this.add(bgcolor);
this.add(bacgrangd);
this.setSize(430, 330);
this.setIconImage(Toolkit.getDefaultToolkit().createImage("images/ 透明照片.png"));// 窗体图标
this.setLocationRelativeTo(null);// 保持居中
this.setUndecorated(true);// 去顶部
this.setFocusable(true);// 面板首先获得焦点
this.setBackground(new Color(255, 255, 255));// 背景颜色
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
this.setAlwaysOnTop(true);// 最顶层
this.setVisible(true);// 显示
}
public static void main(String[] args)
{
new Login();
}
// 点击不恢复
public void mouseClicked(MouseEvent e)
{
}
// 点击后
public void mousePressed(MouseEvent e)
{
if (e.getSource() == jan)
{
setExtendedState(JFrame.ICONIFIED);
}
else if (e.getSource() == this)
{
origin.x = e.getX();
origin.y = e.getY();
}
else if (e.getSource() == bi)
{
System.exit(0);
}
else if (e.getSource() == ku1 || e.getSource() == text1)
{
if (f == 0)
{
gou1.setVisible(true);
g = 1;
f = 1;
}
else if (g == 1)
{
gou1.setVisible(false);
f = 0;
g = 0;
}
}
else if (e.getSource() == ku2 || e.getSource() == text2)
{
if (h == 0)
{
gou2.setVisible(true);
j = 1;
h = 1;
}
else if (j == 1)
{
gou2.setVisible(false);
h = 0;
j = 0;
}
}
else if (e.getSource() == submit || e.getSource() == text5)
{
text5.setFont(new Font("微软雅黑", 0, 14));
dispose();
String users = user.getText();
String password = pass.getText();
if (users.equals("itcast") && password.equals("123"))
{
//new Table();//打开新的主界面如果要关闭登录界面可以写dispose();
}
else
{
JOptionPane.showMessageDialog(null, "用户名:itcast,密码:123,您并未设置打开界面!");
new Login();
}
}
}
// 点击时
public void mouseReleased(MouseEvent e)
{
if (e.getSource() == submit || e.getSource() == text5)
{
text5.setFont(new Font("微软雅黑", 0, 15));
}
}
// 悬停
public void mouseEntered(MouseEvent e)
{
if (e.getSource() == jan)
{
an1.setOpaque(true);
}
else if (e.getSource() == bi)
{
an2.setOpaque(true);
}
else if (e.getSource() == user)
{
if (a == 0 && c == 0)
{
lie1.setIcon(new javax.swing.ImageIcon("images/直线4.png"));
}
}
else if (e.getSource() == pass)
{
if (b == 0 && d == 0)
{
lie2.setIcon(new javax.swing.ImageIcon("images/直线4.png"));
}
}
else if (e.getSource() == text3)
{
text3.setForeground(Color.GRAY);
}
else if (e.getSource() == text4)
{
text4.setForeground(Color.GRAY);
}
else if (e.getSource() == ma)
{
ma.setIcon(new javax.swing.ImageIcon("images/二维码2.png"));
}
}
public void mouseExited(MouseEvent e) // 悬停后
{
if (e.getSource() == jan)
{
an1.setOpaque(false);
}
else if (e.getSource() == bi)
{
an2.setOpaque(false);
}
else if (e.getSource() == user)
{
if (a == 0)
{
lie1.setIcon(new javax.swing.ImageIcon("images/直线2.png"));
}
}
else if (e.getSource() == pass)
{
if (b == 0)
{
lie2.setIcon(new javax.swing.ImageIcon("images/直线2.png"));
}
}
else if (e.getSource() == text3)
{
text3.setForeground(new Color(170, 170, 170));
}
else if (e.getSource() == text4)
{
text4.setForeground(new Color(170, 170, 170));
}
else if (e.getSource() == ma)
{
ma.setIcon(new javax.swing.ImageIcon("images/二码.png"));
}
}
}
上述代码中,第19-30行代码,定义了一些成员变量,方便响应的逻辑实现。第33-58行代码,对一些图片对象进行实例化。第60-85行,设置图片、文本框等的位置。第87-120行,设置各个文本框,文字等的样式。第122-134行,为各个文本框、按钮等设置监听事件。
第136-143行,为窗体拖动事件设置窗体监听。第144-170,为账号文本框设置鼠标聚焦事件。第171-200,为密码文本框设置鼠标聚焦事件。第201-227行,将各个按钮,图片文本框对象放入容器内。
第228-238,对界面进行布局。mouseClicked()方法中编写了按钮,文本框,文字等点击不回复的逻辑。mousePressed()方法中编写了按钮,文本框,文字等点击后的逻辑。mouseReleased()方法中编写了按钮,文本框,文字等点击时的逻辑。mouseEntered()方法中编写了按钮,文本框,文字等悬停时的逻辑。mouseExited()方法中编写了按钮,文本框,文字等悬停后的逻辑。