1. 程式人生 > >徐思201771010132《面向物件程式設計(java)》第十四周學習總結

徐思201771010132《面向物件程式設計(java)》第十四周學習總結

一、理論知識部分

設計模式(Design pattern)是設計者一種流行的思考設計問題的方法,是一套被反覆使用,多數人知曉的,經過分類編目的,程式碼設計經驗的總結。使用設計模式是為了可重用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。每一個模式描述了一個不斷重複發生的設計問題,以及該問題的核心解決方案

模型-檢視-控制器設計模式(Model –ViewController )是Java EE平臺下建立 Web 應用程式 的重要設計模式。

MVC設計模式 – Model(模型):是程式中用於處理程式資料邏輯的部分,通常模型負責在資料庫中存取資料。– View(檢視):是程式中處理資料顯示的部分,通常檢視依據模型存取的資料建立。 – Controller(控制器):是程式中處理使用者互動的部分。通常控制器負責從檢視讀取資料,控制使用者輸入,並向模型傳送資料。

MVC模式可應用於Java的GUI元件設計中。MVC模式GUI元件設計的唯一的模式,還有很多設計的模式(設計方法)。

Java元件有內容、外觀、行為三個主要元素;這三個主要元素與模型—檢視—控制器模式的 三部件的對應關係為:內容——控制器(作用:處理使用者輸入)  外觀——檢視(作用:顯示內容)行為——模型(作用:儲存內容)

佈局管理器是一組類。實現 java.awt.LayoutManager 介面;決定容器中元件的位置和大小

Java.awt包中定義了5種佈局管理類,每一種佈局管理類對應一種佈局策略。每個容器都有與之相關的預設佈局管理器。當一個容器選定一種佈局策略時,它應該建立該 策略對應的佈局管理器物件,並將此物件設定為 自己的佈局管理器。

5種佈局管理器:(1)FlowLayout:流佈局(Applet和Panel的預設佈局管理器) (2)BorderLayout:邊框佈局( Window、Frame和Dialog的預設佈局管理器)(3)GridLayout:網格佈局(4)GridBagLayout: 網格組佈局(5)CardLayout :卡片佈局

FlowLayout Manager 元件採用從左到右,從上到下逐行擺放。

GridBagLayout不需要元件的尺寸一致,容許元件擴充套件到多行、多列。

每個容器物件在沒有設定新的佈局前,在容器中新增元件都按照該容器的預設佈局排列。通過setLayout( )方法為容器設定新的佈局。格式 : 容器元件名.setLayout( 佈局類物件名)

FlowLayout (流佈局管理器):用於對元件逐行地定位,每完成一行,一個新行便又開始。與其他佈局管理器不同的是,流佈局管理器不限制它所管理元件的大小,允許它們有自己的最佳大小。

建構函式有:FlowLayout( ):生成一個預設的流式佈局物件 ; FlowLayout(int align): 設定每一行元件的對齊方式(FlowLayout.LEFT, FlowLayout.CENTER, FlowLayout.RIGHT);FlowLayout(int align,int hgap,int vgap):可以設定元件間的水平和垂直距離(預設時元件之間沒有空隙)

流佈局是面板的預設佈局管理器

BorderLayout (邊框佈局管理器):邊框佈局管理器是每個JFrame的內容窗格的預設佈局管理器;流佈局管理器可將元件置於內容窗格的中部,北 部、南部、東部或西部位置。流佈局管理器會擴充套件元件尺寸並填滿指定方位區域。

BorderLayout的使用方法:設定容器的佈局管理器為BorderLayout ;向容器中加入元件時,若使用兩個引數的add() 方法,第二個引數必須說明加入元件在容器中的放置位置;位置引數是BorderLayout 類的常量:CENTER、 NORTH、SOUTH、EAST、WEST 例如: frame.add(component,BorderLayout.SOUTH);

BorderLayout( ) :建立新的BorderLayout,元件之間沒有間距 ;setHgap(int hgap) :將元件間的水平間距設定為指定的值; setVgap(int vgap) :將元件間的垂直間距設定為指定的值

GridLayout (網格佈局管理器):網格佈局按行列排列所有的元件;在網格佈局物件的構造器中,需要指定行數和列數: panel.setLayout(new GridLayout(6,10));放置元件的每個單元具有相同的尺寸。新增元件,從第一行和第一列開始,然後是第一行的第二列。以此類推。

GridLayout:指定網格中的行數和列數,建立網格佈局

GridLayout的使用方法:GridLayout的建構函式如下:(1)GridLayout():生成一個單行單列的網格佈局(2)GridLayout(int rows,int cols):生成一個設定行數和列數的網格佈局 (3)GridLayout(int rows,int columns,int hgap,int vgap): 可以設定元件之間的水平和垂直間隔

由於網格中所有單元的寬度、高度是相同的,所以Grid佈局管理器總是忽略元件的最佳大小。將元件新增到網格中的命令次序決定元件佔有的單元。單元的列數是從左到右填充,而行是從上到下由行填充。

