Java awt

@TOC

容器

默认布局管理器会导致下面图片内容显示不正常

window

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

在这里插入图片描述

Panel

panel不能单独存在需在window基础上

public static void main(String[] args) {
        //创建一个window对象
        Frame frame=new Frame("这里测试Panel窗口");
        //创建Panel
        Panel p=new Panel();
        //创建一个文本和按钮,将其放入容器中
        p.add(new TextField("这里是一个测试文本"));
        p.add(new Button("这里是一个测试按钮"));
        //把Panel放入Frame中
        frame.add(p);
        //指定窗口的位置和大小
        frame.setLocation(100,100);
        frame.setSize(500,500);
        //设置窗口对象可见
        frame.setVisible(true);
    }

编码问题自己解决
在这里插入图片描述

Scrollpane(滚动条)

  //创建一个window对象
        Frame frame=new Frame("这里测试Scrollpane窗口");
        //创建Scrollpane对象
        ScrollPane s=new ScrollPane(ScrollPane.SCROLLBARS_ALWAYS);
        //添加内容
        s.add(new TextField("这里是一个测试文本"));
        s.add(new Button("这里是一个测试按钮"));
        //把ScrollPane放入Frame中
        frame.add(s);
        //指定窗口的位置和大小
        frame.setLocation(100,100);
        frame.setSize(500,500);
        //设置窗口对象可见
        frame.setVisible(true);

在这里插入图片描述

布局管理器 layoutmanager

在这里插入图片描述

FlowLayOut(流式布局)

在FlowLayout布局管理器中,组件像水流一样向某方向流动(排列),遇到障碍(边界)就折回,重头开始排列。在默认情况下,FlowLayout布局管理器从左向右排列所有组件,遇到边界就会折回下一行重新开始。

构造方法方法功能
FlowLayout()使用默认的对齐方式及默认的垂直间距、水平间距创建FlowLayout布局管理器。
FlowLayout(int align)使用指定的对齐方式及默认的垂直间距、水平间距创建FlowLayout布局管理器。
FlowLayout(int align,int hgap,intvgap)使用指定的对齐方式及指定的垂直问距、水平间距创建FlowLayout布局管理器。
FlowLayout中组件的排列方向(从左向右、从右向左、从中间向两边等),该参数应该使用FlowLayout类的静态常量:FlowLayout.LEFT、FlowLayout.CENTER、FlowLayout. RIGHT,默认是左对齐。 FlowLayout中组件中间距通过整数设置,单位是像素,默认是5个像素。 ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210718144247310.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NpbXBsZXpoYW8=,size_16,color_FFFFFF,t_70)
 //创建一个window对象
        Frame frame = new Frame("这里测试Flowlayout");
        //通过setLayout方法设置容器的布局管理器
        frame.setLayout(new FlowLayout(FlowLayout.LEFT,20,20));
        //添加多个按钮到frame
        for(int i=0;i<100;i++){
            frame.add(new Button("按钮"+i));
        }
        //设置最佳大小
        frame.pack();
        frame.setVisible(true);

BorderLayout

BorderLayout将容器分为EAST、SOUTH、WEST、NORTH、CENTER五个区域,普通组件可以被放置在这5个区域的任意一个中。BorderLayout布局管理器的布局示意图如图所示。

在这里插入图片描述

当改变使用BorderLayaut的容器大小时,NORTH、SOUTH和CENTER区域水平调整,而EAST、WEST和CENTER区域垂直调整。使用BorderLayout有如下两个注意点:
    1.当向使用BorderLayaut布局管理器的容器中添加组件时,需要指定要添加到哪个区域中。如果没有指定添加到哪个区域中,则默认添加到中间区域中;
    2.如果向同一个区域中添加多个组件时,后放入的组件会覆盖先放入的组件;

构造方法方法功能
BorderLayout()使用默认的水平间距、垂直间距创建BorderLayout布局管理器。
BorderLayout(int hgap,int vgap)使用指定的水平间距、垂直间距创建 BorderLayout布局管理器。

