只要你做的是一個專案,就免不了一定會有使用者involve在你的專案中,舉凡網頁、手機App都是如此,因此事件處理便變得格外重要。
Java的事件處理是採用"委派模式",委派事件是指當事件發生時,產生事件的物件會把此訊息轉給"事件監聽者(Event Linstener)"來處理。
如下圖:
(圖片取至網路)
接著讓我們來看一下今天要實作的小專案吧~
還記得前幾周的猜數字遊戲嗎? 讓我們把它視覺化吧!!
請設計如以下介面所示的猜數字遊戲
當按下送出,會提示使用者是否猜對,並可點選
"我想看答案"按鈕,查看正確答案,也可選擇清除,清空輸入框中的資料。
並在當使用者輸入非數字時跳出錯誤提示訊息。
看過題目後,先別急著寫程式,我們來想一下它的運作流程。跟之前的console程式不同,流程中加入了一些與使用者互動的環節,我們可以把它轉換成以下的流程圖。
轉換為實際程式碼囉~
須注意要使用Java swing以及awt需要import對應的javax.swing與java.awt類別。
另外,還記得昨天的元件架構嗎? 當我們new了一個Jcomponent後,需要把它add進frame中。
建立兩個檔案GuessGame.java與Guess.java,Guess.java將作為我們的專案的進入點,也就是主函式所在的地方。
GuessGame.java
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;
import javax.swing.*;
public class GuessGame {
private JFrame frame;
private JLabel lb1, lb2,lb3;
private JTextField tf1;
private JButton btn1, btn2, btn3;
public GuessGame(){
Random ran = new Random();
int ans = ran.nextInt(100);
// 建立 JFrame 物件,同時設定標題
frame = new JFrame("猜數字遊戲");
// 設定佈局
frame.setLayout(null);
// 建立標籤
lb1 = new JLabel("請輸入0-100的數字 : ");
lb1.setBounds(5, 5, 200, 20); // 設定絕對座標
frame.add(lb1); // 將元件加入版面
// 建立文字框
tf1 = new JTextField();
tf1.setBounds(107, 5, 100, 20); // 設定絕對座標
frame.add(tf1); // 將元件加入版面
// 建立"確認"按鈕
btn1 = new JButton("送出");
btn1.setBounds(5, 37, 100, 20); // 設定絕對座標
frame.add(btn1); // 將元件加入版面
btn1.addActionListener(new ActionListener() { // 註冊事件,使用匿名類別的匿名物件
// 處理觸發的事件
@Override
public void actionPerformed(ActionEvent e) {
try{
if(Integer.parseInt(tf1.getText()) == ans) {
lb2.setText("答對了! 太強了吧!");
}else {
lb2.setText("猜錯囉! 加油好嗎!");
}
}catch(Exception ex){
// JOptionPane 可以輕鬆彈出一個標準對話框
JOptionPane.showMessageDialog(null, "請輸入數字", "輸入錯誤", JOptionPane.ERROR_MESSAGE);
}
}
});
// 建立"清除"按鈕
btn2 = new JButton("清除");
btn2.setBounds(107, 37, 100, 20); // 設定絕對座標
frame.add(btn2); // 將元件加入版面
btn2.addActionListener(new ActionListener() { // 註冊事件,使用匿名類別的匿名物件
// 處理觸發的事件
@Override
public void actionPerformed(ActionEvent e) {
tf1.setText(""); // 將文字框清除
lb2.setText(""); // 將 lb2 標籤清除
}
});
// 建立"點我看答案"按鈕
btn3 = new JButton("好啦! 點我看答案");
btn3.setBounds(5, 70, 150, 20); // 設定絕對座標
frame.add(btn3); // 將元件加入版面
btn3.addActionListener(new ActionListener() { // 註冊事件,使用匿名類別的匿名物件
// 處理觸發的事件
@Override
public void actionPerformed(ActionEvent e) {
lb3.setText("答案是 " + ans);
}
});
// 建立標籤
lb2 = new JLabel("");
lb2.setBounds(220, 5, 100, 20); // 設定絕對座標
frame.add(lb2); // 將元件加入版面
// 設定版面大小
frame.setSize(350, 150);
// 顯示視窗
frame.setVisible(true);
// 建立標籤
lb3 = new JLabel("");
lb3.setBounds(5, 100, 200, 40); // 設定絕對座標
frame.add(lb3); // 將元件加入版面
// 設定版面大小
frame.setSize(350, 200);
// 顯示視窗
frame.setVisible(true);
String path = "/resource/numbers.png";
frame.setIconImage(Toolkit.getDefaultToolkit().getImage(Guess.class.getResource(path)));;
frame.setLocationRelativeTo(null);
// JFrame 關閉視窗的設定,有這一行才能結束程式
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Guess.java
public class Guess {
public static void main(String[] args) {
new GuessGame();
}
}
執行Guess.java之後就會跑出一個遊戲視窗囉~
是不是很有趣呢?
今天的內容就先到這裡惹。
Hi, I am Grant.
個人部落格 - https://grantliblog.wordpress.com/
個人網站 - https://grantli-website.netlify.app/#/mainpage
我的寫作專題 - https://vocus.cc/user/5af2e9b5fd89780001822db4#