????01-GUI(概述)
? ? ? ? 終于要學(xué)圖形用戶界面啦份名,啦啦啦φ(≧ω≦*)?
? ? ? ? 我們有兩種和用戶交互的方式,一種是命令行(這節(jié)課之前我們一直用的方式)妓美,另一種就是圖形用戶界面僵腺。
? ? ? ? Java為GUI提供的對(duì)象都存在java.Awt和javax.Swing兩個(gè)包中。
? ? ? ? 這兩個(gè)包有什么區(qū)別呢壶栋?
? ? ? ? java.Awt:Abstract Window ToolKit(抽象窗口工具包)辰如,需要調(diào)用本地系統(tǒng)方法實(shí)現(xiàn)功能,屬重量級(jí)控件贵试。
? ? ? ? 但它的缺點(diǎn)是有點(diǎn)依賴平臺(tái)丧没,跨平臺(tái)性不太好。所以為了提高跨平臺(tái)型锡移,Java又為我們提供了另外一個(gè)包:
? ? ? ? javax.Swing:在AWT的基礎(chǔ)上呕童,建立的一套圖形界面系統(tǒng),其中提供了更多的組件淆珊,而且完全由Java實(shí)現(xiàn)夺饲,增強(qiáng)了移植性,屬輕量級(jí)控件施符。
? ? ? ? 我們以后開(kāi)發(fā)組件一般都是用javax.Swing哦往声。
? ? ? ? 我們都知道,Eclipse是用純Java編寫(xiě)戳吝,但是它用的既不是Awt界面也不是Swing界面浩销,而是Swt界面。這個(gè)外觀包也是基于Awt的听哭,但是是IBM支持Eclipse的這個(gè)小組獨(dú)立編寫(xiě)的圖形化外觀包慢洋。
? ? ? ? 也就是說(shuō)塘雳,現(xiàn)在做圖形化界面的有Awt、Swing普筹、Swt败明,Swt可在官網(wǎng)上下載到。
? ? ? ? 在圖形化界中太防,到底提供了哪些組件供我們使用呢妻顶?
? ? ? ? 來(lái)看一下它的組成:
????02-GUI(布局)
? ? ? ? 窗體中組件的排放方式,叫做布局蜒车。
? ? ? ? 常見(jiàn)的布局管理器:
? ? ? ? (接下來(lái)的課程中為了節(jié)省時(shí)間讳嘱,有現(xiàn)成的文字就不手打啦,都直接通過(guò)截屏貼過(guò)來(lái)哦)
? ? ? ? 流式布局管理器:
? ? ? ? 邊界布局管理器:
? ? ? ? 在邊界布局管理器中酿愧,若沒(méi)有指定組件的方位沥潭,則會(huì)變成這樣。充斥整個(gè)畫(huà)面:
? ? ? ? 網(wǎng)格布局管理器:
? ? ? ? 網(wǎng)格包布局管理器:
? ? ? ? 卡片布局管理器:
? ? ? ? ? 我們需要哪種布局寓娩,new這個(gè)布局管理器的對(duì)象就可以啦叛氨。但是做圖像界面最痛苦的也在這兒,做之前都要先打個(gè)草稿棘伴,先把圖形化界面用筆畫(huà)一畫(huà)寞埠,要不然做出來(lái)的東西雖然功能都實(shí)現(xiàn)了,但是可能會(huì)奇丑無(wú)比焊夸。
? ? ? ? 還有一個(gè)很膩害的布局方式仁连,就是坐標(biāo)式,我們想將組件放在哪里就放在哪里阱穗。這也是讓我們用高級(jí)一些的編譯器的原因饭冬,到時(shí)候直接將組件拖拉拽進(jìn)畫(huà)面中,代碼就自動(dòng)生成了揪阶。當(dāng)然昌抠,我們現(xiàn)在剛開(kāi)始學(xué)還是采取手寫(xiě)代碼的方式。
? ? ? ? 如果我們一個(gè)頁(yè)面同時(shí)需要多種布局方式鲁僚,只需要給畫(huà)面中插入多個(gè)panel炊苫,然后設(shè)置每個(gè)panel的布局方式就OK啦。
????03-GUI(Frame)
? ? ? ? 講了這么多冰沙,接下來(lái)我們手寫(xiě)代碼來(lái)構(gòu)造圖形化界面:
? ? ? ??圖形化界面是由另外一個(gè)線程控制的侨艾,只要開(kāi)啟圖形化界面,就會(huì)多一個(gè)線程拓挥。
? ? ? ? 我們看到唠梨,這個(gè)圖形化界面好mini哦:
? ? ? ? 不過(guò)它可以拉大:
? ? ? ? 設(shè)置它的尺寸,第一個(gè)數(shù)字是長(zhǎng)侥啤,第二個(gè)數(shù)字是寬:
? ? ? ? 我們發(fā)現(xiàn)当叭,每次窗體出現(xiàn)都是在固定的位置:屏幕的左上角茬故,我們重新設(shè)置一下它出現(xiàn)的位置:
? ? ? ? 添加一個(gè)按鈕:
? ? ? ? 我們發(fā)現(xiàn)按鈕充斥了整個(gè)窗體。Frame這個(gè)窗體在new完對(duì)象之后具備一個(gè)默認(rèn)的布局管理器:邊界式布局科展,因?yàn)槲覀儧](méi)有指定按鈕的東南西北均牢,所以如上圖所示糠雨,它居中填充了。
? ? ? ? 我們修改一下界面的布局管理,設(shè)置成流式布局:
? ? ? ? 總結(jié)一下艾船,創(chuàng)建圖形化界面的思路:
? ? ? ? 其實(shí)昔字,創(chuàng)建一個(gè)圖形化界面并不難,更重點(diǎn)的是實(shí)現(xiàn)圖形化界面的功能松邪,我們發(fā)現(xiàn)坞琴,點(diǎn)button并沒(méi)有什么反應(yīng),而且該死的竟然點(diǎn)叉叉都關(guān)不掉這個(gè)窗體逗抑。剧辐。。
????04-GUI(事件監(jiān)聽(tīng)機(jī)制)
? ? ? ? 想讓我們的組件有效果邮府,就要涉及到事件監(jiān)聽(tīng)機(jī)制了荧关。? ? ? ??
? ? ? ? 什么叫事件監(jiān)聽(tīng)機(jī)制呢?
? ? ? ? 簡(jiǎn)單點(diǎn)說(shuō)褂傀,創(chuàng)建一個(gè)組件忍啤,給這個(gè)組件搞一些事情,只要這些事情一發(fā)生仙辟,這個(gè)組件就會(huì)有一些效果同波。
? ? ? ? 事件監(jiān)聽(tīng)機(jī)制的流程圖:
? ? ? ? 舉個(gè)例子,我們安裝了一個(gè)鎖叠国,這個(gè)鎖一被砸警報(bào)器就會(huì)響未檩。
? ? ? ? 鎖就相當(dāng)于事件源,警報(bào)器就相當(dāng)于監(jiān)聽(tīng)器粟焊,1冤狡,將鎖和警報(bào)器連接起來(lái),就是將監(jiān)聽(tīng)器注冊(cè)到事件源吆玖。
????????砸是外部動(dòng)作筒溃,2,發(fā)生了砸這個(gè)動(dòng)作沾乘,就是有監(jiān)聽(tīng)器所監(jiān)聽(tīng)的動(dòng)作作用于事件源上怜奖。
? ? ? ? 這時(shí),3翅阵,監(jiān)聽(tīng)器監(jiān)聽(tīng)到了砸這個(gè)動(dòng)作歪玲,立刻產(chǎn)生了事件迁央。這個(gè)事件會(huì)被封裝成一個(gè)對(duì)象,這個(gè)事件對(duì)象中記錄了到底是哪個(gè)密碼鎖之類(lèi)的具體信息滥崩,
? ? ? ? 4岖圈,將事件對(duì)象傳給事件處理方式。誰(shuí)在監(jiān)聽(tīng)這個(gè)動(dòng)作就傳給誰(shuí)钙皮。
? ? ? ? 傳過(guò)來(lái)之后蜂科,這個(gè)監(jiān)聽(tīng)器里面就會(huì)有相對(duì)應(yīng)的事件處理方式。
? ? ? ? 圖示表示鎖被砸后的事件:
? ? ? ? 事件監(jiān)聽(tīng)機(jī)制包含了這幾個(gè)部分短条,而需要我們?nèi)プ龅牡枷唬褪鞘录奶幚矸绞竭@一部分。
? ? ? ? 事件監(jiān)聽(tīng)機(jī)制的特點(diǎn):
????05-GUI(窗體事件)
? ? ? ? 接下來(lái)我們?yōu)槲覀儎?chuàng)建的窗體注冊(cè)一個(gè)監(jiān)聽(tīng)事件茸时,就要用到addWindowListener這個(gè)方法贡定,但是它需要傳一個(gè)WindowListener類(lèi)型的參數(shù):
? ? ? ? WindowListener是一個(gè)接口,如果實(shí)現(xiàn)它可都,就要復(fù)寫(xiě)里面的7個(gè)方法缓待,實(shí)在太麻煩了,我們只需要用到關(guān)閉的動(dòng)作渠牲,這個(gè)時(shí)候旋炒,它有一個(gè)子類(lèi)WindowAdapter已經(jīng)實(shí)現(xiàn)了WindowListener接口,并覆蓋了其中的所有方法(雖然它里面的方法都是空的嘱兼,因?yàn)樗褪菫榱吮贿@樣使用)国葬,那么我們只需要繼承WindowAdapter類(lèi)并且覆蓋我們需要用到的方法就好啦。
? ? ? ? OK芹壕,我們寫(xiě)一個(gè)MyWin的類(lèi)繼承WindowAdapter類(lèi):
? ? ? ? 這時(shí)汇四,將MyWin對(duì)象傳入addWindowListener方法就好啦:
? ? ? ? 注意哦,它們是awt的一個(gè)子包event中的對(duì)象踢涌,所以記得導(dǎo)入這個(gè)包哦:
? ? ? ? 涉及到事件監(jiān)聽(tīng)都不要忘記導(dǎo)入這個(gè)包哦通孽。
? ? ? ? 現(xiàn)在運(yùn)行,我們一點(diǎn)關(guān)閉按鈕就觸發(fā)了窗體事件:
? ? ? ? 因?yàn)槲覀儚?fù)寫(xiě)的方法中只有打印的功能睁壁,所以每次點(diǎn)擊它只是打印了window closing字符串背苦,窗體并沒(méi)有關(guān)閉。
? ? ? ? 我們也可以打印一下打印事件的詳細(xì)信息:
????????點(diǎn)關(guān)閉會(huì)打印事件所屬的信息:
? ? ? ? 剛剛只是試一試潘明,下面這句才是正正經(jīng)經(jīng)的關(guān)閉窗體的語(yǔ)句:
? ? ? ? 除了上面這種方法行剂,我們也可以寫(xiě)一個(gè)匿名類(lèi):
? ? ? ? 同樣可以實(shí)現(xiàn)窗體的關(guān)閉。
? ? ? ? 除了窗體關(guān)閉事件钳降,還有其他兩個(gè)事件windowActivated和windowOpened也了解一下哦:
????06-GUI(Action事件)
? ? ? ? 接下來(lái)我們把事件的代碼和圖形化界面組件的代碼分離出來(lái)厚宰,下面是比較規(guī)范的代碼示例:
? ? ? ? 下面我們添加一個(gè)退出按鈕,讓它具備退出功能:
????07-GUI(鼠標(biāo)事件)
? ? ? ? 鼠標(biāo)事件和鍵盤(pán)事件,幾乎所有的組件都具備铲觉,我們?cè)赾omponent類(lèi)中找到這兩個(gè)方法:
? ? ? ? addMouseListener中傳入了一個(gè)MouseListener接口型的數(shù)據(jù)澈蝙,我們看一下MouseListener這個(gè)接口:
? ? ? ? 它里面的方法對(duì)鼠標(biāo)事件劃分非常細(xì):
? ? ? ? 我們?cè)囈幌率髽?biāo)進(jìn)入事件,直接把上節(jié)課的代碼拿來(lái)用撵幽,將新的代碼添加進(jìn)去:
? ? ? ? 同理灯荧,鼠標(biāo)點(diǎn)擊事件:
? ? ? ? 按鈕還有一個(gè)監(jiān)聽(tīng)器叫做活動(dòng)監(jiān)聽(tīng),點(diǎn)擊按鈕后點(diǎn)擊事件和活動(dòng)監(jiān)聽(tīng)誰(shuí)會(huì)發(fā)生呢盐杂??
? ? ? ? 后續(xù)不點(diǎn)擊鼠標(biāo)逗载,但是用鍵盤(pán),活動(dòng)監(jiān)聽(tīng)就會(huì)執(zhí)行况褪,因?yàn)橹灰粹o被活動(dòng)著撕贞,不管是鼠標(biāo)還是鍵盤(pán)事件更耻,它都會(huì)執(zhí)行测垛。所以按鈕上加事件,盡量加活動(dòng)監(jiān)聽(tīng)秧均。但是如果同時(shí)也加上Clicked事件食侮,會(huì)發(fā)現(xiàn)Clicked先執(zhí)行,鼠標(biāo)點(diǎn)擊事件會(huì)比活動(dòng)監(jiān)聽(tīng)事件活動(dòng)得更具體一些目胡。
? ? ? ? 雙擊動(dòng)作的判斷:
? ? ? ? 用這個(gè)方法锯七,不僅雙擊動(dòng)作,三擊誉己、四擊...十擊動(dòng)作都可以判斷眉尸。
????08-GUI(鍵盤(pán)事件)
? ? ? ? 依然是為but這個(gè)按鈕添加一個(gè)鍵盤(pán)事件。
? ? ? ? KeyListener接口中的方法:
? ? ? ? 鍵盤(pán)監(jiān)聽(tīng)事件:
? ? ? ? 但是鍵盤(pán)上的有的按鍵不只由一個(gè)字母組成巨双,而是由許多字母組成噪猾,那么用上面的方法就只能獲取第一個(gè)字符,接下來(lái)我們要獲取該鍵的文本筑累,即它的全部字符:
? ? ? ? 小功能袱蜡,鍵盤(pán)按下Esc就結(jié)束:
? ? ? ? 但是27不好記,我們用它對(duì)應(yīng)的常量值:
? ? ? ? 如果我們想監(jiān)聽(tīng)ctrl+Enter呢慢宗?
? ? ? ? 在InputEvent類(lèi)中坪蚁,有這個(gè)方法,判斷ctrl鍵是否被摁下:
? ? ? ? OK镜沽, 這樣寫(xiě):
? ? ? ? 接下來(lái)我們想添加一個(gè)文本框敏晤,里面只能輸數(shù)字:
????????寫(xiě)在鍵盤(pán)監(jiān)聽(tīng)中:
????09-GUI(練習(xí)-列出指定目錄內(nèi)容)
????????先把界面搭出來(lái):? ? ? ??
? ? ? ? ?搭出來(lái)之后,我們發(fā)現(xiàn)界面很丑缅茉,下面做一些排版調(diào)整:
? ? ? ? 界面搭好了嘴脾,接下來(lái)做功能,我們確定事件源為but宾舅,它同時(shí)操作這兩個(gè)框框统阿。
? ? ? ? 我們添加一個(gè)action監(jiān)聽(tīng),這樣鼠標(biāo)和鍵盤(pán)動(dòng)作就都可以監(jiān)聽(tīng)到扶平。
? ? ? ? 因?yàn)楣δ苌婕暗搅宋募僮鞣耄灶^文件中一定要加入io包:
? ? ? ? 但是我們發(fā)現(xiàn)只顯示了一個(gè)文件,原因是每次設(shè)置都會(huì)覆蓋结澄。于是我們將設(shè)置文本改成追加文本:
? ? ? ? OK了:
????10-GUI(對(duì)話框Dialog)
? ? ? ? 窗體的功能實(shí)現(xiàn)了哥谷,但是錯(cuò)誤的提示還沒(méi)有完成,以后這個(gè)窗體可能會(huì)被封裝成一個(gè)可執(zhí)行程序麻献,就可以脫離控制臺(tái)運(yùn)行了们妥。?
? ? ? ? 依然在之前的基礎(chǔ)上添加代碼:
? ? ? ? 這個(gè)對(duì)話框很小,拉大之后發(fā)現(xiàn)確定按鈕覆蓋了整個(gè)窗體:
? ? ? ? 因?yàn)閐ialog默認(rèn)的布局管理器也是邊界布局勉吻,所以我們重新設(shè)置一下它的尺寸和布局方式:
? ? ? ? 把監(jiān)聽(tīng)事件寫(xiě)好:
? ? ? ? 好了监婶,接下來(lái)我們需要將錯(cuò)誤信息顯示在對(duì)話框上:
? ? ? ? 實(shí)現(xiàn)輸入后按回車(chē)就可以顯示目錄:
????11-GUI(菜單)?
? ? ? ? 關(guān)于菜單的對(duì)象:
????????MenuBar 菜單欄 菜單條。
????????MenuBar中有添加菜單(Menu對(duì)象)的方法齿桃。
? ? ? ? 而Menu中又可以添加菜單項(xiàng)(MenuItem對(duì)象)惑惶。
? ? ? ? Menu本身是MenuItem中的一員/子類(lèi):
? ? ? ? 話不多說(shuō),寫(xiě)代碼:
? ? ? ? 效果:
? ? ? ? 給這個(gè)菜單中再添加一個(gè)子菜單:
? ? ? ? 注意:Menu可以添加MenuItem短纵,也可以添加Menu带污。
? ? ? ? 添加事件監(jiān)聽(tīng):
????12-GUI(練習(xí)-打開(kāi)文件)
? ? ? ? 依然在之前的代碼上做添加和改動(dòng),添加/改動(dòng)的地方用紅框框出來(lái)了:
? ? ? ? 界面搭好了:
????????下面我們想做一個(gè)打開(kāi)的效果香到。
? ? ? ? 我們看一下FileDialog對(duì)象的方法:
? ? ? ? 代碼:
? ? ? ? 效果:
? ? ? ? 下面添加文本顯示區(qū)域:
? ? ? ? (如果還是用流式布局界面會(huì)是下面這樣鱼冀,丑丑的):
? ? ? ? 添加的代碼,添加文本區(qū)域:
? ? ? ? 邊界布局效果就好看多了:
? ? ? ? 事件監(jiān)聽(tīng):
? ? ? ? 別忘記寫(xiě)上io包哦:
? ? ? ? 成功打開(kāi)了:
????13-GUI(練習(xí)-保存文件)
? ? ? ? 注意悠就,如果該文件已存在千绪,則點(diǎn)保存不會(huì)彈出對(duì)話框,如果該文件不存在理卑,則點(diǎn)保存會(huì)彈出對(duì)話框翘紊。
? ? ? ? 代碼:
? ? ? ? 該文件不存在,所以保存時(shí)會(huì)彈出對(duì)話框:
????14-GUI(jar包雙擊執(zhí)行)
? ? ? ? 我們剛剛寫(xiě)的這個(gè)java文件中有好多類(lèi):
? ? ? ? 類(lèi)一多就要封裝藐唠,怎么封裝呢帆疟?找個(gè)包就好了。我們?cè)诖a中加入包宇立,并且將類(lèi)改成public型:
? ? ? ? 打個(gè)jar包:
? ? ? ? 但是發(fā)現(xiàn)jar包雙擊無(wú)法打開(kāi):
? ? ? ? 因?yàn)閖ar包中有很多類(lèi)踪宠,它不知道該找哪個(gè)類(lèi)打開(kāi)。這時(shí)就需要我們告訴jar包哪個(gè)是帶主函數(shù)的類(lèi),我們找到它執(zhí)行就OK。
? ? ? ? jar包中都有配置信息:
? ? ? ? 這個(gè)文件夾中有配置信息文件:
? ? ? ? 下面我們重新開(kāi)始蜻韭,刪掉剛剛創(chuàng)建的jar包盒齿。新建一個(gè)txt文件,名字隨便起思瘟,將配置清單的信息寫(xiě)在這個(gè)文件中:
? ? ? ? 重新打jar包:
? ? ? ? 打完包之后浮还,我們?cè)倏磁渲眯畔⑽募拢l(fā)現(xiàn)我們寫(xiě)的配置信息都寫(xiě)入了這個(gè)文件:
? ? ? ? OK倒堕,雙擊jar包灾测,打開(kāi)了我們寫(xiě)的窗體,并且運(yùn)行正常:
? ? ? ?另垦巴, jar文件必須在本地注冊(cè)過(guò)才能用媳搪,一般我們是雙擊安裝的jdk,都會(huì)自動(dòng)注冊(cè)號(hào)骤宣,就像下面這樣:
? ? ? ? 但是如果只是將jdk粘貼進(jìn)電腦中秦爆,就需要我們自己注冊(cè)。下面我們將它刪掉憔披,重新注冊(cè)一遍:
? ? ? ? OK了等限,圖標(biāo)變成了小樹(shù):
? ? ? ? 還有要注意一下配置信息的格式: