黑马程序员----GUI

来源:互联网 发布:杨幂的鼻子知乎 编辑:程序博客网 时间:2024/05/16 09:01

--------------------- <a href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------


13、GUI

13.1计算机与用户交互方式

方式一:Graphical User Interface(图形用户接口)。

用图形的方式,来显示计算机操作的界面,这样更方便更直观。

方式二:Command line User Interface (命令行用户接口)

就是常见的Dos命令行操作。

需要记忆一些常用的命令,操作不直观。

13.2AWT、Swing和SWT

Java为GUI提供的对象都存在java.Awt和javax.Swing两个包中。

13.2.1java.Awt

AbstractWindow ToolKit (抽象窗口工具包),需要调用本地系统方法实现功能(依赖于平台)。属重量级控件(与系统的依赖性强)。

13.2.2javax.Swing

在AWT的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由Java实现。增强了移植性,属轻量级控件。(在任何系统下都一模一样)

13.2.3SWT

(eclipse是用纯java编写的,它的工具是用SWT界面编写的)此外观包也是基于AWT的,但是是IBM支持eclipse小组,他们独立编写的一个图形化界面外观包。在eclipse官方网站可以下载SWT外观包。将其jar包导进来,所有的组件就可以使用了。它的界面做的跟eclipse一样的。

13.3图形化界面中的组件继承关系图

13.3.1继承图简单说明

Container:为容器,是一个特殊的组件,该组件中可以通过add方法添加其他组件进来。

Lable:标签用于封装文字

图形化界面是另一个线程在执行和控制

Container常用子类:Window   Panel(面板,不能单独存在。)

13.4布局管理器

容器中的组件的排放方式,就是布局。

常见的布局管理器有以下几种(在做图形化界面之前,将自己在草稿纸上,规划一下布局)

13.4.1FlowLayout(流式布局管理器)

从左到右的顺序排列。

Panel默认的布局管理器。

13.4.2BorderLayout(边界布局管理器)

位置:东,南,西,北,中

当不指定组件的位置,则它将会以整个最大面积去填充窗体,默认为居中的。添加新组件将会覆盖。

Frame、Dialog默认的布局管理器。

13.4.3GridLayout(网格布局管理器)

规则的矩阵(应用于计算器布局)

13.4.4CardLayout(卡片布局管理器)

选项卡(选项卡)

13.4.5GridBagLayout(网格包布局管理器)

非规则的矩阵

13.4.6坐标式布局

eclipse的图形化插件的使用(自动生成代码)

13.4.7多种布局混合使用

   首先将窗体整体规划分成几个部分,然后添加面板(Panel),把相应的组件添加到面板上,然后设置面板的布局方式

13.5创建图形化界面

13.5.1创建图形化界面的步骤

1、   创建Frame窗体

2、   对窗体进行基本设置:大小、位置、布局等属性

3、   定义组件

4、   将组件通过窗体的add()方法添加到窗体中

5、   让窗体显示,通过setVisible(true);

13.5.2简单的窗体创建过程

•   Frame f = new Frame(“mywindow”);//创建带名窗体

•   f.setLayout(newFlowLayout());//设置窗体布局

•   f.setSize(500,400);//设置窗体大小(x坐标,y坐标

•   f.setLocation(300,200);//设置窗体出现在屏幕的位置

•   f.setVisible(true); //设置窗体可见性

13.6事件监听机制

13.6.1事件监听机制组成

l 事件源(AWT或Swing包中的图形化界面组件)

l 事件(每一个事件源都有自己特有的和共有的Event)

l 监听器(将可以触发某一个事件的多动作,都封装到Listener)

l 事件处理(我们能做的就是:引发事件后处理方式)

13.6.2事件监听机制流程图

13.6.3事件监听机制

l 确定事件源(容器或组件)

l 通过事件源对象的addXXXListener()方法将侦听器注册到该事件源上。

l 该方法中接收XXXListener的子类对象,或者XXXListener的子类XXXAdapter的子类对象。

l 一般用匿名内部类来表示。

l 在覆盖方法的时候,方法的参数一般是XXXEvent类型的变量接收。

l 事件触发后会把事件打包成对象传递给该变量。(其中包括事件源对象。通过getSource()或者,getComponent()获取。)

13.6.4示例——在窗体中通过创建按钮

import java.awt.*;

import java.awt.event.*;

class  FrameDemo//简单的优化

{

//1、(一般)定义该图形中所需的组件的引用。作用于整个类,方便使用

        privateFrame f;//窗体

        privateButton but;//按钮

        FrameDemo()//构造函数

        {

               init();//初始化窗体后就用图形化界面,并具有基本事件

        }

        public voidinit()//对图形化界面进行初始化

        {

               f =new Frame("my frame");//设置窗体名

               //对frame进行基本设置。

               f.setBounds(300,100,600,500);//距左,距右,宽,高

               f.setLayout(newFlowLayout());//设置布局

               but =new Button("my button");//设置按钮

               //将组件添加到frame中

               f.add(but);

               //显示窗体之前,加载一下窗体上事件。调用事件方法

               myEvent();

               f.setVisible(true);//显示窗体;

        }

        private voidmyEvent()//事件

