概述
GUI全称Graphical User Interface(图形用户接口),它的作用是用图形的方式,来显示计算机操作的界面,这样更方便更直观。
CLI全称Command Line User Interface(命令行用户接口),就是常见的DOS命令行操作。需要记忆一些常用的命令,操作不直观。
实现GUI编程的必不可少的三个条件是组件、事件、事件监听。
java为GUI提供的对象都存在java.awt和javax.Swing两个包中。
AWT
java.awt:Abstract Window ToolKit(抽象窗口工具包),属于重量级控件。它依赖于本地操作系统的GUI,缺乏平台独立性。但是AWT组件简单稳定,兼容于任何一个JDK版本。AWT所涉及到的类一般在java.awt的包及其子包中。java.awt中的类负责与本地操作系统进行交互,让本地操作系统显示和操作组件。
AWT中的两个核心类是Container(容器)和Component类。
Component类
Java图形用户界面最基本组成部分是Component,Component类及其子类的对象用来描述以图形化的方式显示在屏幕上并能够与用户进行交互的GUI元素(标签、按钮)。
Container类
用来组织界面上的组件或者单元。有两种常用的Container(容器),一是Window,Window对象表示自由停泊的顶级窗口,另一个是Panel对象可作为容纳其他Component对象,但不能够独立存在,必须被添加到其他Container中,比如说Window或者Applet中。
Container它有一定的范围和大小,一般都是矩形。也有一定的位置,这个位置可分相对位置和绝对位置。
一个Container中可以包含其他Container,Container中可以嵌套Container,当Container显示时候,它里面的元素也被小时出来,当Container隐藏时或者关闭时,它包含的元素也被隐藏。
Component类与Container类关系
Component对象不能独立显示出来,必须放在某一Container对象中才可以显示出来。
Container是Component的子类,Container子类对象可以容纳别的Component对象。Container对象也可以被当作Component对象添加到其他Container对象中。
Frame演示
public class FrameDemo {
public static void main(String[] args) {
//创建窗体
Frame f=new Frame("my frame");
//对窗体做基本设置
// f.setSize(500, 400);//设置窗体大小
// f.setLocation(400, 200);//设置窗体出现在屏幕的位置
f.setBounds(400, 200, 500, 400);
//设置窗体的布局
f.setLayout(new FlowLayout());//设置流式布局
//建立组件
Button b=new Button("button");
//将组件添加到窗体中
f.add(b);//将按钮添加到窗体中
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
// System.out.println("closing..."+e);
// super.windowClosing(e);//复写时产生的
}
});
//在按钮上加上一个监听
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("button run...");
System.exit(0);
}
});
//使窗体可见
f.setVisible(true);
}
}
事件监听机制
事件监听机制组成:
- 事件源(组件):产生事件的组件,例如在一个按钮上的单击就是事件源。
- 事件(Event):用户在界面上的某一个操作,通常使用各种输入设备,如鼠标、键盘等。
- 监听器(Listener):包含事件处理器,负责检查事件是否发生,若发生则激活事件处理器对其处理。
- 事件处理(引发事件后的处理方式)
事件
事件是指组件触发的动作事件,java中不同的事件由不同的监听器处理,组件是事件源对象,而监听器主要用来接收来自事件源对象产生的动作事件,然后对其处理。
监听过程
当事件源对象产生某种事件时,先封装该事件的信息,然后向监听器传送此事件对象,监听器在接收到事件对象后,为了能让监听器检查组件是否发生了该事件,会向该事件源对象(即该组件)注册事件监听器,然后事件处理器会检查事件是否发生,如果发生了,那么激活事件处理器进行处理。
窗体监听(WindowAdapter)
接收窗口事件的抽象适配器类。此类中的方法为空。此类存在的目的是方便创建侦听器对象。
活动监听(ActionListener)
用于接收操作事件的侦听器接口。对处理操作事件感兴趣的类可以实现此接口,而使用该类创建的对象可使用组件的addActionListener方法向该组件注册。在发生操作事件时,调用该对象的actionPerformed方法。
此接口没有适配器。因为它只有一个方法:actionPerformed()
鼠标事件、键盘事件的监听过程演示:
public class MouseAndKeyDemo {
private Frame f;
private TextField tf;
private Button b;
public MouseAndKeyDemo() {
init();
}
private void init() {
f=new Frame("演示鼠标和键盘监听");
f.setBounds(400, 200, 500, 400);
f.setLayout(new FlowLayout());
tf=new TextField(15);
b=new Button("button");
f.add(tf);
f.add(b);
myEvent();
f.setVisible(true);
}
private void myEvent() {
//给文本框添加键盘监听
tf.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
//
//// System.out.println("key run "+/*e.getKeyChar()*/KeyEvent.getKeyText(e.getKeyCode())+":"+e.getKeyCode());
//
// int code=e.getKeyCode();
// if(!(code>=KeyEvent.VK_0&&code<=KeyEvent.VK_9)){
// System.out.println("必须是数字");
// //加入这一句后文本框里就输入不进去非数字的字符了
// e.consume();//使用此事件,以便不会按照默认的方式由产生此事件的源代码来处理此事件。
// }
//
//
/*
if(e.getKeyCode()==KeyEvent.VK_ENTER){
System.out.println("enter run");
*/
if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_ENTER){
System.out.println("ctrl+enter run");
}
}
});
f.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
//在按钮上添加一个动作监听
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("action run ");
}
});
//在按钮上添加一个鼠标监听
b.addMouseListener(new MouseAdapter() {
private int count=1;
@Override
public void mouseEntered(MouseEvent e) {
// System.out.println("mouse entered "+count++);
// tf.setText("mouse entered "+count++);
}
@Override
public void mouseClicked(MouseEvent e) {
// System.out.println("mouse clicked "+count++);
// tf.setText("mouse click "+count++);
if(e.getClickCount()==2)
tf.setText("mouse double click "+count++);
}
});
}
public static void main(String[] args) {
new MouseAndKeyDemo();
}
}
Swing
java.swing:在awt的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由java实现。增强了移植性,属于轻量级控件。
在myeclipse中,使用Swing插件的过程:
1. file-new-java project 输入project name
2. 新建包
3. 在包中右键,选择new-other
4. 选择WindowBuilder->Swing Designer->JFrame
5. 点击 design
点击source出现已经编写好的代码,在事件监听中添加好处理方法(这里是点击按钮便退出):
public class mySwing extends JFrame {
private JPanel contentPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
mySwing frame = new mySwing();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public mySwing() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JButton btnMybutton = new JButton("mybutton");
btnMybutton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
btnMybutton.setBounds(159, 22, 97, 23);
contentPane.add(btnMybutton);
}
}
GUI练习:在文本框中输入目录,点击转到按钮,就将该目录中的文件和文件夹名称列在下面的文本区域中。
代码如下:
public class myWindow extends JFrame {
protected static final String LINE_SEPARATOR = System.getProperty("line.separator");
private JPanel contentPane;
private JTextField textField;
private JTextArea textArea;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
myWindow frame = new myWindow();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public myWindow() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
textField = new JTextField();
textField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode()==KeyEvent.VK_ENTER)
showdir();
}
});
textField.setBounds(5, 5, 248, 21);
contentPane.add(textField);
textField.setColumns(10);
JButton button = new JButton("\u8F6C\u5230");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
showdir();
}
});
button.setBounds(262, 4, 93, 23);
contentPane.add(button);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(5, 36, 350, 215);
contentPane.add(scrollPane);
textArea = new JTextArea();
scrollPane.setViewportView(textArea);
}
/**
*
*/
public void showdir() {
//通过点击按钮获取文本框中的目录
//将目录中的内容显示到文本区域中
String dir_str=textField.getText();
File dir=new File(dir_str);
if(dir.exists()&&dir.isDirectory()){
textArea.setText("");
String[] names=dir.list();
for(String name:names){
textArea.append(name+LINE_SEPARATOR);
}
}
}
}
效果如下: