1.GUI概述和GUI与CLI的区别

2.java.awt和javax.swing包的区别
Java为GUI提供的对象都存在java.Awt和javax.Swing两个包中。
java.awt:Abstract Window ToolKit (抽象窗口工具包),需要调用本地系统方法实现功能。属重量级控件。
javax.swing:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由Java实现。增强了移植性,属轻量级控件。
javax--- java扩展包
轻量级(移植性好),重量级(移植性差)说的是与系统的关联性的大小
3.GUI中组件继承图

那么,从哪里学起呢??
Component??Container??
都不是,应该从Frame学起。


Frame继承的方法太多了,,,,但是Frame本身的方法不多。

4.HelloWorld窗体案例
===============================================
public class FrameDemo {
public static void main(String[] args) {
// 创建窗体对象
// Frame f = new Frame();
// Frame(String title)
Frame f = new Frame("林青霞");//设置窗体标题可以用构造方法
// 设置窗体标题
f.setTitle("HelloWorld");//设置窗口标题的第二个方法
// 设置窗体大小
f.setSize(400, 300); // 单位:像素
// 设置窗体位置(就是设置程序一运行就弹出窗口的位置,默认左上角)
f.setLocation(400, 200);
// 调用一个方法,设置让窗体可见
// f.show();//已过时
f.setVisible(true);//setVisible一般放在最后写,因为设置好窗体才看到窗体比较好(就好像穿好衣服化好妆出门才好)
// System.out.println("helloworld");
}
}
==================================================
以下是一些解析以及注意的问题
窗体直接点右上角(如图红色关闭区域)关闭不了,而是要强制关闭程序才可以。

窗体太小,调大一点

改变打开时窗体弹出的位置

5.优化HelloWorld窗体案例代码
public class FrameDemo2 {
public static void main(String[] args) {
// 创建对象
Frame f = new Frame("方法调用的前后关系");
// f.setVisible(true);
// try {
// Thread.sleep(3000);//让线程睡一会的目的就是说setVisible要放到最后而不要放在前面,也就是先设置窗体位置大小,再显示窗体,就好像先穿衣服,打扮再出门。
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// // f.setSize(400, 300);
// // Dimension(int width, int height)
// Dimension d = new Dimension(400, 300);
// f.setSize(d);
// // f.setLocation(400, 200);
// // Point(int x, int y)
// Point p = new Point(400, 200);
// f.setLocation(p);
// 一个方法搞定
f.setBounds(400, 200, 400, 300);
f.setVisible(true);
}
}
============================================
以下是解析
f.setSize(400, 300);
等价于
// Dimension(int width, int height)
// Dimension d = new Dimension(400, 300);
// f.setSize(d);
=================================
f.setLocation(400, 200);
等价于
// Point(int x, int y)//point是点的意思
// Point p = new Point(400, 200);
// f.setLocation(p);
====================================
其实,
// 设置窗体大小
f.setSize(400, 300); // 单位:像素
// 设置窗体位置
f.setLocation(400, 200);
以上两行代码直接可以用一句来代替
// 一个方法搞定
f.setBounds(400, 200, 400, 300);
也就是,最终三行代码搞掂

============================================================
6.事件监听机制原理概述及举例
事件监听机制:
A:事件源 事件发生的地方
B:事件 就是要发生的事情
C:事件处理 就是针对发生的事情做出的处理方案
D:事件监听 就是把事件源和事件关联起来
举例:人受伤事件。
事件源:人(具体的对象)
Person p1 = new Person("张三");
Person p2 = new Person("李四");
事件:受伤
interface 受伤接口 {
一拳();
一脚();
一板砖();
}
事件处理:
受伤处理类 implements 受伤接口 {
一拳(){ System.out.println("鼻子流血了,送到卫生间洗洗"); }
一脚(){ System.out.println("晕倒了,送到通风处"); }
一板砖(){ System.out.println("头破血流,送到太平间"); }
}
事件监听:
p1.注册监听(受伤接口)
7.窗体关闭案例
public class FrameDemo {
public static void main(String[] args) {
// 创建窗体对象
Frame f = new Frame("窗体关闭案例");
// 设置窗体属性
f.setBounds(400, 200, 400, 300);
// 让窗体关闭
//事件源---f为事件源
//事件:对窗体的处理
//事件处理:关闭窗口(System.exit(0));//退出虚拟机
//事件监听
f.addWindowListener(new WindowListener() {//匿名内部类
@Override
public void windowOpened(WindowEvent e) {
}
@Override
public void windowIconified(WindowEvent e) {
}
@Override
public void windowDeiconified(WindowEvent e) {
}
@Override
public void windowDeactivated(WindowEvent e) {
}
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);//退出虚拟机
}
@Override
public void windowClosed(WindowEvent e) {
}
@Override
public void windowActivated(WindowEvent e) {
}
});
// 设置窗体可见
f.setVisible(true);
}
}
添加事件监听后窗体就可以通过点右上角红色的关闭按钮关闭了
8.适配器设计模式讲解
如上面代码可以看见,代码非常多且累赘,那些并不需要(甚至说不应该或者说不能)实现的方法也强迫要实现
问题:
* 接口(方法比较多) -- 实现类(仅仅使用一个,也得把其他的实现给提供了,哪怕是空实现)
* 太麻烦了。
* 解决方案:
* 接口(方法比较多) -- 适配器类(实现接口,仅仅空实现) -- 实现类(用哪个重写哪个)//适配器类实现了分离
================================================
首先新建一个接口
/*
* 针对用户操作的四种功能
*/
public interface UserDao {
public abstract void add();
public abstract void delete();
public abstract void update();
public abstract void find();
}
=========================================
然后实现这个接口//这个实现类需要实现全部方法比较麻烦
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("添加功能");
}
@Override
public void delete() {
System.out.println("删除功能");
}
@Override
public void update() {
System.out.println("修改功能");
}
@Override
public void find() {
System.out.println("查找功能");
}
}
====================================================
测试类中
public class UserDaoDemo {
public static void main(String[] args) {
UserDao ud = new UserDaoImpl();
ud.add();//为了用add方法必须把其余三个方法也实现了,不太合理
}
}
=====================================================
下面,加入适配器
先建一个抽象类(适配器)实现UserDao接口(空实现)
public abstract class UserAdapter implements UserDao {
@Override
public void add() {
}
@Override
public void delete() {
}
@Override
public void update() {
}
@Override
public void find() {
}
}
===========================================================
然后,新建一个类实现UserDao接口,但是不直接实现UserDao,而是继承UserAdapter (因为它实现了那个接口)
public class UserDaoImpl2 extends UserAdapter {
@Override
public void add() {
System.out.println("添加功能");
}
}
//UserDaoImpl2 比UserDapImpl1简洁多了
================================================
测试类中
public class UserDaoDemo {
public static void main(String[] args) {
// UserDao ud = new UserDaoImpl();
// ud.add();
// 我没有说我们需要四种功能都实现啊。
UserDao ud2 = new UserDaoImpl2();
ud2.add();
}
}
============================================
附上新建截图


9.适配器类改进窗体关闭案例
原来代码是这样的

用适配器改进后
//用适配器类改进
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
简洁了很多
==================================================
10窗体添加按钮并对按钮添加事件案例
需求:把按钮添加到窗体,并对按钮添加一个点击事件。
A:创建窗体对象
B:创建按钮对象
C:把按钮添加到窗体
D:窗体显示
==============================================
public class FrameDemo {
public static void main(String[] args) {
// 创建窗体对象
Frame f = new Frame("添加按钮");
// 设置属性
f.setBounds(400, 200, 400, 300);
// 设置布局为流式布局
f.setLayout(new FlowLayout());
// 创建按钮对象
Button bu = new Button("点我啊");
// bu.setSize(20, 10);
// 把按钮添加到窗体
f.add(bu);
// 设置窗体可以关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
bu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("你再点试试");
}
});
// 窗体显示
f.setVisible(true);
}
}
=================================================
下面是一些解析
首先讲一下为什么要f.setLayout(new FlowLayout());
这个涉及窗体布局方案的问题