文字域(JTextField) : 用於獲取單行文字輸入。文字域的使用方法:JPanel panel = new JPanel(); JTextField textField = new JTextField("Default input", 20); panel.add(textField);第一個引數“Default input”:將文字域的預設顯示值為Default input ;第二個引數20:表示文字域顯示寬度為20列。若要重新設定列數,可使用setColumns方法。

文字輸入常用API:用於文字輸入的元件繼承於JTextComponent抽象類, java.swing.text.JTextComponent 1.2:String getText() ;  void setText(String text) 獲取或設定文字元件中的文字 。 boolean isEditable() ; void setEditable(boolean b) 獲取或設定editable特性,這個特性決定了使用者是否可以編輯文字元件中的內容。 Java.swing. JComponent : void revalidate( ) :重新計算容器內所有元件的大小和位置,並對它們重新佈局。 如 panel.revalidate()

文字域JTextField常用API : Java.swing. JTextField:  JTextField(int cols) 構造一個指定列數的空JTextField物件。  JTextField(String text,int cols) 構造一個指定列數、指定初始字串的JTextField物件 。 int getColumns(int cols) ; void setColumns(int cols) 獲取或設定文字域使用的列數

文字域初始化 :只要不為JTextField構造器提供字串引數,就可以構造一個空白文字域。 JTextField textField=newJTextField(20);可在任何時候呼叫setText方法改變文字域內容。 textField.setText("Hello!"); 可呼叫getText方法獲取鍵入的文字。要將返回的文字域內容的前後空格去掉,就需呼叫trim方法:String text=textField.getText().trim();若想改變顯示文字的字型,則呼叫setFont方法。

文字區(JTextArea)元件可讓使用者輸入多行文字。生成JTextArea元件物件時,可以指定文字區的行數和列數: textArea = new JTextArea(8, 40); // 8行40列。輸入時,如果文字區的文字超出顯示範圍,則其餘的文字會被剪裁;可以使用換行來避免過長的行被裁減: textArea.setLineWrap(true);在Swing中,文字區沒有滾動條,需要手動安裝 :JScrollPane scrollPane = new JScrollPane(textArea)

文字區與文字域的異同相同之處: 文字域和文字區元件都可用於獲取文字輸入。 不同之處:文字域只能接受單行文字的輸入;文字區能夠接受多行文字的輸入。

文字區JTextArea的常用API:JTextArea(int rows, int cols) 構造一個rows行cols列的文字區物件 。JTextArea(String text,int rows, int cols) 用初始文字構造一個文字區物件。void setRows(int rows) 設定文字域使用的行數。 void append(String newText) 將給定文字附加到文字區中已有文字的後面。 void setLineWrap(boolean wrap) 開啟或關閉換行。

標籤是容納文字的元件。它們沒有任何修飾(如沒有邊界 ),也不響應使用者輸入。標籤的常用用途之一就是標識元件,例如標識文字域。其使用步驟如下: 1. 建立一個JLabel元件。例: JLabel label = new JLabel(“hours”, SwingConstants.RIGHT); 或者 JLabel label = new JLabel(“hours”, JLabel.RIGHT);以上程式碼建立了一個label,並指定label的對齊方式為右對齊。 2. 將標籤元件放置在距離被標識元件足夠近的地方。

標籤元件常用API:JLable(String text)   JLable(Icon icon)    JLable(String text,int align) JLable(String text,Icon icon,int align) 構造一個標籤。 String getText()   void setText(String text) 獲取或設定標籤的文字。 Icon getIcon()   void setIcon(Icon icon) 獲取或設定標籤的圖示

密碼域是一種特殊型別的文字域。每個輸入的字元都用回顯字元實現,典型的回顯字元為*。

複選框( JCheckBox ):如果想要接收的輸入只是“是”或“非”,就可以使用複選框元件。使用者通過單擊某個複選框來選擇相應的選項,再點選則取消選擇。當複選框獲得焦點時,使用者也可以通過空格鍵來切換選擇。

複選框構造器:1.bold = new JCheckBox("Bold"); 複選框自動地帶有表示標籤。 2. JCheckBox(String label,Icon icon); 構造帶有標籤與圖示的複選框,預設初始未被選擇。 3.JCheckBox(String label,boolean state); 用指定的標籤和初始化選擇狀態構造一個複選框

複選框常用API: 1.void setSelected(boolean state); 設定複選框的選擇狀態 2.boolean isSelected(); 獲取複選框的選擇狀態

單選按鈕:當需要使用者只選擇幾個選項中的一個。即當用戶選擇另一項的時候,前一項就自動的取消選擇。

單選按鈕的構造器:1.JRadioButton(String label,Icon icon); 建立一個帶標籤和圖示的單選按鈕 2.JRadioButton(String label,boolean state); 用指定的標籤和初始化狀態構造單選按鈕

按鈕組:為單選按鈕組構造一個ButtonGroup的物件。 然後,再將JRadioButton型別的物件新增到按鈕組中。按鈕組負責在新按鈕被按下的時,取消前一個按鈕的選擇狀態。 ButtonGroup group = new ButtonGroup() group.add(JRadioButton物件); 注意:按鈕組僅僅控制按鈕的行為,如果想把這些按鈕組織在一起佈局,還需要把它們新增到容器中 ,如JPanel.

