黑马程序员Java Swing笔记分享(AWT篇)

Swing 类库结构(这边建议边学边看这个图片就可以建立一定的思维导图)

        Swing 组件都采用 MVC(Model-View-Controller,即模型-视图-控制器)的设计,实现 GUI 组件的显示逻辑和数据逻辑的分离,从而允许程序员自定义 Render 来改变 GUI 组件的显示外观,以提供更多的灵活性。

        Swing 围绕 JComponent 组件构建,JComponent 则由 AWT 的容器类扩展而来。Swing 组织结构如图 1 所示。

黑马程序员Java Swing笔记分享(AWT篇)_第1张图片

一.AWT布局管理

(1)_awt_container容器_API

  • Study01(创建Frame窗口)

    public static void main(String[] args) {
        //创建窗口对象
        Frame frame=new Frame("window测试");
       // 创建窗口大小,位置
        frame.setLocation(100,100);
        frame.setSize(500,300);
        //设置窗口对象可见
        frame.setVisible(true);
    }
}

点击IDEA中的RUN,你可以得到一下窗口界面。

黑马程序员Java Swing笔记分享(AWT篇)_第2张图片

但是也有个问题我们需要手动在RUN中点掉暂停键,我们没办法关闭右上角的'X'(取消窗口) 。

  • Study02(创建Panel面板)

        Panel是面板,是一个很少直接使用的基本组件,或者继承重写,或者用来组织其他组件。
panel和Jpanel都为中间层容器,可显示文字、图像、绘制图形,主要功能是在GUI中组织其他组件。

public static void main(String[] args) {
        //1.创建一个window对象,因为,panel以及其他的容器,都不能独立存在,
        //必须依靠window存在
        Frame frame=new Frame();
        //2.创建一个Panel对象
        Panel p=new Panel();
        //3.创建一个文本框和按钮,并且放入到Panel容器中
        p.add(new TextField("测试文本"));
        p.add(new Button("这是一个测试按钮"));
        //4.把Pannel放入window中
        frame.add(p);
        //5.设置window的位置以及大小
        frame.setBounds(100,100,500,300);
        //6.设置window可见
        frame.setVisible(true);
    }

1.点击运行却又出现按钮中乱码现象。

黑马程序员Java Swing笔记分享(AWT篇)_第3张图片

2. 此时由于我们用的是UTF-8,故需要不让乱码出现,则点击下方图片选项

黑马程序员Java Swing笔记分享(AWT篇)_第4张图片

3. 点进去之后,直接Alt+V,在出现的VM options的方框里面添加这么一句话 :

4.-Dfile.encoding=gbk

5.然后再次运行即可。

黑马程序员Java Swing笔记分享(AWT篇)_第5张图片

 Study03(创建滚动窗格)

public static void main(String[] args) {
        Frame frame=new Frame();

        //1.创建一个ScrollPane对象
        ScrollPane sp=new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
        //--->默认创建一个滚动条ScrollPane.SCROLLBARS_ALWAYS

        //2.往ScrollPane中添加内容
        sp.add(new TextField("测试文本"));
        sp.add(new Button("测试按钮"));

        //3.把ScrollPane添加到Frame中
        frame.add(sp);
        frame.setBounds(100,100,500,300);
        frame.setVisible(true);
    }

1.当然你运行的时候还是会有乱码出现,但问题不大,直接参考Study02蓝色字体。

黑马程序员Java Swing笔记分享(AWT篇)_第6张图片

 (2)_awt_LayoutManger布局管理

Study04(创建FlowLayout)

public static void main(String[] args) {
        Frame frame = new Frame("测试FlowLayout");
        //1.通过setLayout方法设置容器的布局管理器

        //1)向左边对齐
        frame.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));//20为像素单位

        //2)向中间对齐
        frame.setLayout(new FlowLayout(FlowLayout.CENTER,20,20));//20为像素单位

        //3)向右边对齐
        frame.setLayout(new FlowLayout(FlowLayout.RIGHT, 40, 20));//20为像素单位

        //2.添加多个按钮到frame中
        for (int i = 0; i <= 100; i++) {
            frame.add(new Button("按钮" + i));
        }
        //3.设置最佳大小,pack方法
        frame.pack();
        frame.setVisible(true);
    }

 输出样例:向右的按钮输出

黑马程序员Java Swing笔记分享(AWT篇)_第7张图片

 Study05(创建BorderLayout)

 public static void main(String[] args) {
        Frame frame=new Frame("这里测试BorderLayout");

        //1.给frame设置BorderLayout布局管理器
        frame.setLayout(new BorderLayout(30,10));

        //2.往frame的指定区域添加组件
        frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
        frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);
        frame.add(new Button("东侧按钮"),BorderLayout.EAST);
        frame.add(new Button("西侧按钮"),BorderLayout.WEST);
        frame.add(new Button("中间按钮"),BorderLayout.CENTER);

        frame.pack();
        frame.setVisible(true);
    }

输出样例: 

黑马程序员Java Swing笔记分享(AWT篇)_第8张图片

 Study06(中间区域放文本)

public static void main(String[] args) {
        Frame frame=new Frame("这里测试BorderLayout");

        //1.给frame设置BorderLayout布局管理器
        frame.setLayout(new BorderLayout(30,10));

        //2.往frame的指定区域添加组件
        frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
        frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);
        frame.add(new Button("中间按钮"),BorderLayout.CENTER);

        frame.add(new TextField("测试文本"));

        frame.pack();
        frame.setVisible(true);
    }

输出样例:

黑马程序员Java Swing笔记分享(AWT篇)_第9张图片

         1.但是这样的话会将中间按钮给覆盖掉了,那么如何将按钮与测试文本共同放在中间且不互相干扰呢?

public static void main(String[] args) {
        Frame frame=new Frame("这里测试BorderLayout");

        //1.给frame设置BorderLayout布局管理器
        frame.setLayout(new BorderLayout(30,10));

        //2.往frame的指定区域添加组件
        frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
        frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);

        Panel p=new Panel();
        p.add(new Button("中间按钮"));
        p.add(new TextField("测试文本框"));
        frame.add(p);
        frame.pack();
        frame.setVisible(true);
    }

输出样例:

黑马程序员Java Swing笔记分享(AWT篇)_第10张图片

 Study07(创建GirdLayout)

如何做一个简单的计算器界面?

public static void main(String[] args) {
        Frame frame = new Frame();

        //1、创建一个Panel对象,里面存放一个TextFiled组件
        Panel p=new Panel();
        p.add(new TextField(30));

        //2、把当前这个Panel添加到frame的北边区域
        frame.add(p,BorderLayout.NORTH);

        //3、创建一个Panel对象,并且设置他的布局管理器为GridLayout
        Panel p2=new Panel();
        p2.setLayout(new GridLayout(5,10,3,3));
        //4.往Panel中添加内容
        for(int i=0;i<10;i++){
            p2.add(new Button(i+""));
        }
        p2.add(new Button("+"));
        p2.add(new Button("-"));
        p2.add(new Button("*"));
        p2.add(new Button("/"));
        p2.add(new Button("."));

        //5.把当前Panel添加到frame中
        frame.add(p2);

        frame.pack();
        frame.setVisible(true);
    }

输出样例:

黑马程序员Java Swing笔记分享(AWT篇)_第11张图片

 Study08(创建CardLayout)

        什么是CardLayout,CardLayout布局管理器以时间而非空间来管理它的组件,它将容器的所有组件看成一叠卡片(每个卡片其实就是一个组件),每次只有最上面的Companent才可见。就好像一副扑克牌,它们叠在一起,每次只有最上面的一张扑克牌可见。

方法名称 方法功能
CardLayout() 创建默认的CardLayout布局管理器
CardLayout(int hgap,int vgap) 通过指定卡片与容器左右边界的间距,上下边界间距来决定CardLayout的布局管理器
first(Container target) 显示target容器中的第一张卡片
last(Container target) 显示target容器中的最后一张卡片
previou(Container target) 显示target容器中前一张卡片
next(Container target) 显示target容器中的后一张卡片
show(Container target,String name) 显示target容器中指定名字的卡片
public static void main(String[] args) {
        Frame frame=new Frame("测试CardLayout");

        //1、创建一个Panel容器,用来存储多张卡片
        Panel p1=new Panel();

        //2、创建一个CardLayout对象,并且把该对象设置给之前创建的Panel容器中
        CardLayout cardLayout=new CardLayout();
        p1.setLayout(cardLayout);

        //3、往Panel中储存多个组织
        String[] name={"第一张","第二张","第三张","第四张","第五张"};

        for(int i=0;i

样例输出:有点类似与windows中的图片浏览软件,可以来回切换上下张图片。

黑马程序员Java Swing笔记分享(AWT篇)_第12张图片

Study09(创建BoxLayout)

方法名称 方法功能
BoxLayout(Container target,int axis) 指定创建基于target容器的BoxLayout布局管理器,该布局管理器里的组件按照axis方向排列。其中axis有BoxLayout.X_AXIS(横向)和BoxLayout.Y_AXIS(纵向)两个方向
public static void main(String[] args) {
        Frame frame=new Frame();

        //1、基于frame容器,创建一个BoxLayout对象,并且,该对象存放的组件是垂直存放
        //BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.Y_AXIS);
        //------>基于frame容器,创建一个BoxLayout对象,并且,该对象存放的组件是水平存放
        BoxLayout boxLayout = new BoxLayout(frame, BoxLayout.X_AXIS);

        //2、把BoxLayout对象设置给Frame
        frame.setLayout(boxLayout);

        //3、往frame中添加两个按钮组件
        frame.add(new Button("按钮1"));
        frame.add(new Button("按钮2"));

        frame.pack();
        frame.setVisible(true);
    }

样例输出:水平方向的按钮

黑马程序员Java Swing笔记分享(AWT篇)_第13张图片

 样例输出:垂直方向的按钮

黑马程序员Java Swing笔记分享(AWT篇)_第14张图片

Study10(创建容器Box)

        在Java.swing中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout,大多数形况下,Box容器去容纳多个GUI组件,然后再把Box容器作为一个组件,添加到其他的容器中,从而形成窗口布局。

方法名称 方法功能
static Box createHorizontalBox() 创建一个水平排列组件的Box容器
static Box creatVerticalBox() 创建一个垂直排列组件的Box容器
public static void main(String[] args) {
        Frame frame = new Frame("测试BoxLayout");

        //1、创建一个水平排列组件的Box容器
        Box hBox = Box.createHorizontalBox();
        //2、往当前容器中添加两个按钮
        hBox.add(new Button("水平按钮1"));
        hBox.add(new Button("水平按钮2"));

        //3、创建一个垂直组件的Box容器
        Box vBox = Box.createVerticalBox();
        //4、往当前容器中添加两个按钮
        vBox.add(new Button("垂直按钮1"));
        vBox.add(new Button("垂直按钮2"));
        //5、把两个Box容器添加到FrameZ中展示
        frame.add(hBox, BorderLayout.NORTH);
        frame.add(vBox);

        frame.pack();
        frame.setVisible(true);
    }

样例输出:

黑马程序员Java Swing笔记分享(AWT篇)_第15张图片

但是这样的排布中间没有空隙, 那么怎么样让按钮之间有空隙呢?

public static void main(String[] args) {
        Frame frame = new Frame();

        //1、创建水平排列的Box容器
        Box hbox = Box.createHorizontalBox();

        //2、往hBox容器中添加按钮,还需要在多个按钮之间添加分割
        hbox.add(new Button("水平按钮1"));
        hbox.add(Box.createHorizontalGlue());//该分割在两个方向上都可以拉伸
        hbox.add(new Button("水平按钮2"));
        hbox.add(Box.createHorizontalStrut(30));//水平2与水平3之间不能拉伸,固定死了
        hbox.add(new Button("水平按钮3"));

        //3、创建垂直排列的Box容器 vBox
        Box vBox = Box.createVerticalBox();

        //4、往vBox容器中添加按钮,还需要在多个按钮之间添加分割
        vBox.add(new Button("垂直按钮1"));
        vBox.add(Box.createVerticalGlue());//该分割在两个方向上都可以拉伸
        vBox.add(new Button("垂直按钮2"));
        vBox.add(Box.createVerticalStrut(30));//垂直按钮2与垂直按钮3之间是定死的,无论你怎么拉伸都不变
        vBox.add(new Button("垂直按钮3"));
        //5、把box容器中添加到frame中
        frame.add(hbox, BorderLayout.NORTH);
        frame.add(vBox);

        frame.pack();
        frame.setVisible(true);
    }

      样例输出:

黑马程序员Java Swing笔记分享(AWT篇)_第16张图片

 二.AWT中常用的组件

(1)_awt_常用基本组件

Study11(创建常用组件)

组件名 功能
Button 按钮
Canvas 用于绘图的画布
Checkbox 复选框组件(也可以当作单选框组件使用)
CheckboxGroup 用于将多个Checkbox组件组合成一组,一组Checkbox组件将有只有一个可以被选中,即全部变成单选框组件
Choice 下拉选择框
Frame 窗口,在GUI程序里面通过该类创建窗口
Label 标签类,用于放置提示性文本
List 列表框组件,可以添加多个项目
Panel 不能单独存在基本容器类,必须放到其他容器当中
Scrollbar 滑动条组件,如果用户输入位于某个范围的值,就可以使用滑动条组件,比如调色板中设置RGB的三个值所用的滑动条。当创建一个滑动条时,必须指定它的方向、c初始值、滑块的大小、最小值以及最大值
ScrollPane 带水平及垂直滚动条的容器组件
TextArea 多行文本框
TextField 单行文本框

        1.如何利用上面组件组装成下面的例子

黑马程序员Java Swing笔记分享(AWT篇)_第17张图片

public class day12 {
    //基本步骤:创建基本组件
    Frame frame = new Frame();

    TextArea te = new TextArea(5, 20);

    Choice colorchoice = new Choice();

    CheckboxGroup cbg = new CheckboxGroup();
    Checkbox male = new Checkbox("男", cbg, true);
    Checkbox female = new Checkbox("女", cbg, false);

    Checkbox isMarried = new Checkbox("是否已婚");

    TextField tf = new TextField(20);
    Button ok = new Button("确认");

    List colorList = new List(6, true);

    public void init() {
        //1、组装界面

        //2、组装底部
        Box bBox = Box.createHorizontalBox();
        bBox.add(tf);
        bBox.add(ok);

        frame.add(bBox, BorderLayout.SOUTH);

        //3、组装 选择部分
        colorchoice.add("蓝色");
        colorchoice.add("红色");
        colorchoice.add("绿色");

        Box cBox = Box.createHorizontalBox();
        cBox.add(colorchoice);
        cBox.add(male);
        cBox.add(female);
        cBox.add(isMarried);

        //4、组装文本域与选择部分
        Box topLeft = Box.createVerticalBox();
        //------->组装文本区域
        topLeft.add(te);
        //------->组装选择区域
        topLeft.add(cBox);

        //5、组装顶部左边和列表框
        colorList.add("蓝色");
        colorList.add("红色");
        colorList.add("绿色");

        Box top = Box.createHorizontalBox();
        top.add(topLeft);
        top.add(colorList);

        frame.add(top);

        //设置frame为最佳大小,并且可见
        frame.pack();
        frame.setVisible(true);


    }


    public static void main(String[] args) {
        new day12().init();//调用init方法
    }
}

 1.首先将需要的组件列出来

 2.将需要的组件组装起来

       ---->由上图可知先用一个box将下面的确定按钮以及文本区域组装在一起,并放在南边,由于文本区域与确定按钮是水平的,故用 :Box.createHorizontalBox()方法,组装为bBox

       ---->其次组装选择颜色的功能,由于也是与性别,已婚水平的也用Box.createHorizontalBox()方法,组装为cBox

       ---->组装最大文本域以及颜色选择,性别,已婚,由于二者是垂直关系,故用:Box.createVerticalBox()方法,将其组装成topLeft

       ---->最后例举colorlist,需要放在最top盒子的右边,那么再建造一个top盒子,将topLeft放在左边,colorlist放在右边,二者水平关系,用Box.createHorizontalBox()方法。

Study12(创建对话框Dialog)

        Dialog是window类的子类,是一个容器类,属于特殊组件。对话框是可以独立存在的顶级窗口,因此与普通窗口的用法几乎完全一样,但是使用对话框需要注意下面两点:

  • 对话框通常依赖其他窗口,就是通常需要有一个父类窗口
  • 对话框有非模式和模式两种,当某个模式对话框被打开后,该模式对话框总是位于它的父窗口之上,在模式对话框被关闭之前,父窗口无法获得焦点。
方法名称 方法功能
Dialog(Frame owner,String title,boolean modal)

创建一个对话框对象:

onwer:当前对话框的父窗口

titile:当前对话框的标题

modal:当前对话框是否为模式对话框

1、什么是模式对话框?

        模态对话框(Modal Dialogue Box,又叫做模式对话框),是指在用户想要对对话框以外的应用程序进行操作时,必须首先对该对话框进行响应。所以无法对对话框以外的应用程序进行操作。

2、什么是非模式对话框

        非模态对话框允许用户在处理非模态对话框的同时处理目标对话框。其实与上面的内容反之即可。

public static void main(String[] args) {
        Frame frame=new Frame();

        //1.创建两个对话框Dialog对象,一个模式,一个非模式
        Dialog d1 = new Dialog(frame, "模式对话框", true);
        Dialog d2=new Dialog(frame,"非模式对话框",false);

        //2、通过setBounds方法设置Dialog的位置与大小
        d1.setBounds(20,30,300,200);
        d2.setBounds(20,30,300,200);

        //3、创建两个按钮
        Button b1=new Button("打开模式对话框");
        Button b2=new Button("打开非模式对话框");
        //4、需要给这两个按钮添加点击后的行为(AWT事件)
        b1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                d1.setVisible(true);
            }
        });

        b2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                d2.setVisible(true);
            }
        });

        //5、把按钮添加到frame中
        frame.add(b1,BorderLayout.NORTH);
        frame.add(b2);

        frame.pack();
        frame.setVisible(true);
    }

 3、但是如何添加组件到对话框里面去呢?

        其实很简单只需要将基本组件装到Box中在将Box中的对象添加到对话框即可。

public static void main(String[] args) {
        Frame frame=new Frame();

        //1.创建两个对话框Dialog对象,一个模式,一个非模式
        Dialog d1 = new Dialog(frame, "模式对话框", true);
        
        //----->创建一个垂直的Box容器,把一个文本框以及确定按钮放在Box容器中
        Box vbox=Box.createVerticalBox();
        vbox.add(new TextField(20));
        vbox.add(new Button("确认"));
    
            //----->将vbox放在d1中去
        d1.add(vbox);
        //2、通过setBounds方法设置Dialog的位置与大小
        d1.setBounds(20,30,300,200);
        

        //3、创建两个按钮
        Button b1=new Button("打开模式对话框");
       
        //4、需要给这两个按钮添加点击后的行为(AWT事件)
        b1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                d1.setVisible(true);
            }
        });
        

        //5、把按钮添加到frame中
        frame.add(b1,BorderLayout.NORTH);
       

        frame.pack();
        frame.setVisible(true);
    }