在这里插入图片描述

        //创建一个window对象
        Frame frame = new Frame("这里测试Borderlayout");
        //通过setLayout方法设置容器的布局管理器
        frame.setLayout(new BorderLayout(30,10));
        //在指定区域添加组件
       frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
        frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);
        frame.add(new Button("西侧按钮"),BorderLayout.WEST);
        frame.add(new Button("东侧按钮"),BorderLayout.EAST);
        frame.add(new Button("中间按钮"),BorderLayout.CENTER);

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

如果不往某个区域中放入组件,那么该区域不会空白出来,而是会被其他区域占用

frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
        frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);
       frame.add(new Button("中间按钮"),BorderLayout.CENTER);
       frame.add(new TextField("ssssss"));

在这里插入图片描述
连一开始的组件都被覆盖了,将后面的组件添加到panel即可

 		frame.add(new Button("北侧按钮"),BorderLayout.NORTH);
        frame.add(new Button("南侧按钮"),BorderLayout.SOUTH);
      
        Panel p=new Panel();
        p.add(new Button("中间按钮"));
        p.add(new TextField("ssssss"));
        frame.add(p);

在这里插入图片描述

GridLayout

GridLayout布局管理器将容器分割成纵横线分隔的网格,每个网格所占的区域大小相同。当向使用GridLayout布局管理器的容器中添加组件时,默认从左向右、从上向下依次添加到每个网格中。与FlawLayout不同的是,放置在 GridLayout布局管理器中的各组件的大小由组件所处的区域决定(每个组件将自动占满整个区域)。

构造方法方法功能
GridLayout(int rows,in t cols)采用指定的行数、列数,以及默认的横向间距、纵向间距将容器分割成多个网格。
GridLayout(int rows,int cols,int采用指定的行数、列数,以及指定的横向间距、纵向间距将容器分割成多个网格。

计算器案例

        //创建一个window对象
        Frame frame = new Frame("计算器");

        //添加一个Panel对象
        Panel p = new Panel();
        p.add(new TextField(30));
        //将panel对象放到frame的北侧
        frame.add(p,BorderLayout.NORTH);
        //创建一个panel对象,并设置他的布局管理器为gridlayout
        Panel pp = new Panel();
        pp.setLayout(new GridLayout(3,5,4,4));
        //往panel中添加内容
        for (int i = 0; i < 10; i++) {
            pp.add(new Button(String.valueOf(i)));
        }
        pp.add(new Button("+"));
        pp.add(new Button("-"));
        pp.add(new Button("*"));
        pp.add(new Button("/"));
        //把当前panel添加到frame中
        frame.add(pp);
        //设置最佳大小
        frame.pack();
        frame.setVisible(true);

在这里插入图片描述

GridBagLayout(了解就好)

GridBagLayout布局管理器的功能最强大,但也最复杂,与GridLayout布局管理器不同的是,在
GridBagLayout布局管理器中,一个组件可以跨越一个或多个网格,并可以设置各网格的大小互不相同,从而增加了布局的灵活性。当窗口的大小发生变化时,GridBagLayout布局管理器也可以准确地控制窗口各部分的拉伸。
在这里插入图片描述
由于在GridBagLayout布局中,每个组件可以占用多个网格,此时,我们往容器中添加组件的时候,就需要具体的控制每个组件占用多少个网格,java提供的GridBagConstaints类,与特定的组件绑定,可以完成具体大小和跨越性的设置。

CardLayout

CardLayout布局管理器以时间而非空间来管理它里面的组件,它将加入容器的所有组件看成一叠卡片(每个卡片其实就是一个组件),每次只有最上面的那个Component 才可见。就好像一副扑克牌,它们叠在一起,每次只有最上面的一张扑克牌才可见.
在这里插入图片描述

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Window {
    public static void main(String[] args) {
        //创建一个window对象
        Frame frame = new Frame("这里测试CardLayout");
        //创建panel和布局管理器
        Panel p=new Panel();
        CardLayout c=new CardLayout();
        p.setLayout(c);
        //往panel里存储多个组件
        String[] names={"第一张","第2张","第3张","第4张","第5张"};
        for (int i = 0; i < names.length; i++) {
            p.add(names[i],new Button(names[i]));
        }
        //放入中间区域
        frame.add(p);
        //创建pp存储按钮
        Panel pp = new Panel();
        //创建五个按钮组件
        Button b1 = new Button("上一张");
        Button b2 = new Button("下一张");
        Button b3 = new Button("第一张");
        Button b4 = new Button("最后一张");
        Button b5 = new Button("第三张");
        //创建一个事件监听器,监听按钮的点击动作
        ActionListener actionListener = new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                String actionCommand = e.getActionCommand();//获取按钮上的文字
                switch (actionCommand){
                    case "上一张":
                        c.previous(p);
                        break;
                    case "下一张":
                        c.next(p);
                        break;
                    case "第一张":
                        c.first(p);
                        break;
                    case "最后一张":
                        c.last(p);
                        break;
                    case "第三张":
                        c.show(p,"第三张");
                        break;
                }
            }
        };
        //把事件监听器和按钮联系到一起
        b1.addActionListener(actionListener);
        b2.addActionListener(actionListener);
        b3.addActionListener(actionListener);
        b4.addActionListener(actionListener);
        b5.addActionListener(actionListener);

        pp.add(b1);
        pp.add(b2);
        pp.add(b3);
        pp.add(b4);
        pp.add(b5);
        //把pp放到南边
        frame.add(pp,BorderLayout.SOUTH);
        //设置最佳大小
        frame.pack();
        frame.setVisible(true);
    }
}