        {

        //窗体添加监听器,传入一个具体的监听对象(使用了匿名内部类)

              f.addWindowListener(newWindowAdapter()

               {

                       //关闭窗体

                       publicvoid windowClosing(WindowEvent e)

                       {

                               System.exit(0);

                       }

               });

13.6.5让事件源具备功能的步骤

1、事件源是按钮。

2、那么选择哪个监听器呢?

3、通过关闭窗体示例了解到,想要知道哪个组件具备什么样的特有监听器。

4、需要查看该组件对象的功能。

5、通过查阅button的描述。发现按钮支持一个特有监听addActionListener。

13.6.6适配器的一些介绍

适配器(adapter)的出现原因只有一个:方便创建监听器对象。因为监听器中一般有多个方法,而当只需要用一个,那么我覆盖很多个很麻烦,所以它给我们提供了已有的子类,它把所有的方法都覆盖完了,我们只要继承他,并复写其中的一个方法就可以了。

ActionListener是少数没有适配器的接口(大约三个)的其中一个。且只有一个方法。另外只要方法超过三个(包含三个)的几乎都有适配器adapter。

               */

               but.addActionListener(newActionListener()

               {

                       privateint count = 1;

//复写按钮监听器的唯一一个方法,使用匿名内部类的形式,传入一个活动事件

                       publicvoid actionPerformed(ActionEvent e)

                       {

                               System.out.println("退出,按钮干的");

                               System.exit(0);//退出虚拟机

                       //f.add(newButton("Button-"+(count++)));

                               //f.setVisible(true);

                               //f.validate();

                               //System.out.println(e.getSource());

                               Buttonb = (Button)e.getSource();

                               Framef1 = (Frame)b.getParent();

                               f1.add(newButton("button-"+count++));

                               f1.validate();

                       }

               });

        }

public static void main(String[] args) //主函数做测试用

        {

               newFrameDemo();

        }

}

13.6.7鼠标事件

java.awt.event 
类 MouseEvent

public class MouseEvent
extends InputEvent指示组件中发生鼠标动作的事件。

static int

BUTTON1(鼠标左键) 
指示鼠标按键 #1;由 getButton() 使用。

static int

BUTTON2 (鼠标右键)
指示鼠标按键 #2;由 getButton() 使用。

static int

BUTTON3 (鼠标中键)
指示鼠标按键 #3;由 getButton() 使用。

13.6.8示例——键盘事件与鼠标事件

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);//一个文本框指定长度为20
               but = new Button("my button");
 
               f.add(tf);
               f.add(but);
               myEvent();//添加事件
               f.setVisible(true);//设置窗体可见
        }
        private void myEvent()
        {
               //添加窗体监听器
               f.addWindowListener(new WindowAdapter()
               {
                       public void windowClosing(WindowEvent e)
                       {
                               System.exit(0);
                       }
               });
               //文本框添加键盘事件
               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();
                               }
                       }
               });
               //给按钮添加一个键盘监听。
               but.addKeyListener(new KeyAdapter()
               {
               //键盘按下
               public void keyPressed(KeyEvent e)
                       {       
//组合键的使用方法,ctrl键是否被按下&&另外一个键
if(e.isControlDown()&&e.getKeyCode()==KeyEvent.VK_ENTER)
               //System.exit(0);
        System.out.println("ctrl+enter is run");
        //返回按键的文本,即返回按下键的文本信息和键对应的码值
        //System.out.println(KeyEvent.getKeyText(e.getKeyCode())+"...."+e.getKeyCode());
        //获取键盘按下的键和键对应的码值
        System.out.println(e.getKeyChar()+"...."+e.getKeyCode());
                       }
               });
//添加按钮活动监听器,只要按钮被活动都会发生的事件,要后于鼠标监听器,此时去键盘也可以操作。
               but.addActionListener(new ActionListener()
               {
                       public void actionPerformed(ActionEvent e)
                       {
                               System.out.println("action ok");
                       }
               });
               */
               //按钮添加一个鼠标监听器,添加一个鼠标适配器
               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++);
                       }
               });
               */
        }
public static void main(String[] args) 
        {
               new MouseAndKeyEvent();
        }
}

13.6.9列出指定目录内容

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,70);//行数,列数
//对话框的参数信息,依赖的窗体,对话框名字,模式true为取消掉才可以操作窗体
               d = new Dialog(f,"提示信息-self",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();
        }
}

13.7菜单继承体系

13.7.1菜单概述

l MenuBar(菜单条/栏)Menu(菜单)MenuItem(菜单项)

l 先创建菜单条,再创建菜单,每一个菜单中建立菜单项。

l 也可以菜单添加到菜单中,作为子菜单。

l 通过setMenuBar()方法,将菜单添加到Frame中。

l 菜单是菜单项的子类。

13.7.2示例——菜单的创建

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);
        }
        private void myEvent()
        {
               //为菜单项添加活动监听
               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 MyMenuDemo();
        }
}

13.7.3一个简单的记事本程序

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);
               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.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 = 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();
        }
}

13.8制作jar包并双击执行

如何制作可以双击执行的jar包呢?
1,将多个类封装到了一个包(package)中。
编译带包源文件  javac –d 路径 *.java
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 href="http://edu.csdn.net"target="blank">ASP.Net+Android+IOS开发</a>、<a href="http://edu.csdn.net"target="blank">.Net培训</a>、期待与您交流! ----------------------