Study13(创建对话框FileDialog)

        Dialog类中还有一个子类:FileDialog,它代表一个文件对话框,用于打开或者保存文件,需要注意的是FileDialog无法指定模态还是非模态,这是因为FileDialog依赖于运行平台的实现,如果运行平台的为文件对话框是模态的,那么FileDialog也是模态的;否则就是非模态的。

方法名称 方法功能
FileDialog(Frame parent,String title.int mode)

创建一个文件对话框:

parent:指定父窗口

title:对话框标题

mode:文件对话框类型,如果指定为FileDialog.LOAD,用于打开文件,如果指定为FileDialog.SAVE,用于保存文件

String getDirectory() 获取被打开或保存文件的绝对路径
String getFile() 获取被打开或保存文件的文件名
public static void main(String[] args) {
        Frame frame = new Frame();
        //1、创建两个FileDialog对象
        FileDialog fileDialog = new FileDialog(frame, "选择要打开的文件", FileDialog.LOAD);
        FileDialog fileDialog1 = new FileDialog(frame, "选择要保存的文件", FileDialog.SAVE);

        //2、创建两个按钮
        Button b1 = new Button("打开文件");
        Button b2 = new Button("保存文件");

        //3、给这两个按钮设置点击后的行为:获取打开或者保存的路径文件名
        b1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {

                fileDialog.setVisible(true);//代码会阻塞到这里

                //获取选择的路径及文件
                String directory = fileDialog.getDirectory();
                String file = fileDialog.getFile();
                System.out.println("打开的文件路径为:" + directory);
                System.out.println("打开的文件名称为:" + file);

            }
        });
        b2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                fileDialog1.setVisible(true);

                //获取选择的路径及文件
                String directory = fileDialog1.getDirectory();
                String file = fileDialog1.getFile();
                System.out.println("打开的文件路径为:" + directory);
                System.out.println("打开的文件名称为:" + file);
            }
        });

        //4、把按钮添加到Frame中
        frame.add(b1, BorderLayout.NORTH);
        frame.add(b2);

        frame.pack();
        frame.setVisible(true);
    }

样例输出:

黑马程序员Java Swing笔记分享(AWT篇)_第18张图片

Study14(创建事件处理)

1)定义:当在某个组件上发生某些操作的时候,会自动的触发-段代码的执行。
2)在GUI事件处理机制中涉及到4个重要的概念需要理解:
        事件源(Event Source) :操作发生的场所,通常指某个组件,例如按钮、窗口等;
        事件( Event) : 在事件源上发生的操作可以叫做事件, GUI会把事件都封装到一个Event对象中 ,如果需要知道该事件的详细信息,就可以通过Event对象来获取。
        事件监听器(Event Listener):当在某个事件源上发生了某个事件,事件监听器就可以对这个事件进行处理。
        注册监听:把某个事件监听器(A)通过某个事件(B)绑定到某个事件源(C)上,当在事件源C上发生了事件B之后,那么事件监听器A的代码就会自动执行。 

黑马程序员Java Swing笔记分享(AWT篇)_第19张图片

黑马程序员Java Swing笔记分享(AWT篇)_第20张图片了解了上面机制,那么要如何实现下面图片呢,点击确定会有hello world出现?

------->黑马程序员Java Swing笔记分享(AWT篇)_第21张图片

------->黑马程序员Java Swing笔记分享(AWT篇)_第22张图片 

public class day15 {
    Frame frame=new Frame();

    TextField tf = new TextField(30);
    Button ok = new Button("确定");

    public void init(){
        //组装视图

        //监听器
        //MyListener myListener=new MyListener();
        //注册监听
        ok.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                tf.setText("hello world");
            }
        });

        //把tf和ok放到Frame中
        frame.add(tf,BorderLayout.NORTH);
        frame.add(ok);

        frame.pack();
        frame.setVisible(true);
    }
//    private class MyListener implements ActionListener {
//
//        @Override
//        public void actionPerformed(ActionEvent e) {
//            tf.setText("hello world");
//        }
//    }

    public static void main(String[] args) {
        new day15().init();
    }

 Study15(常见事件和事件监听器)

        事件监听器必须实现事件监听器接口,AWT提供了大量的事件监听器接口用于实现不同类型的事件监听器,用于监听不同类型的事件。AWT中提供了丰高的事件类,用于封装不同组件上所发生的特定操作, AWT的事件类都是AWTEvent类的子类,AWTEvent是EventObject的子类。

1、AWT把事件分为了两大类:
        1)低级事件:这类事件是基于某个特定动作的事件。比如进入。点击、拖放等动作的鼠标事件,再比如得到焦点和失去焦点等焦点事件。

事件 触发时机
ComponentEvent 组件事件,当组件尺寸发生变化、位置发生移动、显示/陶藏状态发生改变时触发该事件。
ContainerEvent 容器事件,当容器里发生添加组件、删除组件时触发该事件。
WindowEvent 窗口事件,当窗口状态发生改变(如打开、关闭。最大化、最小化)时触发该事件。
FocusEvent 焦点事件,当组件得到焦点或失去焦点时触发该事件。
KeyEvent 键盘事件,当按键被按下、松开、单击时触发该事件。
MouseEvent 鼠标事件,当进行单击、按下、松开、移动鼠标等动作时触发该事件。
PaintEvent 组件绘制事件。该事件是一个特殊的事件类型 ,当GUI组件调用update/paint方法来呈现自身时触发该事件,该事件并非专用于事件处理模型。

        2)高级事件:这类事件并不会基于某个特定动作,而是根据功能含义定义的事件。

事件 触发时机
ActionEvent 动作事件,当按钮、菜单项被单击,在TextField中按Enter键时触发。
AjustmentEvent 调节事件,在滑动条上移动滑块以调节数值时触发该事件。
ItemEvent 选项事件,当用户选中某项,或取消选中某项时触发该事件。
TextEvent 文本事件,当文本框、文本域里的文本发生改变时触发该事件。

