1. 程式人生 > >201771010135 楊蓉慶《面對物件程式設計(java)》第十六週學習總結

201771010135 楊蓉慶《面對物件程式設計(java)》第十六週學習總結

1、實驗目的與要求

(1) 掌握執行緒概念;

(2) 掌握執行緒建立的兩種技術;

(3) 理解和掌握執行緒的優先順序屬性及排程方法;

(4) 掌握執行緒同步的概念及實現技術;

一、理論知識

⚫ 執行緒的概念

 

(1)多執行緒是程序執行過程中產生的多條執行線索。

‐執行緒是比程序執行更小的單位。

‐執行緒不能獨立存在,必須存在於程序中,同一進 程的各執行緒間共享程序空間的資料。

‐每個執行緒有它自身的產生、存在和消亡的過程, 是一個動態的概念。

‐多執行緒意味著一個程式的多行語句可以看上去幾 乎在同一時間內同時執行。

(2)Java實現多執行緒有兩種途徑: ‐建立Thread類的子類

‐在程式中定義實現Runnable介面的類

(3)用Thread類的子類建立執行緒:首先需從Thread類派生出一個子類,在該子類中 重寫run()方法,然後用建立該子類的物件,最後用start()方法啟動執行緒。

(4)用Runnable()介面實現執行緒:首先設計一個實現Runnable介面的類; 然後在類中根據需要重寫run方法;  再建立該類物件,以此物件為引數建立Thread 類的物件; 呼叫Thread類物件的start方法啟動執行緒,將 CPU執行權轉交到run方法。

(5)執行緒兩種建立方法比較:

實現Runnable介面的優勢: 符合OO設計的思想 •便於用extends繼承其它類

採用繼承Thread類方法的優點:程式碼簡單

⚫ 中斷執行緒

(1)當執行緒的run方法執行方法體中最後一條語句後, 或者出現了在run方法中沒有捕獲的異常時,線 程將終止,讓出CPU使用權。

(2)呼叫interrupt()方法也可終止執行緒。 void interrupt() – 向一個執行緒傳送一箇中斷請求,同時把這個線 程的“interrupted”狀態置為true。

(3)Java提供了幾個用於測試執行緒是否被中斷的方法。 ⚫ static boolean interrupted() – 檢測當前執行緒是否已被中斷 , 並重置狀態 “interrupted”值為false。 ⚫ boolean isInterrupted() – 檢測當前執行緒是否已被中斷 , 不改變狀態 “interrupted”值 。

⚫ 執行緒狀態

(1)利用各執行緒的狀態變換,可以控制各個執行緒輪流 使用CPU,體現多執行緒的並行性特徵。

(2)執行緒有如下7種狀態: ➢ New (新建) ➢ Runnable (可執行) ➢ Running(執行) ➢ Blocked (被阻塞) ➢ Waiting (等待) ➢ Timed waiting (計時等待) ➢ Terminated (被終止)

(3)其他判斷和影響執行緒狀態的方法:

➢join():等待指定執行緒的終止。

➢join(long millis):經過指定時間等待終止指定 的執行緒。

➢isAlive():測試當前執行緒是否在活動。

➢yield():讓當前執行緒由“執行狀態”進入到“就 緒狀態” ,從而讓其它具有相同優先順序的等待執行緒 獲取執行權。

⚫ 多執行緒排程

(1)Java提供一個執行緒排程器來監控程式啟動後進入 可執行狀態的所有執行緒。執行緒排程器按照執行緒的 優先順序決定應排程哪些執行緒來執行。

(2)Java 的執行緒排程採用優先順序策略:

➢ 優先順序高的先執行,優先順序低的後執行;

➢ 多執行緒系統會自動為每個執行緒分配一個優先順序,預設 時,繼承其父類的優先順序;

➢ 任務緊急的執行緒,其優先順序較高;

➢ 同優先順序的執行緒按“先進先出”的佇列原則;

(3)呼叫setPriority(int a)重置當前執行緒的優先順序, a 取值可以是前述的三個靜態量。

呼叫getPriority()獲得當前執行緒優先順序。

(4)下面幾種情況下,當前執行執行緒會放棄CPU: – 執行緒呼叫了yield() 或sleep() 方法;