Boxlayout

为了简化开发,Swing引入了一个新的布局管理器:BoxLayout。BoxLayout 可以在垂直和水平两个方向上摆放GUI组件,BoxLayout提供了如下一个简单的构造器:
在这里插入图片描述

 //创建一个window对象
        Frame frame = new Frame("这里测试BoxLayout");
        //基于Frame创建一个Boxlayout对象,并且组件垂直存放
        BoxLayout boxLayout = new BoxLayout(frame,BoxLayout.Y_AXIS);
        //对象给frame
        frame.setLayout(boxLayout);

        //添加两个组件
        frame.add(new Button("1"));
        frame.add(new Button("2"));
        
        //设置最佳大小
        frame.pack();
        frame.setVisible(true);

在这里插入图片描述

在java.swing包中,提供了一个新的容器Box,该容器的默认布局管理器就是BoxLayout,大多数情况下,使用Box容器去容纳多个GUI组件,然后再把Box容器作为一个组件,添加到其他的容器中,从而形成整体窗口布局。
在这里插入图片描述

        //创建一个window对象
        Frame frame = new Frame("这里测试BoxLayout");
        //创建一个水平排列组件的Box容器
        Box hbox=Box.createHorizontalBox();
        //往当前容器中添加两个按钮
        hbox.add(new Button("1"));
        hbox.add(new Button("2"));
        //创建一个垂直排列组件的Box容器
        Box vbox = Box.createVerticalBox();
        vbox.add(new Button("3"));
        vbox.add(new Button("4"));

        frame.add(hbox,BorderLayout.SOUTH);
        frame.add(vbox,BorderLayout.CENTER);

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

在这里插入图片描述
通过之前的两个BoxLayout演示,我们会发现,被它管理的容器中的组件之间是没有间隔的,不是特别的美观,但之前学习的几种布局,组件之间都会有一些间距,那使用BoxLayout如何给组件设置间距呢?
其实很简单,我们只需要在原有的组件需要间隔的地方,添加间隔即可,而每个间隔可以是一个组件,只不过该组件没有内容,仅仅起到一种分隔的作用。
在这里插入图片描述

        //创建一个window对象
        Frame frame = new Frame("这里测试BoxLayout");
        //创建一个水平排列组件的Box容器
        Box hbox=Box.createHorizontalBox();
        //往当前容器中添加三个按钮并分割
        hbox.add(new Button("1"));
        hbox.add(Box.createHorizontalGlue());
        hbox.add(new Button("2"));
        hbox.add(Box.createHorizontalStrut(30));
        hbox.add(new Button("3"));
        //创建一个垂直排列组件的Box容器
        Box vbox = Box.createVerticalBox();
        vbox.add(new Button("4"));
        vbox.add(Box.createVerticalGlue());
        vbox.add(new Button("5"));
        vbox.add(Box.createVerticalStrut(30));
        vbox.add(new Button("6"));
        frame.add(hbox,BorderLayout.SOUTH);
        frame.add(vbox,BorderLayout.CENTER);

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

