1 GUI的概念

  • GUI(Graphical User Interface)即图形用户界面,它能够使应用程序看上去更加友好,更加方便用户操作。

2 Swing概述

  • Swing是纯Java组件,使得应用程序在不同的平台上运行时具有相同外观和相同的行为;

  • Swing中的大部分组件类位于javax.swing包中;

  • Swing中的组件非常丰富,支持很多功能强大的组件。

3 容器组件

3.1 概述

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

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

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

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

3.2 常用容器

1.JFrame

  • 用于在Swing程序中创建窗体;

构造方法:

构造方法 说 明
JFrame() 创建新窗体,该窗体初始为不可见
JFrame(String title) 创建新窗体,使用参数title指定标题,该窗体初始为不可见

常用方法:

方 法 说 明
void setSize(int width, int height) 设置窗口大小
void setVisible(boolean b) 设置窗口是否显示,默认为不显示
void setTitle(String title) 设置窗口标题
void setResizable(boolean resizable) 是否可以设置窗口大小
void setLocation(int x,int y) 设置位置坐标(坐标以屏幕左上角为原点)
void setLocationRelativeTo(null) 设置窗口水平居中
void setDefaultCloseOperation(int operation) 关闭窗口选项
void dispose() 释放窗口

2.Jpanel

  • JPanel提供面板,它是轻量级的容器;

  • 面板中可以添加其它组件,也可以设置布局,我们一般使用面板来实现布局嵌套;

构造方法:

构造方法 说 明
JPanel() 创建一个空面板
JPanel(LayoutManaer layout) 创建带有指定布局的面板
  • 框架(JFrame) 内部包含一个名叫Container(内容面板)的面板容器,如果要给框架中添加图形控件,通常将它们加入到这个内容面板中;

  • 通过JFrame类中的getContentPane()方法即可获得此框架的内容面板;

  • 也可以自己创建Jpanel面板对象,把JPanel作为一个组件添加到某个容器中。

常用方法:

方 法 说 明
void setBackground(Color bg) 设置面板的背景色,由参数bg指定颜色
void setLayout(LayoutManager mgr) 设置面板的布局,参数是布局管理器
Component add(Component comp) 往面板中添加一个组件

案例:

import javax.swing.*;
import java.awt.*;
​
public class Demo1Frame extends JFrame {
​public Demo1Frame() throws HeadlessException {JFrame jFrame = new JFrame();/*this是当前对象,即窗口*/this.setTitle("窗口标题");//设置窗口标题this.setSize(500,500);//设置窗口大小//this.setLocation(200,500);//设置位置坐标(坐标以屏幕左上角为原点)this.setLocationRelativeTo(null);//设置窗口水平居中this.setResizable(false);//禁止设置窗口大小//this.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);//关闭窗口选项 (DO_NOTHING_ON_CLOSE关闭时什么都不做)
​//在窗口上添加面板(多个面板嵌套可以实现布局)JPanel jPanel = new JPanel();jPanel.setBackground(Color.PINK);//设置面板背景颜色//jPanel.setBackground(new Color(250, 120, 50));
​//默认是流式布局,组件居中JButton jButton = new JButton("按钮1");
​jPanel.add(jButton);//按钮添加到面板上this.add(jPanel);//面板添加到窗口上this.setVisible(true);//显示窗口,加到最后,让窗口显示}
​public static void main(String[] args) {new Demo1Frame();}
}

效果图:

4 布局管理器

  • swing中,提供了布局管理器类的对象可以管理

  • 每个Jpanel都有一个布局管理器对象,当容器需要对某个组件进行定位或判断其大小尺寸时,就会调用其对应的布局管理器,调用Jpanel的setLayout方法改变其布局管理器对象或通过构造方法设置。

  • Java中的图形界面在布局管理上采用容器和布局管理相分离的方案,也就是说容器只是把组件放进来,但它不管怎样放置。至于如何放置需要 用到布局管理器(Container)。

  • Java中有几种常用的布局管理器,分别是:

    • FlowLayout(流式布局)