– 搶先式系統下,有高優先順序的執行緒參與排程;

– 由於當前執行緒進行I/O訪問、外存讀寫、等待用 戶輸入等操作導致執行緒阻塞;或者是為等候一 個條件變數,以及執行緒呼叫wait() 方法。

⚫ 執行緒同步

(1)多執行緒併發執行不確定性問題解決方案:引入線 程同步機制,使得另一執行緒要使用該方法,就只 能等待

(2)在Java中解決多執行緒同步問題的方法有兩種:

解決方案一:鎖物件與條件物件

用ReentrantLock保護程式碼塊的基本結構如下: myLock.lock();

try { critical section }

finally{ myLock.unlock(); }

(3)解決方案二: synchronized關鍵字

synchronized關鍵字作用: ➢ 某個類內方法用synchronized 修飾後,該方 法被稱為同步方法;

➢ 只要某個執行緒正在訪問同步方法,其他執行緒欲要訪問同步方法就被阻塞,直至執行緒從同步方法返回前喚醒被阻塞執行緒,其他執行緒方可能進入同步方法。

(4)在同步方法中使用wait()、notify 和notifyAll()方法

一個執行緒在使用的同步方法中時,可能根據問題 的需要,必須使用wait()方法使本執行緒等待,暫 時讓出CPU的使用權,並允許其它執行緒使用這個 同步方法。

執行緒如果用完同步方法,應當執行notifyAll()方 法通知所有由於使用這個同步方法而處於等待的 執行緒結束等待。

、實驗內容和步驟

 實驗1:測試程式並進行程式碼註釋。

測試程式1:

l 在elipse IDE中除錯執行ThreadTest,結合程式執行結果理解程式;

l 掌握執行緒概念;

l 掌握用Thread的擴充套件類實現執行緒的方法;

l 利用Runnable介面改造程式,掌握用Runnable介面建立執行緒的方法。

class Lefthand extends Thread { 
   public void run()
   {
       for(int i=0;i<=5;i++)
       {  System.out.println("You are Students!");
           try{   Thread.sleep(500);   }
           catch(InterruptedException e)
           { System.out.println("Lefthand error.");}    
       } 
  } 
}
class Righthand extends Thread {
    public void run()
    {
         for(int i=0;i<=5;i++)
         {   System.out.println("I am a Teacher!");
             try{Thread.sleep(300);  }
             catch(InterruptedException e)
             { System.out.println("Righthand error.");}
         }
    }
}
public class ThreadTest 
{
     static Lefthand left;
     static Righthand right;
     public static void main(String[] args)
     {   Runnable left=new Lefthand();
         Runnable right=new Righthand();
         Thread t=new Thread(left);
         Thread s=new Thread(right);
         left=new Lefthand();
         right=new Righthand();
          t.start();
           s.start();
     }
}
Thread

  

測試程式2

l 在Elipse環境下除錯教材625頁程式14-1、14-2 14-3,結合程式執行結果理解程式;

l 在Elipse環境下除錯教材631頁程式14-4,結合程式執行結果理解程式;

l 對比兩個程式,理解執行緒的概念和用途;

l 掌握執行緒建立的兩種技術。

(1)

package bounce;

import java.awt.geom.*;

/**
 * A ball that moves and bounces off the edges of a rectangle
 * @version 1.33 2007-05-17
 * @author Cay Horstmann
 */
public class Ball
{//定義球的大小
   private static final int XSIZE = 15;
   private static final int YSIZE = 15;
   private double x = 0;
   private double y = 0;
   private double dx = 1;
   private double dy = 1;

   /**
    * Moves the ball to the next position, reversing direction if it hits one of the edges
    */
   public void move(Rectangle2D bounds)
   {  // 定義球的執行軌跡
      x += dx;
      y += dy;
      if (x < bounds.getMinX())
      {
         x = bounds.getMinX();
         dx = -dx;
      }
      if (x + XSIZE >= bounds.getMaxX())
      {
         x = bounds.getMaxX() - XSIZE;
         dx = -dx;
      }
      if (y < bounds.getMinY())
      {
         y = bounds.getMinY();
         dy = -dy;
      }
      if (y + YSIZE >= bounds.getMaxY())
      {
         y = bounds.getMaxY() - YSIZE;
         dy = -dy;
      }//四次定義移動邏輯,
   }