在这里插入图片描述

基本组件

在这里插入图片描述
案例:
在这里插入图片描述
代码:

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

public class Window {
    //创建一个window对象
    Frame frame = new Frame("这里测试组件");

    TextArea a=new TextArea(5,20);

    Choice c=new Choice();

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

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

    TextField tx=new TextField(20);

    Button ok=new Button("确认");

    //true表示多选
    List colorlist=new List(6,true);


    public void init(){
        //组装界面
        //组装底部
        Box bbox=Box.createHorizontalBox();
        bbox.add(tx);
        bbox.add(ok);
        frame.add(bbox,BorderLayout.SOUTH);
        //组装左侧
        Box lbbox=Box.createHorizontalBox();
        c.add("蓝色");
        c.add("绿色");
        c.add("红色");
        lbbox.add(c);
        lbbox.add(male);
        lbbox.add(female);
        lbbox.add(isMarried);

        Box lbox=Box.createVerticalBox();
        lbox.add(a);
        lbox.add(lbbox);


        //组装上边
        Box nb=Box.createHorizontalBox();
        nb.add(lbox);
        nb.add(colorlist);

        frame.add(nb);

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

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

    }
}

对话框dialog

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

  • ·对话框通常依赖于其他窗口,就是通常需要有一个父窗口;
  • ·对话框有非模式(non-modal)和模式(modal)两种,当某个模式对话框被打开后,该模式对话框总是位于它的父窗口之上,在模式对话框被关闭之前,父窗口无法获得焦点。
方法名称 方法功能
Dialog(Frame owner, String title, boolean modal) 创建一个对话框对象:
owner:当前对话框的父窗口
title:当前对话框的标题
modal:当前对话框是否是模式对话框,true/false
案例: ![在这里插入图片描述](https://img-blog.csdnimg.cn/20210720141431790.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3NpbXBsZXpoYW8=,size_16,color_FFFFFF,t_70)
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Window {


    public static void main(String[] args) {
        //创建一个window对象
        Frame frame = new Frame("这里测试Dialog");
        //创建对话框dialog,一个模式一个非模式
        Dialog d1=new Dialog(frame,"moshi",true);
        Dialog d2=new Dialog(frame,"feimoshi",false);
        //通过setBounds设置对话框位置大小
        d1.setBounds(20,30,200,300);
        d2.setBounds(20,30,200,300);
        //创建两个按钮并添加点击后行为
        Button b1=new Button("打开模式对话框");
        Button b2=new Button("打开非模式对话框");
        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);
            }
        });

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

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

通过add往dialog里添加内容。

Filedialog

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

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

public class Window {


    public static void main(String[] args) {
        //创建一个window对象
        Frame frame = new Frame("这里测试fileDialog");
        //创建对话框
        FileDialog f1=new FileDialog(frame,"选择要打开的文件",FileDialog.LOAD);
        FileDialog f2=new FileDialog(frame,"选择要保存的文件",FileDialog.SAVE);
        //创建两个按钮并添加点击后行为
        Button b1=new Button("打开");
        Button b2=new Button("保存");
        b1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                f1.setVisible(true);
                System.out.println("打开的文件名为"+f1.getFile());
                System.out.println("打开的文件地址为"+f1.getDirectory());
            }
        });
        b2.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                f2.setVisible(true);
                System.out.println("保存的文件名为"+f2.getFile());
                System.out.println("保存的文件地址为"+f2.getDirectory());
            }
        });

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

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

