Java 程序设计基础(第四版)下

第 10 章 Java 语言的输入输出与文件处理

  1. 什么是文件的输入输出?

    程序从文件读取数据称为文件的输入;程序向文件写入数据称为文件的输出。
    
  2. 什么是流?Java 语言中分为哪两种流?这两种流有何差异?

    流是指计算机个部件之间的数据流动。在 Java 语言中,把不同类型的输入输出源(键盘、屏幕、文件、网络等)抽象为流,而其中输入或输出的数据称为数据流;
    按照数据的传输方向,流可以分为输入流和输出流。从流的内容上划分,流分为字节流和字符流;
    将数据从外设或外存(如键盘、鼠标、文件等)传递到应用程序的流称为输入流;将数据从应用程序传递到外设或外存(如屏幕、打印机、文件等)的流称为输出流。对于输入流只能从其读取数据而不能向其写入数据,同样对于输出流只能向其写入数据而不能从其读入数据。
    
  3. InputStream、OutputStream、Reader 和 Writer 4 个类在功能上有何异同?

    InputStream 和 OutputStream 类通常是用来处理 “字节流” 即 “位流” 的,也就是二进制文件,而Reader 和 Writer 类则是用来处理 “字符流” 的, 也就是文本文件。
    InputStream、OutputStream、Reader 和 Writer 4 个类均是抽象类,所以不能直接使用这四个类,而是使用它们的子类来创建对象,再利用对象来处理读写操作。
    
  4. 利用基本输入输出流实现从键盘读入一个字符,然后显示在屏幕上。

import java.io.*;
public class Exercise {
    public static void main(String[] args) throws IOException{
        byte[] c = new byte[2];
        InputStream in = new DataInputStream(System.in);
        in.read(c);
        OutputStream out = new DataOutputStream(System.out);
        out.write(c);
        in.close();
        out.close();
    }
}
  1. 顺序输入输出流与管道输入输出流的区别什么?

    顺序输入流类 SequenceInputStream 是 InputStream 的直接子类,其功能是将多个输入流顺序连接在一起,形成单一的输入数据流,没有对应的输出数据流存在。在进行输入时,顺序输入流依次打开每个输入流并读取数据,在读取完毕后将该流关闭,然后自动切换到下一个输入流。
    管道字节输入流 PipedInputStream 和 管道字节输出流 PipedOutputStream 类提供了利用管道方式进行数据输入输出管理的类。管道流用来将一个程序或线程的输出连接到另一个程序或线程作为输入,使得相应线程能够通过 PipedInputStream 和 PipedOutputStream 类进行数据交换,从而实现程序内部线程间的通信或不同程序间的通信。
    
  2. Java 语言中定义的三个标准输入输出流是什么?它们对应什么设备?

    标准输入流,标准输出流,标准错误输出流;
    标准输入流通常对应的设备是键盘;
    标准输出流和标准错误输出流通常对应的设备是显示器。
    
  3. 利用文件输出流创建一个文件 file1.txt,写入字符 “文件已被成功创建!”,然后用记事本打开该文件,看是否正确写入。

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File file = new File("file1.txt");
        FileOutputStream out = new FileOutputStream(file);
        String s = new String("文件已被创建成功!\n");
        byte[] bytes = s.getBytes("UTF-8");
        out.write(bytes);
        out.flush();
        out.close();
    }
}
  1. 利用文件输入流打开第 7 题中创建的文件 file1.txt,读出其内容并显示在屏幕上。
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File file = new File("file1.txt");
        FileInputStream in = new FileInputStream(file);
        byte[] bytes = new byte[1024];
        while (in.read(bytes) != -1) {
            System.out.println(new String(bytes));
        }
        in.close();
    }
}
  1. 利用文件输入输出流打开第 7 题中创建的文件 file1.txt,然后在文件末尾追加一行字符串 “又添加了一行文字!”。
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File file = new File("file1.txt");
        FileOutputStream out = new FileOutputStream(file, true);
        String s = "又添加了一行文字!";
        byte[] bytes = s.getBytes("UTF-8");
        out.write(bytes);
        out.close();
    }
}
  1. 产生 15 个 20~9999 之间的随机整数,然后利用 BufferedWriter 类将其写入文件 file2.txt 中;之后再读取该文件中的数据并将它们升序排序。
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;

public class Exercise {
    public static void main(String[] args) throws IOException {
        File file = new File("file2.txt");
        BufferedWriter writer = new BufferedWriter(new FileWriter(file));
        for (int i = 0; i < 15; i++) {
            String s = "" + ((int)(Math.random() * 9979) + 20) + "\n";
            writer.write(s);
        }
        writer.flush();
        writer.close();

        BufferedReader reader = new BufferedReader(new FileReader(file));
        int[] nums = new int[15];
        for (int i = 0; i < 15; i++) {
            nums[i] = Integer.parseInt(reader.readLine());
        }
        reader.close();
        Arrays.sort(nums);

        writer = new BufferedWriter(new FileWriter(file));
        for (int i = 0; i < 15; i++) {
            String s = "" + (nums[i]) + "\n";
            writer.write(s);
        }
        writer.flush();
        writer.close();
    }
}
  1. Java 语言中使用什么类来对文件与文件夹进行管理?

    在 java.io 包中定义了一个 File 类,专门用来管理磁盘文件或文件夹,而不负责数据的输入输出。
    

