Java 编程入门(下)

Swing | 多线程 | 网络通信 | 数据库

Posted by Paradise on April 26, 2021

教材链接:https://book.douban.com/subject/11534743/

示例代码:https://pan.baidu.com/s/1EQW8Ijyqvak0vxscaMfjtg | 提取码:k3q4

第十三章 Swing程序设计

Swing的使用很复杂,本章只掌握基础的容器、组件和窗体布局等。本章包括:了解Swing组件、掌握常用窗体、掌握在标签上设置图标、掌握应用程序中的布局管理器、掌握常用面板、掌握按钮组件、掌握列表组件、掌握文本组件。

13.1 Swing概述

Swing是GUI(Graphic User Interface)开发工具包,在AWT的基础上,使开发跨平台的Java应用程序成为可能。早期的AWT组件一定程度上依赖于平台。Swing并不能完全替代AWT,开发Swing程序时通常需要借助AWT的一些对象。

13.2 Swing常用窗体

Swing窗体就是Swing的一个组件,是创建GUI的容器,用来装载组件。

  • 13.2.1 JFrame框架窗体
    • 开发程序时可以通过继承javax.swing.JFrame类创建一个窗体,在其中添加组件,同时为组件设置事件。由于继承了JFrame类,它拥有一些最大化、最小化和关闭的按钮。
    • 语法格式:
      • JFrame jf = new JFrame(title);
      • Container container = jf.getContentPane();
    • 示例:创建Example_01类。
  • 13.2.2 JDialog窗体
    • JDialog窗体是Swing组件中的对话框,继承了AWT组件中的java.awt.Dialog类。功能是从一个窗体弹出另一个窗体,例如对话框。JDialog类在使用时与JFrame类似。
    • 创建JDialog窗体需要实例化JDialog类,通常使用以下构造方法:
      • public JDialog(); 创建一个没有标题和父窗体的对话框
      • public JDialog(Frame f); 有父窗体
      • public JDialog(Frame f, boolean model); 有父窗体且指定类型
      • public JDialog(Frame f, String title); 有标题和父窗体
      • public JDialog(Frame f, String title, boolean model); 全都有
    • 示例:创建MyJDialog类与MyFrame类。
  • 13.2.3 范例:设置窗口大小,创建Example_02类。
  • 13.2.4 范例:禁止改变窗口大小,创建Example_03类。

13.3 标签组件与图标

  • 13.3.1 标签的使用
    • 标签由JLabel定义,它的父类为JComponent类。标签可以显示一行只读文本、一个图像或带图像的文本,它不会产生任何类型的事件。
    • JLabel类常用的构造方法:
      • public JLabel(); 创建一个只有文本的JLabel对象
      • public JLabel(Icon icon); 创建一个带图标的JLabel对象
      • public JLabel(Icon icon, int alignment); 带图标且可设置水平对齐方式
      • public Jlabel(String text, int alignment); 可设置水平对齐方式的文本
      • public JLabel(String text, Icon icon, int alignment); 都有
  • 13.3.2 图标的使用
    • Swing中的图标可以放在按钮、标签等控件上,用于提示组件的用途。支持使用图片文件,也可使用java.awt.Graphics类的方法来创建。
    • 通过使用Icon接口创建图标,使用时必须实现Icon接口的以下方法:
      • public int getIconHeight()
      • public int getIconWidth()
      • public void paintIcon(Component arg0, Graphics arg1, int arg2, int arg3)
    • 示例:创建Example_03类,实现自定义的图标。
    • 除了直接绘制,还可以使用某个图片来创建,支持多种图片格式。Swing利用 javax.swing.ImageIcon 类根据现有图片创建图标,ImageIcon类实现了Icon接口。
    • ImageIcon类常用构造方法:
      • public ImageIcon(); 创建一个通用的ImageIcon对象,使用时再具体设置
      • public ImageIcon(Image image); 直接从源图片创建图标
      • public ImageIcon(Image image, String description); 带有描述信息
      • public ImageIcon(URL url); 用网络位置上的图片创建图标
    • 示例:创建Example_04类,实现自定义的图标。
  • 13.3.3 范例:为图片添加说明,创建Example_05类。

13.4 常用布局管理器