   /**
    * Gets the shape of the ball at its current position.
    */
   public Ellipse2D getShape()
   {
      return new Ellipse2D.Double(x, y, XSIZE, YSIZE);
   }
}
Ball
package bounce;

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

/**
 * The component that draws the balls.
 * @version 1.34 2012-01-26
 * @author Cay Horstmann
 */
public class BallComponent extends JPanel
{  //定義長、寬
   private static final int DEFAULT_WIDTH = 450;
   private static final int DEFAULT_HEIGHT = 350;

   private java.util.List<Ball> balls = new ArrayList<>();

   /**
    * Add a ball to the component.
    * @param b the ball to add
    */
   public void add(Ball b)
   {
      balls.add(b);
   }

   public void paintComponent(Graphics g)
   {
      super.paintComponent(g); // erase background
      Graphics2D g2 = (Graphics2D) g;
      for (Ball b : balls)
      {
         g2.fill(b.getShape());
      }
   }
   
   public Dimension getPreferredSize() { return new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT); }
}
BallComponent
package bounce;

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

/**
 * Shows an animated bouncing ball.
 * @version 1.34 2015-06-21
 * @author Cay Horstmann
 */
public class Bounce
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new BounceFrame();
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//關閉介面
         frame.setVisible(true);//結果可見
      });
   }
}

/**
 * The frame with ball component and buttons.
 */
class BounceFrame extends JFrame
{
   private BallComponent comp;
   public static final int STEPS = 1000;
   public static final int DELAY = 3;

   /**
    * Constructs the frame with the component for showing the bouncing ball and
    * Start and Close buttons
    */
   public BounceFrame()
   {
      setTitle("Bounce");
      comp = new BallComponent();
      add(comp, BorderLayout.CENTER);//放到框架居中位置
      JPanel buttonPanel = new JPanel();
      addButton(buttonPanel, "Start", event -> addBall());//按鈕物件新增到buttonPanel中
      addButton(buttonPanel, "Close", event -> System.exit(0));
      add(buttonPanel, BorderLayout.SOUTH);//整體放到南端
      pack();
   }

   /**
    * Adds a button to a container.
    * @param c the container
    * @param title the button title
    * @param listener the action listener for the button
    */
   public void addButton(Container c, String title, ActionListener listener)
   {
      JButton button = new JButton(title);//生成title按鈕
      c.add(button);
      button.addActionListener(listener);
   }

   /**
    * Adds a bouncing ball to the panel and makes it bounce 1,000 times.
    */
   public void addBall()
   {
      try
      {
         Ball ball = new Ball();
         comp.add(ball);

         for (int i = 1; i <= STEPS; i++)
         {
            ball.move(comp.getBounds());//呼叫move方法來顯示 
            comp.paint(comp.getGraphics());
            Thread.sleep(DELAY);//休眠
         }
      }
      //丟擲異常
      catch (InterruptedException e)
      {
      }
   }
}
Bounce

(2)   前兩個程式如(1)所示,

package bounceThread;

import java.awt.*;
import java.awt.event.*;

import javax.swing.*;

/**
 * Shows animated bouncing balls.
 * @version 1.34 2015-06-21
 * @author Cay Horstmann
 */
public class BounceThread
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new BounceFrame();
         frame.setTitle("BounceThread");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);
      });
   }
}

/**
 * The frame with panel and buttons.
 */
class BounceFrame extends JFrame
{
   private BallComponent comp;
   public static final int STEPS = 1000;
   public static final int DELAY = 5;


   /**
    * Constructs the frame with the component for showing the bouncing ball and
    * Start and Close buttons
    */
   public BounceFrame()
   {
      comp = new BallComponent();
      add(comp, BorderLayout.CENTER);//放到框架居中位置
      JPanel buttonPanel = new JPanel();
      addButton(buttonPanel, "Start", event -> addBall());//
      addButton(buttonPanel, "Close", event -> System.exit(0));
      add(buttonPanel, BorderLayout.SOUTH);//整體放到南端
      pack();
   }

   /**
    * Adds a button to a container.
    * @param c the container
    * @param title the button title
    * @param listener the action listener for the button
    */
   public void addButton(Container c, String title, ActionListener listener)
   {
      JButton button = new JButton(title);
      c.add(button);
      button.addActionListener(listener);
   }

   /**
    * Adds a bouncing ball to the canvas and starts a thread to make it bounce
    */
   public void addBall()
   {
      Ball ball = new Ball();
      comp.add(ball);
      Runnable r = () -> { //實現一個BallRunnable類,將動畫程式碼放到run方法中
         try
         {  
            for (int i = 1; i <= STEPS; i++)
            {
               ball.move(comp.getBounds());
               comp.repaint();
               Thread.sleep(DELAY);//捕獲sleep方法丟擲的異常InterruptedException
            }
         }
         catch (InterruptedException e)
         {
         }
      };
      Thread t = new Thread(r);
      t.start();
   }
}
BounceThread

 

 

測試程式3:分析以下程式執行結果並理解程式。

class Race extends Thread {
  public static void main(String args[]) {
    Race[] runner=new Race[4];
    for(int i=0;i<4;i++) 
        runner[i]=new Race( );
   for(int i=0;i<4;i++)
       runner[i].start( );
   runner[1].setPriority(MIN_PRIORITY);//設定執行緒的最小優先順序
   runner[3].setPriority(MAX_PRIORITY);}//設定執行緒的最大優先順序
  public void run( ) {
      for(int i=0; i<1000000; i++);//延時作用,執行空語句
      System.out.println(getName()+"執行緒的優先順序是"+getPriority()+"已計算完畢!");
    }
}

測試程式4

l 教材642頁程式模擬一個有若干賬戶的銀行,隨機地生成在這些賬戶之間轉移錢款的交易。每一個賬戶有一個執行緒。在每一筆交易中,會從執行緒所服務的賬戶中隨機轉移一定數目的錢款到另一個隨機賬戶。

l 在Elipse環境下除錯教材642頁程式14-5、14-6,結合程式執行結果理解程式;

 bank

package unsynch;

/**
 * This program shows data corruption when multiple threads access a data structure.
 * @version 1.31 2015-06-21
 * @author Cay Horstmann
 */
public class UnsynchBankTest
{
   public static final int NACCOUNTS = 100;
   public static final double INITIAL_BALANCE = 1000;
   public static final double MAX_AMOUNT = 1000;
   public static final int DELAY = 10;
   
   public static void main(String[] args)
   { 
      Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
      for (int i = 0; i < NACCOUNTS; i++)
      {
         int fromAccount = i;
         Runnable r = () -> {
            try
            {
               while (true)
               {
                  int toAccount = (int) (bank.size() * Math.random());
                  double amount = MAX_AMOUNT * Math.random();
                  bank.transfer(fromAccount, toAccount, amount);
                  Thread.sleep((int) (DELAY * Math.random()));
               }
            }
            catch (InterruptedException e)
            {
            }            
         };
         Thread t = new Thread(r);
         t.start();
      }
   }
}
UnsynchBankTest

綜合程式設計練習

程式設計練習1

  1. 設計一個使用者資訊採集程式,要求如下:

(1) 使用者資訊輸入介面如下圖所示:

(1) 使用者點選提交按鈕時,使用者輸入資訊顯示控制檯介面;

(2) 使用者點選重置按鈕後,清空使用者已輸入資訊;

(3) 點選視窗關閉,程式退出。

import java.awt.EventQueue;

import javax.swing.JFrame;

public class Main {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            DemoJFrame page = new DemoJFrame();
        });
    }
}
Main
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.Window;