邊框:如果在一個視窗中有多組複選框或單選按 鈕,就需要視覺化的形式指明哪些按鈕屬於同 一組。Swing提供了一 組很有用的邊框 ( borders)來解決這個問題。

邊框的建立方法:可以呼叫BorderFactory類的靜態方法建立。可選的風格有:凹斜面:BorderFactory.createLoweredBevelBorder() 凸斜面:BorderFactory.createRaisedBevelBorder() 蝕刻:BorderFactory.createEtchedBorder() 直線:BorderFactory.createLineBorder(Color) 不光滑:BorderFactory.createMatteBorder()還可以給邊框加標題 BorderFactory.createTitledBorder()

組合框:如果有多個選擇項,使用單選按鈕佔據的螢幕空間太大時,就可以選擇組合框。

組合框構造器與常用方法:faceCombo = new JComboBox(); faceCombo.setEditable(true); 讓組合框可編輯 faceCombo.addItem("Serif"); faceCombo.insertItemAt("Monospace",0); 增加組合框選項 faceCombo.removeItem("Monospace"); faceCombo.removeItemAt(0); 刪除組合框選項內容

滑動條( JSlider ):可以讓使用者從一組離散值中進行選擇,並且它還允許進行連續值得選擇。

滑動條的修飾可通過顯示標尺(tricks)對滑動條進行修飾。 slider.setMajorTickSpacing(20); 大標尺標記 slider.setMinorTickSpacing(5); 小標尺標記要想顯示以上標記,還需呼叫: slider.setPaintTicks(true);

可以呼叫下列方法為大標尺新增標尺標籤: slider.setPaintLabels(true); 會根據構建標尺時的min,max,和大標尺的間距自動新增 還可以提供其他形式的標尺標記: Hashtable<integer,component> labelTable = new Hashtable<integer,component>(); 構造一個鍵為Integer型別且值為Component型別 的散列表。

選單的建立:首先建立一個選單欄選單欄是一個可以新增到容器元件任何位置的元件。通常放置在框架的頂部。 JMenuBar menuBar=new JMenuBar();呼叫框架的setJMenuBar方法可將一個選單欄物件新增到框架上 frame.setJMenuBar(menuBar); 建立選單物件,並將選單物件新增到選單欄中 JMenu editMenu=new Jmenu("Edit"); menuBar.add(editMenu);向選單物件新增一個選單項。 JMenItem pasteItem=new JMenItem(); editMenu.add(pasteItem); 向選單物件新增分隔符行。 editMenu.addSeperator();向選單物件項新增子選單。 JMenu optionsMenu=new Jmenu(“option”); editMenu.add(optionsMenu);

彈出選單是不固定在選單欄中隨處浮動的選單。

建立彈出選單:建立一個彈出選單與建立一個常規選單的方法類似,但是彈出選單沒有標題: JPopupMenu popup = new JPopupMenu();然後用常規方法為彈出選單新增選單項: JMenuItem item = new JMenuItem("Cut"); item.addActionListener(listener); popup.add(item);彈出選單呼叫show方法才能顯示出來: popup.show(panel,x,y);

彈出式觸發器(pop-up trigger):使用者點選滑鼠某個鍵時彈出選單。在Windows或者Linux中,彈出式觸發器是滑鼠右鍵。要想在使用者點選某一個元件的時候彈出選單,該元件就要呼叫以下方法設定彈出式觸發器:component.setComponentPopupMenu(popup);

快捷鍵:可以為選單項設定快捷鍵。在當前選單開啟的情況下,可以按下某選單項的快捷鍵,相當於滑鼠單擊了該選單項。JMenuItem CutItem=new JMenuItem(" Index "); CutItem.setMnemonic(" I ");此快捷鍵就會自動顯示在選單項中,快捷鍵下面有一條下劃線。

加速器:加速器可以在不開啟選單的情況下選中選單項的快捷鍵。 例如,很多應用程式把CTRL + O和CTRL + S關 聯到選單中的Open和Save項。使用SetAccelerator方法可以將加速器關聯到一個選單項。該方法使用KeyStroke型別的物件作為引數。例如: openItem.setAccelerator(KeyStroke.getKeyStroke("ctrl o" ));當用戶按下加速器組合鍵時,就自動選擇了相應的選單項,同時啟用一個動作事件。加速器只能關聯在選單項,而不能關聯選單;加速器實際上並不開啟選單,而是直接啟用選單關聯 的動作事件。

啟用和禁用選單項:在程式執行過程中,經常需要遮蔽某些暫時不適用的命令,待到條件允許時再使之重新可用。遮蔽 /啟用選單項的方法: aMenuItem.setEnabled(boolean):當引數值為false時,遮蔽該選單項; 當引數值為true時,啟用該選單項; 如果需要動態啟用 /遮蔽某選單項,則需要為 “menu selected ”事件註冊監聽器。 javax.swing.event包定義了MenuListener介面,它有三個方法: void menuSelected(MenuEvent event)  ; void menuDeselected(MenuEvent event)  ; void menuCanceled(MenuEvent event) ;

工具欄(JToolBar):工具欄在程式中提供快速訪問常用命令的按鈕欄。工具欄的優點在於可以移動,脫離工具欄或拖拽到框架其他地方。關閉包含工具欄的框架後,工具欄回到原始的框架中。

工具提示:工具提示(tooltips)提示使用者小按鈕的含義。當游標停留在某個按鈕上片刻是,工具提示就會啟用。工具提示文字顯示在一個有顏色的矩形裡。當用戶移開滑鼠是,工具提示就會自動地消失;在Swing中,可以呼叫setToolTest方法將工具提示新增到JComponent上;exitButton.setToolTipText(" Exit ");另外一種方法是,如果使用Action物件,就可以用 SHORT-DESCRIPTION關聯工具提示: exitButton.putValue(Action.SHORT-DESCRIPTION, " Exit ");

網格組佈局 (GridBagLayout):GridBagLayout與GridLayout有點相似,它也是將元件排在格子裡,但是GridBagLayout在網格的基礎上提供更復雜的佈局。GridBagLayout允許單個元件在一個單元中不填滿整個單元,而只是佔用最佳大小,也允許單個元件擴充套件成不止一個單元,並且可以用任意順序加入元件。

GridBagLayout 的API:使用GridBagLayout,必須構造一個GridBagConstraints物件。GridBagConstraints 用於指定如何用GridBagLayout放置元件。 GridBagConstraints物件包含一些重要的約束,以指定元件的放置方式,這些約束的含義如下:

1.gridx 、gridy 、gridwidth 和gridheight引數。這四個引數用於指定元件在網格中的位置。gridx 和 gridy值用於指定元件左上角的座標;gridwidth 和gridheight決定元件將佔用多少行和列.

2.增量域(weightx和weighty)。 GridBagLayout內的每個區域都必須設定它的增量域,即weightx和weighty。如果將權值設定為0,那麼這個區域就不會在那個方向上擴張或收縮,超出它的初始大小。 增量引數屬於行和列的屬性,而不屬於某個單獨的單元格。但卻需在單元格上指定它們,這是因為 網格組佈局並不暴露行和列。

3.fill 和anchor引數。fill引數用於指定元件在單元格 內進行伸縮時的填充方式,該引數可以有四種有效 值:GridBagConstraints.NONE(不伸縮 ) 、 GridBagConstraints.HORIZONTAL(水平伸縮 ) 、 GridBagConstraints.VERTICAL(垂直伸縮 ) 和 GridBagConstraints.BOTH 。 如果元件沒有填充整個區域,可以通過設定 anchor域指定其對齊位置。有效值為 GridBagConstraints.CENTER, GridBagConstraints.NORTH, GridBagConstraints.NORTHEAST, GridBagConstraints.EAST 等

4 . 填 塞 : 填 充 參 數 insets , ipadx 和 ipady 。 insets引數用於設定沿單元格邊界的外部填充空白區域。ipadx和ipady則用於指定在環繞元件四周的單元格內部填充空白區域。

對話方塊(JDialog):對話方塊是一種大小不能變化、不能有選單的容器視窗;對話方塊不能作為一個應用程式的主框架,而必須包含在其他的容器中。Java提供多種對話方塊類來支援多種形式的對話方塊。JOptionPane類支援簡單、標準的對話方塊;JDialog類支援定製使用者自己的對話方塊; JFileChooser類支援檔案開啟、儲存對話方塊;ProgressMonitor類支援操作進度條控制對話方塊等。

對話方塊依賴於框架。當框架撤銷時,依賴該框架的對話方塊也撤銷。當框架圖示化時,依賴它的對話方塊也從螢幕上消失。當框架視窗恢復時,依賴框架的對話方塊又返回螢幕。對話方塊分為無模式和有模式兩種。有模式的對話方塊處於啟用狀態時,程式只能響應對話方塊內部的事件,不能再啟用它所依賴的視窗或元件,而且它將堵塞當前執行緒的執行,即堵塞使得對話方塊處於啟用狀態的執行緒,直到該對話方塊消失不可見。無模式對話方塊處於啟用狀態時,程式仍能啟用它所依賴的視窗或元件,它也不堵塞執行緒的執行。

選項對話方塊(JOptionPane):JOptionPane提供的對話方塊是模式對話方塊。當模式對話方塊顯示時,它不允許使用者輸入到程式的其他的視窗。使用JOptionPane,可以建立和自定義問題、資訊、警告和錯誤等幾種型別的對話方塊。

Swing提供了用於顯示選項對話方塊(JOptionPane )的JOptionPane 類,定義了多個showXxxDialog形式的靜態方法 :showMessageDialog —— 資訊對話方塊,顯示資訊,告知使用者發生了什麼情況 。showConfirmDialog —— 確認對話方塊,顯示問題,要求使用者進行 確認(yes/no/cancel )。showOptionDialog —— 選項對話方塊,顯示選項,要求使用者進行選 擇 。 showInputDialog —— 輸入對話方塊,提示使用者進行輸入

