JavaSE第十一章.GUI

概述

GUI(Graphical User Interface)即图形用户界面

Swing组件

(1)顶层容器::常用有JFrame,JDialog

(2)中间容器:JPanel,JOptionPane,JScrollPane,JLayeredPane 等,主要以panel结尾。

(3)基本组件:JLabel,JButton,JTextField,JPasswordField,JRadioButton 等。
在这里插入图片描述

在这里插入图片描述

容器组件

  • Java的图形用户界面的基本组成部分是组件,组件是一个以图形化的方式显示在屏幕上并能与用户进行交互的对象

  • 组件不能独立地显示出来,必须将组件放在一定的容器(container)中才可以显示出来

  • 容器可以容纳多个组件,通过调用容器的add(Component comp)方法向容器中添加组件

窗口(Frame)和面板(Panel)是最常用的两个容器。

JFrame

void setSize(int width, int height) 设置大小
void setTitle(String title) 标题
void setLocation(int x,int y) 窗口位置
void setBounds(int x, int y, int width, int height) 设置窗口的x,y位置,窗口大小x,y.
void setLocationRelativeTo(null) 设置窗口居中
void setDefaultCloseOperation(int operation) 关闭按钮选项
void setIconImage(new ImageIcon("wy.png").getImage()) 更换窗口图标
void setResizable(boolean resizable) 是否能设置大小
void setResizable(boolean resizable) 设置该框架是否可以由用户调整大小
void setVisible(boolean b) 显示窗口(放最后)
public class Demo1 extends JFrame {
    //设置窗口特征
    public void createFrame() {
        this.setSize(500, 500);
        //this.setLocation(200, 200);
        this.setLocationRelativeTo(null);//设置窗口居中
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭按钮选项
        this.setTitle("这是GUI窗口");//标题
        this.setResizable(false);//不能设置大小
        this.setIconImage(new ImageIcon("wy.png").getImage());//更换窗口图标
        this.setResizable(true);//设置该框架是否可以由用户调整大小
        this.setVisible(true);//显示窗口(放最后)
    }
    
    public static void main(String[] args) {
        new Demo1().createFrame();
    }
}

JPanel

框架(JFrame) 内部包含一个名叫Container(内容面板)的面板容器,如果要给框架中添加图形控件,通常将它们加入到这个内容面板中。

void setBackground(Color bg)设置面板的背景色,由参数bg指定颜色
void setLayout(LayoutManager mgr)设置面板的布局,参数是布局管理器
Component add(Component comp)往面板中添加一个组件
void remove(Component comp)从面板中移除指定的组件
void removeAll()从面板中移除所有组件

JPanel jp = new JPanel();//默认内容居中
JScrollPane jsp = new JScrollPane(jt);//可以自动添加滚动条的面板

布局管理器

在这里插入图片描述

FlowLayout

FlowLayout布局管理器是流式布局管理器,它将组件按照从左到右、从上到下的顺序来安排,并在默认情况下使组件尽量居中放置。

FlowLayout布局管理器对组件逐行定位,行内从左到右,一行排满后换行。

不改变组件的大小,按组件原有尺寸显示组件,可设置不同的组件间距,行距以及对齐方式。

//面板的布局方式默认是流式布局 new FlowLayout(FlowLayout.LEFT,10,20) 宽高间距
	JPanel jp = new JPanel(new FlowLayout(FlowLayout.LEFT)); //流式布局,居左对齐
BorderLayout

BorderLayout布局管理器只允许在容器内放置5个组件,这5个组件的位置是由BorderLayout类中的

North、South、East、West和Center5个常量来确定的,他们对应着容器中的上下左右中,用法如下:

//边界布局  总共有5个区域 上,下,左,右,中间(必须),添加进来的组件,默认最大化
	JPanel jp = new JPanel(new BorderLayout());

 //创建按钮组件
              JButton jb1 = new JButton("测试按钮1");
              JButton jb2 = new JButton("测试按钮2");
                       jp.add(jb1, BorderLayout.NORTH);
                       jp.add(jb2,BorderLayout.SOUTH);  //按钮位置

组件在BorderLayout中的大小都是可以改变的。一般情况下可以让中间区域大一些,而且可以只用其中几个区域。

  • BorderLayout将整个容器的布局划分成东(EAST)西(WEST)南(SOUTH)北(NORTH)中(CENTER)五个区域,组件只能被添加到指定的区域。

  • 如不指定组件的加入部位,则默认加入到CENTER区。

  • 每个区域只能加入一个组件,如加入多个,则先前加入的会被覆盖。

  • BorderLayout型布局容器尺寸缩放原则:

    ● 北、南两个区域在水平方向缩放。

    ● 东、西两个区域在垂直方向缩放。

    ● 中部可在两个方向上缩放。

GridLayout

GridLayout布局管理器是矩形网格,在网格中放置组件,每个网格的高度和宽度都相等,组件随着网格的大小而在水平和垂直方向上拉伸,网格的大小是由容器的

大小和创建网格的多少来确定的。其用法如下:

//网格布局(表格)  设置行数,列数,从第一行第一列开始添加组件,一行占满时,从第二行开始
//组件数量超出后,会扩展一列
	JPanel jp = new JPanel(new GridLayout(2, 2));//2行2列
		jp.add(new JButton("测试按钮1"););
  • 当组件数目大于网格数时,GridLayout保持行数不变而自动增加列数。
  • GridLayout型布局管理器将空间划分成规则的矩形网格,每个单元格区域大小相等。组件被添加到每个单元格中,先从左到右添满一行后换行,再从上到下。
  • 在 GridLayout 构造方法中指定分割的行数和列数.

功能组件

JLabel

标签是容纳文本和图标的控件,通常用来在界面中标识别的控件。

JLabel() 创建一个空的标签 
JLabel(String text) 创建一个带文本的标签 
JLabel(Icon image) 创建一个带图像的标签               

//创建标签组件  可以容纳文本,图标
           JLabel  accountLabel = new JLabel("账号");
                   accountLabel.setFont(new Font("楷体",Font.BOLD,20));//字体,样式,大小
JTextField

单行文本框

//单行文本输入框
JTextField accountText = new JTextField(15);       										System.out.println(accountText.getText());    //获取内容   
//accountText.setText("asdasdsad"); //设置默认内容      
//accountText.setEditable(false);//不可编辑
JTextArea

文本区域

//多行文本输入框
JTextArea jt = new JTextArea(5,20);
jt.setLineWrap(true);//强制换行           
//jt.setWrapStyleWord(true);//英文单词换行
JPasswordField

密码框

JPasswordField jPasswordField = new JPasswordField("123",15); 
//获得密码框输入的内容  
	char [] array = jPasswordField.getPassword();  
	String pwd  = new String(array);  
	System.out.println(pwd);
JButton

按钮

JButton jb = new JButton("登录");
jb.addActionListener(new ActionListener() {});//监听
JMenuBar

菜单栏

         //创建菜单栏
         JMenuBar  jMenuBar = new JMenuBar();
         //创建菜单
         JMenu jm  = new JMenu("帮助");
         jMenuBar.add(jm);

         //创建菜单项
         JMenuItem ji = new JMenuItem("退出");
         jm.add(ji);

          //将菜单栏添加到窗口
          this.setJMenuBar(jMenuBar);
          this.setVisible(true);//显示窗口

事件处理

监听

 jb1.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                
            }
        });
按钮监听
JButton jb = new JButton("登录");
                      
//注册组件事件监听器       创建ActionListener接口的匿名内部类对象(简化写法)
         jb.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
                 try {
                     String msg = jt.getText();
                     if(msg.length()==0){
                         JOptionPane.showMessageDialog(null,"账号信息不能为空!","操作提示",JOptionPane.WARNING_MESSAGE);//弹窗
                         return;
                     }
                 } catch (Exception ex) {
                     JOptionPane.showMessageDialog(null,"系统忙,请稍后再试!","操作提示",JOptionPane.ERROR_MESSAGE);
                 }
             }
         });