2、事件监听器
        不同的事件需要使用不同的监听器监听,不同的监听器需要实现不同的监听器接口,当指定事件发生后,事件监听器就会调用所包含的事件处理器(实例方法)来处理事件。

黑马程序员Java Swing笔记分享(AWT篇)_第23张图片

3、案例一:

public static void main(String[] args) {
        Frame frame=new Frame("测试监听器");
        //创建组件(事件源)
        TextField tf=new TextField();
        Choice names=new Choice();
        names.add("刘岩");
        names.add("舒淇");
        names.add("闫妮");

        //给文本添加TextListener,监听内容变化
        tf.addTextListener(new TextListener() {
            @Override
            public void textValueChanged(TextEvent e) {
                String text = tf.getText();
                System.out.println("当前文本的内容为:"+text);
            }
        });

        //给下拉选择框添加ItemListener,监听条目选项的变化
        names.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                Object item = e.getItem();
                System.out.println("当前选中的条目为:"+item);
            }
        });

        //给frame注册ContainerListener监听器,监听容器组件的添加
        frame.addContainerListener(new ContainerListener() {
            @Override
            public void componentAdded(ContainerEvent e) {//添加方法
                Component child = e.getChild();
                System.out.println("frame中添加了:"+child);
            }

            @Override
            public void componentRemoved(ContainerEvent e) {//移除方法

            }
        });


        //添加到frame中
        Box hBox=Box.createHorizontalBox();
        hBox.add(names);
        hBox.add(tf);
        frame.add(hBox);

        //设置frame最佳大小并可见

        frame.pack();
        frame.setVisible(true);


    }

 样例输出:

每次点击都会记录下监听内容: 

 黑马程序员Java Swing笔记分享(AWT篇)_第24张图片

4、 案例二:如何关闭右上角x键

public static void main(String[] args) {

        Frame frame=new Frame("测试WindowListener");
        frame.setBounds(200,200,500,300);

        //设置WindowListener,监听用户点击右上角X的动作,则关闭窗口
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

        frame.setVisible(true);
    }

样例输出:

黑马程序员Java Swing笔记分享(AWT篇)_第25张图片

 Study16(创建菜单组件)

        前面讲了GUI界面的构建,其实就是把一些GUI的组件,按照一定的布局放在容器即可。在实际开发中,除了主界面,还有一类比较重要的内容就是菜单相关组件,可以通过菜单相关组件很方便的使用特定的功能,在AWT中,菜单组件的使用和之前学习的组件时一模一样的,只需要把菜单条、菜单、菜单项组合在一起,按照一定的布局,放入到容器中即可。

菜单组件名称 功能
MenuBar 菜单条,菜单的容器
Menu 菜单组件,菜单项的容器。它也是MenuItem的子类,所以可作为菜单项使用
PopupMenu 菜单项组件
MenuItem 菜单项组件
CheckboxMenuItem 复选框菜单项组件

黑马程序员Java Swing笔记分享(AWT篇)_第26张图片

菜单相关组件使用: 

        1、准备菜单项组件,这些组件可以是MenuItem及子类对象

        2、准备菜单组件Menu或者PopupMenu(右击弹出子菜单),把第一步中准备好的菜单项组件添加进来

        3、准备菜单条组件MenuBar,把第二步准备好的菜单组件Menu添加进来

        4、把第三步中准备好的菜单条组件添加到窗口对象中显示

小技巧:

        1、如果要在某个菜单的菜单项之间添加分割线,那么只需要调用Menu的add(new MenuItem("-"))即可。

        2、如果要给某个菜单项关联快捷键功能,那么只需要在创建菜单项对象设置即可,例如给菜单项关联ctrl+shift+Q快捷键,只需要:new MenuItem("菜单项名字",new MenuShortcut(KeyEvent.VK_Q,true);

案例一:如何做出下图呢?

------->黑马程序员Java Swing笔记分享(AWT篇)_第27张图片

------->黑马程序员Java Swing笔记分享(AWT篇)_第28张图片 

public class day18 {
    //创建窗口
    private Frame frame = new Frame();

    //创建菜单条
    MenuBar menuBar = new MenuBar();

    //创建菜单组件
    Menu fileMenu = new Menu("文件");
    Menu editMenu = new Menu("编辑");
    Menu formatMenu = new Menu("格式");


    //菜单项组件
    MenuItem auto = new MenuItem("菜单换行");
    MenuItem copy = new MenuItem("复制");
    MenuItem paste = new MenuItem("粘贴");

    //关联快捷键
    MenuItem comment = new MenuItem("注释", new MenuShortcut(KeyEvent.VK_Q, true));
    MenuItem canceComment = new MenuItem("取消注释");

    TextArea ta = new TextArea(6,40);

    public void init() {
        //组装视图
        comment.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //在监听器下e.getActionCommand()点击后最后都返回注释功能
                ta.append("您点击菜单项:" + e.getActionCommand()+"\n");
            }
        });

        formatMenu.add(comment);
        formatMenu.add(canceComment);

        //组装编辑菜单
        editMenu.add(auto);
        editMenu.add(copy);
        editMenu.add(paste);
        editMenu.add(formatMenu);

        //组装菜单条
        menuBar.add(fileMenu);
        menuBar.add(editMenu);

        //把菜单条放入到Frame中
        frame.setMenuBar(menuBar);
        frame.add(ta);

        //设置frame最佳大小
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {

        new day18().init();

 案例二:通过PopupMenu实现下图效果

黑马程序员Java Swing笔记分享(AWT篇)_第29张图片

黑马程序员Java Swing笔记分享(AWT篇)_第30张图片

黑马程序员Java Swing笔记分享(AWT篇)_第31张图片

实现思路:

1、创建PopupMenu菜单组件

2、创建多个MenuItem菜单项,并添加到PopupMenu中

3、将PopupMenu添加到目标组件中

4、为需要右击出现PopupMenu菜单的组件,注册鼠标监听事件,当监听到用户释放右键时,弹出菜单。

public class day19 {
    private Frame frame=new Frame("这里测试PopupMenu");

    //创建文本域
    TextArea ta=new TextArea("我爱中华",6,40);

    //创建Panel容器
    Panel p=new Panel();

    //创建PopupMenu
    PopupMenu popupMenu=new PopupMenu();

    //创建菜单项
    MenuItem comment=new MenuItem("注释");
    MenuItem cancalcomment=new MenuItem("取消注释");
    MenuItem copy=new MenuItem("复制");
    MenuItem save=new MenuItem("保存");


    public void init(){
        //组装视图
        ActionListener listener=new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String actionCommand = e.getActionCommand();
                ta.append("您点击了右键:"+actionCommand+"\n");
            }
        };

        //传入监听器
        comment.addActionListener(listener);
        cancalcomment.addActionListener(listener);
        copy.addActionListener(listener);
        save.addActionListener(listener);

        //将功能放到popupMenu当中去
        popupMenu.add(comment);
        popupMenu.add(cancalcomment);
        popupMenu.add(copy);
        popupMenu.add(save);

        //将popupMenu放到面板中Panel中去
        p.add(popupMenu);

        //设置Panel的大小
        p.setPreferredSize(new Dimension(40,100));

        //给Panel注册鼠标事件,监听用户释放鼠标的动作,展示菜单
        p.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                //isPopupTrigger()用来判断是否为鼠标右键点击
                boolean flag = e.isPopupTrigger();
                if(flag){
                    //显示popupMenu
                    popupMenu.show(p,e.getX(),e.getY());
                }
            }
        });
        frame.add(ta);
        frame.add(p,BorderLayout.SOUTH);

        //设置frame最佳大小,并可视化
        frame.pack();
        frame.setVisible(true);
    }



    public static void main(String[] args) {
        new day19().init();
    }
}

 Study17(绘图)

        很多程序如各种游戏需要在窗口中绘制各种图形,除此之外,及时要开发JavaEE项目时,有时候也必须"动态"地向客户端生成各种图形、图标,比如:图形验证码、统计图等,这都需要利用AWT地绘图功能。

