CLI
Command Line User Interface(命令行用户接口):就是常见的DOS命令行操作,需要记忆一些常用的命令,操作不直观。
GUI(图形用户界面)
Graphical User InterFace(图形用户接口):用图形的方式,来显示计算机操作的界面,这样更方便直观。
基本体系构成图
java为GUI提供的对象都存在java.Awt和javax.Swing两个包中。
Awt:java.Awt:Abstract Window ToolKit(抽象窗口工具包),需要调用本地系统方法实现功能。属于重量级控件。
Swing:javax.Swing:在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由java实现。增强了移植性,属于轻量级控件,javax表示java的扩展。
Awt(java.awt.*)
AWT:它由三部分组成:
1.组件:界面元素;
2.容器:装载组件的容器(如窗体);
3.布局管理器:负责决定容器中组件的摆放位置。
图形界面的应用分四步:
1.选择一个容器
(1).Window:带标题的容器(如Frame);
(2).Panel:面板。Panel也是一种容器,但是不可见的,所以在设置它的时候不要忘记设置它的可见性。
2.设置一个布局管理器:用setLayout();
3.向容器中添加组件;通过add();向容器中添加组件。
4.添加组件的事务处理。
注意:Java的图形界面依然是跨平台的。但是在调用了一个窗体之后只生成一个窗体,没有事件的处理,关闭按钮并不工作。此时只能使用CTRL+C终止程序。
Swing(javax.swing.*)
概述:AWT是Java最早出现的图形界面,但很快就被Swing所取代。Swing才是一种真正的图形开发。
AWT在不同平台所出现的界面可能有所不同,因为每个OS都有自己的UI组件库,java调用不同系统的UI。不同OS的组件库都存在BUG。必须多种平台进行测试,并且AWT的组件库并不丰富。为解决以上问题,SUN和IBM以及NETSCAPE联合开发出JAVA基础类包Swing。
Swing与awt的区别:
Swing为JAVA自身的组件。已经不是对等实体,与底层的OS无关。在Swing组件中,基本上都是在AWT组件名称前面加“J”。
Swing与AWT在事件模型处理上是一致的。
Applet(这个技术基本已经被淘汰)
Applet为Panel的子类,Applet是java的自动执行方式(这是它的优势,主要用于HTML)。
四种状态:init(),start(),stop(),destory()。
Applet的优势:
网络传输,自动下载。
Application的优势:没有执行限制。
WebStart:可在网络传输,并且在本地无限制。
布局
容器中的组件的排放方式,就是布局。
常见的布局管理器:
FlowLayout(流式布局管理器)
Panel默认的布局管理器。
BorderLayout(边界布局管理器)
东,南,西,北,中。NORTH
、SOUTH
、EAST
、WEST
、CENTER
。
Frame和Dialog默认的布局管理器。
注意:一个区域只能放置一个组件,如果想在一个区域放置多个组件就需要使用Panel来装载。
GridLayout(网格布局管理器)
CardLayout(卡片布局管理器)
GridBagLayout(网格包布局管理器)
事件监听机制
组成:
1. 事件源(组件)
2. 事件(Event)
3. 监听器(Listener)
4. 事件处理(引发事件后处理方式)
使用:
1. 确定事件源(容器或组件)。
2. 通过事件源对象的addXXXListener()方法将侦听器注册到该事件源上。
3. 该方法中接收XXXListener的子类对象,或XXXListener的子类XXXAdapter的子类对象。
4. 在覆盖方法时,方法的参数一般是XXXEvent类型的变量接收。
5. 事件触发后会把事件打包成对象传递给该对象。(包括事件源对象。通过getSource()或getComponent()获取)
注意:一般用匿名内部类来表示。
事件监听机制流程图
制作可以双击执行的jar包
1,将多个类封装到了一个包(package)中。
2,定义一个jar包的配置信息。定义一个文件a.txt。文件内容内容为:Main-Class:(空格)包名.类名(回车)
3,打jar包。jar -cvfm my.jar a.txt包名
4,通过winrar程序进行验证,查看该jar的配置文件中是否有自定义的配置信息。
5,通过工具--文件夹选项--文件类型--jar类型文件,通过高级,定义该jar类型文件的打开动作的关联程序。
jdk\bin\javaw.exe -jar
6,双击。
注意:文件名可以随便起,不是一定要是a.txt。
代码示例
示例:实现Frame窗体关闭按钮
import java.awt.*;
import java.awt.event.*;
class AwtDemo
{
private Frame f;
private Button b;
AwtDemo(){
f = new Frame("标题栏名称");
f.setSize(500,400);//设置窗体大小
f.setLocation(300,200);//调节窗体在显示屏中的位置
f.setLayout(new FlowLayout());//设置布局
b = new Button("按钮");
f.add(b);//把按钮加进容器中
f.addWindowListener(new WindowAdapter()//窗体监听
{
public void windowClosing(WindowEvent e)
{
System.out.println("程序关闭");
System.exit(0);
}
});
f.setVisible(true);//显示窗体
}
public static void main(String[] args)
{
new AwtDemo();
}
}
示例:AWT实现打开文件与保存文件
import java.awt.*;
import java.awt.event.*;
import java.io.*;
public class MyMenuTest
{
private Frame f;
private MenuBar bar;
private TextArea ta;
private Menu fileMenu;
private MenuItem openItem,saveItem,closeItem;
private FileDialog openDia,saveDia;
private File file;
MyMenuTest()
{
init();
}
public void init()
{
f = new Frame("my window");
f.setBounds(300,100,650,600);
bar = new MenuBar();
ta = new TextArea();
fileMenu = new Menu("文件");
openItem = new MenuItem("打开");
saveItem = new MenuItem("保存");
closeItem = new MenuItem("退出");
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(closeItem);
bar.add(fileMenu);
f.setMenuBar(bar);
openDia = new FileDialog(f,"我要打开",FileDialog.LOAD);
saveDia = new FileDialog(f,"我要保存",FileDialog.SAVE);
f.add(ta);
myEvent();
f.setVisible(true);
}
private void myEvent()//定义动作监听方法
{
saveItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
if(file==null)
{
saveDia.setVisible(true);
String dirPath = saveDia.getDirectory();
String fileName = saveDia.getFile();
if(dirPath==null || fileName==null)
return ;
file = new File(dirPath,fileName);
}
try
{
BufferedWriter bufw = new BufferedWriter(new FileWriter(file));
String text = ta.getText();
bufw.write(text);
bufw.close();
}
catch (IOException ex)
{
throw new RuntimeException();
}
}
});
openItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
openDia.setVisible(true);
String dirPath = openDia.getDirectory();
String fileName = openDia.getFile();
if(dirPath==null || fileName==null)
return ;
ta.setText("");
file = new File(dirPath,fileName);
try
{
BufferedReader bufr = new BufferedReader(new FileReader(file));
String line = null;
while((line=bufr.readLine())!=null)
{
ta.append(line+"\r\n");
}
bufr.close();
}
catch (IOException ex)
{
throw new RuntimeException("读取失败");
}
}
});
closeItem.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
f.addWindowListener(new WindowAdapter()
{
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
}
public static void main(String[] args)
{
new MyMenuTest();
}
}
示例:用Swing实现的进度条功能
import java.awt.Color;
import javax.swing.*;
public class LoadDemo extends JFrame {//继承 窗体
private static final long serialVersionUID = 1L;
private JProgressBar bar;//生明一个私有的进度条
private JLabel imgLabel;//生明一个私有的标签 jlabel:用于短文本字符串或图像或二者的显示区。
private Icon icon;// 创建一个图片对象 icon:一个小的固定大小图片,通常用于装饰组件。 生明一个私有的图标
public LoadDemo() {
icon = new ImageIcon("D:/img/1.jpg");//添加图片
imgLabel = new JLabel(icon);//显示图片
bar = new JProgressBar();
bar.setMinimum(0);//开始点
bar.setMaximum(100);//结束点
bar.setBounds(0, 710, 980, 40);//设定进度条的x轴 y轴 宽 高 ,也就是界限
bar.setStringPainted(true);// 在进度条上显示百分比(n%) 如果是false进度条上就没有数
bar.setForeground(Color.green);//调节进度条的颜色
this.add(bar);//把 进度条添加进容器
//this.getLayeredPane().add(bar);//区层添加
this.add(imgLabel);
this.setSize(980, 769);//设置窗体的宽与高
this.setResizable(false);//false窗体右上角最大化不可用不可调节窗体大小 true相反
this.setVisible(true);//显示窗体
this.setLocationRelativeTo(null);//让窗体相对于屏幕居中对齐
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//当窗体关闭或退出的时候,控制台也被关闭。
}
// 设置进度条上的加载数据 只有调用了这个方法 进度条才会走值
public void setvalue() {
for (int i = 0; i < 101; i++) {
bar.setValue(i);//把值赋给进度条
try {
// 间隔指定时间执行一次 单位毫秒
Thread.sleep(10);//睡眠时间
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new LoadDemo().setvalue();
}
}
示例:Swing实现登录界面功能
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class LoginDemo extends JFrame{
private JLabel namelabel, pwdlabel1;
private JTextField namefield;
private JPasswordField pwdfield1;
private JButton commitbtn, resetbtn, denglu;
private JComboBox combo;
public Toolkit tool;
public LoginDemo() {
setTitle("用户登录界面");
setSize(800, 764);
this.setLocationRelativeTo(null);
setVisible(true);
// 设置窗体标题栏图标
tool = Toolkit.getDefaultToolkit();
Image imgs = tool.getImage("img/6.jpg");
this.setIconImage(imgs);
// 设置背景图
ImageIcon img = new ImageIcon("img/4.jpg");
JLabel jl = new JLabel(img);
this.add(jl);
// 设置关闭窗体时程序结束
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);// false窗体右上角最大化不可用不可调节窗体大小 true相反
namelabel = new JLabel("用户名");
namelabel.setForeground(Color.WHITE);
namelabel.setFont(new Font("黑体", Font.BOLD, 25));//设置字体
pwdlabel1 = new JLabel("密 码");
pwdlabel1.setForeground(Color.WHITE);
pwdlabel1.setFont(new Font("黑体", Font.BOLD, 25));
//设置文本框
namefield = new JTextField(16);
//设置密码文本框
pwdfield1 = new JPasswordField(16);
pwdfield1.setEchoChar('*');
//把组件加进容器并调整位置
this.getLayeredPane().add(namelabel);
namelabel.setBounds(430, 230, 100, 100);
this.getLayeredPane().add(pwdlabel1);
pwdlabel1.setBounds(430, 290, 100, 100);
this.getLayeredPane().add(namefield);
namefield.setBounds(530, 270, 150, 25);
this.getLayeredPane().add(pwdfield1);
pwdfield1.setBounds(530, 325, 150, 25);
//设置下拉菜单
combo = new JComboBox();
combo.addItem("普通用户");
combo.addItem("管理员用户");
combo.setBounds(530, 375, 80, 25);
this.getLayeredPane().add(combo);
//设置按钮
commitbtn = new JButton("注册");
commitbtn.setForeground(Color.WHITE);
commitbtn.setBackground(new Color(0, 0, 0));
commitbtn.setFont(new Font("黑体", Font.BOLD, 12));
commitbtn.setBounds(700, 450, 60, 30);
this.getLayeredPane().add(commitbtn);
resetbtn = new JButton("重置");
resetbtn.setForeground(Color.WHITE);
resetbtn.setBackground(new Color(0, 0, 0));
resetbtn.setFont(new Font("黑体", Font.BOLD, 12));
resetbtn.setBounds(610, 450, 60, 30);
this.getLayeredPane().add(resetbtn);
denglu = new JButton("确定");
denglu.setForeground(Color.WHITE);
denglu.setBackground(new Color(0, 0, 0));
denglu.setFont(new Font("黑体", Font.BOLD, 12));
denglu.setBounds(520, 450, 60, 30);
this.getLayeredPane().add(denglu);
}
public JButton getCommitbtn() {
return commitbtn;
}
public JButton getResetbtn() {
return resetbtn;
}
public JButton getDenglu() {
return denglu;
}
public JTextField getNamefield() {
return namefield;
}
public JPasswordField getPwdfield1() {
return pwdfield1;
}
public JComboBox getCombo() {
return combo;
}
public void addActionListener(ActionListener listener) {// 事件监听
commitbtn.addActionListener(listener);
resetbtn.addActionListener(listener);
denglu.addActionListener(listener);
combo.addActionListener(listener);
}
}
运行类
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JOptionPane;
public class LoginTest implements ActionListener {
private String username, pass, nclass;
private LoginDemo login;
LoginTest() {
login = new LoginDemo();
login.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {// 处理事件
username = login.getNamefield().getText().trim();// 获取用户名 trim()是去空格
pass = new String(login.getPwdfield1().getPassword());// 获取密码
if (e.getSource() == login.getCommitbtn()) {// 如果单击了注册按钮
nclass = login.getCombo().getSelectedItem().toString();// 获取用户类型
if (username.length() == 0) {
JOptionPane.showMessageDialog(null, "\t 用户名不能为空");// 显示信息对话框
return;
} else if (pass.length() == 0) {
JOptionPane.showMessageDialog(null, "\t 密码不能为空 ");
return;
}
if (username != null && pass != null) {
JOptionPane.showMessageDialog(null, "\t 注册成功!" + " \n 姓名:"
+ username + "\n 注册类型: " + nclass);
login.getNamefield().setText("");// 清空用户名框
login.getPwdfield1().setText("");// 清除密码框
}
} else if (e.getSource() == login.getResetbtn()) { // 点击重置按钮
login.getNamefield().setText("");
login.getPwdfield1().setText("");
login.getNamefield().requestFocus(); // 获取光标焦点 让它到用户名文本框里
login.getCombo().setSelectedIndex(0);// 让下拉回到最初
} else if (e.getSource() == login.getCombo()) {// 点击了下拉菜单
if ((login.getCombo().getSelectedItem() + "").equals("管理员用户")) {// 如果是管理员用户
login.getNamefield().setText("admin");// 这里我给用户名文本框一个值
login.getPwdfield1().setText("admin");
login.getCommitbtn().setEnabled(false);// 点到管理员用户 注册按钮就不被激活
} else {
login.getNamefield().setText("");
login.getCommitbtn().setEnabled(true);// Enabled是激活的意思
}
} else if (e.getSource() == login.getDenglu()) {// 点击登录按钮
if (username.length() == 0) {
JOptionPane.showMessageDialog(null, "\t 用户名不能为空");
return;
} else if (pass.length() == 0) {
JOptionPane.showMessageDialog(null, "\t 密码不能为空 ");
return;
} else {
if ((login.getCombo().getSelectedItem() + "").equals("普通用户")) {
JOptionPane.showMessageDialog(null, "\t 普通用户登录成功");
login.getNamefield().setText("");
login.getPwdfield1().setText("");
}
}
// 这里判断的是管理员用户登录
if ((login.getCombo().getSelectedItem() + "").equals("管理员用户")) {
if (username.equals("admin")&& pass.equals("admin")) {
JOptionPane.showMessageDialog(null, "\t 管理员用户登录成功");
login.getNamefield().setText("");
login.getPwdfield1().setText("");
} else{
JOptionPane.showMessageDialog(null, "用户名或密码错误------");
login.getNamefield().setText("");
login.getPwdfield1().setText("");
}
}
}
}
public static void main(String[] args) {
new LoginTest();
}
}
总结:
组件必须加在容器中,而容器本身具有层次的关系。.setLayout(null);表示不要布局管理器。
AWT为重量级组件,相当消耗资源,且不同系统的组件可能不同。因为这个问题使得AWT开发的软件难以作到跨平台。Swing比AWT更加复杂且灵活。
一个事件源可以授权多个监听者(授权也称为监听者的注册),多个事件源也可以注册多个事件监听器。