GUI事件处理机制

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

使用步骤︰
1.创建事件源组件对象;
2.自定义类,实现XxxListener接口,重写方法;
3.创建事件监听器对象(自定义类对象)
4.调用事件源组件对象的addXxxListener方法完成注册监听

案例:
在这里插入图片描述

import com.sun.org.apache.bcel.internal.generic.NEW;

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

public class Window {
    //创建一个window对象
    Frame frame = new Frame("这里测试事件处理");

    TextField tf=new TextField(30);
    //事件源
    Button ok=new Button("确定");

    public void init(){
        //组装视图
        //监听器
        MyListener myListener=new MyListener();

        //注册监听
        ok.addActionListener(myListener);

        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("nihao");
        }
    }
    public static void main(String[] args) {
        new Window().init();
    }
}

事件

AWT把事件分为了两大类:
1.低级事件︰这类事件是基于某个特定动作的事件。比如进入、点击、拖放等动作的鼠标事件,再比如得到焦点和失去焦点等焦点事件。
在这里插入图片描述
⒉高级事件:这类事件并不会基于某个特定动作,而是根据功能含义定义的事件。
在这里插入图片描述

事件监听器

在这里插入图片描述

案例:

一:
通过ContainerListener监听Frame容器添加组件;
通过TextListener监听TextFiled内容变化;
通过ltemListener监听Choice条目选中状态变化;

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

import com.sun.org.apache.bcel.internal.generic.NEW;

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

public class Window {



    public static void main(String[] args) {
        //创建一个window对象
        Frame frame = new Frame("这里测试窗口监听");

        TextField tf=new TextField(30);
        Choice c=new Choice();
        c.add("呵");
        c.add("aaaa");
        c.add("bbbb");

        //给文本域添加TextListener,监听内容变化
        tf.addTextListener(new TextListener() {
            @Override
            public void textValueChanged(TextEvent e) {
                String text = tf.getText();
                System.out.println("当前文本框的内容为:"+text);
            }
        });
        //给下拉选择框添加ItemListener,监听条目选项的变化
        c.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("添加了"+child);
            }

            @Override
            public void componentRemoved(ContainerEvent e) {

            }
        });
        //添加到frame中
        Box hbox=Box.createHorizontalBox();
        hbox.add(c);
        hbox.add(tf);
        frame.add(hbox);

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

二:
给Frame设置WindowListner,监听用户点击X的动作,如果用户点击×,则关闭当前窗口

import com.sun.org.apache.bcel.internal.generic.NEW;

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

public class Window {



    public static void main(String[] args) {
        //创建一个window对象
        Frame frame = new Frame("这里测试windows listener");
        frame.setBounds(200,200,500,300);

        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                //停止当前程序
                 System.exit(0);
            }
        });
        frame.setVisible(true);
    }
}

菜单组件

在这里插入图片描述
菜单相关组件使用:
1.准备菜单项组件,这些组件可以是Menultem及其子类对象
⒉.准备菜单组件Menu或者PopupMenu(右击弹出子菜单),把第一步中准备好的菜单项组件添加进来;
3.准备菜单条组件MenuBar,把第二步中准备好的菜单组件Menu添加进来;
4.把第三步中准备好的菜单条组件添加到窗口对象中显示。

小技巧:
1.如果要在某个菜单的菜单项之间添加分割线,那么只需要调用Menu的add ( new Menultem("-"))即可。⒉.如果要给某个菜单项关联快捷键功能,那么只需要在创建菜单项对象时设置即可,例如给菜单项关联ctrl+shift+Q快捷键,只需要: new Menultem(“菜单项名字” ,new MenuShortcut(KeyEvent.MVK_Q,true);
案例:

import com.sun.org.apache.bcel.internal.generic.NEW;

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

public class Window {
    //创建一个window对象
    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("注释 Crtl+Shift+Q",new MenuShortcut(KeyEvent.VK_Q,true));
    MenuItem cancelcomment=new MenuItem("取消注释");

    TextArea ta=new TextArea(6,10);
    public void init(){
        //组装试图
        comment.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                ta.append("注释");
            }
        });
        formatmenu.add(comment);
        formatmenu.add(cancelcomment);

        editmenu.add(copy);
        editmenu.add(paste);
        editmenu.add(auto);
        editmenu.add(new MenuItem("-"));
        editmenu.add(formatmenu);

        menuBar.add(filemenu);
        menuBar.add(editmenu);

        frame.setMenuBar(menuBar);
        frame.add(ta);

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

    public static void main(String[] args) {


        new Window().init();
    }
}


案例:
实现思路:
1.创建PopubMenu菜单组件;
⒉.创建多个Menultem菜单项,并添加到PopupMenu中;
3.将PopupMenu添加到目标组件中;
4.为需要右击出现PopubMenu菜单的组件,注册鼠标监听事件,当监听到用户释放右键时,弹出菜单。
在这里插入图片描述

import com.sun.org.apache.bcel.internal.generic.NEW;

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

public class Window {
    //创建一个window对象
    Frame frame = new Frame("这里测试菜单相关组件");

    Panel p=new Panel();
    PopupMenu popupMenu=new PopupMenu();

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



    TextArea ta=new TextArea(6,10);
    public void init(){
        //组装试图




        popupMenu.add(copy);
        popupMenu.add(paste);
        popupMenu.add(auto);

        p.add(popupMenu);
        p.setPreferredSize(new Dimension(300,400));
        p.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseReleased(MouseEvent e) {
                if(e.isPopupTrigger()){
                    popupMenu.show(p,e.getX(),e.getY());
                }
            }
        });


        frame.add(ta);
        frame.add(p,BorderLayout.SOUTH);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

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

    public static void main(String[] args) {


        new Window().init();
    }
}

画图

画图的步骤:
1.自定义类,继承Canvas类,重写paint(Graphics g)方法完成画图;
2.在paint方法内部,真正开始画图之前调用Graphics对象的setColor()、setFont()等方法设置画笔的颜色、字体等属性;
3.调用Graphics画笔的drawXxx()方法开始画图。
在这里插入图片描述

import com.sun.org.apache.bcel.internal.generic.NEW;

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

public class Window {
   private final String RECT_SHAPE="rect";
   private final String OVAL_SHAPE="oval";
   private Frame frame=new Frame("这里测试绘图");

   Button b1= new Button("绘制矩形");
   Button b2= new Button("绘制椭圆");
    //定义一个变量来确定当前绘制矩形还是椭圆
    private String shape="";

   //自定义类,继承Canvas类,重写paint(Graphics g)方法完成画图;
    private class MyCanvas extends Canvas{
       @Override
       public void paint(Graphics g) {
           //绘制不同图形
            if(shape.equals(RECT_SHAPE)){
                //绘制矩形
                g.setColor(Color.BLACK);
                g.drawRect(100,100,200,150);
           }else if(shape.equals(OVAL_SHAPE)){
                //绘制椭圆
                g.setColor(Color.red);
                g.drawOval(100,100,200,150);
            }
       }
   }
    //创建自定义绘图对象
    MyCanvas drawArea=new MyCanvas();
   public void init(){
        //组装视图
       b1.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {
               shape=RECT_SHAPE;
               drawArea.repaint();
           }
       });
       b2.addActionListener(new ActionListener() {
           @Override
           public void actionPerformed(ActionEvent e) {
               shape=OVAL_SHAPE;
               drawArea.repaint();
           }
       });

       Panel p=new Panel();
       p.add(b1);
       p.add(b2);
       frame.add(p,BorderLayout.SOUTH);

       drawArea.setPreferredSize(new Dimension(500,500));
       frame.add(drawArea);
       frame.pack();
       frame.setVisible(true);
   }


    public static void main(String[] args) {

    new Window().init();

    }
}

在这里插入图片描述

弹球小游戏

import com.sun.org.apache.bcel.internal.generic.NEW;

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

public class Window {
   //创建窗口对象
    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 RACKRT_HEIGHT=20;

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

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

    //定义变量记录小球移动速度
    private int speedX=10;
    private int speedY=5;

    //定义变量记录球拍坐标
    private int racketX=120;
    private int racketY=340;

    //定义变量判断是结束
    private boolean isOver=false;

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

     //自定义一个类,继承canvas,充当画布
      private class MyCanvas extends Canvas{
      @Override
      public void paint(Graphics g) {
       // 这里绘制内容
       if(isOver){
        //游戏结束
        g.setColor(Color.BLUE);
        g.setFont(new Font("Times",Font.BOLD,30));
        g.drawString("游戏结束",100,200);
       }
       else{
        //游戏中
        //绘制小球
        g.setColor(Color.red);
        g.fillOval(ballX,ballY,BALL_SIZE,BALL_SIZE);

        //绘制球拍
        g.setColor(Color.red);
        g.fillRect(racketX,racketY,RACKET_WIDTH,RACKRT_HEIGHT);
       }

      }
     }

     MyCanvas drawArea=new MyCanvas();
   public void init() {
    //组装视图
    //完成球拍坐标的变化
    KeyListener listener = new KeyAdapter() {
     @Override
     public void keyPressed(KeyEvent e) {
      //获取当前按键
      int keyCode = e.getKeyCode();
      if (keyCode == KeyEvent.VK_LEFT) {
       if (racketX > 0) {
        racketX -= 10;
       }
      }
       if (keyCode == KeyEvent.VK_RIGHT) {
        if (racketX < TABLE_WIDTH - RACKET_WIDTH) {
         racketX += 10;
        }
       }
     }
    };
    frame.addKeyListener(listener);
    drawArea.addKeyListener(listener);
   //小球坐标的控制
    ActionListener task=new ActionListener() {
     @Override
     public void actionPerformed(ActionEvent e) {
      //更新小球的坐标
      if(ballX<=0 || ballX>=TABLE_WIDTH-RACKET_WIDTH){
       speedX=-speedX;
      }
      if (ballY<=0||(ballY>=racketY-BALL_SIZE&& ballX>=(racketX-BALL_SIZE/2)&&(ballX<=racketX+RACKET_WIDTH-BALL_SIZE/2))){
       speedY=-speedY;
      }
      if(ballY>racketY+RACKRT_HEIGHT){
       timer.stop();
       isOver=true;
       drawArea.repaint();
      }
      ballX+=speedX;
      ballY+=speedY;
      drawArea.repaint();
     }
    };
    timer = new Timer(100,task);
    timer.start();

    drawArea.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));
    frame.add(drawArea);
    frame.pack();
    frame.setVisible(true);
   }

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

    }
}

位图

如果仅仅绘制一些简单的几何图形,程序的图形效果依然比较单调。AMT也允许在组件上绘制位图,
Graphics提供了drawlmage(Image image)方法用于绘制位图,该方法需要一个Image参数——代表位图,通过该方法就可以绘制出指定的位图。
位图使用步骤:
1.创建lmage的子类对象Bufferedlmage(int width,int height,int lmageType),创建时需要指定位图的宽高及类型属性;此时相当于在内存中生成了一张图片;
⒉调用Bufferedlmage对象的getGraphics()方法获取画笔,此时就可以往内存中的这张图片上绘图了,绘图的方法和之前学习的一模一样;
3.调用组件paint方法中提供的Graphics对象的drawlmage()方法,一次性的内存中的图片Bufferedlmage绘制到特定的组件上。
使用位图绘制组件的好处:
使用位图来绘制组件,相当于实现了图的缓冲区,此时绘图时没有直接把图形绘制到组件上,而是先绘制到内存中的Bufferedlmage上,等全部绘制完毕,再一次性的图像显示到组件上即可,这样用户的体验会好一些。
案例:

import com.sun.org.apache.bcel.internal.generic.NEW;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.sql.Time;