public class WinCenter {
    public static void center(Window win){
        Toolkit tkit = Toolkit.getDefaultToolkit();
        Dimension sSize = tkit.getScreenSize();
        Dimension wSize = win.getSize();
        if(wSize.height > sSize.height){
            wSize.height = sSize.height;
        }
        if(wSize.width > sSize.width){
            wSize.width = sSize.width;
        }
        win.setLocation((sSize.width - wSize.width)/ 2, (sSize.height - wSize.height)/ 2);
    }
}
WinCenter
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
public class DemoJFrame extends JFrame {
    public DemoJFrame() {
        JPanel panel1 = new JPanel();
        panel1.setPreferredSize(new Dimension(700, 45));
        panel1.setLayout(new GridLayout(1, 4));
        JLabel label1 = new JLabel("Name:");
        JTextField j1 = new JTextField("");
        JLabel label2 = new JLabel("Qualification:");
        JComboBox<Object> j2 = new JComboBox<>();
        j2.addItem("chuzhong");
        j2.addItem("gaozhong");
        j2.addItem("undergraduate");
        panel1.add(label1);
        panel1.add(j1);
        panel1.add(label2);
        panel1.add(j2);

        JPanel panel2 = new JPanel();
        panel2.setPreferredSize(new Dimension(700, 65));
        panel2.setLayout(new GridLayout(1, 4));
        JLabel label3 = new JLabel("Address:");
        JTextArea j3 = new JTextArea();
        JLabel label4 = new JLabel("Hobby:");
        JPanel p = new JPanel();
        p.setLayout(new GridLayout(3, 1));
        p.setBorder(BorderFactory.createLineBorder(null));
        JCheckBox c1 = new JCheckBox("Reading");
        JCheckBox c2 = new JCheckBox("Singing");
        JCheckBox c3 = new JCheckBox("Dancing");
        p.add(c1);
        p.add(c2);
        p.add(c3);
        panel2.add(label3);
        panel2.add(j3);
        panel2.add(label4);
        panel2.add(p);

        JPanel panel3 = new JPanel();
        panel3.setPreferredSize(new Dimension(700, 150));
        FlowLayout flowLayout1 = new FlowLayout(FlowLayout.LEFT, 70, 40);
        panel3.setLayout(flowLayout1);
        JLabel label5 = new JLabel("Sex:");
        JPanel p1 = new JPanel();
        p1.setLayout(new GridLayout(2,1));
        p1.setBorder(BorderFactory.createLineBorder(null));
        ButtonGroup bu = new ButtonGroup();
        JRadioButton jr1 = new JRadioButton("Male");
        JRadioButton jr2 = new JRadioButton("Female");
        bu.add(jr1);
        bu.add(jr2);
        p1.add(jr1);
        p1.add(jr2);
        panel3.add(label5);
        panel3.add(p1);
        add(panel1);
        add(panel2);
        add(panel3);

        JPanel panel4 = new JPanel();
        panel4.setPreferredSize(new Dimension(700, 150));
        JButton b1 = new JButton("Validate");
        panel4.add(b1);
        JButton b2 = new JButton("Reset");
        panel4.add(b2);
        add(panel4);

        FlowLayout flowLayout = new FlowLayout();
        this.setLayout(flowLayout);
        this.setTitle("Students Detail");
        this.setBounds(300, 300, 800, 400);
        this.setVisible(true);
        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);

        b1.addActionListener(new ActionListener() {

        
            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                String xueli = j2.getSelectedItem().toString();
                System.out.println("Name:" + j1.getText());
                System.out.println("Qualification:" + xueli);
                String hobbystring = "Hobby:";
                if (c1.isSelected()) {
                    hobbystring += "Reading";
                }
                if (c2.isSelected()) {
                    hobbystring += "Singing";
                }
                if (c3.isSelected()) {
                    hobbystring += "Dancing";
                }
                System.out.println("Address:" + j3.getText());
                if (jr1.isSelected()) {
                    System.out.println("Sex:Male");
                }
                if (jr2.isSelected()) {
                    System.out.println("Sex:Female");
                }
                System.out.println(hobbystring);
            }
        });
        b2.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                // TODO 自動生成的方法存根
                j1.setText(null);
                j3.setText(null);
                j2.setSelectedIndex(0);
                c1.setSelected(false);
                c2.setSelected(false);
                c3.setSelected(false);
                bu.clearSelection();
            }
        });
    }

    public static void main(String args[]) {
        new DemoJFrame();
    }

}
DemoJFrame

 

結果如下:

重置:

2.建立兩個執行緒,每個執行緒按順序輸出5次“你好”,每個“你好”要標明來自哪個執行緒及其順序號。

class Lefthand implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(i + 1 + ":first.你好!");
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                System.out.println("Lefthand error.");
            }
        }
    }
}

class Righthand implements Runnable {
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(i + 1 + ":second.你好!");
            try {
                Thread.sleep(300);
            } catch (InterruptedException e) {
                System.out.println("Righthand error.");
            }
        }
    }
}

public class ThreadTest {
    public static void main(String[] args) {
        Runnable left = new Lefthand();
        Thread l = new Thread(left);
        Runnable right = new Righthand();
        Thread r = new Thread(right);
        l.start();
        r.start();
    }
}
ThreadTest

3. 完善實驗十五 GUI綜合程式設計練習程式。

1、

package 身份證;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Scanner;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

public class Main extends JFrame {
    private static ArrayList<Student> studentlist;
    private static ArrayList<Student> list;
    private JPanel panel;
    private JPanel buttonPanel;
    private static final int DEFAULT_WITH = 900;
    private static final int DEFAULT_HEIGHT = 500;

    public Main() {
        studentlist = new ArrayList<>();
        Scanner scanner = new Scanner(System.in);
        File file = new File("D:\\java\\身份證號.txt");
        try {
            FileInputStream fis = new FileInputStream(file);
            BufferedReader in = new BufferedReader(new InputStreamReader(fis));
            String temp = null;
            while ((temp = in.readLine()) != null) {

                Scanner linescanner = new Scanner(temp);

                linescanner.useDelimiter(" ");
                String name = linescanner.next();
                String number = linescanner.next();
                String sex = linescanner.next();
                String age = linescanner.next();
                String province = linescanner.nextLine();
                Student student = new Student();
                student.setName(name);
                student.setnumber(number);
                student.setsex(sex);
                int a = Integer.parseInt(age);
                student.setage(a);
                student.setprovince(province);
                studentlist.add(student);

            }
        } catch (FileNotFoundException e) {
            System.out.println("學生資訊檔案找不到");
            e.printStackTrace();
        } catch (IOException e) {
            System.out.println("學生資訊檔案讀取錯誤");
            e.printStackTrace();
        }
        panel = new JPanel();
        panel.setLayout(new BorderLayout());
        JTextArea jt = new JTextArea();
        panel.add(jt);
        add(panel, BorderLayout.NORTH);
        buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(1, 8));
        JButton jButton = new JButton("字典排序");
        JButton jButton1 = new JButton("年齡最大和年齡最小");
        JLabel lab = new JLabel("查詢你的同鄉");
        JTextField jt1 = new JTextField();
        JLabel lab1 = new JLabel("查詢與你年齡相近的人:");
        JTextField jt2 = new JTextField();
        JLabel lab2 = new JLabel("輸入你的身份證號碼:");
        JTextField jt3 = new JTextField();
        JButton jButton2 = new JButton("退出");
        jButton.setBounds(900, 200,100, 90);
        jButton1.setBounds(50, 120, 90, 60);
        jt1.setBounds(900, 120, 100, 80);
        jt2.setBounds(800, 200, 100, 80);
        jt3.setBounds(450, 120, 80, 90);
        jButton2.setBounds(800,200, 60, 50);
        jButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Collections.sort(studentlist);
                jt.setText(studentlist.toString());
            }
        });
        jButton1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                int max = 0, min = 100;
                int j, k1 = 0, k2 = 0;
                for (int i = 1; i < studentlist.size(); i++) {
                    j = studentlist.get(i).getage();
                    if (j > max) {
                        max = j;
                        k1 = i;
                    }
                    if (j < min) {
                        min = j;
                        k2 = i;
                    }

                }
                jt.setText("年齡最大:" + studentlist.get(k1) + "年齡最小:" + studentlist.get(k2));
            }
        });
        jButton2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                dispose();
                System.exit(0);
            }
        });
        jt1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String find = jt1.getText();
                String text="";
                String place = find.substring(0, 3);
                for (int i = 0; i < studentlist.size(); i++) {
                    if (studentlist.get(i).getprovince().substring(1, 4).equals(place)) {
                        text+="\n"+studentlist.get(i);
                        jt.setText("老鄉:" + text);
                    }
                }
            }
        });
        jt2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                String yourage = jt2.getText();
                int a = Integer.parseInt(yourage);
                int near = agenear(a);
                int value = a - studentlist.get(near).getage();
                jt.setText("年齡相近:" + studentlist.get(near));
            }
        });
        jt3.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                list = new ArrayList<>();
                Collections.sort(studentlist);
                String key = jt3.getText();
                for (int i = 1; i < studentlist.size(); i++) {
                    if (studentlist.get(i).getnumber().contains(key)) {                        
                        list.add(studentlist.get(i));                        
                        jt.setText("你或許是:\n" + list);
                        
                    }                    
                }
            }
        });
        buttonPanel.add(jButton);
        buttonPanel.add(jButton1);
        buttonPanel.add(lab);
        buttonPanel.add(jt1);
        buttonPanel.add(lab1);
        buttonPanel.add(jt2);
        buttonPanel.add(lab2);
        buttonPanel.add(jt3);
        buttonPanel.add(jButton2);
        add(buttonPanel, BorderLayout.SOUTH);
        setSize(DEFAULT_WITH, DEFAULT_HEIGHT);
    }

    public static int agenear(int age) {
        int min = 53, value = 0, k = 0;
        for (int i = 0; i < studentlist.size(); i++) {
            value = studentlist.get(i).getage() - age;
            if (value < 0)
                value = -value;
            if (value < min) {
                min = value;
                k = i;
            }
        }
        return k;
    }

}
Main

 

package 身份證;

public class Student implements Comparable<Student> {

    private String name;
    private String number ;
    private String sex ;
    private int age;
    private String province;
   
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getnumber() {
        return number;
    }
    public void setnumber(String number) {
        this.number = number;
    }
    public String getsex() {
        return sex ;
    }
    public void setsex(String sex ) {
        this.sex =sex ;
    }
    public int getage() {

        return age;
        }
        public void setage(int age) {
            // int a = Integer.parseInt(age);
        this.age= age;
        }

    public String getprovince() {
        return province;
    }
    public void setprovince(String province) {
        this.province=province ;
    }

    public int compareTo(Student o) {
       return this.name.compareTo(o.getName());
    }

    public String toString() {
        return  name+"\t"+sex+"\t"+age+"\t"+number+"\t"+province+"\n";
    }    
}
Student
package 身份證;

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

public class ButtonText {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new Main();
            frame.setTitle("身份證");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}
ButtonText

2、

package 答題;
 
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.util.Random;
import javax.swing.*;
 
public class Exam extends JFrame {
    JPanel p=new JPanel();
    JLabel timeLabel=new JLabel();
      
    JLabel[] label1=new JLabel[10];
    JLabel[] label2=new JLabel[10];
    JLabel[] label3=new JLabel[10];
    JLabel[] label4=new JLabel[10];
    JLabel[] label5=new JLabel[10];
    JTextField[] field=new JTextField[10];
    JLabel[] label6=new JLabel[10];
    String[] btn_name= {"開始","重置","提交","重考"};
    JButton[] btn=new JButton[4];
    Panel2 panel2=null;
    int ExamCount=0;
    JLabel examLabel=new JLabel();
    double[] result=new double[10];
    public static void main(String[] args) {
        new Exam("測試").setVisible(true);
    }
      
    public Exam(String title) {
        setTitle(title);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(3);
        setSize(400,500);
        setResizable(false);
        setForeground(Color.blue);
        add(new Panel1(),BorderLayout.NORTH);
        panel2=new Panel2();
        add(new JScrollPane(panel2));
        add(new Panel3(),BorderLayout.WEST);      
    }
 