    • BorderLayout(边界布局)

    • GridLayout(网格布局)

4.1 FlowLayout

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

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

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

构造方法:

构造方法 说 明
new FlowLayout(FlowLayout.RIGHT,20,40) 右对齐,组件之间水平间距20个像素,垂直间距40个像素
new FlowLayout(FlowLayout.LEFT) 左对齐,水平和垂直间距为缺省值(5)
new FlowLayout() 使用缺省的居中对齐方式,水平和垂直间距为缺省值(5)

案例:

import javax.swing.*;
import java.awt.*;
​
public class Demo2Frame extends JFrame {
​public Demo2Frame() throws HeadlessException {JFrame jFrame = new JFrame();/*this是当前对象,即窗口*/this.setTitle("流式布局示例");//设置窗口标题this.setSize(400,200);//设置窗口大小this.setLocationRelativeTo(null);//设置窗口水平居中this.setResizable(false);//禁止设置窗口大小
​/*JPanel默认是流式布局,组件居中对齐*///在窗口上添加面板,设置布局为流式布局//JPanel jPanel = new JPanel(new FlowLayout(FlowLayout.LEFT,20,10));//new FlowLayout(对齐方式,垂直距离,水平距离)JPanel jPanel = new JPanel(new FlowLayout());jPanel.setBackground(new Color(183, 227, 251));//设置面板背景颜色
​JButton jButton1 = new JButton("按钮1");JButton jButton2 = new JButton("按钮2");JButton jButton3 = new JButton("按钮3");JButton jButton4 = new JButton("按钮4");
​jPanel.add(jButton1);jPanel.add(jButton2);jPanel.add(jButton3);jPanel.add(jButton4);
​this.add(jPanel);//面板添加到窗口上this.setVisible(true);//显示窗口,加到最后,让窗口显示}
​public static void main(String[] args) {new Demo2Frame();}
}

效果:

4.2 BorderLayout

BorderLayout布局管理器只允许在容器内放置5个组件,这5个组件的位置是由BorderLayout类中的North、South、East、West和Center5个常量来确定的,他们对应着容器中的上下左右中。

  • 组件在BorderLayout中的大小都是可以改变的。

  • 一般情况下可以让中间区域大一些,而且可以只用其中几个区域。

  • BorderLayout将整个容器的布局划分成东(EAST)西(WEST)南(SOUTH)北(NORTH)中 (CENTER)五个区域,组件只能被添加到指定的区域,如不指定组件的加入部位,则默认加入到CENTER区,每个区域只能加入一个组件,如加入多个,则先前加入的会被覆盖。

  • BorderLayout型布局容器尺寸缩放原则: 北、南两个区域在水平方向缩放,东、西两个区域在垂直方向缩放,中部可在两个方向上缩放。

案例:

import javax.swing.*;
import java.awt.*;
​
public class Demo3Frame extends JFrame {
​public Demo3Frame() throws HeadlessException {JFrame jFrame = new JFrame();/*this是当前对象,即窗口*/this.setTitle("边界布局示例");//设置窗口标题this.setSize(400,200);//设置窗口大小this.setLocationRelativeTo(null);//设置窗口水平居中this.setResizable(false);//禁止设置窗口大小
​/*JPanel默认是流式布局*///在窗口上添加面板,设置布局为边界布局JPanel jPanel = new JPanel(new BorderLayout());jPanel.setBackground(new Color(183, 227, 251));
​JButton jButton1 = new JButton("按钮1");JButton jButton2 = new JButton("按钮2");JButton jButton3 = new JButton("按钮3");JButton jButton4 = new JButton("按钮4");JButton jButton5 = new JButton("按钮5");
​jPanel.add(jButton1,BorderLayout.EAST);jPanel.add(jButton2,BorderLayout.WEST);jPanel.add(jButton3,BorderLayout.SOUTH);jPanel.add(jButton4,BorderLayout.NORTH);jPanel.add(jButton5,BorderLayout.CENTER);
​this.add(jPanel);//面板添加到窗口上this.setVisible(true);//显示窗口,加到最后,让窗口显示}
​public static void main(String[] args) {new Demo3Frame();}
}

效果:

4.3 GridLayout

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