public class Window {
   //创建窗口对象
    private Frame frame=new Frame("简单手绘程序");
    //定义画图区的宽高
    private final int AREA_WIDTH=500;
    private final int AREA_HEIGHT=400;
    //定义变量,记录鼠标拖动过程中,上一次所处的坐标
    private int preY=-1;
    private int preX=-1;
    //定义一个右键菜单,用于设置画笔的颜色
    private PopupMenu colorMenu=new PopupMenu();
    private MenuItem redItem=new MenuItem("红色");
    private MenuItem blueItem=new MenuItem("蓝色");
    private MenuItem greenItem=new MenuItem("绿色");
    //定义一个变量,记录当前画笔的颜色
    private Color forceColor=Color.black;
    //创建一个BufferedImage位图对象
    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);
        }
    }
    MyCanvas myCanvas=new MyCanvas();

    public void init() {
    ActionListener listener=new ActionListener() {
        @Override
        public void actionPerformed(ActionEvent e) {
            String actionCommand = e.getActionCommand();
            switch (actionCommand){
                case "红色":
                    forceColor=Color.red;
                    break;
                case "绿色":
                    forceColor=Color.green;
                    break;
                case "蓝色":
                    forceColor=Color.blue;
                    break;
            }
        }
    };
    redItem.addActionListener(listener);
    greenItem.addActionListener(listener);
    blueItem.addActionListener(listener);
    colorMenu.add(redItem);
    colorMenu.add(greenItem);
    colorMenu.add(blueItem);

    myCanvas.add(colorMenu);

    myCanvas.addMouseListener(new MouseAdapter() {
        @Override
        public void mouseReleased(MouseEvent e) {
            boolean popupTrigger = e.isPopupTrigger();
            if (popupTrigger){
                colorMenu.show(myCanvas,e.getX(),e.getY());
            }
            preY=-1;
            preX=-1;
        }
    });

    g.setColor(Color.white);
    g.fillRect(0,0,AREA_WIDTH,AREA_HEIGHT);

    myCanvas.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
            if(preX>0&&preY>0) {
                g.setColor(forceColor);
                g.drawLine(preX,preY,e.getX(),e.getY());
            }
            preY=e.getY();
            preX=e.getX();
            myCanvas.repaint();
        }
    });
    myCanvas.setPreferredSize(new Dimension(AREA_WIDTH,AREA_HEIGHT));
    frame.add(myCanvas);
    frame.pack();
    frame.setVisible(true);
   }

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

    }
}

在这里插入图片描述

ImageIO的使用

在这里插入图片描述
案例:
编写图片查看程序支持另存操作

import com.sun.org.apache.bcel.internal.generic.NEW;

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.Time;

public class Window {
   //创建窗口对象
    private Frame frame=new Frame("图片查看器");

    MenuBar menuBar=new MenuBar();
    Menu menu=new Menu("文件");
    MenuItem open=new MenuItem("打开");
    MenuItem save=new MenuItem("另存为");

    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() throws Exception{
        open.addActionListener(e -> {
            FileDialog fileDialog=new FileDialog(frame,"打开文件",FileDialog.LOAD);
            fileDialog.setVisible(true);
            String file = fileDialog.getFile();
            String directory = fileDialog.getDirectory();

            try {
                Image = ImageIO.read(new File(directory, file));
                drawArea.repaint();
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        });

        save.addActionListener(e -> {
            FileDialog fileDialog=new FileDialog(frame,"保存文件",FileDialog.SAVE);
            fileDialog.validate();
            String file = fileDialog.getFile();
            String directory = fileDialog.getDirectory();
            try {
                ImageIO.write(Image,"JPEG",new File(directory,file));
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        });
        menu.add(open);
        menu.add(save);
        menuBar.add(menu);
        frame.setMenuBar(menuBar);
        frame.add(drawArea);

        frame.setBounds(200,200,700,800);
        frame.setVisible(true);
        frame.addWindowListener(new WindowAdapter() {
            @Override
            public void windowClosing(WindowEvent e) {
                System.exit(0);
            }
        });

   }

    public static void main(String[] args) throws Exception {
    new Window().init();

    }
}

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值