Java基础——GUI概述

来源:互联网 发布:qq会员永久软件 编辑:程序博客网 时间:2024/05/29 17:24

GUI图形用户界面

GUI

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

CLI

命令行用户接口:就是常见的dos命令行操作,需要记忆一些常用的命令,操作不直观

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

Awt和Swing

  • java.Awt抽象窗口工具包,需要调用本地系统方法实现功能,属于重量级控件
  • javax.Swing在Awt的基础上,建立的一套图形界面系统,其中提供了更多的组件,而且完全由java实现,增强了移植性,属轻量级控件。

这里写图片描述

容器中的组件的排放方式,就是布局。
常见的布局管理器:

  • FlowLayout(流式布局管理器)
    • 从左到右的顺序排列
    • Panel默认的布局管理器
  • BorderLayout(边界布局管理器)
    • 东,南,西,北,中
    • Frame默认的布局管理器
  • GridLayout(网格布局管理器)
    • 规则的矩阵
  • CardLayout(卡片布局管理器)
    • 选项卡
  • GridBagLayout(网格包布局管理器)
    • 非规则的矩阵

那么我们开始建立一个新的窗体,
步骤是:
建立一个窗体;
设置窗体的基本属性,包括大小,位置,布局
通过add方法在窗体中添加组件
通过setVisible()里边传true值使窗体可见。

演示:

//演示基本窗体的建立import java.awt.*;public class FrameDemo {    public static void main(String[] args)     {        Frame f = new Frame("myFrame");//先创建一个窗体对象        f.setLayout(new FlowLayout());//设置布局方式为流式布局        f.setLocation(300,200);//设置窗体位置在距离左边300px,距离上边200px        f.setSize(500,400);//设置窗体大小为500*400        Button b = new Button("按钮1");//创建一个按钮对象        f.add(b);//将按钮对象添加进窗体中        f.setVisible(true);//将窗体设置为可见    }}

运行结果:

这里写图片描述

注意:
Frame窗体默认的是面板式布局,就是添加进来的组件会布满整个窗体,所以这里使用了流式布局。
setVisible方法必须放在最后一行,否则有些效果出不来。

当我们在操作创建下的窗体的时候,发现,最大化最小化都可以实现,但是关闭按钮点了没有反应,窗体不会关闭,这是为什么呢?

这就设计到了事件监听机制的问题:

事件监听机制的组成:

  • 事件源
  • 事件
  • 监听器
  • 事件处理(引发事件后处理方式)

这里写图片描述

事件源:就是Awt包或者Swing包中的那些图形化界面组件

事件:每一个事件源都有自己特有的对应事件和共性事件。

监听器:将可以触发某一个事件的动作(不止一个动作)都封装到了监听器中,

以上三者,在java中都已经定义好了,直接获取拿来用就可以了

我们要做的就是对产生的动作进行处理。

//演示基本窗体的建立import java.awt.*;import java.awt.event.*;public class FrameDemo {    public static void main(String[] args)     {        Frame f = new Frame("myFrame");//先创建一个窗体对象        f.setLayout(new FlowLayout());//设置布局方式为流式布局        f.setLocation(300,200);//设置窗体位置在距离左边300px,距离上边200px        f.setSize(500,400);//设置窗体大小为500*400        Button b = new Button("按钮1");//创建一个按钮对象        f.add(b);//将按钮对象添加进窗体中        //给窗体添加一个事件监听器        f.addWindowListener(new WindowAdapter()//传进来一个事件监听器WindowListener但是这里边有7个抽象方法,        {            //WindowAdapter实现了WindowListener接口,而且覆盖了所有的方法            //可以直接拿过来创建匿名内部类进行方法的复写            //关闭窗口的方法            public void windowClosing(WindowEvent e)//当事件发生的时候,调用该方法            {                System.out.println("关闭");                System.exit(0);            }            //当窗口被打开的时候调用            public void windowOpened(WindowEvent e)            {                System.out.println("打开窗体");            }            //当窗口获得焦点的时候会自动调用            public void windowActivated(WindowEvent e)            {                System.out.println("激活窗口");            }        });        f.setVisible(true);//将窗体设置为可见    }}

运行结果:

窗口可以直接被关闭,而且控制台上会有数据打印出来。

这里写图片描述

其实加监听器的方法就是先给窗体调用添加监听器的方法addWindowListener
同时参数要传进去一个WindowListener对象,可是WindowListener是一个接口,
发现了WindowListener有一个子类,WindowAdapter实现了WindowListener接口,并且复写了WindowListener所有的方法,而且方法体都是空的,
但是WindowAdapt是一个抽象的类,不可以创建对象,
于是用内部类的方式,复写里边的方法
每一个处理方法被调用的时候,都要有个事件传进来。

//规范化书写,将窗体布局的设置和添加监听器分离开//给按钮添加监听器,能够关闭掉窗体import java.awt.*;import java.awt.event.*;class MyFrame{    MyFrame()    {        inis();    }    Frame f = null;    Button b = null;    public void inis()    {        f = new Frame("我的窗体");        b = new Button("关闭");        f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高        f.setLayout(new FlowLayout());        f.add(b);        myListener();//该方法可以添加进来全部的监听器        f.setVisible(true);    }    //这里添加监听器    public void myListener()    {        //关闭键关闭窗体的监听器        f.addWindowListener(new WindowAdapter()        {            public void windowClosing(WindowEvent e)            {                System.exit(0);            }        });        //通过按钮关闭窗体        b.addActionListener(new ActionListener()        {            public void actionPerformed(ActionEvent e)            {                System.out.println("关闭,按钮干的");                System.exit(0);            }        });    }}public class FrameDemo2 {    public static void main(String[] args)     {        new MyFrame();    }}

运行结果:
这里写图片描述

操作成功,为什么WindowListener需要有Adapter(适配器)呢?而按钮监听器不用呢?

这是因为,Window上边的监听器(接口)中的方法有7个,要是一个一个去复写,很累的,所以就出现了适配器,适配器覆盖了所有的方法但是方法体为空的,我们使用适配器,用哪个方法就复写哪个方法,很方便的。

但是在按钮的监听器中,只有一个方法,actionPerformed,所以用不着适配器。

鼠标事件:

在按钮上添加鼠标活动事件:

实例如下:

//规范化书写,将窗体布局的设置和添加监听器分离开//给按钮添加鼠标监听器import java.awt.*;import java.awt.event.*;class MyFrame{    MyFrame()    {        inis();    }    Frame f = null;    Button b = null;    public void inis()    {        f = new Frame("我的窗体");        b = new Button("关闭");        f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高        f.setLayout(new FlowLayout());        f.add(b);        myListener();//该方法可以添加进来全部的监听器        f.setVisible(true);    }    //这里添加监听器    public void myListener()    {        //关闭键关闭窗体的监听器        f.addWindowListener(new WindowAdapter()        {            public void windowClosing(WindowEvent e)            {                System.exit(0);            }        });        //鼠标进入按钮监听器        b.addMouseListener(new MouseAdapter()        {            int count = 1;            public void mouseEntered(MouseEvent e)            {                System.out.println("鼠标进入按钮区域:"+count++);            }        });        //鼠标点击事件监听器        b.addMouseListener(new MouseAdapter()        {            int count = 1;            public void mouseClicked(MouseEvent e)            {                System.out.println("鼠标点击"+count++);            }        });        //MouseEvent中有可以获取鼠标点击次数的方法int getClickCount()        //可以用来设置单击双击事件。        //也可以设置动作监听器:        b.addActionListener(new ActionListener()        {            public void actionPerformed(ActionEvent e)            {                System.out.println("action   run");            }        });    }}public class FrameDemo3 {    public static void main(String[] args)     {        new MyFrame();    }}

运行结果:
这里写图片描述

结果可以发现,在给按钮同时加上鼠标监听器和动作监听器之后,点击一次鼠标,是鼠标监听器先执行,
这是因为鼠标监听事件更具体一些,所以先执行。

给按钮添加键盘监听事件:

//规范化书写,将窗体布局的设置和添加监听器分离开//给按钮添加键盘监听器import java.awt.*;import java.awt.event.*;class MyFrame{    MyFrame()    {        inis();    }    Frame f = null;    Button b = null;    public void inis()    {        f = new Frame("我的窗体");        b = new Button("关闭");        f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高        f.setLayout(new FlowLayout());        f.add(b);        myListener();//该方法可以添加进来全部的监听器        f.setVisible(true);    }    //这里添加监听器    public void myListener()    {        //关闭键关闭窗体的监听器        f.addWindowListener(new WindowAdapter()        {            public void windowClosing(WindowEvent e)            {                System.exit(0);            }        });        b.addKeyListener(new KeyAdapter()        {            public void keyPressed(KeyEvent e)            {                System.out.println(KeyEvent.getKeyText(e.getKeyCode()));                //getKeyCode方法可以根据键盘键入的值获取到相应的int类型的值                //getKeyText方法可以根据传入的int类型的值获取到键盘上的文字形式的字符串            }        });    }}public class FrameDemo3 {    public static void main(String[] args)     {        new MyFrame();    }}

运行结果为:

这里写图片描述

然后演示一个扣扣号的输入框:
需求是:一个输入框,只能输入数字,如果输入其他字符,则提示这个字符是非法的,而且该非法字符不可以写入到输入框中:

//一个扣扣输入框,只能输入数字import java.awt.*;import java.awt.event.*;class MyFrame{    MyFrame()    {        inis();    }    Frame f = null;    TextField tf = null;    Button b = null;    public void inis()    {        f = new Frame("QQ窗体");        b = new Button("登陆");        tf = new TextField(15);//新建一个文本框,列数为15        f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高        f.setLayout(new FlowLayout());        f.add(tf);        f.add(b);        myListener();//该方法可以添加进来全部的监听器        f.setVisible(true);    }    //这里添加监听器    public void myListener()    {        //关闭键关闭窗体的监听器        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("输入的字符是非法的");                    //默认是键盘一敲就文字就会到了输入框中,                    //consume方法就是改变这种默认的方式。                    e.consume();                }            }        });    }}public class MouseAndKeyTest {    public static void main(String[] args)     {        new MyFrame();    }}

运行结果为:

这里写图片描述

演示组合键怎么读取的:

//组合键的使用import java.awt.*;import java.awt.event.*;class MyFrame{    MyFrame()    {        inis();    }    Frame f = null;    Button b = null;    public void inis()    {        f = new Frame("我的窗体");        b = new Button("关闭");        f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高        f.setLayout(new FlowLayout());        f.add(b);        myListener();//该方法可以添加进来全部的监听器        f.setVisible(true);    }    //这里添加监听器    public void myListener()    {        //关闭键关闭窗体的监听器        f.addWindowListener(new WindowAdapter()        {            public void windowClosing(WindowEvent e)            {                System.exit(0);            }        });        b.addKeyListener(new KeyAdapter()        {            public void keyPressed(KeyEvent e)            {                //判断Ctrl键是否已经按下,和按键是否为Enter键                if(e.isControlDown() && e.getKeyCode() == KeyEvent.VK_ENTER)                    System.out.println("Control   +   enter    run ");            }        });    }}public class FrameDemo4 {    public static void main(String[] args)     {        new MyFrame();    }}

运行结果:

这里写图片描述

练习:列出指定的目录中的内容:

//列出指定目录下的文件名称//具体是:在最上方的文本框中输入一个目录,然后在下方的文本区域中输出该目录下的所有文件import java.io.*;import java.awt.*;import java.awt.event.*;class MyFrame{    MyFrame()    {        inis();    }    //在外边建立所有对象的引用,省的等会找不到还是怎么的    Frame f = null;    Button b = null;    TextField tf = null;    TextArea ta = null;    //从这里开始定义的是弹出错误对话框的对象    Dialog d = null;    Label l = null;    Button but = null;    public void inis()    {        f = new Frame("我的Window");        b = new Button("转到");        tf = new TextField(55);        ta = new TextArea(40,62);        f.setBounds(300,200,500,400);//该方法取代的setSize和setLocation设置的值分别表示横坐标,纵坐标,宽和高        f.setLayout(new FlowLayout());        f.add(tf);        f.add(b);        f.add(ta);        myListener();//该方法可以添加进来全部的监听器        f.setVisible(true);    }    //这里添加监听器    public void myListener()    {        //关闭键关闭窗体的监听器        f.addWindowListener(new WindowAdapter()        {            public void windowClosing(WindowEvent e)            {                System.exit(0);            }        });        //给转到按钮添加时间监听器        b.addActionListener(new ActionListener()        {            public void actionPerformed(ActionEvent e)            {                showDir();            }        });        //键盘监听器,输完目录之后按回车可以直接显示出目录中的文件        tf.addKeyListener(new KeyAdapter()        {            public void keyPressed(KeyEvent e)            {                if(KeyEvent.VK_ENTER==e.getKeyCode())                {                    showDir();                }            }        });    }    //这里封装的是按照文本框中输入的目录获取到目录下的文件的方法    private void showDir()    {        //每一次列出目录的时候,都把文本区域中的数据清空        ta.setText("");        String line = tf.getText();        File dir = new File(line);        //判断如果存在,而且文件是目录,则写入数据,如果不是目录,或者目录不存在,弹出对话框        if(dir.exists() && dir.isDirectory())        {            String[] names = dir.list();            for(String name:names)            {                ta.append(name+"\r\n");            }        }        else        {            d = new Dialog(f,"温馨提示",true);            l = new Label();            but = new Button("确定");            d.setBounds(500,400,270,100);            d.setLayout(new FlowLayout());            d.add(l);            d.add(but);            String s = "对不起,您输入的内容"+line+"有误,请重输";            l.setText(s);            //点关闭按钮可以使对话框关闭            d.addWindowListener(new WindowAdapter()            {                public void windowClosing(WindowEvent e)                {                    d.setVisible(false);                }            });            //鼠标点击按钮可以使对话框关闭            but.addActionListener(new ActionListener()            {                public void actionPerformed(ActionEvent e)                {                    d.setVisible(false);                }            });            //按回车键可以使对话框关闭            but.addMouseListener(new MouseAdapter()            {                public void mouseClicked(MouseEvent e)                {                    d.setVisible(false);                }            });            but.addKeyListener(new KeyAdapter()            {                public void keyPressed(KeyEvent e)                {                    d.setVisible(false);                }            });            d.setVisible(true);        }        tf.setText("");//将目录中的文件输入文本区域后就把文本框中的数据清空    }}public class MyWindowDemo {    public static void main(String[] args)     {        new MyFrame();    }}

运行结果:
当输入正确的目录之后是这样的结果:

这里写图片描述

当输入错误的目录之后是这样的结果:

这里写图片描述

图形化界面中的菜单

MenuBar菜单栏,用窗体的setMenuBar方法添加,而不是add方法
Menu:菜单,用MenuBar对象调用add方法添加进菜单栏中
MenuItem:条目,菜单中的一个一个的选项。

演示:

//菜单条的添加演示import java.awt.*;import java.awt.event.*;class MenuDemo{    MenuDemo()    {        isit();    }    private Frame f = null;    private MenuBar mb = null;    private Menu m1 = null;    private Menu m2 = null;    private MenuItem mi1= null;    private MenuItem mi2= null;    private MenuItem mi3= null;    private MenuItem mi4= null;    private MenuItem mi5= null;    public void isit()    {        f = new Frame("我的菜单");        mb = new MenuBar();        m1 = new Menu("文件");//这是一个菜单        m2 = new Menu("新建");//这是一个菜单中的子菜单,下边还有条目        mi1 = new MenuItem("打开");//这是文件菜单中的条目        mi2 = new MenuItem("保存");        mi3 = new MenuItem("退出");        mi4 = new MenuItem("java");//这是子菜单中的子条目中的内容        mi5 = new MenuItem("文本文件");        f.setBounds(400,300,400,300);        f.setLayout(new FlowLayout());        f.setMenuBar(mb);//使用这个方法添加MenuBar菜单栏,而不是用add方法        mb.add(m1);        m1.add(m2);        m2.add(mi4);        m2.add(mi5);        m1.add(mi1);        m1.add(mi2);        m1.add(mi3);        myEvent();        f.setVisible(true);    }    public void myEvent()    {        //点关闭按钮可以关掉窗体        f.addWindowListener(new WindowAdapter()        {            public void windowClosing(WindowEvent e)            {                System.exit(0);            }        });        //菜单中的退出条目,可以结束窗体        mi3.addActionListener(new ActionListener()        {            public void actionPerformed(ActionEvent e)            {                System.exit(0);            }        });    }}public class MyMenuDemo {    public static void main(String[] args)     {        new MenuDemo();    }}

运行结果:

这里写图片描述

文件对话框的使用:
保存文件和打开文件:

实例:

//练习,打开文件,和保存文件的过程import java.awt.*;import java.awt.event.*;import java.io.*;class MenuDemo{    MenuDemo()    {        isit();    }    private Frame f = null;    private MenuBar mb = null;    private Menu m1 = null;    private Menu m2 = null;    private MenuItem mi1= null;    private MenuItem mi2= null;    private MenuItem mi3= null;    private MenuItem mi4= null;    private MenuItem mi5= null;    private TextArea ta =null;    private FileDialog open = null;    private FileDialog save = null;    private File file=null;    public void isit()    {        f = new Frame("我的菜单");        mb = new MenuBar();        m1 = new Menu("文件");//这是一个菜单        m2 = new Menu("新建");//这是一个菜单中的子菜单,下边还有条目        mi1 = new MenuItem("打开");//这是文件菜单中的条目        mi2 = new MenuItem("保存");        mi3 = new MenuItem("退出");        mi4 = new MenuItem("java");//这是子菜单中的子条目中的内容        mi5 = new MenuItem("文本文件");        ta = new TextArea();        open = new FileDialog(f,"我的打开",FileDialog.LOAD);        save= new FileDialog(f,"我的保存",FileDialog.SAVE);        f.setBounds(300,200,600,500);        f.setMenuBar(mb);//使用这个方法添加MenuBar菜单栏,而不是用add方法        mb.add(m1);        m1.add(m2);        m2.add(mi4);        m2.add(mi5);        m1.add(mi1);        m1.add(mi2);        m1.add(mi3);        f.add(ta);        myEvent();        f.setVisible(true);    }    public void myEvent()    {        //点关闭按钮可以关掉窗体        f.addWindowListener(new WindowAdapter()        {            public void windowClosing(WindowEvent e)            {                System.exit(0);            }        });        //菜单中的退出条目,可以结束窗体        mi3.addActionListener(new ActionListener()        {            public void actionPerformed(ActionEvent e)            {                System.exit(0);            }        });        //想要在点打开的时候,弹出一个文件对话框来:        mi1.addActionListener(new ActionListener()        {            public void actionPerformed(ActionEvent e)            {                open.setVisible(true);                //FileDialog对象获取到打开的文件的目录和文件名                String dirPath = open.getDirectory();                String fileName = open.getFile();                //如果这个时候点了取消,返回的值都是空的,容易造成空指针异常,这里如果都为空就什么都不做                if(dirPath==null || fileName==null)                    return;                BufferedReader bufr = null;                ta.setText("");//每一次读取之前把ta里边的数据清空                try                {                    file = new File(dirPath+fileName);                    bufr = new BufferedReader(new FileReader(file));                    String line = null;                    while((line = bufr.readLine())!=null)                    {                        ta.append(line+"\r\n");                    }                }                catch (IOException ex)                {                    throw new RuntimeException("文件读取失败");                }                finally                {                    if(bufr!=null)                        try                        {                            bufr.close();                        }                        catch (IOException ex)                        {                            ex.printStackTrace();                        }                }            }        });        //想要在点保存的时候,弹出一个保存的对话框        mi2.addActionListener(new ActionListener()        {            public void actionPerformed(ActionEvent e)            {                save.setVisible(true);                save.setVisible(true);                String dirPath = save.getDirectory();                String fileName = save.getFile();                if(dirPath==null || fileName==null)                    return;                file = new File(dirPath+fileName);                BufferedWriter bufw = null;                try                {                    bufw = new BufferedWriter(new FileWriter(file));                    String text = ta.getText();                    bufw.write(text);                    bufw.flush();                }                catch (IOException ex)                {                    throw new RuntimeException("数据写入异常");                }                finally                {                    if(bufw!=null)                    {                        try                        {                            bufw.close();                        }                        catch (IOException ex)                        {                            ex.printStackTrace();                        }                    }                }            }        });    }}public class MyMenuDemo {    public static void main(String[] args)     {        new MenuDemo();    }}

运行结果可以实现,文件的LOAD和SAVE

这里写图片描述

这里写图片描述

jar包双击执行

想要将写好的程序可以双击就执行的,就像某一个软件一样的,
我们以前学过的jar命令,将类文件编译到指定的文件夹。

javac -d e:\others\myclass MyMenuDemo.java
将类文件编译到指定的包中

在和mymenu包同级目录下,创建一个文本文件,取名为1.txt
里边写上:
这里写图片描述

jar -cvfm my.jar 1.txt mymenu
将指定的包打成jar包

这样的话就可以双击执行了。

0 0