第 11 章 多线程

  1. 简述线程的基本概念。程序、进程、线程的关系是什么?

    线程与进程相似,但线程是一个比进程更小的执行单位。一个进程在其执行的过程中可以产生多个线程,形成多条执行路径。
    程序是含有指令和数据的文件,被存储在磁盘或其他的数据存储设备中,也就是说程序是静态的代码。进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。线程是进程划分成的更小的运行单位。
    
  2. 什么是多线程?为什么程序的多线程功能是必要的?

    所谓多线程就是同时执行一个以上的线程,一个线程的执行不必等待另一个线程执行完成后才执行,所有线程都可以发生在同一时刻。
    单一的进程在执行任务时会出现资源空闲,采用多线程可以让 CPU 在同一段时间之内执行一个程序中的好几个程序段来完成工作,提高效率。
    
  3. 多线程与多任务的差异是什么?

    多任务与多线程是两个不同的概念,多任务是针对操作系统而言的,表示操作系统可以同时运行多个应用程序,而多线程是针对一个进程而言的,表示在一个进程内部可以同时执行多个线程。
    
  4. 线程有哪些基本状态?这些状态是如何定义的?

    新建状态、就绪状态、运行状态、阻塞状态和消亡状态。
    新建状态:当线程对象已经被分配了内存空间和其他资源,并已被初始化,但是该线程尚未被调度。
    就绪状态:就绪状态也称为可运行状态。处于新建状态的线程被启动后,将进入线程队列排队等待 CPU 时间片,此时它已具备了运行的条件,也就是处于就绪状态。
    运行状态:当就绪状态的线程被调度并获得 CPU 资源时,便进入了运行状态。该状态表示线程正在运行,该线程已经拥有了对 CPU 的控制权。
    阻塞状态:正在执行的线程如果在某些特殊情况下,将让出 CPU 并暂时中止自己的执行,线程所处于这种不可运行的状态被称为阻塞状态。阻塞状态是因为某种原因,系统不能执行线程的状态,在这种状态下即使 CPU 空闲也不能执行线程。
    消亡状态:处于消亡状态的线程不具有继续运行的能力。
    
  5. Java 程序实现多线程有哪两种途径?

    Java 语言中实现多线程的方法有两种:一种是继承 java.lang 包中的 Thread 类,另一种是用户在自己定义的类中实现 Runnable 接口。但不管采用哪种方法,都要用到 Java 语言类库中的 Thread 类以及相关的方法。
    
  6. 在什么情况下,必须以类实现 Runnable 接口来创建线程?

    如果类本身已经继承了某个父类,由于 Java 语言不允许类的多重继承,所以无法再继承 Thread 类,此时就必须以类实现 Runnable 接口来创建线程。
    Runnable 接口适合处理多线程访问同一资源的情况,并且可以避免由于 Java 语言的单继承性带来的局限。
    
  7. 什么是线程的同步?程序中为什么要实现线程的同步?是如何实现同步的?

    当一个线程对共享的数据进行操作时,应使之成为一个 “原子操作”,即在没有完成相关的操作之前,不允许其他的线程打断它,否则,就会破坏数据的完整性,必然会得到错误的处理结果,这就是线程的同步。
    因为线程间的数据共享使得这些线程共同拥有对内存空间中数据的处理权力,这样会导致因为多个线程同时处理数据而使数据出现不一致,为了解决这一问题而提出同步的概念,即同步是在共享的基础之上的。
    在并发程序设计中,对多线程共享的资源或数据称为临界资源或同步资源,而把每个线程中访问临界资源的那一段代码称为临界代码或临界区。简单地说,在一个时刻只能被一个线程访问的资源就是临界资源,而访问临界资源的那段代码就是临界区。临界区必须互斥地使用,即一个线程执行临界区中的代码时,其他线程不准进入临界区,直至该线程退出为止。为了使临界代码对临界资源的访问成为一个不可中断的原子操作,Java 技术利用对象 “互斥锁” 机制来实现线程间的互斥操作以实现同步操作。
    
  8. 假设某家银行可接受顾客的汇款,每次进行一次汇款,便可计算出汇款的总额。现有两名顾客,没人分 3 次,每次 100 元将钱汇入。是编写来模拟顾客的汇款操作。

public class Exercise {
    public static void main(String[] args) {
        Customer customer1 = new Customer("1 ");
        Customer customer2 = new Customer("2 ");
        customer1.start();
        customer2.start();

    }
}

class Customer extends Thread {
    public Customer (String s) {
        super(s);
    }
    public void run() {
        for (int i = 0; i < 3; i++) {
            Bank.deposit(100);
        }
    }
}

class Bank {
    public static int balance = 0;
    public synchronized static void deposit (int b) {
        int temp = balance;
        temp += b;
        try {
            Thread.sleep((int) (Math.random() * 1000));
        } catch (InterruptedException e) {
        }
        balance = temp;
        System.out.println(Thread.currentThread().getName() + " 汇款后总金额:" + balance);
    }
}

第 12 章 图形界面设计

  1. Swing 组件分为哪三类?

    容器类(container class)、辅助类(helper class)和组件类(component class)。
    
  2. Swing 的顶层容器包含哪些窗格?大部分的可见组件都放在哪个窗格中?

    Swing 的顶层容器主要有 JFrame、JApplet 和 JDialog 等;一般独立应用程序主要使用框架 JFrame 作为容器。
    
  3. 框架组件与面板组件的区别有哪些?

    以 JFrame 为代表的框架是一种带标题栏并且可以改变大小的窗口,而以 JPanel 类为代表的面板类与窗口类似,但它是一种没有标题栏的容器,且不能独立存在,必须包含在另一个容器之中。
    
  4. 颜色类 Color 中提供了哪些表示颜色的变量?