如果不设置布局的话,默认是边界布局(BoderLayout),但是可以看到,这个按钮填充了整个窗体

因为边界布局分东,南,西,北,中按钮默认在中间,而其它位置有没有任何东西,所以它填充满了
整个窗体
还有名字忘了不要紧,会查就行---setLayout传的参数就是LayoutManager(接口)

还有适配器的问题,为什么ActionListener不用适配器呢?---原因是,整个接口本来就只需要实现一个方法,没必要动用到适配器类

运行示例

11.把文本框的值转移到文本域案例
案例预览
需求:如下图
把文本框数据转移到文本域

=======================================================
public class FrameDemo {
public static void main(String[] args) {
// 创建窗体对象
Frame f = new Frame("数据转移");
// 设置窗体属性和布局
f.setBounds(400, 200, 400, 300);
f.setLayout(new FlowLayout());
// 创建文本框
final TextField tf = new TextField(20);
// 创建按钮
Button bu = new Button("数据转移");
// 创建文本域
final TextArea ta = new TextArea(10, 40);
// 把组件添加到窗体
f.add(tf);
f.add(bu);
f.add(ta);
// 设置窗体关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// 对按钮添加事件
bu.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 获取文本框的值
String tf_str = tf.getText().trim();//trim防止多余空格的输入
// 清空数据
tf.setText("");
// 设置给文本域
// ta.setText(tf_str);
// 追加和换行
ta.append(tf_str + "\r\n");//\r\n起到换行的作用,但是直接\n也可以??
//获取光标
tf.requestFocus();//点击按钮后光标自动回到TextField中
}
});
// 设置窗体显示
f.setVisible(true);
}
}
=================================================
以下为解析以及一些注意事项
TextField一般用列数那个构造方法

以下的问题在eclipse3.7(JDK1.7)报错,但是在eclipse4.4(JDK1.8)却不报错,我也不知道为什么
附上网上解析:
局部内部类,只能访问被final修饰的局部变量
内部类绝对不能访问非final的成员变量
因为内部类 也是类,他们实例化后存储在堆中;局部变量存储在栈中,所以一般情况而言内部类的声明周期长于局部变量。
试想一个活着的内部类去访问一个声明周期已经结束的局部变量~
因为内部类 也是类,他们实例化后存储在堆中;局部变量存储在栈中,所以一般情况而言内部类的声明周期长于局部变量。
试想一个活着的内部类去访问一个声明周期已经结束的局部变量~
所以,极有可能的原因是: jdk1.8版本内部类成员变量不用final修饰也能访问

以前关于局部内部类的笔记

解决后
// 创建文本框
final TextField tf = new TextField(20);
// 创建文本域
final TextArea ta = new TextArea(10, 40);
=============================================
获取光标的意图

12.通过鼠标移动到按钮上更改背景色案例
需求:

public class FrameDemo {
public static void main(String[] args) {
// 创建窗体对象
final Frame f = new Frame("更改背景色");
// 设置窗体属性和布局
f.setBounds(400, 200, 400, 300);
f.setLayout(new FlowLayout());
// 创建四个按钮
Button redButton = new Button("红色");
Button greenButton = new Button("绿色");
Button buleButton = new Button("蓝色");
// 添加按钮
f.add(redButton);
f.add(greenButton);
f.add(buleButton);
// 设置窗体关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// 对按钮添加动作事件
// redButton.addActionListener(new ActionListener() {
// @Override
// public void actionPerformed(ActionEvent e) {
// f.setBackground(Color.RED);
// }
// });
// 对按钮添加鼠标点击事件
// redButton.addMouseListener(new MouseAdapter() {
// @Override
// public void mouseClicked(MouseEvent e) {
// f.setBackground(Color.RED);
// }
// });
// 对按钮添加鼠标的进入事件
redButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
f.setBackground(Color.RED);
}
});
redButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseExited(MouseEvent e) {
f.setBackground(Color.WHITE);
}
});
greenButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
f.setBackground(Color.GREEN);
}
});
greenButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseExited(MouseEvent e) {
f.setBackground(Color.WHITE);
}
});
buleButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
f.setBackground(Color.BLUE);
}
});
buleButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseExited(MouseEvent e) {
f.setBackground(Color.WHITE);
}
});
// 设置窗体显示
f.setVisible(true);
}
}
==============================================
解析
代码看着很长,其实很多重复的内容
动作事件和鼠标事件

redButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
f.setBackground(Color.RED);
}
});
鼠标事件用了适配器,因为原监听器接口要实现的方法挺多
mouseEntered: 鼠标移动到按钮区域就变颜色(移动到但是没有点按钮)
mouseExited: 鼠标离开按钮区域就变颜色(离开但是没有点按钮)
====================================================
13.如何控制在文本框里面只能输入数字字符案例
需求:

/*
* 你输入的如果是非数字字符,就取消你键盘录入的效果。
*/
public class FrameDemo {
public static void main(String[] args) {
// 创建窗体对象并设置属性
Frame f = new Frame("不能输入非数字字符");
f.setBounds(400, 200, 400, 300);
f.setLayout(new FlowLayout());
// 创建Label标签对象
Label label = new Label("请输入你的QQ号码,不能是非数字,不信你试试");
TextField tf = new TextField(40);
// 添加到窗体上
f.add(label);
f.add(tf);
// 设置窗体关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
// 给文本框添加事件
tf.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
// 如果你取得的字符不是数字字符就取消事件
// 思路:先获取字符,判断字符,取消事件
// char getKeyChar()
char ch = e.getKeyChar();
// System.out.println(ch);
if(!(ch>='0' && ch<='9')){
e.consume();//取消该键盘录入事件
}
}
});
// 设置窗体可见
f.setVisible(true);
}
}
===============================================
以下为解析
keyPressed---keyAdapter接口中

可以看见,有三个方法,所以适配器替代了原来的监听器
还有,注意几个方法,getKeyChar(),consume() ----都在KeyEvent 类中

consume在代码中意思是取消该事件,让事件不再发生。在本案例中是当检测到非法字符时不输入(忽略输入非法字符)
14.一级菜单案例
需求:
/*
* 一级菜单
*/
public class FrameDemo {
public static void main(String[] args) {
// 创建窗体对象并设置属性
Frame f = new Frame("一级菜单");
f.setBounds(400, 200, 400, 300);
f.setLayout(new FlowLayout());
// 创建菜单栏
MenuBar mb = new MenuBar();
// 创建菜单
Menu m = new Menu("文件");
// 创建菜单项
MenuItem mi = new MenuItem("退出系统");
// 谁添加谁呢
m.add(mi);
mb.add(m);
// 设置菜单栏
f.setMenuBar(mb);
// 设置窗体关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
mi.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
// 设置窗体可见
f.setVisible(true);
}
}
===============================================
一个注意的问题
setMenuBar而不是add

15.多级菜单案例
需求

*
* 多级菜单
*/
public class FrameDemo {
public static void main(String[] args) {
// 创建窗体对象并设置属性
final Frame f = new Frame("多级菜单");
f.setBounds(400, 200, 400, 300);
f.setLayout(new FlowLayout());
final String name = f.getTitle();
// 创建菜单栏
MenuBar mb = new MenuBar();
// 创建菜单
Menu m1 = new Menu("文件");
Menu m2 = new Menu("更改名称");
// 创建菜单项
final MenuItem mi1 = new MenuItem("好好学习");
final MenuItem mi2 = new MenuItem("天天向上");
MenuItem mi3 = new MenuItem("恢复标题");
MenuItem mi4 = new MenuItem("打开记事本");
MenuItem mi5 = new MenuItem("退出系统");
// 谁添加谁呢
m2.add(mi1);
m2.add(mi2);
m2.add(mi3);
m1.add(m2);
m1.add(mi4);
m1.add(mi5);
mb.add(m1);
// 设置菜单栏
f.setMenuBar(mb);
// 设置窗体关闭
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
mi1.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
f.setTitle(mi1.getLabel());//getLabel表示这个Item的名称是什么就把它设置为Frame的标题
}
});
mi2.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
f.setTitle(mi2.getLabel());
}
});
mi3.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
f.setTitle(name);//name为最初的标题
}
});
mi4.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
Runtime r = Runtime.getRuntime();//打开记事本,单例模式
try {
r.exec("notepad");
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
mi5.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
// 设置窗体可见
f.setVisible(true);
}
}
=======================================================
一些注意事项
前面写final String name = f.getTitle();的作用(原因)

初始默认值为"多级菜单",如上图所示,窗体标题已经被改为"天天向上",所以要恢复初始值不能直接getTitle
16.Netbeans的概述和使用
首先解决安装问题
安装成功的前提是有JDK
配好环境变量
然后,发现还是安装不了

用命令行



然后就可以安装了

NetBeans主要用来做GUI方便,其它并不常用

仅有的优点

拖放使用非常方便

常用快捷键(不用记)
完成代码:ctrl+\ //任何地方按下此组合键,均会提示相应的参考字段;
导入所需包:ctrl+shift+i
格式化代码:alt+shift+F
psvm+Tab 生成Main方法
sout + Tab //生成输出语句
================================
17.模拟四则运算案例
具体内容看视频


在NetBeans中需要手动改动的代码
默认是没有标题的,所以编写初始化标题的代码
public NewJFrameDemo() {
initComponents();
init();
}
private void init() {
this.setTitle("模拟四则运算");
}
// 红字为手写的方法,初始化标题
====================================================
事件监听的代码(计算器四则运算)
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
//获取第一个操作数
String firstNumberString = this.firstNumber.getText().trim();
//获取运算符
String selectOperator = this.selectOperator.getSelectedItem().toString();
//获取第二个操作数
String secondNumberString = this.secondNumber.getText().trim();
// System.out.println(firstNumberString);
// System.out.println(selectOperator);
// System.out.println(secondNumberString);
int firstNumber = Integer.parseInt(firstNumberString);
int secondNumber = Integer.parseInt(secondNumberString);
int resultNumber = 0;
switch (selectOperator) {
case "+":
resultNumber = firstNumber + secondNumber;
break;
case "-":
resultNumber = firstNumber - secondNumber;
break;
case "*":
resultNumber = firstNumber * secondNumber;
break;
case "/":
resultNumber = firstNumber / secondNumber;
break;
}
//把结果赋值给结果框
this.resultNumber.setText(String.valueOf(resultNumber));
}
然后修改窗体的图标代码
看图就好
首先建一个cn.itcast.util包
Uiutil类
然后建一个resource包,把图标图片放进包里

Toolkit是抽象类

在NewJFrame类中改代码
this代表当前对象(窗体)

修改后运行

再设置一下初始运行时窗体的默认位置为居中
在UiUtil类中
//设置窗体居中
public static void setFrameCenter(JFrame jf) {
/*
思路:
A:获取屏幕的宽和高
B:获取窗体的宽和高
C:(用屏幕的宽-窗体的宽)/2,(用屏幕的高-窗体的高)/2作为窗体的新坐标。
*/
//获取工具对象
Toolkit tk = Toolkit.getDefaultToolkit();
//获取屏幕的宽和高
Dimension d = tk.getScreenSize();
double srceenWidth = d.getWidth();
double srceenHeigth = d.getHeight();
//获取窗体的宽和高
int frameWidth = jf.getWidth();
int frameHeight = jf.getHeight();
//获取新的宽和高
int width = (int) (srceenWidth - frameWidth) / 2;
int height = (int) (srceenHeigth - frameHeight) / 2;
//设置窗体坐标
jf.setLocation(width, height);
}
=======================================
在NewJFrame类中
public NewJFrame() {
initComponents();
init();
}
private void init() {
this.setTitle("模拟四则运算");
UiUtil.setFrameImage(this,"jjcc.jpg");
UiUtil.setFrameCenter(this);
}
附上UiUtil类
/**
* 专门做界面效果的类
*
* @author Administrator
*/
public class UiUtil {
private UiUtil() {
}
//修改窗体的图标
public static void setFrameImage(JFrame jf) {
//获取工具类对象
//public static Toolkit getDefaultToolkit():获取默认工具包。
Toolkit tk = Toolkit.getDefaultToolkit();
//根据路径获取图片
Image i = tk.getImage("src\\cn\\itcast\\resource\\user.jpg");
//给窗体设置图片
jf.setIconImage(i);
}
public static void setFrameImage(JFrame jf,String imageName) {
//获取工具类对象
//public static Toolkit getDefaultToolkit():获取默认工具包。
Toolkit tk = Toolkit.getDefaultToolkit();
//根据路径获取图片
Image i = tk.getImage("src\\cn\\itcast\\resource\\"+imageName);
//给窗体设置图片
jf.setIconImage(i);
}
//设置窗体居中
public static void setFrameCenter(JFrame jf) {
/*
思路:
A:获取屏幕的宽和高
B:获取窗体的宽和高
C:(用屏幕的宽-窗体的宽)/2,(用屏幕的高-窗体的高)/2作为窗体的新坐标。
*/
//获取工具对象
Toolkit tk = Toolkit.getDefaultToolkit();
//获取屏幕的宽和高
Dimension d = tk.getScreenSize();
double srceenWidth = d.getWidth();
double srceenHeigth = d.getHeight();
//获取窗体的宽和高
int frameWidth = jf.getWidth();
int frameHeight = jf.getHeight();
//获取新的宽和高
int width = (int) (srceenWidth - frameWidth) / 2;
int height = (int) (srceenHeigth - frameHeight) / 2;
//设置窗体坐标
jf.setLocation(width, height);
}
}
================================================
修改UI----皮肤包(略)
如何修改窗体的皮肤

附上MyLookAndFeel 类
=========================================================
//这里面定义了常见的要使用的皮肤的字符串路径。
public abstract class MyLookAndFeel {
// 系统自带皮肤,5种都能用
public static String SYS_METAL = "javax.swing.plaf.metal.MetalLookAndFeel";
public static String SYS_NIMBUS = "com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel";
// 有个性
public static String SYS_CDE_MOTIF = "com.sun.java.swing.plaf.motif.MotifLookAndFeel";
public static String SYS_WINDOWS = "com.sun.java.swing.plaf.windows.WindowsLookAndFeel";
public static String SYS_WINDOWS_CLASSIC = "com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel";
// JIattoo jar包资源
public static String JTATTOO_ACRYL = "com.jtattoo.plaf.acryl.AcrylLookAndFeel";
public static String JTATTOO_AERO = "com.jtattoo.plaf.aero.AeroLookAndFeel";
// 还可以
public static String JTATTOO_ALUMINUM = "com.jtattoo.plaf.aluminium.AluminiumLookAndFeel";
// 很喜欢
public static String JTATTOO_BERNSTEIN = "com.jtattoo.plaf.bernstein.BernsteinLookAndFeel";
public static String JTATTOO_FAST = "com.jtattoo.plaf.fast.FastLookAndFeel";
// 有个性
public static String JTATTOO_HIFI = "com.jtattoo.plaf.hifi.HiFiLookAndFeel";
public static String JTATTOO_LUNA = "com.jtattoo.plaf.luna.LunaLookAndFeel";
// 很喜欢
public static String JTATTOO_MCWIN = "com.jtattoo.plaf.mcwin.McWinLookAndFeel";
public static String JTATTOO_MINT = "com.jtattoo.plaf.mint.MintLookAndFeel";
// 有个性
public static String JTATTOO_NOIRE = "com.jtattoo.plaf.noire.NoireLookAndFeel";
public static String JTATTOO_SMART = "com.jtattoo.plaf.smart.SmartLookAndFeel";
// liquidlnf.jar包资源
// 很喜欢
public static String LIQUIDINF = "com.birosoft.liquid.LiquidLookAndFeel";
}
========================================================
测试几个看看效果


最后,对四则运算案例加入校验和提示
代码(绿字为新增代码)
………………………………………………………………………………………………………………………………
………………………………………………省略前面代码……………………………………………………
//获取第二个操作数
String secondNumberString = this.secondNumber.getText().trim();
//数据校验,必须是数字字符串
String regex = "\\d+";
//校验第一个数
if (!firstNumberString.matches(regex)) {
// System.out.println("数据不匹配");
//public static void showMessageDialog(Component parentComponent,Object message)
JOptionPane.showMessageDialog(this, "第一个操作数不满足要求必须是数字");
this.firstNumber.setText("");
this.firstNumber.requestFocus();
return;//回去吧
}
if (!secondNumberString.matches(regex)) {
// System.out.println("数据不匹配");
//public static void showMessageDialog(Component parentComponent,Object message)
JOptionPane.showMessageDialog(this, "第二个操作数不满足要求必须是数字");
this.secondNumber.setText("");
this.secondNumber.requestFocus();
return;//回去吧
}
//把字符串数据转换为整数
int firstNumber = Integer.parseInt(firstNumberString);
int secondNumber = Integer.parseInt(secondNumberString);
…………………………………………省略后面代码…………………………………………………………
…………………………………………………………………………………………………………………………
附:JOptionPane类方法

运行示例


18.用户登录注册案例

包结构

pojo包下
User类
public class User {
private String username;
private String password;
public User(){}
/**
* @return the username
*/
public String getUsername() {
return username;
}
/**
* @param username the username to set
*/
public void setUsername(String username) {
this.username = username;
}
/**
* @return the password
*/
public String getPassword() {
return password;
}
/**
* @param password the password to set
*/
public void setPassword(String password) {
this.password = password;
}
}
注意:


============================================================
dao包下
UserDao接口
*/
public interface UserDao {
/**
* 这是用户登录功能
*
* @param username 用户名
* @param password 密码
* @return 登录是否成功
*/
public abstract boolean login(String username, String password);
/**
* 这是用户注册功能
*
* @param user 被注册的用户信息
*/
public abstract void regist(User user);
}
=======================================================
dao.impl包下UserDaoImpl类(与IO流的是一样的)
public class UserDaoImpl implements UserDao {
//定义文件
private static File file = new File("user.txt");
//类加载的时候就把文件创建
static {
try {
file.createNewFile();
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public boolean login(String username, String password) {
boolean flag = false;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(file));
String line = null;
while ((line = br.readLine()) != null) {
String[] datas = line.split("=");
if (datas[0].equals(username) && datas[1].equals(password)) {
flag = true;
break;
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
br.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
return flag;
}
@Override
public void regist(User user) {
BufferedWriter bw = null;
try {
bw = new BufferedWriter(new FileWriter(file, true));
bw.write(user.getUsername() + "=" + user.getPassword());
bw.newLine();
bw.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
bw.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
=============================================================
19.用户登录注册的界面实现,界面跳转
借助于NetBeans实现

再修改一下代码
public LoginFrame() {
initComponents();
init();
}
private void init() {
this.setTitle("登录界面");
UiUtil.setFrameCenter(this);
UiUtil.setFrameImage(this,"user.jpg");
}
注册界面同理,略

接着是界面跳转
dispose----使当前窗体关闭


this.setResizable(false);
还有就是让窗体大小不可改变

private void init() {
this.setTitle("登录界面");
this.setResizable(false);//窗体大小不可改变
UiUtil.setFrameCenter(this);
UiUtil.setFrameImage(this,"user.jpg");
}
在注册按钮添加事件,跳转到注册界面

private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {
RegistFrame rf = new RegistFrame();
// this.setVisible(false);
rf.setVisible(true);//让注册界面可见
this.dispose();//让登录界面不可见
}

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
LoginFrame lf = new LoginFrame();
lf.setVisible(true);
this.dispose();
}
======================================================
20. 用户登录注册的最终版
LoginFrame类中
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton2ActionPerformed
this.jtfUsername.setText("");
this.jpfPassword.setText("");
}//GEN-LAST:event_jButton2ActionPerformed
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton1ActionPerformed
/*
思路:
A:获取用户名和密码
B:正则表达式校验用户名和密码
C:创建对象调用功能,返回一个boolean值
D:根据boolean值给出提示
*/
//获取用户名和密码
String username = this.jtfUsername.getText().trim();
String password = this.jpfPassword.getText().trim();
//用正则表达式做数据校验
//定义规则
//用户名规则
String usernameRegex = "[a-zA-z]{5}";
//密码规则
String passwordRegex = "\\w{6,12}";
//校验
if(!username.matches(usernameRegex)) {
JOptionPane.showMessageDialog(this, "用户名不满足条件(5个英文字母组成)");
this.jtfUsername.setText("");
this.jtfUsername.requestFocus();
return;
}
if(!password.matches(passwordRegex)) {
JOptionPane.showMessageDialog(this, "密码不满足条件(6-12个任意单词字符)");
this.jpfPassword.setText("");
this.jpfPassword.requestFocus();
return;
}
//创建对象调用功能,返回一个boolean值
UserDao ud = new UserDaoImpl();
boolean flag = ud.login(username, password);
if(flag){
JOptionPane.showMessageDialog(this, "恭喜你登录成功");
// NewJFrame njf = new NewJFrame();
NewJFrame njf = new NewJFrame(username);
njf.setVisible(true);
this.dispose();
}else {
JOptionPane.showMessageDialog(this, "用户名或者密码有误");
this.jtfUsername.setText("");
this.jpfPassword.setText("");
this.jtfUsername.requestFocus();
}
}
=============================================================
RegistFrame类
private void jButton3ActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_jButton3ActionPerformed
/*
分析:
A:获取用户名和密码
B:用正则表达式做数据校验
C:封装成用户对象
D:调用用户操作的功能进行注册
E:回到登录界面
*/
//获取用户名和密码
String username = this.jtfUsername.getText().trim();
String password = this.jpfPassword.getText().trim();
//用正则表达式做数据校验
//定义规则
//用户名规则
String usernameRegex = "[a-zA-z]{5}";
//密码规则
String passwordRegex = "\\w{6,12}";
//校验
if(!username.matches(usernameRegex)) {
JOptionPane.showMessageDialog(this, "用户名不满足条件(5个英文字母组成)");
this.jtfUsername.setText("");
this.jtfUsername.requestFocus();
return;
}
if(!password.matches(passwordRegex)) {
JOptionPane.showMessageDialog(this, "密码不满足条件(6-12个任意单词字符)");
this.jpfPassword.setText("");
this.jpfPassword.requestFocus();
return;
}
//封装成用户对象
User user = new User();
user.setUsername(username);
user.setPassword(password);
//调用用户操作的功能进行注册
UserDao ud = new UserDaoImpl();
ud.regist(user);
//给出提示
JOptionPane.showMessageDialog(this, "用户注册成功,回到登录界面");
goLogin();
}
private void goLogin() { //跳转功能
LoginFrame lf = new LoginFrame();
lf.setVisible(true);
this.dispose();
}
补充:四则运算修改

==============================================
day25补充笔记
注意一个工具"exe4j" jar转exe可执行文件
如何让Netbeans的东西Eclipse能访问。
在Eclipse中创建项目,把Netbeans项目的src下的东西给拿过来即可。
注意:修改项目编码为UTF-8(NetBeans默认编码是UTF-8,而eclipse是GBK)
事件监听机制(理解)
A:事件源
B:事件
C:事件处理
D:事件监听
适配器模式(理解)
A:接口
B:抽象适配器类
C:实现类