此爲Java課程機考中的一道題目,當是時,做的不太理想,後再次完善,加強了對整個界面的把握,對事件的響應也有了更清晰的認識,在此之上,添加了較爲簡單的異常處理,對於異常也有了更好的認知。
系統界面描述
問題分析
- 整個頁面佈局比較整齊,所以佈局上,所以JFrame的內容窗格採用其默認的邊框佈局管理器,座位面板使用網格佈局(4 X 4),座位的選擇面板使用網格佈局(1 X 2),單項的選擇面板內爲默認的流佈局管理器。
- 組件參數題目並沒有給出,後續代碼內的設定值都是試驗值,整體感覺還算良好,也比較整齊。
- 在頁面設計中,顯示內容都使用了禁用狀態的按鈕,較爲簡單;座位選擇使用了標籤和文本域的組合,比較常規;在爲了方便操作,座位按鈕與座位選擇文本域都使用了數組,在添加文本域時,爲其添加鍵盤監聽,擴展KeyAdapter類,只需重寫自己需要的方法;同時爲輸入添加了異常處理(題目並沒有要求,但畢竟是自己再次做,就把想到的都實現了,而且有異常不處理總歸是令人不舒服)。
知識點
-
佈局管理器:
- 面板的默認佈局管理器爲流佈局管理器;JFrame的內容窗格的默認佈局管理器是邊框佈局管理器;每個容器都有一個默認的佈局管理器,但可以進行重新設置。
- 通常組件放置在容器中,佈局管理器決定容器中組件具體放置的位置和大小:流佈局將維持每個組件的最佳尺寸,並且完全控制每個組件的放置位置;邊框佈局會拓展所有組件的尺寸以便填滿整個可用空間,它允許爲每個組件選擇一個放置位置(東西南北中);網格佈局按行列排列所有的組件,每個單元大小都是一樣的,在其構造器中,需要指定行數和列數。
-
鍵盤監聽
- 本題的動作較爲簡單,所以沒有使用輸入映射與動作映射,只是擴展了抽象KeyAdapter 類(僅重寫有用的方法)。然後使用組件的addKeyListener 方法將從該類所創建的偵聽器對象向該組件註冊。生成鍵盤事件後調用偵聽器對象中的相關方法並將該KeyEvent 傳遞給它。
- 用同一個動作響應按鈕、菜單項或者按鍵的方式總結:
(1) 實現一個拓展於AbstractAction類的類。多個相關的動作可以使用同一個類。
(2) 構造一個動作類的對象。
(3) 使用動作對象創建按鈕或菜單項。構造器將從動作對象中讀取標籤文本和圖標。
(4) 爲了能夠通過按鍵觸發動作,必須額外的執行幾步操作。首先定位頂層窗口組件。
(5) 然後,得到頂層組件的輸入映射。爲需要的按鍵創建一個KeyStrike對象。創建一個描述動作字符串這樣的動作鍵對象。將(按鍵,動作鍵)對添加到輸入映射中。
(6) 最後,得到頂層組件的動作映射。將(動作鍵,動作對象)添加到映射中。
-
異常處理
- 在Java程序設計時,需要關注Exception層次結構。這個層次結構又分解爲兩個分支:一個分支派生於RuntimeException;另一個分支包含其他異常。編程時應該注意通過檢測避免出現RuntimeException異常。
- 如果某個異常發生的時候沒有在仍何地方進行捕獲,那程序就會終止,並在控制檯上打印出異常信息,其中包括異常的類型和堆棧的內容。對於圖形用戶界面程序(applet和應用程序),在捕獲異常後,也會打印出堆棧的信息,但程序將返回到用戶界面的處理循環中。
- 如果在try語句塊中的仍何代碼拋出了一個在catch子句中說明的異常類,那麼程序將跳過try語句塊的其餘代碼,將執行catch子句中的處理器代碼。如果在try語句中的代碼沒有拋出任何異常,那麼程序將跳過catch子句。如果方法中的任何代碼拋出了一個在catch子句中沒有聲明的異常類型,那麼這個方法就會立刻退出(希望調用者爲這種類型的異常設計了catch子句)。
最終代碼
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
/**
* this program is a ticketing system
* @author sun
* @date 2019-5-29
*/
public class seatTest
{
public static void main(String[] args)
{
EventQueue.invokeLater(()->
{
JFrame frame = new seat();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
});
}
}
class seat extends JFrame
{
private static final long serialVersionUID = 1L;
private static final int DEFAULT_WIDTH = 600;//界面長度
private static final int DEFAULT_HEIGHT = 200;//界面寬度
private static final int SEAT_ROW = 3;//座位行數
private static final int SEAT_COL = 4;//座位列數
private static final int TEXT_COLUMNS = 4;//文本域寬度
private static final String systemName = "紅星電影院售票系統";
private static final String[] seatLabels = {
"1排1號空", "1排2號空", "1排3號空", "1排4號空",
"2排1號空", "2排2號空", "2排3號空", "2排4號空",
"3排1號空", "3排2號空", "3排3號空", "3排4號空"
};
private static final String[] chooseLabels = {
"請輸入需要座位的行號", "請輸入需要座位的列號"
};
private JButton display;//系統名稱顯示
private JButton[] seat;
private JPanel pan1;
private JPanel pan2;
private JTextField[] choose;
public seat()
{
setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
setLayout(new BorderLayout());
setTitle(systemName);
display = new JButton(systemName);
display.setEnabled(false);
add(display, BorderLayout.NORTH);
pan1 = new JPanel();
pan1.setLayout(new GridLayout(SEAT_ROW, SEAT_COL));
seat = new JButton[12];
for (int i = 0; i < seat.length; i++)
{
seat[i] = addButton(seatLabels[i]);
seat[i].setEnabled(false);
pan1.add(seat[i]);
}
add(pan1, BorderLayout.CENTER);
choose = new JTextField[2];
pan2 = new JPanel();
pan2.setLayout(new GridLayout(1, 2));
for (int i = 0; i < choose.length; i++)
pan2.add(addPanel(chooseLabels[i], i));
add(pan2, BorderLayout.SOUTH);
}
/**
* Adds a button to the seat
* @param label the button label
* @return a button
*/
private JButton addButton(String label)
{
return new JButton(label);
}
/**
* Adds a panel to the pan2
* @param label of label
* @return a panel
*/
private JPanel addPanel(String label, int i)
{
JPanel panel = new JPanel();
JLabel l = new JLabel(label);
choose[i] = new JTextField(TEXT_COLUMNS);
choose[i].addKeyListener(new KeyAdapter()
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyChar() == KeyEvent.VK_ENTER)
{
/*
* 檢測文本讀入:
* 1、輸入爲空
* 2、輸入爲非法字符(不是數字)
* 3、選擇超出限制
*/
try
{
String srow = choose[0].getText().trim();
String scol = choose[1].getText().trim();
int row = Integer.parseInt(srow);
int col = Integer.parseInt(scol);
if (row < 0 || row > SEAT_ROW || col < 0 || col > SEAT_COL)
throw new IllegalArgumentException();
int choice = (row - 1) * 4 + col - 1;
seat[choice].setText(row + "排" + col + "號售出");
}
catch (NumberFormatException exception)
{
String message = choose[0].getText().trim().equals("") ? "行號" : "";
message += choose[1].getText().trim().equals("") ? "列號" : "";
message += message.equals("") ? "輸入異常!" : "輸入爲空!";
JOptionPane.showMessageDialog(seat.this, message,
"Warning", JOptionPane.WARNING_MESSAGE);
}
catch (IllegalArgumentException exception)
{
int row = Integer.parseInt(choose[0].getText().trim());
int col = Integer.parseInt(choose[1].getText().trim());
String message = new String();
if (row < 0 || row > SEAT_ROW)
{
message += "行號";
choose[0].setText("");
}
if (col < 0 || col > SEAT_COL)
{
message += "列號";
choose[1].setText("");
}
JOptionPane.showMessageDialog(seat.this, message + "輸入超出範圍!",
"Warning", JOptionPane.WARNING_MESSAGE);
}
}
}
});
panel.add(l);
panel.add(choose[i]);
return panel;
}
}
運行結果
後記
儘管考試不是那麼如意,但學無止盡,考完了也還是要繼續學習,甚至正是因爲知道自己的不如意,才更要好好學習,Java的用處很廣泛,希望自己能夠學的更深更精,加油吧!少年!