变量名代表颜色
black 或 BLACK黑色
blue 或 BLUE蓝色
cyan 或 CYAN蓝青色
darkGray 或 DARK_GRAY深灰色
gray 或 GRAY灰色
green 或 GREEN绿色
lightGray 或 LIGHT_GRAY浅绿色
megenta 或 MAGENTA红紫色
orange 或 ORANGE桔黄色
pink 或 PINK粉红色
red 或 RED红色
white 或 WHITE白色
yellow 或 YELLOW黄色

5. 字体类 Font 的主要用途有哪些?

    字体类 Font 是 java.awt 包中的类,是用来设置组件所用字体的样式、大小与字形等属性的。
  1. 图像图标类 ImageIcon 的主要作用是什么?Java 语言当前支持哪三种图像格式?

    图像图标类 ImageIcon 的主要作用是用来装饰组件的;Java 语言当前支持三种图像格式:GIF、JPEG 和 PNG,这三种图像文件的扩展名分别 gif、jpg 和 png。
    
  2. Swing 主要用来处理文字输入的组件有几个?这几个组件有何不同点?

    文本编辑组件分为三种:
    第一种是单行文本编辑组件,简称文本行,也称文本框,是通过 JTextField 类实现的;
    第二种是密码文本行组件,是通过 JPasswordField 类实现的;
    第三种是多行文本编辑组件,简称文本区,是通过 JTextArea 类实现的。
    
  3. 在将组件添加到窗口中时,为什么需将组件设置为不透明状态才能将其底色显现出来?

    因为 JFrame 的框架一旦被创建,其中就已经包含一个内容窗格,设置的 JFrame 背景颜色,仍然会被内容窗格遮盖,由框架内容窗格的委托特性可知,在往 JFrame 中添加组件时,组件都加在了内容窗格中。
    
  4. 如何设置才能将窗口的底色显现出来?

    内容窗格可以通过调用 JFrame 的成员方法 getContentPane() 获得,然后再设置内容窗格的背景色,这样才能显现出窗口的背景色。
    
  5. 设计一个窗口,内含一个文本框、三个复选框、两个单选按钮、一个标签和一个按钮。各组件的位置、大小和其上的文字由用户自己设定。

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

public class Exercise {
    public static void main(String[] args) {
        JFrame window = new JFrame("A Windows");
        window.setLayout(new FlowLayout());

        JTextField textField = new JTextField(20);
        window.add(textField);

        JCheckBox checkBox1 = new JCheckBox("CheckBox1");
        JCheckBox checkBox2 = new JCheckBox("CheckBox2");
        JCheckBox checkBox3 = new JCheckBox("CheckBox3");
        window.add(checkBox1);
        window.add(checkBox2);
        window.add(checkBox3);

        JRadioButton radioButton1 = new JRadioButton("RadioButton1");
        JRadioButton radioButton2 = new JRadioButton("RadioButton2");
        ButtonGroup bg = new ButtonGroup();
        bg.add(radioButton1);
        bg.add(radioButton2);

        window.add(radioButton1);
        window.add(radioButton2);

        JLabel label = new JLabel("This is a label");
        window.add(label);

        JButton button = new JButton("Button");
        window.add(button);

        window.pack();
        window.setVisible(true);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
  1. Java 语言中常用的布局管理器有哪几个?它们各有什么特点?

    java.awt 包中共定义了五种布局管理器,每个布局管理器对应一种布局策略,分别是流式布局管理器 FlowLayout、边界式布局管理器 BorderLayout、卡片式布局管理器 CradLayout、网格式布局管理器 GridLayout 和网格包布局管理器 GridBagLayout。javax.swing 包中提供的布局管理器有盒式布局管理器 BoxLayout、重叠布局管理器 OverlayLayout 和弹簧布局管理器 SpringLayout 等。
    1. 流式布局管理器 FlowLayout:
        流式布局是一种 最基本的布局,它是一种流式页面设计。流式布局管理器 FlowLayout 的布局策略是:
        1. 组件按照加入容器的先后顺序从左向右排列。
        2. 一行排满之后就自动地转到下一行继续从左向右排列。
        3. 每一行中的组件默认设置为居中排列。
        FlowLayout 布局管理器是 JPanel 默认的布局管理方式。
    2. 边界式布局管理器 BorderLayout:
        边界式布局管理器 BorderLayout 将显示区域按地理方位为东(East)、西(West)、南(South)、北(North)、中(Center)5 个区域。在将组件加入容器时,都应该指出把这个组件加入到哪个区域中,若没有指定区域,则默认为中间。若将组件加入到已被其它组件占用的区域,将会取代原先的组件。
    3. 网格式布局管理器 GridLayout:
        网格式布局管理器 GridLayout 提供的页面布局规则是将容器的空间划分成若干行与列的网格形式,每个网格称为单元格,在容器上添加组件时,它们会按从左到右、从上到下的顺序在网格中排列。网格的行数和列数可以在创建 GridLayout 对象的构造方法中指定。利用 GridLayout 布局策略时,容器中各组件占用一个单元格,所以各组件的宽度相同,同样,所有组件的高度也是相同的。当容器的尺寸发生变化时,各组件的相对位置不变,但各自的尺寸会发生变化。
    4. 卡片式布局管理器 CardLayout:
        卡片式布局管理器 CardLayout 的页面布局方式是把 “容器” 中的所有组件如同堆叠起来的一副 “扑克牌”,每次只能显示最上面的一张一样,这个被显示的组件将占据所有的容器空间。“容器” 有可能只是一个 JFrame,或者是将 JFrame 细分为数个 “容器”,每个 “容器” 可拥有自己的窗口对象以及布局管理器。所有基于 CardLayout 布局方式在显示区域内每次只有一个组件是可见的。
        利用卡片布局管理器时,通常要用到多个容器,其中一个容器使用卡片布局管理器,而另外的容器使用其他的布局管理器。
    5. 网格包布局管理器 GridBagLayout:
        网格包布局管理器 GridBagLayout 是在网格布局管理器 GridLayout 的基础上发展而来的,所以它与 GridLayout 类似,它们都是用网格的形式来组织组件的。使用 GridBagLayout 布局比较复杂,但其功能比较强大。由于 GridLayout 中每个网格的大小相同,并且强制组件与网格大小相同,从而使得容器中的每个组件也都是相同的大小,显得很不自然,而且组件加入容器也必须按照固定的排列顺序,因此不够灵活。GridBagLayout 布局管理器也是将容器中的组件按行、列的位置摆放,但在 GridBagLayout 布局管理器中允许组件栈用不同行或者不同列的多个单元格,这些被占用的单元格称为组件的显示区域。
    6. 盒式布局管理器 BoxLayout:
        BoxLayout 是一种 Swing 布局管理器,这种布局策略是在一行或一列中摆放组件。如果采用沿水平方向排列组件方式,当组件的总宽度超出容器的宽度时,组件也不会换行,而是沿同一行继续排列组件。如果采用竖直方向排列组件也是一样。这时需要改变容器的大小才能见到所有的组件,即有些组件可能处于不可见状态。
    7. 重叠布局管理器 OverlayLayout 和弹簧布局管理器 SpringLayout 简介:
        重叠布局管理器 OverlayLayout 和弹簧布局管理器 SpringLayout 均是 Swing 中定义的布局管理器。具有 OverlayLayout 布局管理策略的容器,将加入该容器的所有组件叠放在一起,第一个被加入容器的组件会放在容器的最前面,这样后加入容器的组件会被先加入的组件遮盖住。这时可将前面的组件利用 JComponent.setOpaque(false) 方法将其设置为透明的,则下面组件被遮盖部分就能显示出来。弹簧布局管理器 SpringLayout 的主要思想在组件的周围放置一个灵活的弹簧,这种弹簧可以压缩或伸长,把组件堆放到要求的位置。
    

第 13 章 事件处理

  1. 什么是事件?简述 Java 语言的委托事件模型。

    所谓事件(Event),就是用户使用鼠标或键盘对窗口中的组件进行交互时所发生的事情。事件用于描述发生了什么事情,对这些事件作出响应的程序称为事件处理程序。
    在 Java 语言中对事件的处理,采用的是委托事件模型机制。 委托事件模型是将事件源(如命令按钮)和对事件做出的具体处理(利用监听者来对事件进行具体的处理)分离下来。一般情况下,组件(事件源)不处理自己的事件,而是将事件处理委托给外部的处理实体(监听者),这是事件处理模型就是事件的委托处理模型,即事件源将事件处理任务委托给监听者。总的来说,委托事件模型是有产生事件的对象(事件源)、事件对象以及事件监听者对象之间的关系所组成。而其中的 “事件监听者” 就是用来处理事件的对象,也就是说,监听者对象会等待事件的发生,并在事件发生时收到通知。事件源会在事件产生时,将关于该事件的信息封装在一个对象中,这就是 “事件对象”,并将该事件对象作为参数传递给事件监听者,监听者就可以根据该 “事件对象” 内的信息决定适当的处理方式,即调用相应的事件处理程序。
    
  2. 若要处理事件,就必须要有事件监听者,通常哪些对象的可以担任监听者?

    1. 让包含 “事件源” 的容器对象来担任监听者。
    2. 定义内部类来担任监听者。
    3. 使用匿名内部类来担任监听者。
    
  3. 写出组件可能产生的事件的对应关系。

    见书中表 13.2 Swing 事件源通常可能触发的事件类型及事件监听者接口。
    
  4. Java 语言中处理事件的具体方法是什么?

    1. 确认触发的事件,取得事件类的名字,如 ActionEvent,去掉其中的 “Event” 字样,在剩下的部分加入 “Listener”,这就是在类中需要实现的事件监听者接口。
    2. 实现上述的接口,针对想要捕获的事件编写方法代码。如要捕获单击按钮事件,就要为 ActionListener 接口里的 actionPerformed() 方法编写代码。
    3. 为事件监听者创建一个对象,让组件调用方法完成对它的注册,方法是在监听者接口的名字里加一个前缀 “add”,如 addActionListener()。
    
  5. 在进行事件处理时,可以使用实现多个监听者接口的方式,也可以尽可能地使用继承适配器类型的方式。使用适配器类的好处是什么?

    当需要对某种事件进行处理时,只需让事件处理类继承事件所对应的适配器类,这样只需覆盖本次操作用到的事件处理方法即可,而不必实现无关的事件处理方法。
    
  6. 设计一个窗口,在窗口内放置一个按钮,当不断地单击该按钮时,在其上显示它被单击的次数。

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

public class Exercise {
    public static void main(String[] args) {
        new Window();
    }
}

class Window extends JFrame {
    private JButton button;
    private int time;
    private JLabel label;
    public Window() {
        button = new JButton("Click Me");
        label = new JLabel("0");
        label.setHorizontalAlignment(JLabel.CENTER);
        time = 0;
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                time++;
                label.setText("" + time);
            }
        });
        add(button, BorderLayout.NORTH);
        add(label, BorderLayout.SOUTH);
        pack();
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
  1. 设计一个窗口,在该窗口中添加一个 JList 组件,该组件中有 5 门课程名称的选项。然后再在窗口中添加一个文本区,当选择 JList 组件中的某个选项后,文本区中显示对该课程的介绍。
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;

public class Exercise {
    public static void main(String[] args) {
        new Window();
    }
}

class Window extends JFrame {
    private JList<String> courses;