建立對話方塊(JDialog):對話方塊的構造方法:JDialog(Frame owner) ——構造一個沒有標題的非模式對話方塊。JDialog(Frame owner, boolean modal) ——構造一個沒有標題的對話方塊,boolean型引數modal指定對話方塊是否為模式視窗。 JDialog(Frame owner, String title) ——構造一個有標題的非模式對話方塊. JDialog(Frame owner, String title, boolean modal) ——構造一個有標題的對話方塊。

showXxxDialog方法的引數:Component parentComponent對話方塊的父視窗物件,其螢幕座標將決定對話方塊的顯示位置;此引數也可以為null,表示採用預設的Frame 作為父視窗,此時對話方塊將設定在螢幕的正中 。 String title  對話方塊的標題 。 Object message  顯示在對話方塊中的描述資訊。該引數通常是一個String物件,但也可以是一個圖示、一個元件或者一個物件陣列。int messageType – 對話方塊所傳遞的資訊型別。int optionType對話方塊上按鈕的型別,可以為以下常量:DEFAULT_OPTION YES_NO_OPTION YES_NO_CANCEL_OPTION OK_CANCEL_OPTION 。Object[] options:對話方塊上的選項。在輸入對話方塊中,通常以組合框形式顯示,在選項對話方塊中,則指按鈕的選項型別。該引數通常是一個String陣列,但也可以是圖示或元件陣列。Icon icon  對話方塊上顯示的裝飾性圖示,如果沒有指定,則根據 messageType 引數顯示預設圖示。 Object initialValue 初始選項或輸入值

showXxxDialog()返回型別:showMessageDialog()沒有返回值 。 showConfirmDialog() 和showOptionDialog()方法返 回int型數值,代表使用者選擇按鈕的序號 。(JOptionPane中定義了YES_OPTION、 NO_OPTION、CANCEL_OPTION、OK_OPTION和 CLOSED_OPTION等常量,分別代表使用者選擇了 YES、NO、CANCEL、OK按鈕以及未選擇而直接關 閉了對話方塊)。 showInputDialog()方法的返回值為String或 Object,代表使用者的輸入或選項

資料交換:輸入對話方塊含有供使用者輸入文字的文字框、一個確認和取消按鈕,是有模式對話方塊。當輸入對話方塊可見時,要求使用者輸入一個字串。javax.swing包中的JOptionPane類的靜態方法:public static String showInputDialog(Component parentComponent, Object message,String title,int messageType)。建立一個輸入對話方塊,其中引數parentComponent指定訊息對話方塊所依賴的元件,確認對話方塊會在該元件的正前方顯示出來,引數message指定對話方塊上的提示資訊,引數 title指定對話方塊上的標題,引數messageType可取的有效值是JoptionPane中的類常量

檔案對話方塊(JFileChooser):專門用於對檔案(或目錄)進行瀏覽和選擇的對話方塊,常用的構造方法: JFileChooser():根據使用者的預設目錄建立檔案對話方塊。JFileChooser(File currentDirectory):根據File型引數currentDirectory指定的目錄建立檔案對話方塊。JFileChooser(String currentDirectoryPath):根據 String型引數currentDirectoryPath指定的目錄建立檔案對話方塊。

二、實驗部分

1、實驗目的與要求

(1) 掌握GUI佈局管理器用法;

(2) 掌握各類Java Swing元件用途及常用API;

2、實驗內容和步驟

實驗1: 匯入第12章示例程式,測試程式並進行組內討論。

測試程式1

在elipse IDE中執行教材479頁程式12-1,結合執行結果理解程式;

掌握各種佈局管理器的用法;

理解GUI介面中事件處理技術的用途。

在佈局管理應用程式碼處添加註釋;

package calculator;

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

/**
 * @version 1.34 2015-06-12
 * @author Cay Horstmann
 */
public class Calculator {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            CalculatorFrame frame = new CalculatorFrame();
            frame.setTitle("Calculator");// 設定視窗標題
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}
Calculator
package calculator;

import javax.swing.*;

/**
 * A frame with a calculator panel.
 */
public class CalculatorFrame extends JFrame {
    public CalculatorFrame() {
        add(new CalculatorPanel());
        pack();
    }
}
CalculatorFrame
package calculator;

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

/**
 * A panel with calculator buttons and a result display.
 */
public class CalculatorPanel extends JPanel {
    private JButton display;
    private JPanel panel;
    private double result;
    private String lastCommand;
    private boolean start;

    public CalculatorPanel() {
        setLayout(new BorderLayout());// 構造一個邊框佈局管理器

        result = 0;
        lastCommand = "=";
        start = true;

        // add the display

        display = new JButton("0");// 用來顯示計算的計算結果
        display.setEnabled(false);// 禁止使用按鈕
        add(display, BorderLayout.NORTH);

        ActionListener insert = new InsertAction();
        ActionListener command = new CommandAction();// 設定兩個監聽器物件

        // add the buttons in a 4 x 4 grid

        panel = new JPanel();
        panel.setLayout(new GridLayout(4, 4));// 設定4行4列的網格佈局

        addButton("7", insert);
        addButton("8", insert);
        addButton("9", insert);
        addButton("/", command);

        addButton("4", insert);
        addButton("5", insert);
        addButton("6", insert);
        addButton("*", command);

        addButton("1", insert);
        addButton("2", insert);
        addButton("3", insert);
        addButton("-", command);

        addButton("0", insert);
        addButton(".", insert);
        addButton("=", command);
        addButton("+", command);

        add(panel, BorderLayout.CENTER);// 新增按鈕到指定方位
    }

    /**
     * Adds a button to the center panel.
     * 
     * @param label    the button label
     * @param listener the button listener
     */
    private void addButton(String label, ActionListener listener) {
        JButton button = new JButton(label);
        button.addActionListener(listener);
        panel.add(button);
    }

    /**
     * This action inserts the button action string to the end of the display text.
     */
    private class InsertAction implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            String input = event.getActionCommand();
            if (start) {
                display.setText("");
                start = false;
            }
            display.setText(display.getText() + input);
        }
    }

    /**
     * This action executes the command that the button action string denotes.
     */
    private class CommandAction implements ActionListener {
        public void actionPerformed(ActionEvent event) {
            String command = event.getActionCommand();

            if (start) {
                if (command.equals("-")) {
                    display.setText(command);
                    start = false;
                } else
                    lastCommand = command;
            } else {
                calculate(Double.parseDouble(display.getText()));
                lastCommand = command;
                start = true;
            }
        }
    }

    /**
     * Carries out the pending calculation.
     * 
     * @param x the value to be accumulated with the prior result.
     */
    public void calculate(double x) {
        if (lastCommand.equals("+"))
            result += x;
        else if (lastCommand.equals("-"))
            result -= x;
        else if (lastCommand.equals("*"))
            result *= x;
        else if (lastCommand.equals("/"))
            result /= x;
        else if (lastCommand.equals("="))
            result = x;
        display.setText("" + result);
    }
}
CalculatorPanel

測試程式2

在elipse IDE中除錯執行教材486頁程式12-2,結合執行結果理解程式;

掌握各種文字元件的用法;

記錄示例程式碼閱讀理解中存在的問題與疑惑。

package text;

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

/**
 * @version 1.41 2015-06-12
 * @author Cay Horstmann
 */
public class TextComponentTest {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new TextComponentFrame();
            frame.setTitle("TextComponentTest");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}
TextComponentTest
package text;

import java.awt.BorderLayout;
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingConstants;

/**
 * A frame with sample text components.
 */
public class TextComponentFrame extends JFrame {
    public static final int TEXTAREA_ROWS = 8;
    public static final int TEXTAREA_COLUMNS = 20;

    public TextComponentFrame() {
        JTextField textField = new JTextField();
        JPasswordField passwordField = new JPasswordField();

        JPanel northPanel = new JPanel();
        northPanel.setLayout(new GridLayout(2, 2));
        northPanel.add(new JLabel("User name: ", SwingConstants.RIGHT));
        northPanel.add(textField);
        northPanel.add(new JLabel("Password: ", SwingConstants.RIGHT));
        northPanel.add(passwordField);// 建立了兩個個label,並指定label的對齊方式為右對齊

        add(northPanel, BorderLayout.NORTH);// 北區域的邊框佈局約束(容器頂部)。

        JTextArea textArea = new JTextArea(TEXTAREA_ROWS, TEXTAREA_COLUMNS);// 構造具有指定行數和列數的新的空 TextArea
        JScrollPane scrollPane = new JScrollPane(textArea);// 建立一個顯示指定元件內容的 JScrollPane,只要元件的內容超過檢視大小就會顯示水平和垂直滾動條。

        add(scrollPane, BorderLayout.CENTER);

        // add button to append text into the text area

        JPanel southPanel = new JPanel();

        JButton insertButton = new JButton("Insert");
        southPanel.add(insertButton);
        insertButton.addActionListener(event -> textArea.append(
                "User name: " + textField.getText() + " Password: " + new String(passwordField.getPassword()) + "\n"));

        add(southPanel, BorderLayout.SOUTH);
        pack();
    }
}
TextComponentFrame

測試程式3

在elipse IDE中除錯執行教材489頁程式12-3,結合執行結果理解程式;

掌握複選框元件的用法;

記錄示例程式碼閱讀理解中存在的問題與疑惑。

package checkBox;

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

/**
 * @version 1.34 2015-06-12
 * @author Cay Horstmann
 */
public class CheckBoxTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new CheckBoxFrame();
         frame.setTitle("CheckBoxTest");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);
      });
   }
}
CheckBoxTest
package checkBox;

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

/**
 * A frame with a sample text label and check boxes for selecting font
 * attributes.
 */
public class CheckBoxFrame extends JFrame {
    private JLabel label;
    private JCheckBox bold;
    private JCheckBox italic;
    private static final int FONTSIZE = 24;

    public CheckBoxFrame() {
        // add the sample text label

        label = new JLabel("The quick brown fox jumps over the lazy dog.");
        label.setFont(new Font("Serif", Font.BOLD, FONTSIZE));// 設定元件的字型。
        add(label, BorderLayout.CENTER);// 中間區域的佈局約束(容器中央)。

        // this listener sets the font attribute of
        // the label to the check box state

        ActionListener listener = event -> {
            int mode = 0;
            if (bold.isSelected())
                mode += Font.BOLD;
            if (italic.isSelected())
                mode += Font.ITALIC;
            label.setFont(new Font("Serif", mode, FONTSIZE));
        };

        // add the check boxes

        JPanel buttonPanel = new JPanel();

        bold = new JCheckBox("Bold");// 複選框自動地帶有表示標籤。
        bold.addActionListener(listener);
        bold.setSelected(true);// 使用setSelected方法來選定或取消選定複選框
        buttonPanel.add(bold);

        italic = new JCheckBox("Italic");
        italic.addActionListener(listener);
        buttonPanel.add(italic);

        add(buttonPanel, BorderLayout.SOUTH);
        pack();
    }
}
CheckBoxFrame

測試程式4

在elipse IDE中除錯執行教材491頁程式12-4,執行結果理解程式;

掌握單選按鈕元件的用法;

記錄示例程式碼閱讀理解中存在的問題與疑惑。

package radioButton;

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

/**
 * @version 1.34 2015-06-12
 * @author Cay Horstmann
 */
public class RadioButtonTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         JFrame frame = new RadioButtonFrame();
         frame.setTitle("RadioButtonTest");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);
      });
   }
}
RadioButtonTest
package radioButton;

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

/**
 * A frame with a sample text label and radio buttons for selecting font sizes.
 */
public class RadioButtonFrame extends JFrame {
    private JPanel buttonPanel;
    private ButtonGroup group;
    private JLabel label;
    private static final int DEFAULT_SIZE = 36;

    public RadioButtonFrame() {
        // add the sample text label

        label = new JLabel("The quick brown fox jumps over the lazy dog.");
        label.setFont(new Font("Serif", Font.PLAIN, DEFAULT_SIZE));//設定元件的字型
        add(label, BorderLayout.CENTER);//中間區域的佈局約束(容器中央)

        // add the radio buttons

        buttonPanel = new JPanel();
        group = new ButtonGroup();

        addRadioButton("Small", 8);
        addRadioButton("Medium", 12);
        addRadioButton("Large", 18);
        addRadioButton("Extra large", 36);

        add(buttonPanel, BorderLayout.SOUTH);//新增按鈕到指定方位
        pack();
    }

    /**
     * Adds a radio button that sets the font size of the sample text.
     * 
     * @param name the string to appear on the button
     * @param size the font size that this button sets
     */
    public void addRadioButton(String name, int size) {
        boolean selected = size == DEFAULT_SIZE;
        JRadioButton button = new JRadioButton(name, selected);
        group.add(button);
        buttonPanel.add(button);

        // this listener sets the label font size

        ActionListener listener = event -> label.setFont(new Font("Serif", Font.PLAIN, size));

        button.addActionListener(listener);
    }
}
RadioButtonFrame

測試程式5

在elipse IDE中除錯執行教材494頁程式12-5,結合執行結果理解程式;

掌握邊框的用法;

記錄示例程式碼閱讀理解中存在的問題與疑惑。

package border;

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

/**
 * @version 1.34 2015-06-13
 * @author Cay Horstmann
 */
public class BorderTest {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new BorderFrame();
            frame.setTitle("BorderTest");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}
BorderTest
package border;

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

/**
 * A frame with radio buttons to pick a border style.
 */
public class BorderFrame extends JFrame {
    private JPanel demoPanel;
    private JPanel buttonPanel;
    private ButtonGroup group;

    public BorderFrame() {
        demoPanel = new JPanel();
        buttonPanel = new JPanel();
        group = new ButtonGroup();

        addRadioButton("Lowered bevel", BorderFactory.createLoweredBevelBorder());//建立一個具有凹入斜面邊緣的邊框,將元件當前背景色的較亮的色度用於高亮顯示,較暗的色度用於陰影。(在凹入邊框中,陰影位於頂部,高亮顯示位於其下。) 
        addRadioButton("Raised bevel", BorderFactory.createRaisedBevelBorder()); //建立一個具有凸出斜面邊緣的邊框,將元件當前背景色的較亮的色度用於高亮顯示,較暗的色度用於陰影。(在凸出邊框中,高亮顯示位於頂部,陰影位於其下。) 
        addRadioButton("Etched", BorderFactory.createEtchedBorder());//建立一個具有“浮雕化”外觀效果的邊框,將元件的當前背景色用於高亮顯示和陰影顯示。
        addRadioButton("Line", BorderFactory.createLineBorder(Color.BLUE));//建立一個具有指定顏色的線邊框。
        addRadioButton("Matte", BorderFactory.createMatteBorder(10, 10, 10, 10, Color.BLUE));//使用純色建立一個類似襯邊的邊框
        addRadioButton("Empty", BorderFactory.createEmptyBorder());//建立一個不佔用空間的空邊框

        Border etched = BorderFactory.createEtchedBorder();
        Border titled = BorderFactory.createTitledBorder(etched, "Border types");
        buttonPanel.setBorder(titled);

        setLayout(new GridLayout(2, 1));//建立2行1列的網格佈局
        add(buttonPanel);
        add(demoPanel);
        pack();
    }
//單選按鈕元件監聽器
    public void addRadioButton(String buttonName, Border b) {
        JRadioButton button = new JRadioButton(buttonName);
        button.addActionListener(event -> demoPanel.setBorder(b));
        group.add(button);
        buttonPanel.add(button);
    }
}
BorderFrame