组件绘图原理:

        之前我们已经学习很多组件,如:Button、Frame、Checkbox等等,不同的组件,展示出来的图形都不一样,其实这些组件展示出来的图形,其本质就是用AWT的绘图完成。

        在AWT中,真正提供绘图功能的是Graphics对象,那么Component组件和Graphics对象存在什么关系,才能让Component绘制呢?在Component类中,提供了下列三个方法来完成组件图案的绘制于刷新;

        paint(Graphics g):绘制组件的外观;

        update(Graphics g):内部调用paint方法,刷新组件外观;

        repaint():调用update方法,刷新组件外观;

黑马程序员Java Swing笔记分享(AWT篇)_第32张图片

        一般情况下,update和paint方法是由AWT系统负责调用,如果程序要希望系统重新绘制组件,可以调用repaint方法完成。 

1、Graphics对象的使用

        实际生活中如果需要画图,首先我们得准备一张纸,然后在拿一支笔,配和一些颜色,就可以在纸上画出来各种各样的图形,例如:圆形、矩形等等。

        程序绘图也一样,也需要画布,画笔,颜料等等。AWT中提供了Canvas类充当画布,提供Graphics类来充当画笔,通过调用Graphics对象的setColor()方法可以给画笔设置颜色。

2、画图的步骤

        1.自定义类,继承Canvas类,重写paint(Graphics g)方法完成画图。

        2.在paint方法内部,真正开始画图之前调用Graphics对象的setColor()、setFont()等方法设置画笔的颜色,字体等属性;

        3.调用Graphics画笔的drawXxx()方法开始画图。

        其实画图的核心就在使用Graphics画笔在Canvas画布上画出什么颜色、什么样式的图形,什么样式的图形,所以核心在画笔上,下表中列出了Graphics类中常用的一些方法:

方法名称 方法功能
setColor(Color c) 设置颜色
setFont(Font font) 设置字体
drawLine() 绘制直线
drawRect() 绘制矩形
drawRoundRect() 绘制圆角矩形
drawOval() 绘制椭圆形
drawPolygon() 绘制多边形
drawArc() 绘制圆弧
drawPolyline 绘制折线
fileRect() 填充圆角矩形区域
fillRoundRect() 填充圆角矩形区域
fillOval()

填充椭圆区域 

fillPolygon() 填充多边形区域
fillArc() 填充圆弧对应的扇形区域
drawImage() 绘制位图

3、案例一:按钮点击成图像

------>黑马程序员Java Swing笔记分享(AWT篇)_第33张图片

------>黑马程序员Java Swing笔记分享(AWT篇)_第34张图片 

------> 黑马程序员Java Swing笔记分享(AWT篇)_第35张图片

public class day20 {
    //定义一个RECT_SHAPE以及OVAL_SHAPE当点击按钮的时候监听器打开,将二者分别进行赋值操作
    private final String RECT_SHAPE = "reat";
    private final String OVAL_SHAPE = "oval";

    private Frame frame = new Frame("测试绘图");

    Button butreat = new Button("绘制矩形");
    Button butoval = new Button("绘制椭圆");

    //定义一个变量,记录当前要绘制椭圆还是矩形
    private String shape = "";

    //1、自定义类,继承Canvas,重写paint(Graphics g)方法完成画图;
    private class Mycnvas extends Canvas {
        @Override
        public void paint(Graphics g) {
            //绘制不同的图形
            if (shape.equals(RECT_SHAPE)) {
                //绘制矩形
                g.setColor(Color.BLACK);//设置当前画笔的颜色
                g.drawRect(100, 100, 150, 100);
            } else if (shape.equals(OVAL_SHAPE)) {
                //绘制椭圆
                g.setColor(Color.RED);
                g.drawOval(100, 100, 150, 100);
            }

        }
    }

    //创建自定义的画布对象
    Mycnvas drawArea = new Mycnvas();

    public void init() {
        //当我点击绘制矩形的时候,就会执行监听器代码
        butreat.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //将定义的RECT_SHAPE赋值给shape
                shape = RECT_SHAPE;
                //并且在画布中repaint()
                drawArea.repaint();
            }
        });
        //当我点击绘制椭圆的时候,就会执行监听器代码
        butoval.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //将定义的OVAL_SHAPE赋值给shape
                shape = OVAL_SHAPE;
                drawArea.repaint();
            }
        });

        //创建Panel,承载按钮
        Panel p = new Panel();
        p.add(butoval);
        p.add(butreat);

        frame.add(p, BorderLayout.SOUTH);

        //drawArea的大小需要设置
        drawArea.setPreferredSize(new Dimension(300, 300));
        frame.add(drawArea);

        //frame自适应
        frame.pack();
        frame.setVisible(true);
    }


    public static void main(String[] args) {
        new day20().init();
    }
}