    public Window() {
        String[] model = {"English", "Chinese", "C Programing Language", "Java Programing Language", "Math"};
        courses = new JList<>(model);

        JScrollPane scrollPane = new JScrollPane(courses);
        add(scrollPane, BorderLayout.CENTER);

        JTextArea textArea = new JTextArea();
        textArea.setEditable(false);
        add(textArea, BorderLayout.SOUTH);

        courses.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent listSelectionEvent) {
                String s =courses.getSelectedValue();
                switch (s) {
                    case "English" :
                        textArea.setText("This is English");
                        break;
                    case "Chinese" :
                        textArea.setText("This is Chinese");
                        break;
                    case "C Programing Language" :
                        textArea.setText("This is C Programing Language");
                        break;
                    case "Java Programing Language" :
                        textArea.setText("This is Java Programing Language");
                        break;
                    case "Math" :
                        textArea.setText("This is Math");
                        break;
                }
            }
        });
        pack();
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
  1. 设计一个窗口,其中包含一个文本区、两个复选框和 3 个横向滑动条,其中滑动条用来调整 R、G、B 三色的分量从 0 ~ 255 变化;两个复选框分别用于设定把滑动条调出的颜色应用于文本区的前景色还是背景色。
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

public class Exercise {
    public static void main(String[] args) {
        new Window();
    }
}

class Window extends JFrame {

    JCheckBox frontGroundColor = new JCheckBox("frontGroundColor");
    JCheckBox backGroundColor = new JCheckBox("backGroundColor");
    JTextArea textArea = new JTextArea("选择前景色和背景色,滑动滑动条查看颜色变化", 20, 30);
    JSlider rJSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
    JSlider gJSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);
    JSlider bJSlider = new JSlider(JSlider.HORIZONTAL, 0, 255, 0);

    public Window() {
        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
        add(textArea);

        JPanel select = new JPanel();
        select.setLayout(new FlowLayout());
        select.add(frontGroundColor);
        select.add(backGroundColor);
        add(select);

        JPanel colorPanel = new JPanel();
        colorPanel.setLayout(new BoxLayout(colorPanel,BoxLayout.Y_AXIS));
        colorPanel.add(rJSlider);
        colorPanel.add(gJSlider);
        colorPanel.add(bJSlider);

        rJSlider.setMajorTickSpacing(30);
        rJSlider.setMinorTickSpacing(3);
        rJSlider.setPaintTicks(true);
        rJSlider.setPaintLabels(true);
        gJSlider.setMajorTickSpacing(30);
        gJSlider.setMinorTickSpacing(3);
        gJSlider.setPaintTicks(true);
        gJSlider.setPaintLabels(true);
        bJSlider.setMajorTickSpacing(30);
        bJSlider.setMinorTickSpacing(3);
        bJSlider.setPaintTicks(true);
        bJSlider.setPaintLabels(true);
        add(colorPanel);

        frontGroundColor.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                if (frontGroundColor.isSelected()) {
                    textArea.setForeground(new Color(rJSlider.getValue(), gJSlider.getValue(), bJSlider.getValue()));
                }
                else {
                    textArea.setForeground(new Color(0, 0, 0));
                }
            }
        });

        backGroundColor.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent actionEvent) {
                if (backGroundColor.isSelected()) {
                    textArea.setBackground(new Color(rJSlider.getValue(), gJSlider.getValue(), bJSlider.getValue()));
                }
                else {
                    textArea.setBackground(new Color(255, 255, 255));
                }
            }
        });
        rJSlider.addChangeListener(new ColorListen());
        gJSlider.addChangeListener(new ColorListen());
        bJSlider.addChangeListener(new ColorListen());

        pack();
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    class ColorListen implements ChangeListener {
        @Override
        public void stateChanged(ChangeEvent changeEvent) {
            if (frontGroundColor.isSelected()) {
                textArea.setForeground(new Color(rJSlider.getValue(), gJSlider.getValue(), bJSlider.getValue()));
            }
            if (backGroundColor.isSelected()) {
                textArea.setBackground(new Color(rJSlider.getValue(), gJSlider.getValue(), bJSlider.getValue()));
            }
        }
    }
}
  1. 编写一个应用程序,在其中窗口内包含一个菜单栏和一个文本区。菜单栏包括 “设置” 和 “操作” 两个菜单。“操作” 菜单包括 “退出” 菜单项,当用户选择 “退出” 菜单项时,则关闭窗口退出整个应用程序的运行;“设置” 菜单包括 “字体” 和 “风格” 两个菜单项和一个 “只读” 复选菜单项。“字体” 菜单项包括 “宋体”、“楷体” 和 “黑体” 3 个单选子菜单项,“风格” 菜单项包括 “普通”、“粗体”、“斜体” 等 3 个复选子菜单项。当 “只读” 菜单项未被选中时,用户可以在文本区内输入字符:当 “只读” 菜单项被选中时,用户不能在文本区内输入字符。当用户选择其他菜单项时,文本区内的文字随之变化。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTextArea;