  • 当组件数目大于网格数时,GridLayout保持行数不变而自动增加列数。

  • GridLayout型布局管理器将空间划分成规则的矩形网格,每个单元格区域大小相等。组件被添加到每个单元格中,先从左到右添满一行后换行,再从上到下。

  • 在 GridLayout 构造方法中指定分割的行数和列数.

案例:

package com.ffyc.javagui.fream;
​
import javax.swing.*;
import java.awt.*;
​
public class Demo4Frame extends JFrame {
​public Demo4Frame() throws HeadlessException {JFrame jFrame = new JFrame();/*this是当前对象,即窗口*/this.setTitle("网格布局示例");//设置窗口标题this.setSize(400,200);//设置窗口大小this.setLocationRelativeTo(null);//设置窗口水平居中this.setResizable(false);//禁止设置窗口大小
​/*JPanel默认是流式布局,组件居中对齐*///在窗口上添加面板,设置布局为网格布局(三行两列)JPanel jPanel = new JPanel(new GridLayout(3,2));jPanel.setBackground(new Color(183, 227, 251));//设置面板背景颜色
​JButton jButton1 = new JButton("按钮1");JButton jButton2 = new JButton("按钮2");JButton jButton3 = new JButton("按钮3");JButton jButton4 = new JButton("按钮4");JButton jButton5 = new JButton("按钮5");JButton jButton6 = new JButton("按钮6");
​jPanel.add(jButton1);jPanel.add(jButton2);jPanel.add(jButton3);jPanel.add(jButton4);jPanel.add(jButton5);jPanel.add(jButton6);
​this.add(jPanel);//面板添加到窗口上this.setVisible(true);//显示窗口,加到最后,让窗口显示}
​public static void main(String[] args) {new Demo4Frame();}
}

效果:

5 常用组件

5.1 标签(JLabel)

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

构造函数:

构造方法 常用方法
JLabel() 创建一个空的标签
JLabel(String text) 创建一个带文本的标签
JLabel(Icon image) 创建一个带图像的标签

常用方法:

方 法 说 明
void setText(String text) 设置标签上的文本
String getText() 获得标签上的文本
setFont(new Font(“宋体”,Font.BOLD, 18)) 设置字体

5.2 单行文本(JTextField)

构造函数:

构造函数 说 明
JTextField() 创建一个空的单行文本
JTextField(String text ) 创建一个带文本的单行文本
JTextField(int columns) 创建一个指定列数的单行文本
JTextField(String text, int columns) 创建一个带文本的、指定列数的单行文本

常用方法:

方 法 说 明
void setText(String text) 设置文本框中的文本
String getText() 获得文本框中的文本
void setEditable(boolean b) 设置文本框是否可以编辑
setColumns(20) 设置列数

5.3 多行文本框(JTextArea)

构造函数:

构造函数 说 明
JTextArea() 创建一个空的文本域
JTextArea(String text) 用指定文本初始化文本域
JTextArea(int rows, int columns) 创建一个指定行数和列数的空文本域
JTextArea(String text,int rows, int columns) 创建一个带文本,并指行数和列数的

常用方法:

方 法 说 明
void setText(String text) 设置文本域中的文本
String getText() 获得文本域中的文本
void setFont(Font font) 设置文本域中文本的字体
void setLineWrap(boolean wrap) 是否自动换行,默认false

如果需要文本区自动出现滚动条,可将文本区对象放入滚动窗格(JScrollPane)中:

JScrollPane scrollPane = new JScrollPane(txtArea);
add(scrollPane );

案例:

import javax.swing.*;
import java.awt.*;
​
public class Demo7Frame extends JFrame{public Demo7Frame() throws HeadlessException {this.setTitle("多行文本示例");this.setSize(400, 250);//大小this.setLocationRelativeTo(null);//相对位置 水平垂直居中this.setResizable(false);//禁止设置窗口大小this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口选项/*JPanel默认是流式布局, 组件居中对齐*/JPanel  jp = new JPanel();
​JTextArea jt = new JTextArea(10,20);jt.setLineWrap(true);//强制换行jt.setWrapStyleWord(true);//有英文单词时用此方法换行JScrollPane jsp = new JScrollPane(jt);//创建一个滚动条
​jp.add(jsp);//this--窗口this.add(jp);this.setVisible(true);//显示窗口,最后让窗口显示}
​public static void main(String[] args) {new Demo7Frame();}
}

运行效果:

5.4 密码框(JPasswordField)

构造函数:

构造方法 说 明
JPasswordField() 创建一个空的密码框
JPasswordField(String text) 创建一个密码框并设置其初始字符串
JPasswordField(String text, int columns) 创建一个新的密码框并为其设置初始字符和字段长度

方法:

方 法 说 明
char[] getPassword() 获取密码框的内容

5.4 按钮(JButton)

构造方法:

构造方法 说 明
JButton(String text) 创建一个带文本的标签
JButton(Icon image) 创建一个带图像的标签

方法:

方 法 说 明
void setBackground(Color bg) 设置按钮的背景色
void setEnabled(boolean b) 设置启用(或禁用)按钮,由参数b决定
void setToolTipText(String text) 设置按钮的悬停提示信息

5.5 菜单栏组件:

构造方法:JMenuBar();

方法:add(menu); 向菜单栏添加菜单

5.6 菜单组件:

构造方法:JMenu(“菜单名称");

方法:add(menuItem); 向菜单添加菜单选项

5.7 菜单项组件:

构造方法:JMenuItem(“菜单项名称");

将菜单栏添加到窗口:

setJMenuBar(menuBar);

案例:

import javax.swing.*;
import java.awt.*;
​
public class Demo8Frame extends JFrame{public Demo8Frame() throws HeadlessException {this.setTitle("窗口标题");this.setSize(500, 200);//大小this.setLocationRelativeTo(null);//相对位置 水平垂直居中this.setResizable(false);//禁止设置窗口大小this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口选项
​JPanel  jp = new JPanel();/*菜单有三部分构成,菜单栏 ,菜单,菜单项*///菜单栏JMenuBar jMenuBar = new JMenuBar();//菜单JMenu jMenu1 = new JMenu("文件");//菜单项JMenuItem ji1 = new JMenuItem("新建");JMenuItem ji2 = new JMenuItem("保存");JMenuItem ji3 = new JMenuItem("打开");JMenuItem ji4 = new JMenuItem("分享");jMenu1.add(ji1);jMenu1.add(ji2);jMenu1.add(ji3);jMenu1.add(ji4);//菜单JMenu jMenu2 = new JMenu("编辑");//菜单项JMenuItem ji5 = new JMenuItem("剪切");JMenuItem ji6 = new JMenuItem("复制");jMenu2.add(ji5);jMenu2.add(ji6);//菜单JMenu jMenu3 = new JMenu("帮助");//菜单项JMenuItem ji7 = new JMenuItem("关于");jMenu3.add(ji7);
​
​jMenuBar.add(jMenu1);jMenuBar.add(jMenu2);jMenuBar.add(jMenu3);this.setJMenuBar(jMenuBar);//添加菜单栏this.add(jp);this.setVisible(true);//显示窗口,最后让窗口显示}
​public static void main(String[] args) {new Demo8Frame();}
}

效果:

6 事件处理

  • 对于采用了图形用户界面的程序来说,事件控制是非常重要的,到目前为止,我们编写的图形用户界面程序都仅仅只是完成了界面,而没有任何实际的功能,要实现相应的功能,必须进行事件处理;

  • 用户与GUI组件进行交互就会发生事件;

    • 如:按下一个按钮、用键盘输入一个字符、点击鼠标等等;

  • 当前我们要关注的并不是“事件是如何产生的”,而是讨论当发生事件后,我们应当“如何处理之”。

Java中,事件处理的基本思路:

  • 一个源(事件源)产生一个事件(事件对象)并把它送到监听器那里,监听器只是简单地等待,直到它收到一个事件,一旦事件被接受,监听器将处理这些事件;

  • 一个事件源必须注册监听器以便监听器可以接受关于一个特定事件的通知。

案例:

  • 由于我们想要处理按钮的点击事件,因此,按钮便是事件源;

  • 监听器类型是ActionListener。

添加事件监听器(此处即为匿名内部类) :

按钮对象.addActionListener(new ActionListener() { // 事件处理
@Override
public void actionPerformed(ActionEvent e) { //执行操作 }
});

案例:

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/*定义了一个外部类,虽然也可以用,但是它只能拿到事件源的信息,访问不到别的信息所以定义外部类实现接口的方式不可取,这个时候我们就要使用内部类*/
public class MyAction  implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("被点击了");}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
​
public class Demo9Frame extends JFrame{
​JTextField accountText;
​public Demo9Frame() throws HeadlessException {this.setTitle("窗口标题");this.setSize(500, 500);//大小//this.setLocation(300, 500);//位置坐标this.setLocationRelativeTo(null);//相对位置 水平垂直居中this.setResizable(false);//禁止设置窗口大小this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭窗口选项
​JPanel  jp = new JPanel();JLabel label = new JLabel("账号");label.setForeground(Color.blue);label.setFont(new Font("楷体", Font.BOLD,20));
​accountText = new JTextField(15);
​JButton jb = new JButton("登录");jp.add(label);jp.add(accountText);jp.add(jb);
​//this--窗口this.add(jp);this.setVisible(true);//显示窗口,最后让窗口显示
​
​//为登录按钮注册时间监听器  创建ActionListener的匿名内部类对象/*jb.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println(accountText.getText());}});*//* MouseListener是一个接口(public interface MouseListener extends EventListener {}),里边的方法都是抽象方法,所以在实现的时候需要重写里边所有的方法,为了解决这个不足,java提供了一个抽象类MouseAdapter,实现了MouseListener接口中的抽象方法,所以我们就可以直接用MouseAdapter这个实现类,就不用重写所有的方法,只重写我们需要的就可以了。
​*//*jb.addMouseListener(new MouseListener() {@Overridepublic void mouseClicked(MouseEvent e) {System.out.println("鼠标点击,按下释放");}
​@Overridepublic void mousePressed(MouseEvent e) {System.out.println("鼠标按下");}
​@Overridepublic void mouseReleased(MouseEvent e) {System.out.println("鼠标释放");}
​@Overridepublic void mouseEntered(MouseEvent e) {System.out.println("鼠标移入");}
​@Overridepublic void mouseExited(MouseEvent e) {System.out.println("鼠标移出");}});*//*  jb.addMouseListener(new MouseAdapter() {@Overridepublic void mouseClicked(MouseEvent e) {System.out.println("鼠标点击");}});*///同理,键盘事件监听处理中也有对应的实现类accountText.addKeyListener(new KeyAdapter() {@Overridepublic void keyReleased(KeyEvent e) {System.out.println(accountText.getText());System.out.println(e.getKeyChar()+":"+e.getKeyCode());}});/*为了简化内部类的定义,可以使用匿名内部类方式简化语法,只使用一次*/accountText.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {
​}});
​//jb.addActionListener(new MyAction());
​}
​//将只在本类中使用的功能,定义在内部类中,实现封装,在哪儿使用,new 内部类即可/*class MyAction  implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println("被点击了");System.out.println(accountText.getText());//使用外部类的成员}}*/
​public static void main(String[] args) {new Demo9Frame();}
}

7 对话框

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 确定/取消
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
​
public class Demo10Frame extends JFrame{
​public Demo10Frame() throws HeadlessException {this.setTitle("欢迎登陆");this.setSize(450,270);this.setLocationRelativeTo(null);//设置窗口水平居中this.setResizable(false);//禁止设置窗口大小this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//创建面板,网格布局(三行一列)JPanel jPanel = new JPanel(new GridLayout(3,1));
​//面板布局,流式布局JPanel accountPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,10,35));JPanel passwordPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,10,35));JPanel btnPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,10,20));
​JLabel accountLable = new JLabel("管理员");accountLable.setForeground(Color.black);accountLable.setFont(new Font("黑体", Font.CENTER_BASELINE, 20));JLabel passwordLable = new JLabel("密  码");passwordLable.setForeground(Color.black);passwordLable.setFont(new Font("黑体", Font.CENTER_BASELINE, 20));JTextField accountText = new JTextField(20);JPasswordField passwordField = new JPasswordField(20);
​JButton loginBtn = new JButton("登陆");JButton cancelBtn = new JButton("取消");cancelBtn.setToolTipText("点击退出");
​accountPanel.add(accountLable);accountPanel.add(accountText);passwordPanel.add(passwordLable);passwordPanel.add(passwordField);btnPanel.add(loginBtn);btnPanel.add(cancelBtn);
​jPanel.add(accountPanel);jPanel.add(passwordPanel);jPanel.add(btnPanel);
​this.add(jPanel);this.setVisible(true);//显示窗口/*事件处理*///给取消按钮添加事件处理loginBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {String account = accountText.getText();if(account.length()>10){//JOptionPane.showMessageDialog(null, "账号不能大于10位字符!");JOptionPane.showMessageDialog(null, "账号不能大于10位字符!","登录提示",JOptionPane.QUESTION_MESSAGE);return;//因为此方法没有返回值,return只是让程序终止,不继续往下走}}});//给登录按钮添加事件处理cancelBtn.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {int res = JOptionPane.showConfirmDialog(null, "您确定要退出吗?", "操作提示", JOptionPane.OK_CANCEL_OPTION);System.out.println(res);//取消为2 确定为0if(res==0){/*此处不能使用this.dispose,因为此处的this指的不是窗口,而是匿名内部类的对象可以直接使用dispose(),因为这个匿名内部类中没有dispose这个方法,所以它就会向上找,找上一级窗口对象中的dispo()*/dispose();//释放当前窗口}return;}});}public static void main(String[] args) {new Demo10Frame();}
}

效果:

8 内部类

8.1 什么是内部类

● 把类定义在另一个类的内部,该类就被称为内部类。

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

//外部类
public class Outer{//内部类public class Inner{}}

8.2 内部类的分类