4、案例二:弹射小球 (非常有意思,建议自己手动敲一遍理解原理)    

        Java也可以用来开发一些动画。所谓动画,就是间隔一定的时间(通常小于0.1秒)重新绘制的图形,两次绘制的图像之间差异比较小,肉眼看起来就成为所谓的动画。

        为了实现间隔一定的时间就重新调用组件的repain方法,可以借助Swing提供的Timer类,Timer类是一个定时器,它有如下一个构造器:

        Timer(int delay,ActionListener):每间隔delay毫秒,系统自动触发ActionLinster监听器的事件处理器的方法,在方法内部我们就可以调用组件的repaint方法,完成组件重新绘制。

----->黑马程序员Java Swing笔记分享(AWT篇)_第36张图片

----->黑马程序员Java Swing笔记分享(AWT篇)_第37张图片  

package javaswing;


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class day21 {
    private Frame frame = new Frame("弹球游戏");

    //设置桌面宽度
    private final int TABLE_WIDTH = 300;
    //设置桌面高度
    private final int TABLE_HEIGHT = 400;

    //球拍的高度和宽度
    private final int RACKET_WIDTH = 60;
    private final int RACKET_HEIGHT = 20;

    //小球的大小
    private final int BALL_SIZE = 16;

    //定义变量,记录小球的坐标
    private int ballX = 120;
    private int ballY = 20;

    //定义变量,记录小球在x和y方向上分别移动的速度
    private int speedY = 10;
    private int speedX = 5;

    //定义变量,记录球拍的坐标
    private int racketX = 120;
    private final int racketY = 340;//y坐标固定不变的,只会在左右移动

    //定义变量,标识当前游戏是否结束
    private boolean isOver = false;

    //声明一个定时器
    private Timer timer;

    //自定义一个类,继承canvas,充当画布
    private class Mycanvas extends Canvas {
        //记得重写paint
        @Override
        public void paint(Graphics g) {
            //TODO 在这里绘制内容
            if (isOver) {
                //游戏结束的内容
                g.setColor(Color.RED);
                g.setFont(new Font("Times", Font.BOLD, 30));
                g.drawString("游戏结束!", 50, 200);
            } else {
                //游戏进行的内容

                //绘制小球
                g.setColor(Color.BLUE);
                g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);
                //绘制球拍
                g.setColor(Color.PINK);
                g.fillRect(racketX, racketY, RACKET_WIDTH, RACKET_HEIGHT);
            }
        }
    }

    //创建绘画区域
    Mycanvas drawArea = new Mycanvas();

    //组件组装方法
    public void init() {
        //组装视图,以及游戏逻辑的控制
        //----->球拍的控制逻辑
        //----->小球的控制逻辑

        //完成球拍坐标的变化(创建监听器)(按键事件)(键盘事件)
        KeyListener listener = new KeyAdapter() {
            @Override
            public void keyPressed(KeyEvent e) {

                //获取当前按下的键
                int keyCode = e.getKeyCode();//我们的键盘每一个键位都对应一个整数keycode

                if (keyCode == KeyEvent.VK_LEFT) {

                    //应该向左移动
                    if (racketX > 0) {
                        racketX -= 10;
                    }
                }
                if (keyCode == KeyEvent.VK_RIGHT) {

                    //应该向右移动
                    if (racketX < (TABLE_WIDTH - RACKET_WIDTH)) {
                        racketX += 10;
                    }
                }
            }
        };

        //给frame和drawArea注册监听器
        frame.addKeyListener(listener);
        drawArea.addKeyListener(listener);

        //小球坐标的控制
        ActionListener task = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //更新小球的坐标,重绘界面

                //根据边界范围,修正速度
                //----->修正x轴弹出碰到边界的方向
                if (ballX <= 0 || ballX >= (TABLE_WIDTH - BALL_SIZE)) {
                    speedX = -speedX;
                }
                //----->修正y轴弹出碰到边界的方向
                if (ballY <= 0 || ballY > racketY - BALL_SIZE && ballX > racketX && ballX < racketX + RACKET_WIDTH) {
                    speedY = -speedY;
                }
                //----->超出球拍往下,游戏结束
                if (ballY > racketY - BALL_SIZE && (ballX < racketX || ballX > racketX + RACKET_WIDTH)) {
                    //当前小球超出了球拍范围

                    //停止定时器
                    timer.stop();
                    //修改游戏是否结束标记
                    isOver = true;
                    //重新绘制界面
                    drawArea.repaint();

                }

                ballX += speedX;
                ballY += speedY;

                //重新绘制界面
                drawArea.repaint();

            }
        };

        //这里需要手动导包import javax.swing.Timer.*;
        timer = new Timer(100, task);
        timer.start();

        drawArea.setPreferredSize(new Dimension(TABLE_WIDTH, TABLE_HEIGHT));
        frame.add(drawArea);

        //frame窗口关闭
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });
        //frame最佳大小
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new day21().init();
    }

Study18(处理位图)

        如果仅仅绘制一些简单的几何图形,程序的图形依旧十分简单。AWT允许在组件上绘制位图,Graphics提供了drawmage(Image image)方法用于绘制位图,该方法需要一个Image参数一一代表位图,通过该方法就可以绘制出指定的位图。

位图使用步骤:

1、创建Image的子类对象BufferedImage(int width,int heigth,int ImageType),创建时需要指定位图的宽高及类型属性;此时相当于在内存中生成了一张图片;

2、调用BufferedImage对象的getGraphics()方法获取画笔,此时就可以往内存中的这张图片上绘图了,绘图的方法和之前学习的一样。

3、调用组件paint()方法中提供的Graphics对象的drawImage()方法,一次性的内存中的图片BufferedImage绘制到待定的组件上。

使用位图绘制组件的好处:

使用位图来绘制组件,相当于实现了图的缓冲区,此时绘图时没有直接把图形绘制到组件上,而是先绘制到内存中的BufferedImage上,等全部绘制完成后,再一次性的图像显示到组件上即可,这样用户的体验会好很多。

案例:

绘画不精,望谅解,重点是:

drawArea.addMouseMotionListener与drawArea.addMouseListener的区别,我就是在这里踩坑的。

drawArea.addMouseMotionListener指的是按下鼠标移动的

drawArea.addMouseListener值的是不移动鼠标的

黑马程序员Java Swing笔记分享(AWT篇)_第38张图片

 