管理组件在容器中的布局(位置和大小),Swing提供了常用的布局管理器。 包括:流布局管理器、边界布局管理器、网格布局管理器等。

  • 13.4.1 绝对布局
    • 在Swing中,除了使用布局管理器也可以使用绝对布局,即硬性地指定组件在容器中的位置和大小,可以使用坐标的方式指定组件的位置。
    • 使用绝对布局的步骤如下:
        1. 使用Container.setLayout(null)方法取消布局管理器;
        1. 使用Component.setBounds()方法设置组件的位置和大小。
    • 示例:创建Example_06类。
  • 13.4.2 流布局管理器
    • 流布局(FlowLayout)管理器是最基本的布局管理器,顾名思义,就是从左到右,从上到下地摆放组件(先行后列),知道占据所有的空间。默认组件在每一行上都是居中显示的。
    • FlowLayout类中常用的构造方法:
      • public FlowLayout()
      • public FlowLayout(int alignment)
      • public FlowLayout(int alignment, int horizGap, int vertGap) //三个参数分别指定对齐方式、水平间隔、垂直间隔。
    • 示例:创建Example_07类。
  • 13.4.3 边界布局管理器
    • 在不指定窗体布局的情况下,默认使用边界(BorderLayout)布局管理器。
    • 边界布局管理器可以将容器划分为东西南北中5个区域,可以在调用Container类的add方法时指定添加的区域。具体方式为,在add的参数中加入以下BorderLayout类中的成员变量:BorderLayout.NORTH, BorderLayout.SOUTH, …, BorderLayout.CENTER
    • 示例:创建Example_08类。
  • 13.4.4 网格布局管理器
    • 网格布局(GridLayout)管理器将容器划分为网格,将组件按行和列排列
    • 在网格布局管理器中每一组件的大小相同,组件按从左到右、从上到下的顺序加入网格,并且每一组件会填满整个网格。
    • 网格布局管理器主要有两个构造方法:
      • public GridLayout(int rows, int columns)
      • public GridLayout(int rows, int columns, int horizGap, int vertGap)
    • 示例:创建Example_09类。

13.5 常用面板

面板也是一个Swing容器,它可以容纳其他组件,但它也必须添加到Container中。Swing中的常用面板包括JPanel和JScrollPane。

  • 13.5.1 JPanel面板
    • JPanel可以聚集一些组件来实现布局,它也继承自java.awt.Container类
    • 示例:创建Example_10类。
  • 13.5.2 JScrollPane面板
    • 在设置界面中,可能出现在较小的容器中显示一个较大的内容的情况,这时候需要用到滚动面板。但是JScrollPane只能放置一个组件,不可以使用布局管理器。如果需要管理布局,可以将JPanel面板作为一个整体组件添加到JScrollPane面板上。
    • 示例:创建Example_11类。

13.6 按钮组件

按钮用于触发特定动作,Swing中的按钮包括提交按钮、复选框、单选按钮等。这些类都是从AbstractButton类继承来的。

  • 13.6.1 提交按钮组件
    • Swing中的提交按钮组件由JButton对象表示,其构造方法如下:
      • public JButton()
      • public JButton(String text)
      • public JButton(Icon icon)
      • public JButton(String text, Icon icon)
    • 示例:创建Example_12类。
  • 13.6.2 单选按钮组件
    • 在默认情况下,单选按钮(JRadioButton)显示一个圆形图标,并且通常在图标旁边放置说明性文字。在应用程序中,一般将多个单选按钮放置在按钮组中,当用户选中其中一个,其他按钮会被自动取消。
    • JRadioButton类是JToggleButton的子类,而JToggleButton类又AbstractButton类的子类。
    • JRadioButton类的常用构造方法:
      • public JRadioButton()
      • public JRadioButton(Icon icon)
      • public JRadioButton(Icon icon, boolean selected)
      • public JRadioButton(String text)
      • public JRadioButton(String text, Icon icon)
      • public JRadioButton(String text, Icon icon, boolean selected)
    • Swing中存在一个ButtonGroup类用于产生按钮组,通过该类的add方法向按钮组中添加单选按钮组件
    • 示例:创建Example_13类。
  • 13.6.3 复选框组件
    • 复选框(JCheckBox)具有一个方块图标,外加一段描述性文字。复选框中的每个框都提供选中和不选中两种状态。JCheckBox同样继承自AbstractButton类。
    • JCheckBox类常用构造方法:
      • public JCheckBox()
      • public JCheckBox(Icon icon, boolean checked)
      • public JCheckBox(String text, boolean checked)
    • 示例:创建Example_14类。