  • 成员内部类、静态内部类、局部内部类、匿名内部类

1.成员内部类

  • 就是位于外部类成员位置的类

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

public class Outer {
​private int num = 10;
​public void eat(){new Inner();//一般在本类中使用内部类}/*在一个类的内部定义的类称为内部类*///成员内部类public class Inner{public void test(){System.out.println(num);//内部类中可以直接使用外部类的成员,即使是私有属性也可以访问到}}
}

private修饰内部类

  • 如果我们的内部类不想轻易被任何人访问,可以选择使用private修饰内部类,这样我们就无法通过创建对象的方法来访问,想要访问只需要在外部类中定义一个public修饰的方法,间接调用。

    • 优点:可以在这个public方法中增加一些判断语句,起到数据安全的作用。

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

2.静态内部类

  • 被 static 所修饰的内部类,按位置分,属于成员内部类,但也可以称作静态内部类,也常叫做嵌套内部类,不能使用外部类的非static成员变量和成员方法 。

public class Outer {
​private  static int  num = 10;
​public void eat(){new Inner();//一般在本类中使用内部类}/*静态内部类, 只能方访问外部类中静态成员,因为非静态的在创建对象的时候才存在,类加载的时候不存在。*/static class Inner{public  void test(){System.out.println(num);}}
}

3.局部内部类

