31,GUI图形用户界面

一:大致介绍---->

CLI:Command  line  User Interfcae命令行用户接口

GUI:图形用户接口,Graphical  User  Interface

GUI对比于前者,更加形象直观。

Java.awt是图形用户界面常用的工具包(抽象窗口工具包),需要调用本地系统方法实现,重量级控件。

Java.swing是在前者的基础上升级。移植型强,轻量级控件。

而GUI常用的类以及其中的继承关系如图1所示。

黑马程序员 python银行管理系统_黑马程序员 python银行管理系统

                         图1

        其中,Componet(组件),Container(容器),Window(窗口),Frame(框架),Dialog(对话框),FileDialog(文件对话框),Panel(面板),Button(按钮),Label(标签),Checkbox(复选框),TextComponent(文本组件),TextArea(文本区),TextField(文本行)

        Container容器可以添加其他的组件。

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

1,  FlowLayout流式布局,从左到右的排列,这是Panel默认的布局管理器

2,  BorderLayout边界布局,按照方位东南西北中排列,这是Frame默认布局管理器

3,  GridLayout网格布局,例如井格方框

4,  CardLayout卡片布局,选项卡

5,  GridBagLayout网格包布局,不规则排列


设定窗口的一般步骤:

import  java.awt.*;//导入相关的包
class   Wuo6
{
         public  static   void   main(String[] args)
         {
                   //建立一个名字为my_super的框架
                   Frame   fra=new Frame("my_super");
                   //基本设置
                   fra.setSize(200,210);//设置大小
                   fra.setLocation(100,110);//设置框架端点到屏幕左边的距离以及框架端点到屏幕上边的距离
                   fra.setLayout(new   FlowLayout());//设置布局方式
 
                   Button   bu=new Button("按钮一号");//建立名字为按钮一号的按钮组件      
                   //添加组件
                   fra.add(bu);
                   //设置窗口为可见
                  fra.setVisible(true);         
 
         }
         public static  void  sop(Object obj)//打印方法
         {
           System.out.println(obj);               
         }
}



效果如图2 所示:

黑马程序员 python银行管理系统_java_02

           图2

 

二:事情监听机制---->  

        一般,当用户操作某个组件的时候,就会产生对应的事件,为了监听这些事件并且给出对应的处理,先把监听器注册到可能会发生事件的组件上(事件源),当有用户有外部操作时(监听器要监听的动作作用在事件源上),就会产生对应的事件,这些事件封装成对象(事件对象)反馈给监听器,监听器内部就会有相应的处理。

        其中,事情的处理,触发的动作(可以不止一个)都已经封装到监听器里面了。

        事件对象的使用需要先导入相关包java.awt.event

        事件源是哪一个组件就在哪一个组件上添加监听器,添加监听器之后,一般都会把设置窗口可见的句子  fra.setVisible(true);   放在最后面。

以下介绍一些常见的监听器,依然是在上一个例题基础上编写(记得要导入java.awt.event包):

 

//给框架添加一个窗口监听器
                  fra.addWindowListener(new  WindowAdapter(){
                  //WindowAdapter是WindowListener的子类,WindowAdapter的方法都是空的,方便复写,从而建立适配器对象
                 //监听的是窗体,所以返回的是窗体事件WindowEvent
                    public void windowClosing(WindowEvent   e)//监听窗口关闭动作
                   {
                            //窗口关闭了就执行一次该行
                             fra.setVisible(false);//不显示窗口,但是没有退出程序
                             //System.exit(0);//直接退出程序了
                    }
                    public void windowOpened(WindowEvent   e)//监听窗口打开动作
                    {
                             //窗口打开了就执行一次该行
                             sop("窗口打开了!");
                    }
                    public   void windowActivated(WindowEvent   e)//监听窗口存活的动作
                    //特别注意的是当此窗口作为当前窗口时候也会调用该方法,如果当前窗口切换到其他窗口又返回到此窗口时,那么又会调用一次该方法。
                    {
                             //窗口存在时候执行一次该行
                              sop("此时窗口存在");
                    }
                   });
                  
                   //哪个组件具备特有监听器就要看该组件对象的方法
                   //给按钮组件添加活动监听器
                   //ActionListener只有一个方法,不需要另外建立适配器,使用时直接复写该方法
                   bu.addActionListener(new  ActionListener(){
                   //接收的是活动事情对象
                   int  i=0;//可以设定点击的计数器
                   public   void  actionPerformed(ActionEvent  e)//监听按钮活动动作(鼠标点击和快捷键都算活动)
                   {
                            i++;//每点击一次就会加1
                            //按钮只要被活动(鼠标点击或者键盘快捷键)就执行该行
                            sop("按钮被按了"+i+"次!");                                                             
                   }
                   });

     

其中sop是打印方法:

public static  void  sop(Object obj)//打印方法
         {
           System.out.println(obj);               
         }



还有几个是共性事件的,也就是说可以把监听器安装在任意适合的组件上,这就需要从Component类里面寻找相关的方法:

添加键盘监听器void  addKeyListener( KeyListener  l )

添加鼠标监听器void  addMouseListener(MouseListener   l)  

 

鼠标事件MouseEvent:

MouseListener是用来接收组件上感兴趣的鼠标事件,有一个子类MouseAdapter可以建立适配器。里面有几个方法

1,void    mouseClicked(MouseEvent  e)  //鼠标点击组件时候调用该方法

 

2,void    mouseEntered(MouseEvent  e)  //鼠标进入组件上时候调用该方法

 

3,void    mouseExited(MouseEvent  e)   //鼠标离开组件时候调用该方法

 

4,void    mouseProessed(MouseEvent  e)  //鼠标在组件上按下时候调用

 

5,void    mouseReleased(MouseEvent  e)  //鼠标在组件上释放时候调用

           

//还是在上一题基础上编写代码
//给按钮组件添加按钮活动监听器
bu.addActionListener(new ActionListener(){
//接收的是活动事情对象
int  i=0;//可以设定点击的计数器
public   void  actionPerformed(ActionEvent  e)//监听按下动作
{
    i++;//每点击一次就会加1
    //按下按钮后执行该行
    sop("按钮被按了"+i+"次!");                                                             
}
});
          
//在同一个按钮组件上添加鼠标监听器
bu.addMouseListener(new  MouseAdapter(){
public void  mouseClicked(MouseEvent   e)//监听鼠标点击活动
{
//如果鼠标点击的话就执行,并且优先于actionPerformed方法执行
sop("这是鼠标点击");                    
                                                                      
}
});
//如果是双击鼠标才输出“这是鼠标双击”的话,因为鼠标双击是事件,所以相关信息会封装到MouseEvent里面,代码就该改写成:
 
//在同一个按钮组件上添加鼠标监听器
bu.addMouseListener(new  MouseAdapter(){
public void  mouseClicked(MouseEvent   e)//监听鼠标点击活动
{
//用getClickCount方法获取点击次数     
if(e.getClickCount()==2)          
sop("这是鼠标双击");                                                                       
}
});



键盘事件(KeyEvent):     

键盘监听器KeyListener也有自己的适配器KeyAdapter,在书写上也和鼠标监听器MouseListener差不多,里面也有几个常用方法。

void   keyPressed(KeyEvent  e)   //按下某个键时候调用该方法

void   keyReleased(KeyEvent   e)  //释放某个键时候调用该方法

void   keyType(KeyEvent   e)  //键入某个键时候调用该方法

        如果需要知道键入的哪一个键的话,相关信息就封装到KeyEvent类中,调用getKeyChar方法可以返回键入的字符,调用getKeyCode方法可以返回键入符号的编码值。

//给按钮组件添加键盘监听器
        //当该按钮组件为当前事件源的时候会有一个虚线框框住,在此条件下,才会进行监听
                   bu.addKeyListener(new  KeyAdapter(){
                   public  void   keyPressed(KeyEvent   e)
                   {
                            sop(e.getKeyChar());//打印的是键入的字符
                            sop(e.getKeyCode());//打印的是键入的字符所对应的编码值
                       
                   }
                   });



        KeyEvent这个类里面还定义了很多静态的字段,这些字段都是对应着键盘上的键盘按钮所对应字符的编码值。这些字段前面几乎都是被VK_修饰着的,比如VK_CONTROL,就表示control键所对应的编码值,因为是静态所以直接用类名调用KeyEvent.VK_CONTROL,之所以有这些字段的存在就是为了更加方便的判断键入的是哪一个键,例如:

//给按钮组件添加键盘监听器
bu.addKeyListener(new  KeyAdapter(){
public  void   keyPressed(KeyEvent   e)
{
If(e.getKeyCode()==KeyEvent.VK_CONTROL)
//如果键入的是control键,就执行
sop(“哈哈哈”);  
}
});



其中比较常用的还有KeyEvent还从java.awt.event包的InputEvent那里继承了下列方法:

public  boolean   isAltDown() // 判断在此事件中Alt键是否已经按下了

 

public  boolean   isAltGraphDown()  //判断在此事件中AltGraph键是否已经按下

                 

public  boolean   isControlDown()    //判断在此事件中Control键是否已经按下

    

public  boolean   isMetaDown()    //判断在此事件中Meta键是否已经按下 

        

public  boolean   isShiftDown()    // 判断在此事件中ShiftDown键是否已经按下

 

有这些方法配合就可以使用组合键了:

</pre><p></p><pre name="code" class="java">//给按钮组件添加键盘监听器
bu.addKeyListener(new  KeyAdapter(){
public  void   keyPressed(KeyEvent   e)
{
     //判断是否是control键与enter键的组合使用
     if(e.isControlDown()&& e.getKeyCode()==KeyEvent.VK_ENTER)
     sop("这是control键与enter键的组合使用");
}
});



        另外还有比较常用的,也是KeyEvent还从java.awt.event包的InputEvent那里继承了下列方法:public   void   consume()      //此事件不会按照连续事件那般处理

        以下是相关例子:

//导入相关的包
import  java.awt.*;
import  java.awt.event.*;
class   Wuo6
{
         public  static   void   main(String[] args)
         {
                   //建立一个名字为my_super的框架
                   Frame   fra=new Frame("my_super");
                   //基本设置
                   fra.setSize(200,210);//设置大小
                   fra.setLocation(100,110);//设置框架端点到屏幕左边的距离以及框架端点到屏幕上边的距离
                   fra.setLayout(new   FlowLayout());//设置布局方式
 
                   TextField   tf=new TextField(30); //建立长度30的文本框     
                   //添加组件
                   fra.add(tf);
                   //给文本框组件添加键盘监听器
                   tf.addKeyListener(new  KeyAdapter(){
                   public  void   keyPressed(KeyEvent   e)
                   {
                            int   icode= e.getKeyCode();
                            //判断键入的是否是0号键
                            if(icode!=KeyEvent.VK_0)
                                     {
                            sop("按下的不是0按键");
                            e.consume();
                            /*
                            由于键入文本框与判断是否是0号键,两个是连续事件,
                            如果需要不符合条件的键入值不被键入的话,就调用consume方法,
                            调用该方法后,能够被键入文本框的键值就只有0号键。
                            */
                                      }
                   }
                   });          
                   //设置窗口为可见
                   fra.setVisible(true);
         }
         public static  void  sop(Object obj)//打印方法
         {
           System.out.println(obj);               
         }
}



 

三:TextArea文本区---->

文本区TextArea也是经常使用,下面介绍其常见的构造函数和方法:

TextArea的构造函数

TextArea()// 构造一个新文本区,没有名字。

TextArea(int   rows, int   columns)//构造一个新文本区,指定行数和列数,没有名字。

TextArea(String   text)//构造一个新文本区,具有指定的名字。

TextArea(String    text, int     rows, int     columns)//构造一个新文本区,该文本区具有指定的文本,以及指定的行数和列数。

TextArea(String    text, int    rows, int      columns, int     scrollbars)//构造一个新文本区,指定名字,指定行数和列数,以及和滚动条可见性。

 

TextArea的常用方法有:

void   append(String  str)  //将指定的字符串加入到文本区中(不会自动换行,如果需要换行的话需要自己在括号里添加java换行符号)

public   String  getText()  //获取当前文本内容

public   void    setText(String   t)    //将文本区的内容全部替换指定的字符串内容

 

四:Dialog对话框---->

对话框Dialog的常见应用:

Dialog的常用构造函数

Dialog(Frameowner,Stringtitle, boolean modal)  //构造一个最初不可见的带有名字的Dialog,它带有指定的所有者 Frame和模式,这里的模式指定在显示的时候是否阻止用户将内容输入到其他顶级窗口中。