13.7 列表组件

  • 13.7.1 下拉列表框组件
    • Swing中列表框使用JComboBox类对象表示,它是javax.swing.JComponent类的子类。常用构造方法如下:
      • public JComboBox()
      • public JComboBox(ComboBoxModel dataModel)
      • public JComboBox(Object[] arrayData)
      • public JComboBox(Vector vector)
    • 在开发程序中,通常将下拉列表框中的内容封装为ComboBoxModel,它是一个接口,代表一般模型。可以自定义一个类实现该接口,然后在初始化JComboBox对象时向上转型为ComboBoxModel接口类型,必须实现以下两个方法:
      • public void setSelectedItem(Object item)
      • public Object getSelectedItem()
    • ComboBoxModel:在开发程序中,将下拉列表框中的项目封装为ComboBoxModel的情况较多。ComboBoxModel为接口,代表一般模型,可以自定义一个类实现该接口,然后在初始化JComboBox对象时向上转型为ComboBoxModel接口类型。但是,必须实现以下两个方法:
      • public void setSelectedItem(Object Item); //设置下拉列表的选中项
      • public Object getSelectedItem(); //返回选中项
    • 自定义的这个类除了实现了ComboBoxModel接口之外,还继承了AbstractListModel类,在该类中也有两个操作下拉列表的重要方法:
      • getSize(); //返回列表长度
      • getElementAt(int index); //返回指定索引处的值
    • 示例:创建Example_15类。
  • 13.7.2 列表框组件
    • 列表框(JList)与下拉列表框的区别不仅表现在外观上,当激活下拉列表框时,会出现下拉列表框中的内容,但列表框只是在窗体上占据固定的大小如果要是列表框具有滚动效果,可以将列表框放入滚动面板中。并且可以按住shift进行多选。
    • 具体使用:略;
    • 示例:略。

13.8 文本组件

  • 文本框(JTextField)
  • 密码框(JpasswordField)
  • 文本域(JTextArea)

第十四章 高级事件处理

学会处理键盘事件、鼠标事件、窗体焦点变化、窗体状态变化事件、选项事件、表格模型事件

14.1 Swing概述

  • 当向文本框中输入内容时,将发出键盘事件(KeyEvent)。KeyEvent类负责捕获键盘事件,可以通过为组件添加实现了KeyEvent接口的监听器来处理键盘事件。
  • KeyListener接口共有3各抽象方法,分别在击键事件、按键按下和释放时触发。
  • KetListener接口的具体定义如下:
    1
    2
    3
    4
    5
    
      public interface KeyListener extends EventListener{
          public void keyTyped(KeyEvent e);    //击键
          public void keyPressed(KeyEvent e);    //按键
          public void keyReleased(KeyEvent e);    //释放
      }
    
  • 每个抽象方法中均传入了KeyEvent类的对象,KeyEvent类常用方法有:
    • getSource(); 获取触发此次事件的组件对象,返回Object类
    • getKeyChar(); 获取与此次事件相关的按键字符
    • getKeyCode(); 获取与此次事件相关的按键数字
    • getKeyText(int keyCode); 获取描述keyCode的标签,如A、F1、HOME等
    • isActionKey(); 查看事件中的键是否为“动作”键
    • isControlDown(); 是否同时按下Ctrl键
    • isAltDown(); 是否同时按下Alt
    • isShiftDown(); 是否同时按下Shift

14.2 鼠标事件

  • MouseEvent类负责捕捉鼠标事件,可以通过为组件添加实现了MouseListener接口的监听器来处理相应的鼠标事件。
  • MouseListener接口共有5各抽象方法:
    1
    2
    3
    4
    5
    6
    7
    
      public interface MouseListener extends EventListener{
          public void mouseEntered(MouseEvent e);    //鼠标移入组件
          public void mousePressed(MouseEvent e);    //鼠标按键被按下
          public void mouseReleased(MouseEvent e);    //按键释放
          public void mouseClicked(MouseEvent e);    //单击事件
          public void mouseExited(MouseEvent e);    //光标移出组件
      }
    

14.3 窗体事件

在捕获窗体事件(WindowEvent)时,可以通过3个事件监听器接口来实现,分别是WindowFocusListener/WindowStateListener和WindowListener。

  • 14.3.1 捕获窗体焦点变化事件
    1
    2
    3
    4
    
      public interface WindowFocusListener extends EventListener{
          public void windowGainedFocus(WindowEvent e);
          public void windowLostFocus(WindowEvent e);
      }
    
  • 14.3.2 捕获窗体状态变化事件
    1
    2
    3
    
      public interface windowStateListener extends EventListener{
          public void windowStateChanged(WindowEvent e);
      }
    
  • 14.3.3 捕获其他窗体事件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
      public void WindowListener extends EventListener{
          public void windowActivated(WindowEvent e);
          public void windowOpened(WindowEvent e);
          public void windowIconified(WindowEvent e);
          public void windowDeiconified(WindowEvent e);
          public void windowClosing(WindowEvent e);
          public void windowDeactivated(WindowEvent e);
          public void windowClosed(WindowEvent e);
      }
    
      // 示例:创建WindowListener_Example类。
    

14.4 选项事件

当修改下拉菜单中的选中项时,将发出选项事件ItemEvent。ItemEvent类负责捕获选项事件,可以通过为组件添加实现了ItemListener接口的监听器类来处理相应的选项事件。

14.5 表格模型事件

  • 当向表格模型中添加行时,或者是修改或删除表格模型中的现有行时,将发出表格模型事件TableModelEvent。TableModelEvent类负责捕获表格模型事件,可以通过为组件添加实现了TableModelListener接口的监听器来处理相应的表格模型事件。
  • TableModelListener只有一个抽象方法,对表格模型进行增删改时触发:
    1
    2
    3
    
      public interface TableModelListener extends java.util.EventListener{
          public void tableChanged(TableModelEvent e);
      }
    
  • 在上述抽象方法中传入了TableModelEvent类的对象,该类有以下常用方法:
    • getType(); 获取事件类型
    • getFirstRow(); 获得触发此次事件的表格行的最小索引值
    • getLastRow(); 获取最后相关行的索引值
    • getColumn(); 如果事件类型是UPDATE,获取相关的列索引,否则返回-1
  • 示例:创建TableModelEvent_Example类。

第十五章 多线程

多线程机制:程序同时完成多件事情。

多线程应用十分广泛,可以创建窗口程序,网络程序等。

本章内容:了解多线程在Window操作系统中的执行模式、掌握实现多线程的两种方式、掌握线程的状态、掌握使用线程进入各种状态的方法、掌握线程的优先级、掌握线程的安全、掌握线程同步机制、掌握线程之间的通信。

15.1 线程简介

  • Java中的多线程在不同操作系统中的运行方式存在差异,这里主要介绍Windows系统的情况。
  • Windows系统是多任务操作系统,它以进程为单位。一个进程是一个包含自身地址的程序,每个独立执行的程序都可以称为进程。系统分配给每个进程一段有限的使用CPU的时间,称为CPU时间片。由于CPU执行速度快,时间片短,使得每个进程看起来像是同时执行。
  • 线程:一个线程则是进程中的执行流程,一个进程中可以同时包含多个线程,每个线程也分配一小段执行时间,这样一个进程就可以具有多个并发执行的线程。在程序代码中,多线程理解为一个进程同时完成多段代码的操作。

15.2 在Java中实现多线程的两种方式

在Java中提供两种方式实现多线程,分别是继承java.lang.Thread类和实现 java.lang.Runnable接口。

  • 15.2.1 继承Thread类
    • Thread类实例化的对象代表线程,新建一个Thread实例即可启动一个新的线程。两个常用构造方法如下:
      • public Thread(String threadName)
      • public Thread()
    • 继承Thread类创建一个新的线程的语法格式如下:
      • public class ThreadTest extends Thread{
      •         // ...
      • }
    • 完成线程真正功能的代码放在run()方法中。继承Thread类后覆盖重写run方法,然后同时调用Thread类中的start()方法启动线程。
      • public void run(){
      •         // ...
      • }
    • 当执行一个线程程序时,就自动产生一个线程,主方法正是在这个线程上运行的。如果不在启动其他线程,该程序就是单线程程序。主方法线程由Java虚拟机负责启动,程序负责启动自定义的线程:
      • public static void main(String args[]){
      •         new ThreadTest().start();
      • }
    • 示例:创建ThreadTest类。
  • 15.2.2 实现Runnable接口
    • 线程通过扩展Thread类来创建,如果需要继承其他类,并使该程序可以使用线程,就需要使用Runnable接口。例如,继承了JFrame类不能在继承Thread类,Java中不支持多继承,因此需要使用Runnable接口。
    • 实际上,Thread类本身就是通过实现Runnable接口创建线程。
    • 实现Runnable接口的语法格式:
      • public class Thread extends JFrame implements Runnable;
    • 实现Runnable接口的程序会创建一个Thread对象,并将Runnable对象与Thread对象相关联。Thread类有以下两个构造方法:
      • public Thread(Runnable r)
      • public Thread(Runnable r, String name)
    • 使用Runnable接口启动新线程的步骤:
        1. 建立Runnable对象;
        1. 使用Runnable对象作为参数构造Thread实例(相关联);
        1. 调用start()方法启动线程;
    • 示例:创建SwingAndThread类。
  • 15.2.3 范例1:查看线程的运行状态
    • 线程共有新建、运行(可运行)、阻塞、等待、计时等到和终止6种状态。当使用new操作符创建新线程时,线程处于新建状态。当调用start()方法时,线程处于运行(可运行)状态。当线程需要获得对象的内置锁,而该锁正被其他线程拥有时,线程处于阻塞状态。当线程等待其他线程通知调度表可以运行时,线程处于等待状态。对于一些含有时间参数的方法,如Thread类的sleep()方法,可以使线程处于计时等待状态。当run()方法运行完毕或出现异常时,线程处于终止状态。
    • 示例:创建ThreadState类。
  • 15.2.4 范例2:查看JVM中的线程名
    • 在JVM中,除了用户创建的线程,还有服务于用户线程的其他线程。它们根据用途被分配到不同的组中进行管理。可以查看线程所在组的信息,以及线程的状态、线程的优先级、是否为守护线程等其他信息。
    • 示例:创建ThreadList类。