public class day22 {
    private Frame frame = new Frame("简单绘图工具");

    //定义画图区域的宽高
    private final int AREA_WIDTH = 500;
    private final int AREA_HEIGHT = 400;


    //定义一个右键菜单,用于设置画笔的颜色,PopupMenu为鼠标右击
    private PopupMenu colorMenu = new PopupMenu();
    private MenuItem reditem = new MenuItem("红色");
    private MenuItem buleitem = new MenuItem("蓝色");
    private MenuItem greenitem = new MenuItem("绿色");

    //定义一个变量记录当前画笔的颜色
    private Color forceColor = Color.BLACK;

    //创建一个BufferImage位图对象
    BufferedImage image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_RGB);

    //通过位图,获取关联的Graphics对象
    Graphics g = image.getGraphics();

    //自定义一个类,继承Canvas
    private class MyCanvas extends Canvas {
        @Override
        public void paint(Graphics g) {
            g.drawImage(image, 0, 0, null);
        }
    }

    //取自定义类中对象drawArea绘图区域
    MyCanvas drawArea = new MyCanvas();

    //定义一个变量,记录鼠标在拖动过程中上一次所处的坐标
    private int preX = -1;
    private int preY = -1;

    //组装方法
    public void init() {
        //组装视图,逻辑控制
        ActionListener actionListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //e.getActionCommand()获取的是new MenuItem("红色")中的“红色”
                String actionCommand = e.getActionCommand();
                switch (actionCommand) {
                    case "红色":
                        forceColor = Color.RED;
                        break;
                    case "蓝色":
                        forceColor = Color.BLUE;
                        break;
                    case "绿色":
                        forceColor = Color.GREEN;
                        break;
                }
            }
        };

        //将按钮添加监听器并使之进行监听
        reditem.addActionListener(actionListener);
        buleitem.addActionListener(actionListener);
        greenitem.addActionListener(actionListener);

        //colorMenu
        colorMenu.add(reditem);
        colorMenu.add(buleitem);
        colorMenu.add(greenitem);

        //把colorMenu放在绘图区域
        drawArea.add(colorMenu);

        drawArea.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {//当鼠标抬起时被调用
                boolean popupTrigger = e.isPopupTrigger();
                if (popupTrigger) {
                    //将colorMenu在drawArea展现出来,鼠标点击的x与y轴位置
                    colorMenu.show(drawArea, e.getX(), e.getY());
                }

            }

        });

        //设置位图背景为白色
        g.setColor(Color.white);
        g.fillRect(0, 0, AREA_WIDTH, AREA_HEIGHT);

        //通过监听鼠标的移动,完成线条绘制
        drawArea.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                if (preX != -1 && preY != -1) {
                    g.setColor(forceColor);
                    //画线条,需要两组坐标,分别代表起点与终点,e.getX(),e.getY()可以获取坐标
                    g.drawLine(preX, preY, e.getX(), e.getY());
                }
                //修正preX与preY的值
                preX = e.getX();
                preY = e.getY();


                //重绘组件
                drawArea.repaint();

            }
        });
        drawArea.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                //重置preX和preY
                preX = -1;
                preY = -1;
            }
        });
        //将绘画区域设置为最合适的区域
        drawArea.setPreferredSize(new Dimension(AREA_WIDTH, AREA_HEIGHT));
        frame.add(drawArea);

        //设置frame最佳大小并可见
        frame.pack();
        frame.setVisible(true);
    }


    public static void main(String[] args) {
        new day22().init();
    }
}

Study19 ImageIO的使用

在实际生活中,很多软件都支持打开本地磁盘已经存在的图片进行编辑,编辑完毕后,再重新保存到本地磁盘。如果使用AWT要完成这样的功能,那么需要使用到ImageIO类,可以操作本地磁盘的图片文件。

方法名称 方法功能
static BufferedImage read(File input) 读取本地磁盘图片文件
static BufferedImage read(InputStream input) 读取本地磁盘图片文件
static boolean write(RenderedImage im,String formatName,File  output) 往本地磁盘中输出图片文件

案例一:制作图片查看器

黑马程序员Java Swing笔记分享(AWT篇)_第39张图片

package javaswing;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

public class day23 {
    private Frame frame = new Frame("图片查看器");

    //创建菜单条
    MenuBar menuBar = new MenuBar();
    //创建菜单
    Menu menu = new Menu("文件");
    //创建菜单中的菜单名
    MenuItem open = new MenuItem("打开");
    MenuItem save = new MenuItem("另存为");

    //声明BufferImage对象,记录本地存取到内存的图片,到最后读入文件,直接赋值给image
    BufferedImage image;

    private class MyCanvas extends Canvas {
        @Override
        public void paint(Graphics g) {
            g.drawImage(image, 0, 0, null);
        }
    }

    MyCanvas drawArea = new MyCanvas();

    public void init() {
        //组装视图

        open.addActionListener(e -> {
            //打开一个文件对话框
            FileDialog fileDialog = new FileDialog(frame, "打开图片", FileDialog.LOAD);
            fileDialog.setVisible(true);

            //获取用户选择的图片路径以及名称
            String dir = fileDialog.getDirectory();
            String fileName = fileDialog.getFile();

            try {
                //记得这里要写IO读入的文件,并且赋值给image
                image = ImageIO.read(new File(dir, fileName));
                drawArea.repaint();
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        });

        save.addActionListener(e -> {
            //获取用户设置的保存路径以及文件名称

            FileDialog fileDialog = new FileDialog(frame, "保存图片", FileDialog.SAVE);
            fileDialog.setVisible(true);

            //展示用户设置的保存路径以及文件名称
            String dir = fileDialog.getDirectory();
            String fileName = fileDialog.getFile();

            try {
                //注意这里要写写”JPEG“,文件格式名
                ImageIO.write(image, "JPEG", new File(dir, fileName));
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        });

        //将打开文件以及保存文件放到menu组件中
        menu.add(open);
        menu.add(save);

        //将menu组件放在菜单栏中
        menuBar.add(menu);

        //把菜单条放在窗口中
        frame.setMenuBar(menuBar);
        frame.add(drawArea);

        //自定义frame的框架,并且可见
        frame.setBounds(200, 200, 740, 508);
        frame.setVisible(true);

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

    }

    public static void main(String[] args) {
        new day23().init();
    }
}


 

你可能感兴趣的:(Java,Swing学习,java,开发语言,后端,swing,intellij,idea)