//导入相关的包
import  java.awt.*;
import  java.awt.event.*;
class   Wuo7
{
         public  static   void   main(String[] args)
         {
                   //建立一个名字为my_super的框架
                   Frame   fra=new Frame("my_super");
                   //基本设置
                   fra.setSize(200,210);//设置大小
                   fra.setLocation(100,110);//设置框架端点到屏幕左边的距离以及框架端点到屏幕上边的距离
                   fra.setLayout(new   FlowLayout());//设置布局方式
 
 
                   Dialog     dia=new Dialog(fra,"这是对话框",true); //建立初始不可见的对话框
                   dia.setSize(100,50);//设置对话框大小
                   dia.addWindowListener(new  WindowAdapter(){
                      public void  windowClosing(WindowEvent   e)//监听关闭对话框窗口动作
                      {
                             dia.setVisible(false);                
                      }
                   });
                   Label       la=new Label();//建立标签,初始的标签内容还没有定义
                   //Label     la2=new Label("标签");//也可以在一开始的时候就定义标签内容
                   dia.add(la);//对话框加入标签
 
                  TextField   tf=new TextField(30); //建立长度30的文本框     
 
                   fra.add(tf);
                   //给文本框组件添加键盘监听器
                   tf.addKeyListener(new  KeyAdapter(){
                   public  void   keyPressed(KeyEvent   e)
                   {
                            int   icode= e.getKeyCode();
                            //如果按下的是0号键就执行
                            if(icode==KeyEvent.VK_0)
                                     {
                                                 la.setText("红红火火!");
                                                 dia.setVisible(true);//设定对话框可见
                                     }
                   }
                   });          
                   //设置窗口为可见
                   fra.setVisible(true);         
 
         }
         public static  void  sop(Object obj)//打印方法
         {
           System.out.println(obj);               
         }
}



五:菜单---->

关于菜单的知识点,直接给一个例子就可以明了了。

制作菜单:

        MuneBar菜单栏,Mune菜单,MuneItem菜单条,其中菜单栏包含菜单,菜单可以包含子菜单或者菜单条

import java.awt.*;
import java.awt.event.*;
class  Gui5
{
         publicstatic void main(String[] args)
         {
                   //建立窗口
                   Frame   f=new  Frame("这是Frame");
                   //基本设置
                   f.setBounds(200,200,300,300);
                   f.setLayout(new  FlowLayout());
                   MenuBar   mb=new MenuBar();//建立菜单栏
                   f.setMenuBar(mb);//把菜单栏设置到窗体里面
                   Menu    m=new Menu("文件");//建立菜单
                   Menu    m2=new Menu("编辑");
                   Menu    m3=new Menu("查看方式");
                   MenuItem    mi=new MenuItem("新建文件");//建立菜单条
                   MenuItem    mi2=new MenuItem("删除文件");
                   MenuItem    mi3=new  MenuItem("暴风影音");
                   MenuItem    mi4=new MenuItem("Windows  Media  Player");
                   MenuItem    mi5=new MenuItem("退出");
                   mb.add(m);
                   mb.add(m2);
                   m.add(m3);//菜单里面还包含了子菜单
                   m.add(mi);
                   m.add(mi2);
                   m.add(mi5);
                   m3.add(mi3);
                   m3.add(mi4);
                   //菜单条还可以添加活动监听器
                   mi5.addActionListener(new ActionListener()
                   {
                            //点击“退出”菜单条就退出程序
                        public void actionPerformed(ActionEvent    e)
                             {
                                    System.exit(0);                       
                             }
                   });
 
                   f.setVisible(true);
         }
         public  static void  soc(Object   obj)//打印方法
         {
              System.out.println(obj);                              
         }
}



效果如图3所示:

黑马程序员 python银行管理系统_java_03

                                图3

 

六:文件对话框FileDialog---->

        其构造函数是FileDialog(Frame   parent,String   title, int   mode)实际写的时候如下:

       FileDialog   loadfd=new   FileDialog(f,"文件对话框",FileDialog.LOAD);

        //文件对话框持有者是窗体f,名字"文件对话框",设置为打开模式

 

       FileDialog   savefd=new  FileDialog(f,"文件保存对话框",FileDialog.SAVE);

       //文件对话框持有者是窗体f,名字"文件对话框",设置为保存模式

 

以下有综合例子演示:

//导入相关包
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class  N1_1
{
   Frame     f=new  Frame("第一个窗口");
   TextArea    ta=new   TextArea();
   MenuBar    mb=new MenuBar();
   Menu       m=new   Menu("文件");                           
   MenuItem    dakaimi=new   MenuItem("打开"); 
   MenuItem    baocuenmi=new  MenuItem("保存");
   File   fe;//放在这里,作为成员变量,其应用范围是整个类
   N1_1()
   {
        method(); //所有应该执行的代码都放在构造函数中   
   }
   public   static  void main(String[] args) //主函数的作用就是建立一个对象
   {  
        //直接建立本类对象就执行了需要执行的代码,对于主函数的调用非常方便
        new   N1_1();
                  
   }
   public    void method()
  {
        f.setBounds(200,200,600,600);//基本设置
        f.addWindowListener(new   WindowAdapter()
        {
             public  void  windowClosing(WindowEvent    e)
             {
                 System.exit(0); //退出程序                   
             }
  });
                  
  //相关的添加操作
  f.add(ta);
  f.setMenuBar(mb);
  mb.add(m);
  m.add(dakaimi);
  m.add(baocuenmi);
                    
  FileDialog   loadfd=new  FileDialog(f,"文件打开对话框",FileDialog.LOAD);
  //文件对话框持有者是窗体f,名字"文件对话框",打开模式
 
  FileDialog   savefd=new  FileDialog(f,"文件保存对话框",FileDialog.SAVE);
  //文件对话框持有者是窗体f,名字"文件对话框",保存模式
 
  //在保存菜单条添加活动监听器      
  baocuenmi.addActionListener(new ActionListener()
  {
     public   void  actionPerformed(ActionEvent    e)
     {
        //先考虑特殊情况
        //实际文件不存在的情况下做以下处理,如果文件实际存在就跳过此步骤,就不会弹出文件对话框,直接进行保存操作
        if(fe==null)
        {  
            savefd.setVisible(true); 
            String    files=   savefd.getFile(); //获取文件名
            String   dirs=    savefd.getDirectory();//获取路径
                                                 
            if(files==null  || dirs==null)
                 return;
            fe=new  File(dirs,files); 
 
        }
        try
        {
           //把文本框内容写入
           BufferedWriter     bw=new  BufferedWriter(new  FileWriter(fe));
           String   strta=   ta.getText();
            bw.write(strta);//一次性全部写入
            bw.close();    
        }
        catch(IOException   ioex)
        {
        }         
    }
 });
       //在打开菜单条上添加活动监听器       
  dakaimi.addActionListener(new  ActionListener()
  {
      public void actionPerformed(ActionEvent    e)
      {
            //只要打开菜单条被点击了就显示打开文件对话框
            loadfd.setVisible(true);
 
            File      filewj;
            FileReader    fr;
            BufferedReader    br=null;                                       
            String      lujing=     loadfd.getDirectory();//获取路径
            String      wenjian=  loadfd.getFile();  //获取文件名
            if(lujing==null  || wenjian==null)
                    return;//没有选择到文件的情况:如果为路径名为空或者文件名为空直接返回
            //注意一定要把没有选择到文件的情况考虑进去!
            ta.setText("");
            try
            {
                 filewj=new  File(lujing,wenjian);
                 fr=new  FileReader(filewj); 
                 br=new  BufferedReader(fr);
                 String     str=null;
                 while((str=br.readLine())!=null)//一边读取
                 {
                       ta.append(str+"\r\n"); //一边添加,并且换行
                 }
                                                                                            
             }
             catch(IOException   ioe)
             {
                  throw   new RuntimeException("读取错误");
             }
             finally
             {
                 try
                 {
                     br.close();//把关闭资源的操作放在finally块中,这是必须操作
                 }
                 catch(IOException   ioe)
                 {
                      throw   new RuntimeException("br.close();出错");
                 }
                                                               
              }
      }
  });
  f.setVisible(true);//最后才设定显示整个窗口                         
 }
 public  static void  soc(Object  obj)//打印方法
 {
     System.out.println(obj);                          
  }
}



效果如图4和图5所示:

黑马程序员 python银行管理系统_黑马程序员 python银行管理系统_04

                           图4

黑马程序员 python银行管理系统_监听器_05

                            图5

七:jar包的双击执行---->

        写好了一个GUI的java源文件,想要做成jar包然后双击就可以弹出图形界面,那么需要执行以下步骤:

        首先,将多个类封装到了一个包(package)中。(主要是把相关类的.class文件封装到一个包中)然后,定义一个文件a.txt 。文件内容内容为:Main-Class:(空格键)包名.类名(回车符)这是相关的配置信息文件。再接着就打jar包:在DOS命令行中输入jar  -cvfm  my.jar  a.txt 包名

        通过winrar程序进行验证,查看该jar的配置文件中是否有自定义的配置信息。此时这个配置信息文件的作用就出来了,告诉虚拟机先执行的类的主函数是谁,然后虚拟机就可以执行代码了。

        最后一步是通过工具—》文件夹选项—》文件类型—》jar类型文件,通过高级,定义该jar类型文件的打开动作的关联程序。

         jdk\bin\javaw.exe -jar