@liayun
2016-06-30T08:48:07.000000Z
字数 10319
阅读 2358
java基础
Graphical User Interface(图形用户接口),用图形的方式,来显示计算机操作的界面,这样更方便更直观。
Command line User Interface (命令行用户接口),就是常见的Dos命令行操作。需要记忆一些常用的命令,操作不直观。
Java为GUI提供的对象都存在java.Awt和javax.Swing两个包中。
Container:为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。
容器中的组件的排放方式,就是布局。
常见的布局管理器:
但是最屌的布局是坐标式布局。
Container常用子类:Window、Panel(面板,不能单独存在。)
Window常用子类:Frame、Dialog。
简单的窗体创建过程:
创建frame窗体。
Frame f = new Frame("my awt");
对窗体进行基本设置,比如大小、位置、布局。
f.setSize(500, 400); // 设置窗体大小f.setLocation(300, 200); // 设置窗体出现在屏幕的位置f.setLayout(new FlowLayout()); // 设置布局
让窗体显示,通过setVisible(true)来完成。
f.setVisible(true);
了解到事件监听机制之后,Java创建图形化界面的步骤就变为:
创建frame窗体。
Frame f = new Frame("my awt");
对窗体进行基本设置,比如大小、位置、布局。
f.setSize(500, 400); // 设置窗体大小f.setLocation(300, 200); // 设置窗体出现在屏幕的位置f.setLayout(new FlowLayout()); // 设置布局
定义组件。
Button b = new Button("我是一个按钮");
将组件通过窗体的add()方法添加到窗体中。
f.add(b);
通过事件源对象的addXXXListener()方法将监听器注册到该事件源上。该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。
以窗体事件为例,当通过窗体的addWindowListener()方法将监听器注册到该窗体上,并且接收WindowListener的子类对象MyWin。此时要覆盖WindowListener接口中的7个方法,可是我只用到了关闭的动作,其他动作都没有用到,可是却必须覆写,明显不可取。
class MyWin implements WindowListener {// 覆盖7个方法,可是我只用到了关闭的动作。// 其他动作都没有用到,可是却必须复写。}
又因为WindowListener的子类WindowAdapter已经实现了WindowListener接口,并覆盖了其中的所有方法,那么我只要继承自WindowAdapter覆盖我需要的方法即可。
class MyWin extends WindowAdapter {public void windowClosing(WindowEvent e) {// System.out.println("window closing---"+e.toString());System.exit(0);}}
但这样又会多出一个类来,为了使代码更加紧凑,addWindowListener()方法接收的对象一般用匿名内部类来表示。
f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.out.println("我关");System.exit(0);}// 窗体处于最前端,就引发此动作public void windowActivated(WindowEvent e) {System.out.println("我活了");}public void windowOpened(WindowEvent e) {System.out.println("我被打开了,哈哈哈");}});
让窗体显示,通过setVisible(true)来完成。
f.setVisible(true);
通过窗体事件了解到Java创建图形化界面的步骤之后,可通过以下代码了解Action事件。
先将整个图形界面设计出来,为了使代码更加紧凑,可以把代码都写到一个类中。
import java.awt.*;import java.awt.event.*;class FrameDemo {// 定义该图形界面程序中所需的组件引用private Frame f;private Button but;FrameDemo() {init();}public void init() {f = new Frame("my frame");// 对frame进行基本设置f.setBounds(300, 100, 600, 500);f.setLayout(new FlowLayout());but = new Button("my button");// 将组件添加到frame中f.add(but);// 加载一下窗体上事件myEvent();// 显示窗体f.setVisible(true);}}
myEvent()方法作用:通过事件源对象的addXXXListener()方法将监听器注册到该事件源上。
通过窗体的addWindowListener()方法将监听器注册到该窗体上。
f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});
让按钮具备退出程序的功能。
按钮就是事件源。那么选择哪一个监听器呢?
通过关闭窗体示例了解到,想要知道哪个组件具备什么样的特有监听器,需要查看该组件对象的功能,通过查阅button的描述,发现按钮支持一个特有监听ActionListener。
but.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.out.println("退出,按钮干的");System.exit(0);}});
测试代码
public static void main(String[] args) {new FrameDemo();}
先将整个图形界面设计出来,为了使代码更加紧凑,可以把代码都写到一个类中。
import java.awt.*;import java.awt.event.*;class MouseAndKeyEvent {private Frame f;private Button but;private TextField tf;MouseAndKeyEvent() {init();}public void init() {f = new Frame("my frame");f.setBounds(300, 100, 600, 500);f.setLayout(new FlowLayout());tf = new TextField(20);but = new Button("my button");f.add(tf);f.add(but);myEvent();f.setVisible(true);}}
myEvent()方法作用:通过事件源对象的addXXXListener()方法将监听器注册到该事件源上。
通过窗体的addWindowListener()方法将监听器注册到该窗体上。
f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});
给按钮注册一个ActionListener(活动监听器)
but.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.out.println("action ok");}});
再给按钮注册一个MouseListener(鼠标监听器)
but.addMouseListener(new MouseAdapter() {private int count = 1;private int clickCount = 1;public void mouseEntered(MouseEvent e) {System.out.println("鼠标进入到该组件"+count++);}public void mouseClicked(MouseEvent e) {if(e.getClickCount() == 2)System.out.println("双击动作"+clickCount++);}});
注意:按钮尽量添加ActionEvent(活动事件),当还有点击事件时,点击事件先执行。
接着给按钮注册一个KeyListener(键盘监听器)
but.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {// 组合键if(e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER)System.out.println("ctrl+enter is run");//System.out.println(KeyEvent.getKeyText(e.getKeyCode())+"..."+e.getKeyCode());}});
给文本输入框注册一个KeyListener(键盘监听器)。输入0-9之外的字符,提示输入非法,并且无法输入。
tf.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {int code = e.getKeyCode();if(!(code >= KeyEvent.VK_0 && code <= KeyEvent.VK_9)) {System.out.println(code+"....是非法的");e.consume(); // 使用此事件,以便不会按照默认的方式由产生此事件的源代码来处理此事件。(即不会把非数字字符写入)}}});
测试代码
public static void main(String[] args) {new MouseAndKeyEvent();}
在文本框中输入目录,点击“转到”按钮,将该目录中的文件与文件夹名称列在下面的文本区域中。如图所示:
解:
import java.awt.*;import java.awt.event.*;import java.io.*;class MyWindowDemo {private Frame f;private TextField tf;private Button but;private TextArea ta;private Dialog d;private Label lab;private Button okBut;MyWindowDemo() {init();}public void init() {f = new Frame("my window");f.setBounds(300, 100, 600, 500);f.setLayout(new FlowLayout());tf = new TextField(60);but = new Button("转到");ta = new TextArea(25, 68);/*对话框也是一个窗体,最好不要加到Frame里面去*/d = new Dialog(f, "提示信息-self", true); // true:对话框不处理掉,后面的窗体是无法操作的!!d.setBounds(400, 200, 240, 150);d.setLayout(new FlowLayout());lab = new Label();okBut = new Button("确定");d.add(lab);d.add(okBut);f.add(tf);f.add(but);f.add(ta);myEvent();f.setVisible(true);}private void myEvent() {// 点击对话框中的确定按钮,对话框也不显示出来okBut.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {d.setVisible(false);}});// 关闭对话框,对话框不显示d.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {d.setVisible(false);}});tf.addKeyListener(new KeyAdapter() {public void keyPressed(KeyEvent e) {if(e.getKeyCode() == KeyEvent.VK_ENTER)showDir();}});but.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {showDir();}});f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});}private void showDir() {String dirPath = tf.getText();File dir = new File(dirPath);if(dir.exists() && dir.isDirectory()) {ta.setText(""); // 首次查询时,为了防止上一次查询的信息还在,所以要清空一次。String[] names = dir.list();for(String name : names) {ta.append(name+"\r\n"); // 将给定文本追加到文本区的当前文本}} else {String info = "您输入的信息:"+dirPath+"是错误的,请重输";lab.setText(info); // 设置提示信息d.setVisible(true);}}public static void main(String[] args) {new MyWindowDemo();}}
先创建菜单条。
MenuBar mb = new MenuBar();
再创建菜单。
Menu m = new Menu("文件");Menu subMenu = new Menu("子菜单");
接着创建菜单项。
MenuItem subItem = new MenuItem("子条目");MenuItem closeItem = new MenuItem("退出");
可以把菜单或菜单项添加到菜单中,作为子菜单。
subMenu.add(subItem); // 菜单可添加菜单项m.add(subMenu); // 菜单还可添加菜单m.add(closeItem); // 菜单可添加菜单项
将菜单添加到菜单栏中。
mb.add(m);
通过setMenuBar()方法,将菜单添加到Frame中。
f.setMenuBar(mb);
此时创建的菜单栏的图像为:
先将整个图形界面设计出来,为了使代码更加紧凑,可以把代码都写到一个类中。
import java.awt.*;import java.awt.event.*;class MyMenuDemo {private Frame f;private MenuBar mb;private Menu m, subMenu;private MenuItem closeItem, subItem;MyMenuDemo() {init();}public void init() {f = new Frame("my window");f.setBounds(300, 100, 500, 600);f.setLayout(new FlowLayout());mb = new MenuBar();m = new Menu("文件");subMenu = new Menu("子菜单");subItem = new MenuItem("子条目");closeItem = new MenuItem("退出");subMenu.add(subItem);m.add(subMenu); // 菜单还可添加菜单m.add(closeItem); // 菜单可添加菜单项mb.add(m); // 菜单栏可添加菜单f.setMenuBar(mb);myEvent();f.setVisible(true);}}
myEvent()方法作用:通过事件源对象的addXXXListener()方法将监听器注册到该事件源上。
通过窗体的addWindowListener()方法将监听器注册到该窗体上。
f.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent e) {System.exit(0);}});
给closeItem菜单项注册一个ActionListener(活动监听器),点击"退出"菜单项退出整个应用程序。
closeItem.addActionListener(new ActionListener() {public void actionPerformed(ActionEvent e) {System.exit(0);}});
测试代码。
public static void main(String[] args) {new MyMenuDemo();}
运行得到的图形为:
模仿Windows的记事本(notepad.exe)程序完成文件的打开、保存、退出的操作。如图所示:
解:
package mymenu;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);// f.setLayout(new FlowLayout()); // 默认边界布局bar = new MenuBar();ta = new TextArea();fileMenu = new Menu("文件");closeItem = new MenuItem("退出");openItem = new MenuItem("打开");saveItem = 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.flush();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();// System.out.println(dirPath+"..."+fileName);if(dirPath == null || fileName == null)return;ta.setText(""); // 清空File 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();}}
两张图即可说明: