Java GUI 售票系統頁面實現

此爲Java課程機考中的一道題目,當是時,做的不太理想,後再次完善,加強了對整個界面的把握,對事件的響應也有了更清晰的認識,在此之上,添加了較爲簡單的異常處理,對於異常也有了更好的認知。

系統界面描述

在這裏插入圖片描述
在這裏插入圖片描述

問題分析

  • 整個頁面佈局比較整齊,所以佈局上,所以JFrame的內容窗格採用其默認的邊框佈局管理器,座位面板使用網格佈局(4 X 4),座位的選擇面板使用網格佈局(1 X 2),單項的選擇面板內爲默認的流佈局管理器
  • 組件參數題目並沒有給出,後續代碼內的設定值都是試驗值,整體感覺還算良好,也比較整齊。
  • 在頁面設計中,顯示內容都使用了禁用狀態的按鈕,較爲簡單;座位選擇使用了標籤和文本域的組合,比較常規;在爲了方便操作,座位按鈕與座位選擇文本域都使用了數組,在添加文本域時,爲其添加鍵盤監聽,擴展KeyAdapter類,只需重寫自己需要的方法;同時爲輸入添加了異常處理(題目並沒有要求,但畢竟是自己再次做,就把想到的都實現了,而且有異常不處理總歸是令人不舒服)。

知識點

  1. 佈局管理器

    • 面板的默認佈局管理器爲流佈局管理器;JFrame的內容窗格的默認佈局管理器是邊框佈局管理器;每個容器都有一個默認的佈局管理器,但可以進行重新設置。
    • 通常組件放置在容器中,佈局管理器決定容器中組件具體放置的位置和大小:流佈局將維持每個組件的最佳尺寸,並且完全控制每個組件的放置位置;邊框佈局會拓展所有組件的尺寸以便填滿整個可用空間,它允許爲每個組件選擇一個放置位置(東西南北中);網格佈局按行列排列所有的組件,每個單元大小都是一樣的,在其構造器中,需要指定行數和列數。
  2. 鍵盤監聽

    • 本題的動作較爲簡單,所以沒有使用輸入映射與動作映射,只是擴展了抽象KeyAdapter 類(僅重寫有用的方法)。然後使用組件的addKeyListener 方法將從該類所創建的偵聽器對象向該組件註冊。生成鍵盤事件後調用偵聽器對象中的相關方法並將該KeyEvent 傳遞給它。
    • 用同一個動作響應按鈕、菜單項或者按鍵的方式總結:
      (1) 實現一個拓展於AbstractAction類的類。多個相關的動作可以使用同一個類。
      (2) 構造一個動作類的對象。
      (3) 使用動作對象創建按鈕或菜單項。構造器將從動作對象中讀取標籤文本和圖標。
      (4) 爲了能夠通過按鍵觸發動作,必須額外的執行幾步操作。首先定位頂層窗口組件。
      (5) 然後,得到頂層組件的輸入映射。爲需要的按鍵創建一個KeyStrike對象。創建一個描述動作字符串這樣的動作鍵對象。將(按鍵,動作鍵)對添加到輸入映射中。
      (6) 最後,得到頂層組件的動作映射。將(動作鍵,動作對象)添加到映射中。
  3. 異常處理

    • 在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的用處很廣泛,希望自己能夠學的更深更精,加油吧!少年!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章