圖形使用者介面--GUI
不論一個程式有多好,如果是用命令列操作的,估計它的使用率都會非常的低,所以,圖形化介面就相當重要了,一個好看的,符合大眾審美的圖形化介面會大大提高我們軟體的使用量。今天記錄的筆記是關於圖形化介面的。
Java為我們提供的關於圖形化介面的包是awt和swing包。
awt:abstract window toolkit
swing:是在awt的基礎上建立的一套圖形介面系統。
在awt包中,有一個特殊的類。component:是容器的意思,它是一個特殊的元件,這個元件可以通過add()方法把其他元件新增進來。
這個類比較重要的幾個子類包括:window(視窗),
Button(按鈕),
Label(標籤),
CheckBox(複選框),
TextArea(文字區域,此處可以編輯文字),
TextField(文字框,只顯示給定的文字),
Frame(框架),
FileDialog(文字對話方塊)等。
在gui中,最重要的就是佈局,只有確定了主體的佈局,才能在裡面新增元件。四種最常用的佈局方式包括:
1:FlowLayout:流式佈局,裡面新增的元件都是按照從左至右的順序排放,如果放不下了,就自動放入下一行。這是panel的預設佈局方式。
2:BorderLayout:邊界佈局,裡面新增的元件按照東南西北中五個方位排放,如果新增進去的元件沒有指定放置的方位,則會全部填滿整個空間。這是Frame的預設佈局方式。
3:GridLayout:網格佈局,這個佈局是全部分成很多個網格(規則的矩陣),新增進去的元件依次放進每個格子中。
4:GridBagLayout:網格包佈局,它的網格是不規則的。比如有的元件只佔用一格,但是有的元件需要佔用不止一格。
因為不可能把這些類中的方法每個都看一遍,只有在需要用到的時候去查閱api。所以我直接用例子來幫助學習和記憶。
首先,要想有一個圖形化介面,肯定要先有介面的框架,這就要用到frame類,首先新建一個框架,這個框架新建的時候就可以指定它的名字,其次,如果想改變框架的佈局方式,就需要呼叫設定佈局方式的方法改變佈局方式。然後,每個框架出現的預設位置都是螢幕的左上角,因為螢幕的座標起點在那裡,所以還需要指定介面的位置,其次,框架的大小是預設很小的一個框,所以還需要改變框架的大小。所以,基本操作如下:
Frame frame=new Frame("my awt");
frame.setLayout(new FlowLayout());
frame.setLocation(300, 200);
frame.setSize(500,400);
並不是這些操作做完就可以看到我們定義的框架的,還需要一個很重要的函式:把框架設定為可見
frame.setVisible(true);
這個操作做完後才會看見我們的介面。當然,只有這些操作,這個介面沒有任何的意義,而且,這個介面除了能放大,縮小外,沒有任何作用,甚至點關閉都不能關掉。必須要手動停掉程式。這裡開始,才是我們需要去重視的程式碼了。因為定義框架的這一系列操作,純程式碼手寫是很麻煩的,而且需要我們去調整大小什麼的,很麻煩,這些我們是全部可以藉助一些軟體或外掛去很快的完成,而那些元件後面的功能,才是我們需要關注的內容。這裡開始,就涉及到我們的重點,監聽機制了。
我們先來看看監聽機制的組成:事件源(元件):就是awt活著swing包中的那些圖形化介面元件
事件(Event):每一個事件源都有自己特有的對應事件和共性事件
監聽器(Listener):將可以觸發某一個事件的動作都已經封裝到了監聽器中
(以上三者在Java中都已經定義好了,可以直接通過新建物件拿來用)
事件處理(引發事件後的處理方式)
(對於引發事件後的處理方式才是重中之重)
監聽機制的流程:
1:將監聽器註冊到事件源
2:有監聽器所監聽的動作作用於事件源上
3:產生事件物件
4:將事件物件傳給事件處理方式
要處理事件,首先我們需要知道的是有哪些事件。
我們先來講解的是視窗事件:windowEvent。之前我們寫的框架,雖然可以顯示了,但是我們點選關閉按鈕沒有任何的作用。現在我們就為視窗新增監聽器,使之能相應關閉動作。先祭出程式碼在繼續記錄:
frame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); System.out.println("close"); } });
在這段程式碼中,首先看到的是frame物件呼叫add方法把監聽器註冊到事件源上,方法的引數肯定是一個監聽器介面,但是,通過查閱API可知,如果要用視窗監聽器的物件,需要複寫監聽器中所有的抽象方法,這個顯然是不可取的,所以,這裡要引進一個很牛逼哄哄的東西,叫介面卡(adapter),至於為什麼叫這個我也不知道,可能是想表達適合於很多的事件吧,比較適配。gui的大多元件,都用到的介面卡,只有三個用的是listener(我沒有百度出來究竟是哪三個,如果又看到的小夥伴知道是哪三個,希望能留言告知,非常感謝了。)其實用到adapter的都是因為它們的監聽器裡面的方法超過三個了,全部複寫比較麻煩,所以用了一個介面卡類來方便進行事件監聽。
繼續回到程式碼,有了介面卡之後,這個引數是以一個內部類的形式,所以,我們在這個類裡面複寫我們需要的方法,對發生的事件進行處理就可以了。我對這個的處理是點選關閉按鈕可以退出程式並且在控制檯上列印“close”。
現在,這個介面就可以不用通過停止程式來關閉了,但是,我們的介面上不可能只有這麼點東西,所以我們在這上面試著去新增按鈕(畢竟所有程式肯定都要有按鈕嘛)
private Button but;
but=new Button("my button");
f.add(but);
把按鈕新增上後,這個按鈕也是沒有任何作用的,所以也需要我們去新增監聽器,監聽上面發生的事件。
but.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
// TODO Auto-generated method stub
System.exit(0);
}
});
對於之前提到的三個沒有介面卡之一的就是button了。對比上面的監聽器的新增格式我們可以看出,其實大體的程式碼都是一樣的,只是根據我們不同的作用,來對程式碼進行細微的改動。
首先肯定是相應的元件呼叫add()方法來新增監聽器。視窗監聽器就是新增windowListener,按鈕需要我們的動作作用於上面,所以新增的就是ActionListener。窗口裡面的是介面卡,所以就new 一個windowAdapter(),而按鈕是監聽器,所以就new 一個ActionListener()。在內部類裡面,複寫相應的方法的時候,引數列表都是一個事件物件,什麼元件對應的事件就是**Event。比如:WindowEvent,ActionEvent。以此類推其他的事件監聽器的新增。方法內部就沒有規律了。
到這裡,gui中兩個比較重要的點就差不多了。