測試程式6

在elipse IDE中除錯執行教材498頁程式12-6,結合執行結果理解程式;

掌握組合框元件的用法;

記錄示例程式碼閱讀理解中存在的問題與疑惑。

package comboBox;

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

/**
 * @version 1.35 2015-06-12
 * @author Cay Horstmann
 */
public class ComboBoxTest {
    public static void main(String[] args) {
        EventQueue.invokeLater(() -> {
            JFrame frame = new ComboBoxFrame();
            frame.setTitle("ComboBoxTest");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}
ComboBoxTest
package comboBox;

import java.awt.BorderLayout;
import java.awt.Font;

import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

/**
 * A frame with a sample text label and a combo box for selecting font faces.
 */
public class ComboBoxFrame extends JFrame {
    private JComboBox<String> faceCombo;
    private JLabel label;
    private static final int DEFAULT_SIZE = 24;

    public ComboBoxFrame() {
        // add the sample text label

        label = new JLabel("The quick brown fox jumps over the lazy dog.");
        label.setFont(new Font("Serif", Font.PLAIN, DEFAULT_SIZE));//設定元件的字型
        add(label, BorderLayout.CENTER);

        // make a combo box and add face names

        faceCombo = new JComboBox<>();
        faceCombo.addItem("Serif");
        faceCombo.addItem("SansSerif");
        faceCombo.addItem("Monospaced");
        faceCombo.addItem("Dialog");
        faceCombo.addItem("DialogInput");

        // the combo box listener changes the label font to the selected face name

        faceCombo.addActionListener(event -> label
                .setFont(new Font(faceCombo.getItemAt(faceCombo.getSelectedIndex()), Font.PLAIN, DEFAULT_SIZE)));

        // add combo box to a panel at the frame's southern border

        JPanel comboPanel = new JPanel();
        comboPanel.add(faceCombo);
        add(comboPanel, BorderLayout.SOUTH);
        pack();
    }
}
ComboBoxFrame

測試程式7

在elipse IDE中除錯執行教材501頁程式12-7,結合執行結果理解程式;

掌握滑動條元件的用法;

記錄示例程式碼閱讀理解中存在的問題與疑惑。

package slider;

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

/**
 * @version 1.15 2015-06-12
 * @author Cay Horstmann
 */
public class SliderTest
{
   public static void main(String[] args)
   {
      EventQueue.invokeLater(() -> {
         SliderFrame frame = new SliderFrame();
         frame.setTitle("SliderTest");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setVisible(true);
      });
   }
}
SliderTest
package slider;

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

/**
 * A frame with many sliders and a text field to show slider values.
 */
public class SliderFrame extends JFrame {
    private JPanel sliderPanel;
    private JTextField textField;
    private ChangeListener listener;

    public SliderFrame() {
        sliderPanel = new JPanel();
        sliderPanel.setLayout(new GridBagLayout());

        // common listener for all sliders
        listener = event -> {
            // update text field when the slider value changes
            JSlider source = (JSlider) event.getSource();
            textField.setText("" + source.getValue());
        };

        // add a plain slider

        JSlider slider = new JSlider();
        addSlider(slider, "Plain");

        // add a slider with major and minor ticks

        slider = new JSlider();
        slider.setPaintTicks(true);
        slider.setMajorTickSpacing(20);
        slider.setMinorTickSpacing(5);
        addSlider(slider, "Ticks");

        // add a slider that snaps to ticks

        slider = new JSlider();
        slider.setPaintTicks(true);
        slider.setSnapToTicks(true);
        slider.setMajorTickSpacing(20);
        slider.setMinorTickSpacing(5);
        addSlider(slider, "Snap to ticks");

        // add a slider with no track

        slider = new JSlider();
        slider.setPaintTicks(true);
        slider.setMajorTickSpacing(20);
        slider.setMinorTickSpacing(5);
        slider.setPaintTrack(false);
        addSlider(slider, "No track");

        // add an inverted slider

        slider = new JSlider();
        slider.setPaintTicks(true);
        slider.setMajorTickSpacing(20);
        slider.setMinorTickSpacing(5);
        slider.setInverted(true);
        addSlider(slider, "Inverted");

        // add a slider with numeric labels

        slider = new JSlider();
        slider.setPaintTicks(true);
        slider.setPaintLabels(true);
        slider.setMajorTickSpacing(20);
        slider.setMinorTickSpacing(5);
        addSlider(slider, "Labels");

        // add a slider with alphabetic labels

        slider = new JSlider();
        slider.setPaintLabels(true);
        slider.setPaintTicks(true);
        slider.setMajorTickSpacing(20);
        slider.setMinorTickSpacing(5);

        Dictionary<Integer, Component> labelTable = new Hashtable<>