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 相比,數據報通信有何特點?

    數據報是無連接的遠程通信服務,它是一種在網絡中傳輸的、獨立的、自身包含地址信息的數據單位,不保證傳送順序和內容的準確性。
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章