public class Exercise {
    public static void main(String[] args) {
        new Window();
    }
}

class Window extends JFrame {

    JTextArea textArea = new JTextArea(20, 30);

    public Window() {
        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

        JMenuBar menuBar = new JMenuBar();
        JMenu setting = new JMenu("Setting");
        JMenu operating = new JMenu("Operating");
        menuBar.add(setting);
        menuBar.add(operating);

        JMenuItem exit = new JMenuItem("Exit");
        exit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        operating.add(exit);

        JMenu style = new JMenu("Style");
        JMenu font = new JMenu("Font");
        ButtonGroup buttonGroup = new ButtonGroup();
        JRadioButtonMenuItem ssti = new JRadioButtonMenuItem("宋体");
        JRadioButtonMenuItem klti = new JRadioButtonMenuItem("楷体");
        JRadioButtonMenuItem hzti = new JRadioButtonMenuItem("黑体");
        buttonGroup.add(ssti);
        buttonGroup.add(klti);
        buttonGroup.add(hzti);
        font.add(ssti);
        font.add(klti);
        font.add(hzti);
        JCheckBoxMenuItem normal = new JCheckBoxMenuItem("正常");
        JCheckBoxMenuItem black = new JCheckBoxMenuItem("粗体");
        JCheckBoxMenuItem till = new JCheckBoxMenuItem("斜体");
        style.add(normal);
        style.add(black);
        style.add(till);
        JRadioButtonMenuItem readOnly = new JRadioButtonMenuItem("Read-Only");
        setting.add(style);
        setting.add(font);
        setting.add(readOnly);

        add(menuBar);

        add(textArea);

        readOnly.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (readOnly.isSelected()) {
                    textArea.setEditable(false);
                } else {
                    textArea.setEditable(true);
                }
            }
        });

        addText(normal);
        addText(black);
        addText(till);
        addText(ssti);
        addText(klti);
        addText(hzti);
        addText(readOnly);

        setVisible(true);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void addText(JMenuItem item) {
        item.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.append(item.getText() + "\n");
            }
        });
    }
}
  1. 在 9 题的基础上增加如下的功能:每当用户选中 “只读” 菜单项时,都将 “字体” 和 “风格” 两个菜单项变成灰色,使之不能被选中;而每当 “只读” 菜单项为被选中时,再将 “字体” 和 “风格” 两个菜单项恢复成可选状态。
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JTextArea;

public class Exercise {
    public static void main(String[] args) {
        new Window();
    }
}

class Window extends JFrame {

    JTextArea textArea = new JTextArea(20, 30);

    public Window() {
        setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));

        JMenuBar menuBar = new JMenuBar();
        JMenu setting = new JMenu("Setting");
        JMenu operating = new JMenu("Operating");
        menuBar.add(setting);
        menuBar.add(operating);

        JMenuItem exit = new JMenuItem("Exit");
        exit.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        operating.add(exit);

        JMenu style = new JMenu("Style");
        JMenu font = new JMenu("Font");
        ButtonGroup buttonGroup = new ButtonGroup();
        JRadioButtonMenuItem ssti = new JRadioButtonMenuItem("宋体");
        JRadioButtonMenuItem klti = new JRadioButtonMenuItem("楷体");
        JRadioButtonMenuItem hzti = new JRadioButtonMenuItem("黑体");
        buttonGroup.add(ssti);
        buttonGroup.add(klti);
        buttonGroup.add(hzti);
        font.add(ssti);
        font.add(klti);
        font.add(hzti);
        JCheckBoxMenuItem normal = new JCheckBoxMenuItem("正常");
        JCheckBoxMenuItem black = new JCheckBoxMenuItem("黑体");
        JCheckBoxMenuItem till = new JCheckBoxMenuItem("斜体");
        style.add(normal);
        style.add(black);
        style.add(till);
        JRadioButtonMenuItem readOnly = new JRadioButtonMenuItem("Read-Only");
        setting.add(style);
        setting.add(font);
        setting.add(readOnly);

        add(menuBar);

        add(textArea);

        readOnly.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                if (readOnly.isSelected()) {
                    textArea.setEditable(false);
                    style.setEnabled(false);
                    font.setEnabled(false);
                } else {
                    textArea.setEditable(true);
                    style.setEnabled(true);
                    font.setEnabled(true);
                }
            }
        });

        addText(normal);
        addText(black);
        addText(till);
        addText(ssti);
        addText(klti);
        addText(hzti);
        addText(readOnly);

        setVisible(true);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }

    private void addText(JMenuItem item) {
        item.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                textArea.append(item.getText() + "\n");
            }
        });
    }
}