  • 定义在一个方法或者一个作用域里面的类

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

class Outer{private int age1 = 12;public void method(){final int age2 = 21;class Inner{public void show(){System.out.println(age1);//从内部类中访问变量age2,需要将变量声明为最终类型System.out.println(age2);}}}
}

4.匿名内部类

  • 一个没有名字的类,是内部类的简化写法

/*内部类:将只在本类中使用的功能,定义在内部类中,实现封装,在哪儿使用,new 内部类即可
*/
class MyAction  implements ActionListener {@Overridepublic void actionPerformed(ActionEvent e) {System.out.println(accountText.getText());//使用外部类的成员}
}
/*匿名内部类:为了简化内部类的定义,可以使用匿名内部类方式简化语法,只使用一次
*/
accountText.addActionListener(new ActionListener() {@Overridepublic void actionPerformed(ActionEvent e) {
​}
});

内部类的特点:

  • 内部类是一个独立的类,在编译之后内部类会被编译成独立的.class文件,前面冠以外部类的类名和$符号。

  • 内部类不能用普通的方式访问,内部类是外部类的一个成员,所以内部类可以自由地访问外部类的成员变量,无论是否为 private 的都可以访问到。

  • 如果将内部类声明成静态的,就不能随便访问外部类的成员变量,只能访问外部类的静态成员变量。

案例:

public class Car {
​private int num;private String name;
​public Car(int num, String name) {this.num = num;this.name = name;}
​public int getNum() {return num;}
​public void setNum(int num) {this.num = num;}
​public String getName() {return name;}
​public void setName(String name) {this.name = name;}
​@Overridepublic String toString() {return "Car{" +"num=" + num +", name='" + name + '\'' +'}';}
}
import java.util.Comparator;
//为Car类开发的排序比较类
public class CarComparator implements Comparator<Car> {@Overridepublic int compare(Car o1, Car o2) {return o1.getNum()-o2.getNum();}
}
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
​
public class TestCar {
​public static void main(String[] args) {Car car1 = new Car(101, "car1");Car car2 = new Car(102, "car2");Car car3 = new Car(103, "car3");Car car4 = new Car(104, "car4");
​Car [] cars = {car2,car1,car4,car3};
​//Arrays.sort(cars,new CarComparator());Arrays.sort(cars, new Comparator<Car>() {@Overridepublic int compare(Car o1, Car o2) {return o1.getNum()-o2.getNum();}});Arrays.sort(cars,(o1,o2)->{return o1.getNum()-o2.getNum();});
​System.out.println(Arrays.toString(cars));
​ArrayList<Car> carArrayList = new ArrayList<>();carArrayList.add(car2);carArrayList.add(car1);carArrayList.add(car4);carArrayList.add(car3);
​carArrayList.sort(new Comparator<Car>() {@Overridepublic int compare(Car o1, Car o2) {return o1.getNum()-o2.getNum();}});}
}

8.3 内部类的意义

  • 封装性,将一些操作隐藏起来,外界不知道,间接实现多继承

1.封装性

  • 作为一个类的编写者,我们需要对这个类的访问者的访问权限做出一定的限制,将一些我们不愿意让别人看到的操作隐藏起来。

2.实现多继承

/*Son继承Mother,Mother继承Father,从设计上显然是讲不通的,这个时候我们可以在Son类中写两个内部类分别继承Mother、father*/
public class Father {public String powerFul = "市长";
}
public class Mother {public String wealthy = "一百万";
}
public class Son {class Extends_Father extends Father{}class Extends_Mother extends Mother{}public void sayHello(){String father = new Extends_Father().powerFul;String mother = new Extends_Mother().wealthy;System.out.println("my father is:"+father+"my mother is:"+mother);}
}

GUI编程(java)相关推荐

  1. Java基础学习总结(23)——GUI编程

    2019独角兽企业重金招聘Python工程师标准>>> 一.AWT介绍 所有的可以显示出来的图形元素都称为Component,Component代表了所有的可见的图形元素,Compo ...

  2. 9.JAVA之GUI编程列出指定目录内容

    代码如下: /*列出指定目录内容*/ import java.awt.Button; import java.awt.FlowLayout; import java.awt.Frame; import ...

  3. Java华丽转身 —— GUI编程宝典

    GUI,Graphics User Interface,图形用户界面.GUI直观的将计算机的功能呈现给用户,图形界面在视觉上更容易接受.更简单直观. GUI需要操作系统和硬件的支持.因此,GUI编程往 ...

  4. 13.JAVA之GUI编程将程序打包jar

    jar基本命令: 目标:将下列MyMenuDemo.java代码打包成jar. 方法如下: 1.把java代码放到d:\myclass目录下. 2.按下快捷键ctrl+r,打开运行窗口,输入cmd后回 ...

  5. 4.JAVA之GUI编程事件监听机制

    事件监听机制的特点: 1.事件源 2.事件 3.监听器 4.事件处理 事件源:就是awt包或者swing包中的那些图形用户界面组件.(如:按钮) 事件:每一个事件源都有自己特点有的对应事件和共性事件. ...

  6. java 对话框计算器,《Java程序设计》第16周礼拜四:GUI编程及文件对话框的使用 计算器...

    <Java程序设计>第16周周四:GUI编程及文件对话框的使用 计算器 项目三:实验六 图形用户界面(教材P279-280) 目标:完成实验六的内容. 运行代码 import java.a ...

  7. The package javax.swing is not accessible(java GUI 编程时引用swing包和awt包时会报错怎么办)

    Java GUI 编程时引用swing包和awt包时会报错怎么办 一.环境与错误现象 使用的编译器为eclipse,情况为: 二.解决方法 问题主要是由工程中的module-info.java这个文件 ...