15.3 线程的生命周期

  • 线程具有生命周期,包含出生状态、就绪状态、运行状态、等待状态、休眠状态、阻塞状态和死亡状态7种状态。使线程处于就绪状态有以下几种可能:调用sleep()方法、调用wait()方法、等待输入/输出完成。

  • 当线程处于就绪状态,可以通过几种方法使线程再次进入运行状态:调用notify()方法、调用notifyAll()方法、调用interrupt()方法、线程的休眠时间结束、输入/输出结束。

15.4 操作线程的方法

  • 15.4.1 线程的休眠
  • 15.4.2 线程的加入
    • 如果当前程序为多线程程序,存在一个正在进行的线程A,需要插入线程B,使B先执行完毕,在执行线程A。此时可以使用join()方法完成。
    • 示例:创建JoinTest类。
  • 15.4.3 线程的中断
    • 早期的JDK支持调用stop()方法中断线程,但是当前版本已经废除stop()方法,而是提倡在run()中使用无限循环,然后使用一个布尔型标记控制循环的结束。
    • 当线程不是处于无限循环中,而是处于sleep或wait的就绪状态,可以使用Thread类中的interrupt()方法使线程离开run()。
  • 15.4.4 线程的礼让
    • Thread类中提供一种礼让方法yield(),它只是给当前处于运行状态的线程一个提醒,暗示可以将资源让给其他线程,并不存在一种机制保证让出资源。

15.5 线程的优先级

  • 当多个线程处于就绪状态,系统会根据优先级来确定先运行哪个线程。Thread类中包含的成员变量代表了线程的某些优先级,如Thread.MIN_PRIORITY、Thread.NORM_PRIORITY、Thread.MAX_PRIORITY。默认的优先级是NORM。每个新产生的线程都继承父线程的优先级。
  • 线程的优先级可以通过setPriority()方法设置,取值为1~10,超出范围将抛出 IllegalArgumentException。

15.6 线程同步

在单线程程序中,每个时刻只能进行一个操作,后面的操作需要排队进行。如果是多线程程序,则会抢占资源(相当于分时复用)。如果要多线程同时操作,避免抢占资源,则需要利用Java的同步机制。

  • 15.6.1 线程安全
    • 线程的安全问题源于多个线程同时存取单一对象的数据,当一个线程正在进行对数据的操作时,数据可以中途被其他线程更改。
    • 示例:创建ThreadSafeTest类。
  • 15.6.2 线程同步机制
    • 解决上述问题,可以给共享的资源上一道锁,同一时刻只能供一个线程使用。具体方法为通过synchronized关键字使用同步机制。
    • 通常是将资源放在synchronized定义的区域内,称为同步块,语法格式:
      • synchronized(Object){
      •         // ...
      • }
    • 这样当其他线程也获得这个锁时,必须等待锁被释放才能进入该区域。其中Object为任意一个对象,每个对象存在一个标志位(0或1),0状态下,线程在就绪状态等待。切换为1状态才能执行同步块中的代码,并将标志位设置为0,锁定。
    • 示例:创建SynchThreadSafeTest类。
    • 同步的方法:在方法前修饰synchronized关键字:
      • synchronized void fun(){
      •         // ...
      • }
    • 当某个对象调用同步方法时,其他线程对象无法调用。

15.7 线程间的通信

  • 线程之间的通信使用wait()、notify()以及notifyAll()实现。
  • wait()与sleep()的区别:都是暂停线程,但是wait()方法必须用notify唤醒。

第十六章 网络通信

网络应用程序是在已连接的不同计算机上运行的程序,这些程序可以相互交换数据,编写网络应用程序,首先要明确网络协议。本章目标:了解常见网络协议、理解端口和套接字、掌握 InetAddress 类、掌握 ServerSocket 类、编写 TCP 网络程序、掌握 DatagramPacket 类、掌握 DatagramSocket 类、编写 UDP 程序

16.1 网络程序设计基础

  • 16.1.1 局域网与因特网
    • 服务器与客户机的概念和结构。
    • 局域网(Local Area Network,LAN)同一区域连接的一群客户机,没有明确的服务器;
    • 广域网(Wide Area Network,WAN):大量的客户机连成的局域网;
    • 因特网(Internet):由无数的LAN和WAN组成;。
  • 16.1.2 网络协议
    • 网络协议规定了计算机之间连接的物理、机械、电气等特征以及计算机之间的相互寻址规则、数据发送冲突的处理、数据分段和接收等。
    • IP(Internet Protocol)协议:Internet采用的协议是TCP/IP协议(Transmission Control Protocol/Internet Protocol),在全球范围内实现不同硬件结构、不同操作系统、不同网络系统的互联。在Internet上寻在数以亿计的主机,每台主机通过分配到的地址表示身份,称为IP地址。目前IP地址用4个字节,也就是32位二进制数表示,称为IPv4。为了方便将每一位表示为对应的十进制数,例如192.168.1.1。
    • TCP/IP模式是一种层次结构,共分为四层:应用层、传输层、互联网层和主机到网络层。各层实现特定的功能,提供特定的服务和访问接口,并具有相对的独立性。
    • TCP协议是一种以固定连接为基础的协议,提供计算机之间可靠的数据传输
    • UDP协议(User Datagram Protocol)是无连接通信协议,不保证可靠的数据传输。由于对数据准确性要求不高,传输速度更快,适用于网络聊天室、在线影片等场景。
  • 16.1.3 端口和套接字
    • 一般来说,一台计算机只有单一的连到网络的物理连接,所有数据通过该连接进行传输,这个连接称为端口。网络程序中的端口(port)并非真实的物理连接,是一个假想的连接装置,端口被规定在0~65535之间的整数。HTTP服务一般使用80端口,FTP服务使用21端口。
    • 网络程序中的套接字(Socket)将应用程序与端口连接起来,相当于“插座”,由于连接电器和输电线。

16.2 TCP程序设计基础

TCP网络程序设计是指利用Socket类编写通信程序。利用TCP协议进行通信的两个程序是有主次之分的,分为服务器程序和客户机程序。服务器端与客户端的交互过程:

  1. 服务器程序创建一个ServerSocket,调用accept()方法等待客户机连接;
  2. 客户端程序创建一个Socket,请求与服务器连接;
  3. 服务器接收客户机的连接请求,新建一个Socket与客户机建立连接,同时服务器继续等待新的请求。
  • 16.2.1 InetAddress类
    • java.net.InetAddress用于获取IP地址。主机地址等信息,常用方法有:
      • getByName(String host); 返回与host相对应的InetAddress对象
      • getHostAddress(); 获取InetAddress对象所含的IP地址
      • getHostName(); 获取此IP地址的主机名
      • getLocalHost(); 返回本主机对应的InetAddress对象
    • 示例:创建Address类。
  • 16.2.2 ServerSocket类
    • java.net.ServerSocket类用于表示服务器套接字,主要功能是等待来自网络上的请求。它可以通过指定的端口来等待连接的套接字。服务器套接字一次可以与一个套接字连接。如果请求过多,进行排队,如果队列超长(大于50),拒绝请求。
    • ServerSocket类常用方法:
      • accept(); // 等待客户机的连接
      • isBound(); // 判断ServerSocket的绑定状态
      • getInetAddress(); // 返回此服务器套接字的本地地址
      • isClosed(); // 返回服务器套接字的关闭状态
      • close(); // 关闭服务器套接字
      • bind(SocketAddress endpoint); // 将ServerSocket绑定到特定地址
      • getInetAddress(); // 返回服务器套接字等待的端口号
    • accept方法会阻塞线程的继续执行,直到接收到客户的呼叫。如果accept方法没有阻塞线程,很可能是使用了一个被占用的端口号,ServerSocket没有绑定成功。
  • 16.2.3 TCP网络程序
    • 单向通信:只有客户机向服务器发送消息,不用服务器向客户机发送消息。
    • 示例:创建MyTCP类、MyClien类。

16.3 UDP程序设计基础

用户数据包协议(UDP)是网络信息传输的另一种形式。基于UDP的传输更快,但不提供可靠的保证,用户无法确定信息是否正确地到达主机,也不能确定到达的顺序。

发送数据包:

  1. 使用DatagramSocket()方法创建一个数据包套接字
  2. 使用DatagramPacket(byte[] buf, int offset, int length,InetAddress address, int port)方法创建数据包
  3. 使用DatagramSocket类的send()方法发送数据包

接收数据包

  1. 使用DatagramSocket(int port)方法创建数据包套接字,绑定端口号
  2. 使用DatagramPacket(byte[] buf, int length)方法创建字节数组来接收数据包
  3. 使用DatagramPacket类的receive()方法接收UDP数据包
  • 16.3.1 DatagramPacket类
    • 常用方法如上述提到的方法
  • 16.3.2 DatagramSocket类
    • 常用方法如上述提到的方法
    • 接收程序中创建数据包套接字,必须指定端口号;发送程序中可以不指定,由系统分配。
  • 16.3.3 UDP网络程序
    • 示例:创建Weather类。

第十七章 JDBC操作数据库

JDBC是一种可用于执行SQL语句的Java API(Application Programming Interface,应用程序设计接口),是连接数据库和Java程序的桥梁,通过JDBC API可以方便地实现对各种主流数据库的操作。本章目标:了解JDBC概念、掌握JDBC的常用类和接口、掌握通过JDBC操作数据库

17.1 JDBC概述

  • 17.1.1 数据库概述
    • 数据库特点:数据共享、减少数据冗余度、数据独立性、数据集中控制、数据的一致性和可维护性
    • 数据库的种类和功能:
        1. 层次型数据库:类似树结构,是一组通过链接相互联系在一起的记录,由于层次模型层次顺序严格且复杂,会导致对数据的各项操作都较困难。
        1. 网状型数据库:使用网络结构表示实体类型、实体间联系的数据模型
        1. 面向对象型数据库:建立在面向对象模型基础上
        1. 关系型数据库:目前最流行的数据库,是基于关系模型建立的数据库,由一系列的表格组成。
  • 17.1.2 JDBC技术
    • JDBC指定了统一的访问各类关系数据库的标准接口,为各个数据库厂商提供了标准接口的实现。JDBC并不能直接访问数据库,需要结合数据库厂商提供的JDBC驱动程序使用。
    • JDBC优点:易于理解、无需更改大量代码、支持多种关系型数据库、JDBC的API是面向对象的,可以二次封装;

17.2 JDBC的常用类和接口

Java提供了丰富的类和接口用于数据库编程,本节介绍常用的JDBC接口和类,它们都在java.sql包中。

  • 17.2.1 DriverManager类
    • 用于管理数据库中的所有驱动程序,是JDBC的管理层。DriverManager类中的方法都是静态方法,所以在程序中无须对它进行实例化,可以通过类名直接调用。
    • 常用方法:
      • getConnection(String url, String user, String password);
      • setLoginTimeout(): // 获取驱动尝试登录可以等待的最长时间
      • println(String message); // 将一条信息打印到当前的JDBC日志流中
  • 17.2.2 Connection接口
    • 用于连接特定的数据库,通过DriverManager类的getConnection()方法获取Connection实例。
    • 常用方法:
      • createStatement();// 创建Statement对象
      • createStatement(int resultSetType, int resultSetConcurrency)
      • prepareStatement()
      • isReadOnly()
      • setReadOnly(); // 使上一次提交或回滚后的更改成为持久更改
      • commit()
      • roolback(); // 撤销当前事务中对数据库的所有更改,释放锁
      • close()
  • 17.2.3 Statement接口

17.3 通过JDBC操作数据库

  • 17.3.1 加载数据库驱动
    • 将下载的数据库驱动文件添加到项目后,首先需要加载数据库驱动程序,才能进行数据库操作。使用Class类的静态方法forName()加载数据库驱动。加载MySQL数据库示例:
      • try{
      •         Class.froName("com.mysql.jdbc.Driver");
      • }catch(ClassNotFoundException e){
      •         e.printStackTrace();
      • }
  • 17.3.2 建立连接
    • 加载数据库驱动后即可创建连接,使用DriverManager类的静态方法get-Connection()连接数据库。
    • 示例:建立MySQL数据库连接
      1
      2
      3
      4
      5
      6
      
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/db_database17";
        String User = "root";
        String password = "123456";
        // 建立数据库连接,获取连接对象conn
        Connection conn = DriverManager.getConnection(url,user,password);
      
  • 17.3.3 向数据库中添加数据
    • 使用Connection接口的createStatement()方法来获得Statement对象,也可以调用prepareStatement()方法获取PreparedStatement对象,通过executeUpdate()方法执行SQL语句。
    • 示例添加数据(接上例连接):
      1
      2
      3
      4
      5
      
        String sql = "INSERT INTO tb_users (username, password, sex, " +
                    "age) values('张三', '666666', 'male', '24')";
        Statement stmt = conn.createStatement();
        stmt.executeUpdate(sql);
        conn.close();
      
  • 17.3.4 获取查询结果集
    • Statement接口中的executeUpdate()和executeQuery()可以执行sql语句,前者用于数据的增删改,后者用于查询数据,执行SELECT语句,并返回一个ResultSet型的数据集。
    • ResultSet对象类似python的生成器,具有指向当前数据行的光标。通过next()移动到下一行,没有下一行返回false。
    • 查询数据库示例:
      1
      2
      3
      4
      5
      6
      7
      
        String sql = "SELECT * FORM tb_users";
        ResultSet rs = stmt.executeQuery(sql);
        while(re.next()){
            rs.getInt('age');     //返回整型
            rs.getString('username');     //返回字符串
            ...
        }
      
  • 17.3.5 更改数据库中的数据
    • 使用PreparedStatement接口中的executeUpdate()方法修改数据库:
      1
      2
      3
      4
      5
      6
      7
      8
      
        //...
        PreparedStatement ps = conn.prepareStatement(sql);
        String sql = "UPDATE tb_users SET password=? where sex=?";
        ps.setString(1, '88888888');      //为第一个问号赋值
        ps.setString(2, 'male');          //为第二个问号赋值
        int count = ps.executeUpdate();   //执行返回被影响行数
        System.out.println("成功修改" + count + "条数据!");
        conn.close()
      
  • 17.3.6 删除数据库中的数据
    1
    2
    3
    
          String sql = "DELETE FROM tb_users WHERE id=1";
          Statement stmt = conn.createStatement();
          stmt.executeUpdate(sql);
    
  • 17.3.7 模糊查询
    • 使用LIKE关键字进行模糊查询,使用通配符 % 来代替0个或多个字符,使用 _ 代替一个字符。