    int rightResultCount=0;
    public void startExam() {
        int num1=0;
        int num2=0;
        String[] quots= {"+","-","*","/"};
        String quot=null;
        Random ran=null;
        ran=new Random(System.currentTimeMillis());
        Box box=Box.createVerticalBox();
          
        for(int i=0;i<10;i++) {
            num1=ran.nextInt(100)+1;
            num2=ran.nextInt(100)+1;
            int n=ran.nextInt(4);
            quot=new String(quots[n]);
            switch(quot) {
            case "+":
                result[i]=num1+num2;
                break;
            case "-":
                result[i]=num1-num2;
                break;
            case "*":
                result[i]=num1*num2;
                break;
            case "/":
                result[i]=num1/(num2*1.0);
                result[i]=Math.round(result[i]*100)/100.0;
                break;
            }
              
            label1[i]=new JLabel("第"+(i+1)+"題:");
            label2[i]=new JLabel(num1+"");
              
            label3[i]=new JLabel(quot);
            label4[i]=new JLabel(num2+"");
            label5[i]=new JLabel("=");
            field[i]=new JTextField();
            field[i].setPreferredSize(new Dimension(60,20));
            field[i].addKeyListener(new KeyAdapter() {
                public void keyTyped(KeyEvent ee) {
                    if((ee.getKeyChar()>'9' || ee.getKeyChar()<'0') && ee.getKeyChar()!=45 && ee.getKeyChar()!='.') {
                        ee.consume();
                    }
                }
            });
            label6[i]=new JLabel(""); 
            Box hbox=Box.createHorizontalBox();
            hbox.add(label1[i]);      
            hbox.add(Box.createHorizontalStrut(20));
            hbox.add(label2[i]); 
            hbox.add(Box.createHorizontalStrut(5));
            hbox.add(label3[i]);
            hbox.add(Box.createHorizontalStrut(5));
            hbox.add(label4[i]);    
            hbox.add(Box.createHorizontalStrut(5));
            hbox.add(label5[i]);  
            hbox.add(Box.createHorizontalStrut(5));
            hbox.add(field[i]);
            hbox.add(Box.createHorizontalStrut(20));
            hbox.add(label6[i]);
            box.add(hbox);
            box.add(Box.createVerticalStrut(20));
        }
        panel2.add(box);
        panel2.validate();
    }
    int submitCount=0;
    class Listener implements ActionListener{
        public void actionPerformed(ActionEvent e) {
            JButton button=(JButton)e.getSource();
            if(button==btn[0]) {
                startExam();
                ExamCount++;
                btn[0].setEnabled(false);
                  
                for(int i=1;i<4;i++) {
                    btn[i].setEnabled(true);
                }
            }
            if(button==btn[1]) {
                for(int i=0;i<10;i++) {
                    field[i].setText("");
                }
            }
            if(button==btn[2] ) {
                rightResultCount=0;
                btn[2].setEnabled(false);
                double yourResult=0;
                for(int i=0;i<10;i++) {
                    try {
                        yourResult=Double.parseDouble(field[i].getText().trim());
                    }catch(Exception ee) {}
                      
                    if(yourResult==result[i]) {
                        rightResultCount++;
                        label6[i].setText("V");
                        label6[i].setForeground(Color.BLUE);
                          
                    }else {
                        label6[i].setText("X");
                        label6[i].setForeground(Color.RED);
                          
                    }
                }
                examLabel.setText("你答對了 "+rightResultCount+
                        " 道題,答錯了"+(10-rightResultCount)+" 道題!"+
                        "考試得分是: "+rightResultCount*10+" 分!");
            }
            if(button==btn[3]) {
                btn[2].setEnabled(true);
                panel2.removeAll();
                startExam();
                ExamCount++;
                btn[3].setEnabled(false);
                for(int i=0;i<10;i++) {
                    field[i].setText("");
                    label6[i].setText("");
                }
                panel2.repaint();
            }
            if(btn[2].isEnabled()==false && btn[3].isEnabled()==false) {
                btn[1].setEnabled(false);
            }
        }
    }
      
    class Panel1 extends JPanel{
        public Panel1() {
            setPreferredSize(new Dimension(350,120));
            setLayout(new GridLayout(3,1,10,10));
            JTextArea area=new JTextArea("點選“開始”開始答題,答案中有小數的,保留2位!");
            area.setLineWrap(true);
            area.setEditable(false);
            add(area);
            add(examLabel);
            p.add(timeLabel);
            add(p);
        }
    }
  
    class Panel2 extends JPanel{
        public Panel2() {
            setPreferredSize(new Dimension(400,600)); 
        }
    }