  8. Java基础知识学完了,还在看着控制台上输出的结果发呆吗?还不来认识认识GUI编程(初识GUI)

    初识GUI 日常的控制台显示几句话或一串数字,表示已经看厌倦.目前所学内容完全不能满足个人需求,为了能有个看起来不错的界面,开始学习GUI编程,冲冲冲!!! 定义:图形用户界面(Graphical U ...

  9. java gui是什么_Java GUI编程(一)

    ********************第16章 GUI编程 ************************** 一.什么是GUI GUI= Graphical User Interface 图形用 ...

最新文章

  1. 教你如何防范远程桌面协议(RDP)的安全威胁
  2. R语言双因素方差分析
  3. java 使用new新建一个对象时的操作过程
  4. LeetCode 139. 单词拆分(DP)
  5. 从分布式一致性谈到CAP理论、BASE理论
  6. Flutter Listener 监听手指的滑动方向、监听手指上下滑动
  7. 解读 SSDB、LevelDB 和 RocksDB 到 GaussDB(for Redis) 的迁移
  8. Python使用Plotly绘图工具,绘制面积图
  9. JVM常用新生代垃圾收集器
  10. [2019杭电多校第一场][hdu6579]Operation(线性基)
  11. Tensorflow中训练得到Nan错误的分析
  12. C语言equivalent用法,C语言相当于'setw'函数
  13. 智齿科技宣布完成1亿美元D轮融资,暂未取得有效专利
  14. ORACLE学习笔记-CentOS 7.2 Oracle 12C R2安装部署
  15. Windows 11系统如何将“此电脑”显示在桌面?
  16. 《MySQL DBA修炼之道》——1.3 查询执行过程概述
  17. 景联文科技:手势识别如何在自动驾驶中应用,一文告诉你答案
  18. 《新闻联播》报道百度山西数据标注基地 培育新业态打开新就业空间
  19. tkMapper 简记
  20. ijkplayer 音频解码线程

热门文章

  1. ceph---luminous版的安装
  2. 如何免费下载文献(无需翻墙)
  3. Facebook在美上线相亲功能,微软AI成为麻将冠军!...|一周热闻回顾
  4. laravel excel导入导出box/spout
  5. python顺序结构例题_python的顺序结构、选择结构、循环结构的练习代码
  6. rx6700xt相当于什么n卡
  7. Win11和Win10怎么禁用驱动程序强制签名? 关闭Windows系统驱动强制签名的技巧?
  8. 智能机器人为什么连接不上服务器,战争机器人无法连接服务器是什么原因
  9. win7计算机管理找不到文件夹,Win7文件夹选项不见了如何解决?
  10. 成语学习微信小程序源码