第十八章 Swing高级组件

18.1 利用JTable类直接创建表格

  • 18.1.1 创建表格
    • 在JTable中除了默认构造方法,还提供了利用指定表格列名数组和表格数据数组创建表格的构造方法:
      • JTable(Object[][] rowData, Object[][] columnNames)
    • 示例:创建CreateTable类。

18.2 表格模型与表格(略)

18.3 提供行标题栏的表格(略)

18.4 Swing树组件

  • 18.4.1 简单的树
    • 树状结构是一种常用的信息表示形式,可以直观地显示出一组信息的层次结构。利用JTree类创建树:
      • JTree(); 创建一个默认的树
      • JTree(TreeNode root) 根据指定根节点创建树
      • JTree(TreeModel newModel) 根据指定树模型创建树
    • DefaultMutableTreeNode类实现了TreeNode接口,用于创建树节点。一个树指定有一个父节点,可以有0个或多个子节点:
      • DefaultMutableTreeNode();
      • DefaultMutableTreeNode(Object userObj); 创建一个具有指定标签的节点
      • DefaultMutableTreeNode(Object userObj, boolean allowsChildren);
    • DefaultTreeModel类实现了TreeModel接口,创建树模型时必须指定根节点
      • DefaultTreeModel(TreeNode root);
      • DefaultTreeModel(TreeNode root, boolean asksAllowsChildren)
    • 示例:创建SimpleTree类。

第十九章 高级布局管理器

19.1 箱式布局管理器

  • 由BoxLayout类实现的布局管理器称为箱式布局管理器,用来管理一组水平或垂直排列的组件,分别称为水平箱和垂直箱。
  • BoxLayout类仅提供了一个构造方法BoxLayout(Container target, int axis),其入口参数target为要采用该布局的容器对象,axis为布局方式。

19.2 卡片布局管理器

  • 由CardLayout类实现,每个直接添加到其所管理容器中的容器或组件为一个卡片,运行时按顺序显式卡片。
  • CardLayout类中提供了5个显式卡片的方法:
    • first(Container parent); 显示第一个卡片
    • last(Container parent); 显示最后一个卡片
    • next(Container parent); 显示下一个卡片
    • previous(Container parent); 显示上一个卡片 show(Container parent, String name); 显示指定标签的卡片 ·示例:创建CardLayoutn_Example类。

19.3 网格布局管理器

  • 由GridBagLayout类实现了一个动态的矩形网络,这个网络由无数个矩形单元组成,每个组件可以占用一个或多个这样的单元格

19.4 弹簧布局管理器

  • 由StringLayout类实现的布局管理器,当改变窗体大小时,能够在不改变组件间相对位置的前提下自动调整组件大小,使组件布满整个窗口。

第二十章 AWT绘图技术

要开发高级的应用程序,必须掌握图像处理技术。本章要求:了解Java绘图、了解Java绘图颜色与画笔属性、掌握Java绘制文本、掌握Java图片处理。

20.1 绘制图形

  • 20.1.1 Graphics
    • Graphics类是所有图形上下文的抽象基类,它允许应用程序在组件以及闭屏图像上进行绘制。Graphics类封装了Java支持的基本绘图操作所需的状态信息,包括颜色、字体、画笔、文本、图像等。
    • 示例:创建DrawCircle类。
  • 20.1.2 Graphics2D
    • 使用Graphics类可以完成简单的图形绘制,但是功能十分有限,无法实现改变线条粗细、旋转和使用过滤效果等。
    • Graphics2D继承了Graphics类,实现了更强大的绘图功能
    • 示例:类似上例。