第 14 章 绘图程序设计

  1. 简述 Graphics 类的特征。

    Graphics 类是一个特殊类,它是提供与设备无关图形界面的抽象类,它可以在不同平台的屏幕上显示图形和图像。
    
  2. java 语言中提供的用于显示和重画图形的方法有哪几个?

    用于显示图形的方法是 JComponent 类的 paintComponent() 方法,其格式如下:`protected void paintComponent (Graphics g)`
    用于对组件上的图形进行重画可以使用 repaint() 方法,该方法格式如下:`public void repaint ()`。
    
  3. paintComponent() 在什么情况下会自动被调用?

    1. 在组件首次显示或从隐藏变成显示时。
    2. 从缩小的图标还原后。
    3. 正在改变窗口的大小时。
    

第 15 章小程序设计

  1. Java 小程序的基本工作原理是什么?

    将编译好的小程序字节码文件,即 .class 文件保存在特定的 WWW 服务器上,在同一个或另一个 WWW 服务器上保存着嵌有该字节码文件名的 HTML 文件。当某一个浏览器向服务器请求下载嵌入了小程序的 HTML 文件时,该文件从 WWW 服务器上下载到客户端,由 WWW 浏览器解释 HTML 文件中的各种标记,将文件中的信息以一定的格式显示在用户屏幕上。当浏览器遇到 HTML 文件中嵌有小程序的标记时,浏览器会根据这个小程序的名字和位置自动把字节码文件从 WWW 服务器上下载到本地,并利用浏览器本身拥有的 Java 解释器直接执行该字节码文件。
    
  2. init()、start()、stop() 和 destory() 是小程序中非常重要的 4 个方法,请问它们各自的调用时机和功能是什么?

    1. init() 方法:该方法是在小程序被创建时第一个调用的方法,它只运行一次,主要是用来对小程序设置初值之用。它的原理和一个构造方法差不多。一般进行的操作是:设置初始状态和参数值,添加用户接口组件以及装载图像等。
    2. start() 方法:调用完 init() 方法之后,就立即调用 start() 方法。只要小程序画面每出现一次,start() 方法就会被调用一次。如果切换到其它网页浏览,再返回到本页面时,用户使用了浏览器的 Reload(刷新)操作等,start() 方法都会再运行一次。所以对于只打算使用一次的代码,可以放在 init() 方法中,不必定义在这个方法内;而需要经常重复启动的操作则应放在 start() 方法中。在多线程的程序设计中 start() 方法主要用于编写启动线程的代码,如动画、音频的启动运行等。
    3. stop() 方法:stop() 方法类似于 start() 方法的 你操作,当浏览器窗口失去焦点变为不活动状态、切换到其他网页浏览或是关闭浏览器时,需要停止小程序的运行,此时系统会自动调用 stop() 方法以暂停小程序的运行,所以 stop() 方法也可以被重复调用。stop() 方法常常用于完成暂停小程序运行并暂时释放小程序所占用的资源的功能。
    4. destroy() 方法:当用户退出浏览器时,浏览器运行的小程序也将停止运行,释放内存。此时浏览器会自动调用小程序对象的 destroy() 方法来完成一些释放资源、关闭连接之类的操作等。但在关闭浏览器时会先调用 stop() 方法暂停运行小程序,然后再调用 destroy() 方法来释放被小程序所占用的资源。
    
  3. 如何向小程序传递参数?

    Java 应用程序是通过命令行来接受用户参数的,在小程序中这个任务是通过 HTML 文件的一个专门标记 <Param> 来完成的。在 HTML 文件和小程序之间进行参数传递,需要注意以下几点:
    1. 在 HTML 文件中通过 Param 标记来设置要向小程序进行传递的参数。
    2. 小程序中只能在 init() 方法中调用 getParameter() 方法来接收 HTML 文件传递来的参数。
    3. 在 HTML 文件中由 Param 设置的参数名称必须与 getParameter() 方法中接受参数的名成匹配,两者军事区别大小写的。
    4. HTML 文件中的每个 Param 标记只能传递一个且为字符串型的参数。而小程序中接收参数的 getParameter() 方法的返回值也是字符串型,所以如果需要的是其它类型的数据,则还需要将字符串转换成相应的类型。
    
  4. 将 Java 的应用程序转换成小程序的主要步骤有哪些?

    将应用程序转换成小程序,其转换步骤如下:
    1. 制作一个 HTML 网页文件,带有相应的标记,从而能够下载小程序的代码。
    2. 声明一个类,使其继承 Applet 或 JApplet 类。若使用 Swing 组件,则必须继承 JApplet 类,并使其为 public 类型,否则这个小程序不能被下载。
    3. 在应用程序中去掉 mian() 方法。
    4. 在应用程序中,设置窗口的大小是通过调用 setSize() 方法来实现的;在小程序中设定它的大小是通过在 HTML 文件中设置 Width 和 Height 两个参数来实现的。
    5. 小程序在浏览器退出时,它会终止。
    6. 如果在应用程序中使用 setTitle() 为窗口中设置标题,那么在转换成小程序时此方法不能使用。
    7. 用 init() 方法替换构造方法,在浏览器创建这个小程序类的一个对象时,它调用了 init() 方法。 
    
  5. 编写小程序,用 paint() 方法显示一行字符串,小程序包含 “放大” 和 “缩小” 两个按钮。当单击 “放大” 按钮时,显示的字符串的字体放大一号;单击 “缩小” 按钮时,显示的字符串字体缩小一号。

import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JApplet;
import javax.swing.JButton;
import javax.swing.JTextArea;

public class Exercise extends JApplet {

    private String s;
    private JButton big;
    private JButton smaller;
    private int size = 16;
    private JTextArea textArea;
    @Override
    public void init() {
        s = "This is a string";
        big = new JButton("放大");
        smaller = new JButton("缩小");
        textArea = new JTextArea(s);
        textArea.setFont(new Font(s, Font.ITALIC, size));

        Container c = getContentPane();
        c.setLayout(new FlowLayout());
        c.add(textArea);
        c.add(big);
        c.add(smaller);

        big.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                size++;
                textArea.setFont(new Font(s, Font.ITALIC, size));
            }
        });
        smaller.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                size--;
                textArea.setFont(new Font(s, Font.ITALIC, size));
            }
        });
    }
}
  1. 加载与显示图像的操作需要经过哪 3 个步骤?

    1. 声明 Image 类型的对象。
    2. 利用 getImage() 方法加载图像。
    3. 利用 drawImage() 方法绘制出图像。
    

第 17 章 Java 网络编程

  1. 什么是 URL?URL 地址由哪几部分组成?

    URL 是统一资源定位器(Uniform Resource Locator)的英文缩写,它表示 Internet 上某一资源的地址;
    URL 的基本结构由 5 部分组成,其格式如下:
    传输协议://主机名:端口号/文件名#引用
    1. 传输协议(protocol):传输协议是指所使用的协议名,如 HTTP、FTP等。
    2. 主机名(hostname):主机名是指资源所在的计算机。可以是 IP 地址,也可以是计算机的名称或域名。
    3. 端口号(portnumber):一个计算机中可能有多种服务,如 Web 服务、FTP 服务或自己建立的服务等。为了区分这些服务,就需要使用端口号,每一种服务用一个端口号。
    4. 文件名(filename):文件名包括该文件的完整路径。在 HTTP 协议中,有一个默认的文件名 index.html,因此,下列两个地址是等价的。
        http://java.sun.com
        http://java.sun.com/index.html
    5. 引用(reference):引用就是资源内部的某个参考点。如:
        http://java.sun.com/index.html#chapter1
    说明:对于一个 URL 来说,并不是要求它必须包含所有的这 5 部分内容。
    
  2. 什么是 Socket?它与 TCP/IP 协议有何关系?

    Socket 通信属于网络底层通信,它是网络上运行的两个程序之间双向通信的一端,它既可以接受请求,也可以发送请求,利用它可以较方便地进行网络上的数据传输。Socket 是实现客户与服务器(Client/Server)模式的通信方式,它首先需要建立稳定的连接,然后以流的方式传输数据,实现网络通信。Socket 原意为 “插座”,在通信领域中译为 “套接字”,意思是将两个物品套在一起,在网络通信里的含义就是建立一个连接;
    Socket 在 TCP/IP 协议中定义,针对一个特定的连接。
    
  3. 简述流式 Socket 的通信机制。它的最大特点是什么?为什么可以实现无差错通信?

    当两台计算机进行通信时,首先要在两者之间建立一个连接,也就是两者分别运行不同的程序,由一端发出连接请求,另一端等候连接请求。当等候端收到请求并接受请求后,两个程序就建立起一个连接,之后通过这个连接可以进行数据交换。
    
  4. 什么是端口号?服务器和客户端分别如何使用端口号?

    端口号是区分一台主机中的不同应用程序的正整数;服务器和客户端必须为每个程序分配一个唯一的端口号,通过端口号指定要连接的程序。
    
  5. 什么是套接字?其作用是什么?

    套接字是实现客户与服务器模式的通信模式,它首先需要建立稳定的连接,然后以流的方式传输数据,实现网络通信;
    套接字是网络上运行的两个程序间双向通信的一端,既可以接受请求,也可以发送请求,利用它可以较方便地进行网络上的数据传输。
    
  6. 编写 Java 程序,使用 InetAddress 类实现根据域名自动到 DNS(域名服务器)上查找 IP 地址的功能。

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.net.UnknownHostException;

public class Exercise {
    public static void main(String[] args) throws IOException {
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        String dns = bufferedReader.readLine();
        bufferedReader.close();
        InetAddress inetAddress = null;
        try {
            inetAddress = InetAddress.getByName(dns);
            System.out.println(inetAddress.getHostAddress());
        } catch (UnknownHostException e) {
            System.out.println("Your Input Domain Can't Parse.");
        }
    }
}
  1. 用 Java 程序实现流式 Socket 通信,需要使用哪两个类?它们是如何定义的?应怎样使用?

    Socket 类与 ServerSocket 类;
    Socket 类在 java.net.Socket 继承自 java.lang.Object 类。Socket 类用在客户端,用户通过创建一个 Socket 对象来建立与服务器的连接。
    ServerSocket 类在 java.net 包中,java.ner.ServerSocket 继承自 java.lang.Object 类。ServerSocket 类的作用是实现客户机 / 服务器模式的通信方式下服务器端的套接字。
    
  2. 与流式 Socket 相比,数据报通信有何特点?

    数据报是无连接的远程通信服务,它是一种在网络中传输的、独立的、自身包含地址信息的数据单位,不保证传送顺序和内容的准确性。
    
已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页