菜单项监听
         //创建菜单栏
         JMenuBar  jMenuBar = new JMenuBar();
         //创建菜单
         JMenu jm  = new JMenu("帮助");
         jMenuBar.add(jm);

         //创建菜单项
         JMenuItem ji = new JMenuItem("退出");
         jm.add(ji);

          //将菜单栏添加到窗口
          this.setJMenuBar(jMenuBar);
          this.setVisible(true);//显示窗口


         ji.addActionListener(new ActionListener() {
             @Override
             public void actionPerformed(ActionEvent e) {
                 //默认: 是-0,否-1,取消-2
               //int res =   JOptionPane.showConfirmDialog(null, "您确定要退出吗?");
                 //OK_CANCEL_OPTION 确定-0  取消-2
                  int res =   JOptionPane.showConfirmDialog(null, "您确定要退出吗?","操作提示",JOptionPane.OK_CANCEL_OPTION);
                  if(res==0){
                     // this.dispose(); 在匿名内部类中,this表示内部类对象
                      dispose();//释放窗口
                     // new LoginFrame()
                  }
             }
         });
鼠标键盘监听
//在窗口中添加面板
              JPanel jp = new JPanel();
                     jp.setBackground(Color.cyan);

             //文本框
             JTextField jt = new JTextField(15);

              //创建按钮组件
              JButton jb = new JButton("测试按钮");
                      jp.add(jb);
                      jp.add(jt);

              //this表示窗口
              this.add(jp);
              this.setVisible(true);//显示窗口


           //jb.addActionListener(); 给组件添加一个事件监听
             jb.addMouseListener(new MouseAdapter() {
                 @Override
                 public void mouseClicked(MouseEvent e) {
                     System.out.println("鼠标点击事件");
                 }
                 @Override
                 public void mousePressed(MouseEvent e) {
                     System.out.println("鼠标按下事件");
                 }
                 @Override
                 public void mouseReleased(MouseEvent e) {
                     System.out.println("鼠标抬起事件");
                 }
                 @Override
                 public void mouseEntered(MouseEvent e) {
                     System.out.println("鼠标移入事件");
                 }
                 @Override
                 public void mouseExited(MouseEvent e) {
                     System.out.println("鼠标移出事件");
                 }
             });

             jt.addKeyListener(new KeyAdapter() {
                 @Override
                 public void keyPressed(KeyEvent e) {
                     System.out.println("键盘按下"+e.getKeyCode());//获取按下键的编码
                 }
                 @Override
                 public void keyReleased(KeyEvent e) {
                     System.out.println("键盘抬起");
                 }
             });

对话框

对话框

JOptionPane对话框

​ showMessageDialog():消息对话框

主要有五种消息类型,类型不同,图标不同:

  • ERROR_MESSAGE 错误消息提示
  • INFORMATION_MESSAGE 信息提示
  • WARNING_MESSAGE 警告提示
  • QUESTION_MESSAGE 问题提示
  • PLAIN_MESSAGE 简洁提示
  • showConfirmDialog():确认对话框

主要有四种消息类型,类型不同,图标不同:

  • DEFAULT_OPTION 默认选项
  • YES_NO_OPTION 是/否选项
  • YES_NO_CANCEL_OPTION 是/否/取消选项
  • OK_CANCEL_OPTION 确定/取消
JPanel jp = new JPanel();
        jp.setBackground(Color.gray);

        JButton jb1 = new JButton("退出窗口");
        JButton jb2 = new JButton("2");

        jp.add(jb1);
        jp.add(jb2);

        jb1.addActionListener(new ActionListener() {		//监听
            @Override
            public void actionPerformed(ActionEvent e) {
                int res = JOptionPane.showConfirmDialog(null,"确定退出吗","操作提示",JOptionPane.OK_CANCEL_OPTION);
                if (res==0){
                    dispose();
                }
            }
        });

        this.add(jp);

内部类

  • 把类定义在另一个类的内部,该类就被称为内部类。
  • 如果在类 Outer 的内部再定义一个类 Inner,此时类 Inner 就称为内部类 (或称为嵌套类),而类 Outer 则称为外部类(或称为宿主类)。

成员内部类

成员内部类——就是位于外部类成员位置的类

特点:可以使用外部类中所有的成员变量和成员方法(包括private的)

在这里 InnerClassA 类为 InnerClassTest 类的普通内部类,在这种定义方式下,普通内部类对象依赖外部类对象而存在,即在创建一个普通内部类对象时首先需要创建其外部类对象,我们在创建上面代码中的 InnerClassA 对象时先要创建 InnerClassTest 对象,例:

public class InnerClassTest {

    public int outField1 = 1;
    protected int outField2 = 2;
    int outField3 = 3;
    private int outField4 = 4;

    public InnerClassTest() {
        // 在外部类对象内部,直接通过 new InnerClass(); 创建内部类对象
        InnerClassA innerObj = new InnerClassA();
        System.out.println("创建 " + this.getClass().getSimpleName() + " 对象");
        System.out.println("其内部类的 field1 字段的值为: " + innerObj.field1);
        System.out.println("其内部类的 field2 字段的值为: " + innerObj.field2);
        System.out.println("其内部类的 field3 字段的值为: " + innerObj.field3);
        System.out.println("其内部类的 field4 字段的值为: " + innerObj.field4);
    }

    public class InnerClassA {
        public int field1 = 5;
        protected int field2 = 6;
        int field3 = 7;
        private int field4 = 8;
//        static int field5 = 5; // 编译错误!普通内部类中不能定义 static 属性

        public InnerClassA() {
            System.out.println("创建 " + this.getClass().getSimpleName() + " 对象");
            System.out.println("其外部类的 outField1 字段的值为: " + outField1);
            System.out.println("其外部类的 outField2 字段的值为: " + outField2);
            System.out.println("其外部类的 outField3 字段的值为: " + outField3);
            System.out.println("其外部类的 outField4 字段的值为: " + outField4);
        }
    }

    public static void main(String[] args) {
        InnerClassTest outerObj = new InnerClassTest();
        // 不在外部类内部,使用:外部类对象. new 内部类构造器(); 的方式创建内部类对象
//        InnerClassA innerObj = outerObj.new InnerClassA();
    }
}
-----------------------------------------------------------------
创建 InnerClassA 对象
其外部类的 outField1 字段的值为: 1
其外部类的 outField2 字段的值为: 2
其外部类的 outField3 字段的值为: 3
其外部类的 outField4 字段的值为: 4
创建 InnerClassTest 对象
其内部类的 field1 字段的值为: 5
其内部类的 field2 字段的值为: 6
其内部类的 field3 字段的值为: 7
其内部类的 field4 字段的值为: 8
  • 内部类对象可以访问外部类对象中所有访问权限的字段,同时,外部类对象也可以通过内部类的对象引用来访问内部类中定义的所有访问权限的字段

  • private修饰内部类

    如果我们的内部类不想轻易被任何人访问,可以选择使用private修饰内部类,这样我们就无法通过创建对象的方法来访问,想要访问只需要在外部类中定义一个public修饰的方法,间接调用。这样做的好处就是,我们可以在这个public方法中增加一些判断语句,起到数据安全的作用。

        class Outer {
            private class Inner {
                public void show() {
                    System.out.println("密码备份文件");
                }
            }
            //使用getXxx()获取成员内部类,可以增加校验语句(文中省略)
            public Inner getInner() {
                return new Inner();
            }
        }
        public static void main(String[] args) {
            Outer outer = new Outer();
            Outer.Inner inner = outer.getInner();
            inner.show();
        }
    

静态内部类

  • 这种被 static 所修饰的内部类,按位置分,属于成员内部类,但也可以称作静态内部类,也常叫做嵌套内部类.不能使用外部类的非static成员变量和成员方法
  • 一个类的静态成员独立于这个类的任何一个对象存在,只要在具有访问权限的地方,我们就可以通过 类名.静态成员名 的形式来访问这个静态成员,同样的,静态内部类也是作为一个外部类的静态成员而存在,创建一个类的静态内部类对象不需要依赖其外部类对象
public class InnerClassTest {
	public int field1 = 1;
    
	public InnerClassTest() {
		System.out.println("创建 " + this.getClass().getSimpleName() + " 对象");
        // 创建静态内部类对象
        StaticClass innerObj = new StaticClass();
        System.out.println("其内部类的 field1 字段的值为: " + innerObj.field1);
        System.out.println("其内部类的 field2 字段的值为: " + innerObj.field2);
        System.out.println("其内部类的 field3 字段的值为: " + innerObj.field3);
        System.out.println("其内部类的 field4 字段的值为: " + innerObj.field4);
    }
	
    static class StaticClass {

        public int field1 = 1;
        protected int field2 = 2;
        int field3 = 3;
        private int field4 = 4;
        // 静态内部类中可以定义 static 属性
        static int field5 = 5;

        public StaticClass() {
            System.out.println("创建 " + StaticClass.class.getSimpleName() + " 对象");
//            System.out.println("其外部类的 field1 字段的值为: " + field1); // 编译错误!!
        }
    }

    public static void main(String[] args) {
	    // 无需依赖外部类对象,直接创建内部类对象
//        InnerClassTest.StaticClass staticClassObj = new InnerClassTest.StaticClass();
		InnerClassTest outerObj = new InnerClassTest();
    }
}
-------------------------------------------------------
创建 InnerClassTest 对象
创建 StaticClass 对象
其内部类的 field1 字段的值为: 1
其内部类的 field2 字段的值为: 2
其内部类的 field3 字段的值为: 3
其内部类的 field4 字段的值为: 4

静态内部类就像外部类的一个静态成员一样,创建其对象无需依赖外部类对象(访问一个类的静态成员也无需依赖这个类的对象,因为它是独立于所有类的对象的)。但是于此同时,静态内部类中也无法访问外部类的非静态成员,因为外部类的非静态成员是属于每一个外部类对象的,而本身静态内部类就是独立外部类对象存在的,所以静态内部类不能访问外部类的非静态成员,而外部类依然可以访问静态内部类对象的所有访问权限的成员,这一点和普通内部类无异

局本内部类

局部内部类——就是定义在一个方法或者一个作用域里面的类

特点:主要是作用域发生了变化,只能在自身所在方法和属性中被使用

    class Outer {
        private int age = 20;

        public void method() {
            final int age2 = 30;
            class Inner {
                public void show() {
                    System.out.println(age); 
                    //从内部类中访问方法内变量age2,需要将变量声明为最终类型。
                    System.out.println(age2);
                }
            }
            Inner i = new Inner();
            i.show();

匿名内部类

    • 一个没有名字的类,是内部类的简化写法
    • 匿名内部类有多种形式,其中最常见的一种形式莫过于在方法参数中新建一个接口对象 / 类对象,并且实现这个接口声明 / 类中原有的方法了
    • 匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或者实现一个接口。
      两个规则:
      匿名内部类不能是抽象类。
      匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以初始化块,可以通过初始化块来完成构造器需要完成的工作。
public interface Inner {
    public abstract void show();
}

public class Outer {
    public void method(){
        new Inner(){     //不是new接口 , 是new实现接口的类
            @Override
            public void show() {
                System.out.println("Hello");
            }
        }.show();  
    }
}

public class Text {
    public static void main(String[] args) {
        Outer outer = new Outer();
        outer.method();
    }
}

匿名内部类适合创建那种只需要使用一次的类,也就是说创建一个匿名内部类,只需要用一次即可。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EnndmeRedis

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值