天天看點

java圖形界面設計

AWT圖形使用者界面設計(一)

5.1 用AWT生成圖形化使用者界面 

   抽象視窗工具包AWT (Abstract Window Toolkit) 是 API為Java 程式提供的建立圖形使用者界面GUI (Graphics User Interface)工具集,AWT可用于Java的applet和applications中。它支援圖形使用者界面程式設計的功能包括: 使用者界面元件;事件處理模型;圖形和圖像工具,包括形狀、顔色和字型類;布局管理器,可以進行靈活的視窗布局而與特定視窗的尺寸和螢幕分辨率無關;資料傳送類,可以通過本地平台的剪貼闆來進行剪切和粘貼。 

  5.1.1 java.awt包 

   

  java.awt包中提供了GUI設計所使用的類和接口,可從圖5.1中看到主要類之間的關系。 

   java.awt包提供了基本的java程式的GUI設計工具。主要包括下述三個概念: 

  元件--Component 

  容器--Container 

  布局管理器--LayoutManager 

  5.1.2 元件和容器 

  Java的圖形使用者界面的最基本組成部分是元件(Component),元件是一個可以以圖形化的方式顯示在螢幕上并能與使用者進行互動的對象,例如一個按鈕,一個标簽等。元件不能獨立地顯示出來,必須将元件放在一定的容器中才可以顯示出來。 

  類java.awt.Component是許多元件類的父類,Component類中封裝了元件通用的方法和屬性,如圖形的元件對象、大小、顯示位置、前景色和背景色、邊界、可見性等,是以許多元件類也就繼承了Component類的成員方法和成員變量,相應的成員方法包括: 

   getComponentAt(int x, int y) 

   getFont() 

   getForeground() 

   getName() 

   getSize() 

   paint(Graphics g) 

   repaint() 

   update() 

   setVisible(boolean b) 

   setSize(Dimension d) 

   setName(String name)等 

   

  容器(Container)也是一個類,實際上是Component的子類,是以容器本身也是一個元件,具有元件的所有性質,但是它的主要功能是容納其它元件和容器。 

  布局管理器(LayoutManager):每個容器都有一個布局管理器,當容器需要對某個元件進行定位或判斷其大小尺寸時,就會調用其對應的布局管理器。 

  為了使我們生成的圖形使用者界面具有良好的平台無關性,Java語言中,提供了布局管理器這個工具來管理元件在容器中的布局,而不使用直接設定元件位置和大小的方式。 

  在程式中安排元件的位置和大小時,應該注意以下兩點: 

  1.容器中的布局管理器負責各個元件的大小和位置,是以使用者無法在這種情況下設定元件的這些屬性。如果試圖使用Java 語言提供的setLocation(),setSize(),setBounds() 等方法,則都會被布局管理器覆寫。 

  2.如果使用者确實需要親自設定元件大小或位置,則應取消該容器的布局管理器,方法為: 

   setLayout(null); 

  5.1.3 常用容器 

  容器java.awt.Container是Component的子類,一個容器可以容納多個元件,并使它們成為一個整體。容器可以簡化圖形化界面的設計,以整體結構來布置界面。所有的容器都可以通過add()方法向容器中添加元件。 

  有三種類型的容器:Window、Panel、ScrollPane,常用的有Panel, Frame, Applet。 

  1.Frame 

   

  以下是容器的例子: 

  例5.1 

  import java.awt.*; 

  public class MyFrame extends Frame{ 

  public static void main(String args[ ]){ 

        MyFrame fr = new MyFrame("Hello Out There!"); 

                       //構造方法 

        fr.setSize(200,200); 

                //設定Frame的大小,預設為(0,0) 

        fr.setBackground(Color.red); 

                //設定Frame的背景,預設為紅色 

        fr.setVisible(true); 

                //設定Frame為可見,預設為不可見 

  } 

     public MyFrame (String str){ 

        super(str); //調用父類的構造方法 

     } 

  } 

  一般我們要生成一個視窗,通常是用Window的子類Frame來進行執行個體化,而不是直接用到Window類。Frame的外觀就像我們平常在windows系統下見到的視窗,有标題、邊框、菜單、大小等等。每個Frame的對象執行個體化以後,都是沒有大小和不可見的,是以必須調用setSize( )來設定大小,調用setVisible(true)來設定該視窗為可見的。 

  另外,AWT在實際的運作過程中是調用所在平台的圖形系統,是以同樣一段AWT程式在不同的作業系統平台下運作所看到的圖形系統是不一樣的。例如在windows下運作,則顯示的視窗是windows風格的視窗;而在UNIX下運作時,則顯示的是UNIX風格的視窗。 

  2. Panel 

   

  例5.2 

  import java.awt.*; 

  public class FrameWithPanel extends Frame{ 

  public FrameWithPanel(String str){ 

        super(str); 

      } 

      public static void main(String args[]){ 

        FrameWithPanel fr = new FrameWithPanel("Frame with Panel"); 

        Panel pan=new Panel(); 

        fr.setSize(200,200); 

        fr.setBackground(Color.red); 

               //架構fr的背景顔色設定為紅色 

        fr.setLayout(null); 

               //取消布局管理器 

        pan.setSize(100,100); 

        pan.setBackground(Color.yellow); 

               //設定面闆pan的背景顔色為黃色 

        fr.add(pan); //用add方法把面闆pan添加到架構fr中 

        fr.setVisible(true); 

        } 

   } 

  一般我們要生成一個視窗,通常是用Window的子類Frame來進行執行個體化,而不是直接用到Window類。Frame的外觀就像我們平常在windows系統下見到的視窗,有标題、邊框、菜單、大小等等。每個Frame的對象執行個體化以後,都是沒有大小和不可見的,是以必須調用setSize( )來設定大小,調用setVisible(true)來設定該視窗為可見的。 

  另外,AWT在實際的運作過程中是調用所在平台的圖形系統,是以同樣一段AWT程式在不同的作業系統平台下運作所看到的圖形系統是不一樣的。例如在windows下運作,則顯示的視窗是windows風格的視窗;而在UNIX下運作時,則顯示的是UNIX風格的視窗。

  5.1.4 layoutmanager 布局管理器(1) 

  java為了實作跨平台的特性并且獲得動态的布局效果,java将容器内的所有元件安排給一個"布局管理器"負責管理,如:排列順序,元件的大小、位置,當視窗移動或調整大小後元件如何變化等功能授權給對應的容器布局管理器來管理,不同的布局管理器使用不同算法和政策,容器可以通過選擇不同的布局管理器來決定布局。 

   布局管理器主要包括:flowlayout,borderlayout,gridlayout,cardlayout,gridbaglayout 

  例5.3 

    import java.awt.*; 

    public class exgui< 

        private frame f; 

        private button b1; 

        private button b2; 

        public static void main(string args[])< 

            exgui that = new exgui(); 

            that.go(); 

    > 

        public void go()< 

            f = new frame("gui example"); 

            f.setlayout(new flowlayout()); 

            //設定布局管理器為flowlayout 

            b1 = new button("press me"); 

            //按鈕上顯示字元"press me" 

            b2 = new button("dont press me"); 

            f.add(b1); 

            f.add(b2); 

            f.pack(); 

            //緊湊排列,其作用相當于setsize(),即讓視窗 

            盡量小,小到剛剛能夠包容住b1、b2兩個按鈕 

            f.setvisible(true); 

        > 

    > 

  1. flowlayout 

  flowlayout 是panel,applet的預設布局管理器。其元件的放置規律是從上到下、從左到右進行放置,如果容器足夠寬,第一個元件先添加到容器中第一行的最左邊,後續的元件依次添加到上一個元件的右邊,如果目前行已放置不下該元件,則放置到下一行的最左邊。 

  構造方法主要下面幾種: 

  flowlayout(flowlayout.right,20,40); 

   

  flowlayout(flowlayout.left); 

  //居左對齊,橫向間隔和縱向間隔都是預設值5個象素 

  flowlayout(); 

  //預設的對齊方式居中對齊,橫向間隔和縱向間隔都是預設值5個象素 

  例5.4 

    import java.awt.*; 

    public class mybuttons< 

     public static void main(string args[]) 

     < 

        frame f = new frame(); 

        f.setlayout(new flowlayout()); 

        button button1 = new button("ok"); 

        button button2 = new button("open"); 

        button button3 = new button("close"); 

        f.add(button1); 

        f.add(button2); 

        f.add(button3); 

        f.setsize(300,100); 

        f.setvisible(true); 

     > 

    > 

  當容器的大小發生變化時,用flowlayout管理的元件會發生變化,其變化規律是:元件的大小不變,但是相對位置會發生變化。例如上圖中有三個按鈕都處于同一行,但是如果把該視窗變窄,窄到剛好能夠放下一個按鈕,則第二個按鈕将折到第二行,第三個按鈕将折到第三行。按鈕"open"本來在按鈕"ok"的右邊,但是現在跑到了下面,是以說"元件的大小不變,但是相對位置會發生變化"。 

  2. borderlayout 

  borderlayout 是window,frame和dialog的預設布局管理器。borderlayout布局管理器把容器分成5個區域:north,south,east,west和center,每個區域隻能放置一個元件。 

  例5.5 

    import java.awt.*; 

    public class buttondir< 

     public static void main(string args[])< 

      frame f = new frame("borderlayout"); 

      f.setlayout(new borderlayout()); 

      f.add("north", new button("north")); 

      //第一個參數表示把按鈕添加到容器的north區域 

      f.add("south", new button("south")); 

      //第一個參數表示把按鈕添加到容器的south區域 

      f.add("east", new button("east")); 

      //第一個參數表示把按鈕添加到容器的east區域 

      f.add("west", new button("west")); 

      //第一個參數表示把按鈕添加到容器的west區域 

      f.add("center", new button("center")); 

      //第一個參數表示把按鈕添加到容器的center區域 

      f.setsize(200,200); 

      f.setvisible(true); 

     > 

    > 

  在使用borderlayout的時候,如果容器的大小發生變化,其變化規律為:元件的相對位置不變,大小發生變化。例如容器變高了,則north、south區域不變,west、center、east區域變高;如果容器變寬了,west、east區域不變,north、center、south區域變寬。不一定所有的區域都有元件,如果四周的區域(west、east、north、south區域)沒有元件,則由center區域去補充,但是如果center區域沒有元件,則保持空白。 

  3. gridlayout 

  使容器中各個元件呈網格狀布局,平均占據容器的空間。 

  例5.6 

    import java.awt.*; 

    public class buttongrid < 

    public static void main(string args[]) < 

      frame f = new frame("gridlayout"); 

      f.setlayout(new gridlayout(3,2)); 

                 //容器平均分成3行2列共6格 

      f.add(new button("1")); //添加到第一行的第一格 

      f.add(new button("2")); //添加到第一行的下一格 

      f.add(new button("3")); //添加到第二行的第一格 

      f.add(new button("4")); //添加到第二行的下一格 

      f.add(new button("5")); //添加到第三行的第一格 

      f.add(new button("6")); //添加到第三行的下一格 

      f.setsize(200,200); 

      f.setvisible(true); 

    > 

    > 

  5.1.4 layoutmanager 布局管理器(2) 

   4. cardlayout 

  cardlayout布局管理器能夠幫助使用者處理兩個以至更多的成員共享同一顯示空間,它把容器分成許多層,每層的顯示空間占據整個容器的大小,但是每層隻允許放置一個元件,當然每層都可以利用panel來實作複雜的使用者界面。牌布局管理器(cardlayout)就象一副疊得整整齊齊的撲克牌一樣,有54張牌,但是你隻能看見最上面的一張牌,每一張牌就相當于牌布局管理器中的每一層。 

  例5.7 

  import java.awt.*; 

  import java.awt.event.*; //事件處理機制,下一節的内容 

  public class threepages implements mouslistener < 

    cardlayout layout=new cardlayout(); //執行個體化一個牌布局管理器對象 

    frame f=new frame("cardlayout"); 

    button page1button; 

    label page2label; //label是标簽,實際上是一行字元串 

    textarea page3text; //多行多列的文本區域 

    button page3top; 

    button page3bottom; 

  public static void main(string args[]) 

  < new threepages().go(); > 

  public void go() 

  <   f.setlayout(layout); //設定為牌布局管理器layout 

    f.add(page1button=new button("button page"),"page1button");  

    page1button.addmouselistener(this); //注冊監聽器 

    f.add(page2label=new label("label page"),"page2label"); 

    page2label.addmouselisener(this); //注冊監聽器 

    panel panel=new panel(); 

    panel.setlayout(new borderlayout()); 

    panel.add(page3text=new textarea("composite page"),"center"); 

    page3text.addmouselistener(this); 

    panel.add(page3top=new button("top button") , "north"); 

    page3top.addmouselistener(this); 

    panel.add(page3bottom=new button("bottom button") ,"south"); 

    page3bottom.addmouselistener(this); 

    f.add(panel,"panel"); 

    f.setsize(200,200); 

    f.setvisible(true); 

  > 

  …… 

  > 

  5.容器的嵌套 

  在複雜的圖形使用者界面設計中,為了使布局更加易于管理,具有簡潔的整體風格,一個包含了多個元件的容器本身也可以作為一個元件加到另一個容器中去,容器中再添加容器,這樣就形成了容器的嵌套。下面是一個容器嵌套的例子。 

  例5.8 

    import java.awt.*; 

    public class exgui3< 

    private frame f; 

    private panel p; 

    private button bw,bc; 

    private button bfile,bhelp; 

       public static void main(string args[]) 

       < 

         exgui3 gui = new exgui3(); 

         gui.go(); 

       > 

    public void go()< 

       f = new frame("gui example 3"); 

       bw=new button("west"); 

       bc=new button("work space region"); 

       f.add(bw,"west"); 

       f.add(bc,"center"); 

       p = new panel(); 

       f.add(p,"north"); 

       bfile= new button("file"); 

       bhelp= new button("help"); 

       p.add(bfile); 

       p.add(bhelp); 

       f.pack(); 

       f.setvisible(true); 

    > 

    > 

 小 結: 

   1.Frame是一個頂級視窗。Frame的預設布局管理器為BorderLayout。 

   2.Panel 無法單獨顯示,必須添加到某個容器中。 Panel 的預設布局管理器為FlowLayout。 

   3.當把Panel 作為一個元件添加到某個容器中後,該Panel 仍然可以有自己的布局管理器。是以,可以利用Panel 使得BorderLayout 中某個區域顯示多個元件,達到設計複雜使用者界面的目的 。 

   4.如果采用無布局管理器 setLayout(null),則必須使用setLocation(),setSize(),setBounds()等方法手工設定元件的大小和位置,此方法會導緻平台相關,不鼓勵使用。 

  5.2 AWT事件處理模型 

  上一節中的主要内容是如何放置各種元件,使圖形界面更加豐富多彩,但是還不能響應使用者的任何操作,要能夠讓圖形界面接收使用者的操作,就必須給各個元件加上事件處理機制。在事件處理的過程中,主要涉及三類對象: 

  ◇ Event-事件,使用者對界面操作在java語言上的描述,以類的形式出現,例如鍵盤操作對應的事件類是KeyEvent。 

  ◇ Event Source-事件源,事件發生的場所,通常就是各個元件,例如按鈕Button。 

  ◇ Event handler-事件處理者,接收事件對象并對其進行處理的對象 

  例如,如果使用者用滑鼠單擊了按鈕對象button,則該按鈕button就是事件源,而java運作時系統會生成ActionEvent類的對象actionE,該對象中描述了該單擊事件發生時的一些資訊,然後,事件處理者對象将接收由java運作時系統傳遞過來的事件對象actionE并進行相應的處理。 

  由于同一個事件源上可能發生多種事件,是以java采取了授權處理機制(Delegation Model),事件源可以把在其自身所有可能發生的事件分别授權給不同的事件處理者來處理。比如在Canvas對象上既可能發生滑鼠事件,也可能發生鍵盤事件,該Canvas對象就可以授權給事件處理者一來處理滑鼠事件,同時授權給事件處理者二來處理鍵盤事件。有時也将事件處理者稱為監聽器,主要原因也在于監聽器時刻監聽着事件源上所有發生的事件類型,一旦該事件類型與自己所負責處理的事件類型一緻,就馬上進行處理。授權模型把事件的處理委托給外部的處理實體進行處理,實作了将事件源和監聽器分開的機制。事件處理者(監聽器)通常是一個類,該類如果要能夠處理某種類型的事件,就必須實作與該事件類型相對的接口。例如例5.9中類ButtonHandler之是以能夠處理ActionEvent事件,原因在于它實作了與ActionEvent事件對應的接口ActionListener。每個事件類都有一個與之相對應的接口。 

  将事件源對象和事件處理器(事件監聽器)分開。 

     

  打個不太恰當的比喻,比如說有一位李先生,李先生可能會發生很多法律糾紛,可能是民事法律糾紛,也可能是刑事法律糾紛,那麼李先生可以請律師,他可以授權王律師負責幫他打民事法律的官司,同時也可以授權張律師幫他打刑事法律的官司。這個請律師的過程從李先生的角度來看,就是授權的過程,而從王律師和張律師的角度來看,一旦被授權,他們就得時刻對李先生負責,"監聽"着李先生,一旦發生民事糾紛了,王律師就要馬上去處理,而一旦發生刑事糾紛了,張律師就要馬上進行處理。此時此刻,李先生就是事件源,王律師是一個事件處理者,張律師是另外一個事件處理者,民事糾紛和刑事糾紛就是不同類型的事件。 

   

  例5.9 

    import java.awt.*; 

    import java.awt.event.*; 

    public class TestButton { 

    public static void main(String args[]) 

    { 

      Frame f = new Frame("Test"); 

      Button b = new Button("Press Me!"); 

      b.addActionListener(new ButtonHandler());  

      f.setLayout(new FlowLayout()); //設定布局管理器 

      f.add(b); 

      f.setSize(200,100); 

      f.setVisible(true); 

      } 

    } 

    class ButtonHandler implements ActionListener { 

    //實作接口ActionListener才能做事件ActionEvent的處理者 

    public void actionPerformed(ActionEvent e) 

    //系統産生的ActionEvent事件對象被當作參數傳遞給該方法 

    { 

      System.out.println("Action occurred"); 

    //本接口隻有一個方法,是以事件發生時,系統會自動調用本方法,需要做的操作就把代碼寫在則個方法裡。 

    } 

    } 

  使用授權處理模型進行事件處理的一般方法歸納如下: 

  1.對于某種類型的事件XXXEvent, 要想接收并處理這類事件,必須定義相應的事件監聽器類,該類需要實作與該事件相對應的接口XXXListener; 

  2.事件源執行個體化以後,必須進行授權,注冊該類事件的監聽器,使用addXXXListener(XXXListener ) 方法來注冊監聽器。

Swing

9.1 Swing

概述

9.2

事件響應原理

9.3

JLable

元件

9.4

JButton

元件與JToggleButton

元件

9.5

JCheckBox

和JRadioButton

元件

9.6

JComboBox

元件

9.7

JList

元件

9.8

JTextField

與JTextArea

元件

9.1 Swing

圖9.1 圖形使用者界面中常用的元件

9.1.1

JApplet

由于所有的Swing GUI元件都應該包含在JApplet小程式

中,且javax.Swing.JApplet是java.applet.Applet的子類,是以本章

主要介紹javax.Swing的“J元件”,應用程式均以JApplet小程式為

例。JApplet的使用與Applet小程式相似,它們與HTML檔案的

配合沒有什麼差别,差别僅在預設布局政策與個别方法的使用

上,這将在講述到有關内容時加以讨論。

9.1.2 Swing

中常用的包

由于Swing功能相當強大且複雜,考慮到功能分解的原

則,Java系統将Swing按不同功能分為表9.1所示的若幹個包,

它們分别針對于不同的元件及事件。

表9.1 Swing

中常用的包

包 名說 明

javax.swing 最常用的包,包含了各種Swing元件的類

javax.swing.border 包含與Swing元件外框有關的類

javax.swing.colorchooser 針對Swing調色版元件(JColorChooser)設計的類

javax.swing.event 處理由Swing元件産生的事件

javax.swing.filechooser 包含針對Swing檔案選擇對話框(JFileChooser)所設計的類

javax.swing.plaf 處理Swing元件外觀的相關類

javax.swing.table 針對Swing元件表格(JTable)所設計的類

javax.swing.text

包含與Swing文字元件相關的類

javax.swing.text.html

javax.swing.text.html.parser

javax.swing.text.rtf

javax.swing.tree 針對Swing樹狀元素(JTree)所設計的類

javax.swing.undo 提供Swing文字元件的Redo與Undo功能

表9.1 Swing

中常用的包

9.1.3

常用元件的繼承關系

由于本章所述元件所使用的成員方法主要是繼承其直接父類

或更高層父類的成員方法,為了正确地使用這些元件,有必要

了解每個元件的繼承關系。本章所述元件的繼承關系如下:

java.lang.Object

java.awt.Component

java.awt.Container

javax.swing.JComponent

javax.swing.JLabel

javax.swing.JTextField

javax.swing.JTextArea

javax.swing.JList

javax.swing.JComboBox

javax.swing.AbstractButton

javax.swing.JButton

javax.swing.JToggleButton

javax.swing.JCheckBox

javax.swing. JRadioButton

9.2

事件響應原理

設計和實作圖形使用者界面的工作主要有兩個:一是建立組

成界面的各種成分和元素,指定它們的屬性和位置關系,根據

具體需要排列它們,進而構成完整的圖形使用者界面的實體外

觀;二是定義圖形使用者界面的事件和各界面元素對不同僚件的

響應,進而實作圖形使用者界面與使用者的互動功能。

圖形使用者界面之是以能為廣大使用者所喜愛并最終成為事實

上的标準,很重要的一點就在于圖形使用者界面的事件驅動機

制,它可以根據産生的事件來決定執行相應的程式段。事件

(event)代表了某對象可執行的操作及其狀态的變化。例如,在

圖形使用者界面中,使用者可以通過移動滑鼠對特定圖形界面元素

進行單擊、輕按兩下等操作來實作輸入/輸出操作。

9.2.1

委托事件模型

Java采用委托事件模型來處理事件。委托事件模型的特點是

将事件的處理委托給獨立的對象,而不是元件本身,進而将使用

者界面與程式邏輯分開。整個“委托事件模型”由産生事件的對象

(事件源)、事件對象及監聽者對象之間的關系所組成。

産生事件的對象會在事件産生時,将與該事件相關的資訊封

裝在一個稱之為“事件對象”的對象中,并将該對象傳遞給監聽者

對象,監聽者對象根據該事件對象内的資訊決定适當的處理方式。

監聽者對象要收到事件發生的通知,必須在程式代碼中向産生事

件的對象注冊,當事件産生時,産生事件的對象就會主動通知監

聽者對象,監聽者對象就可以根據産生該事件的對象來決定處理

事件的方法。

監聽者對象(listener)就是用來處理事件的對象。監聽者對象

等候事件的發生,并在事件發生時收到通知。

9.2.2 Swing

元件的事件及監聽者

不同僚件源上發生的事件種類不同,不同的事件由不同的

監聽者處理。表9.2列出了Swing中各種元件可激發的事件及事

件監聽者之間的對應關系。表9.3列出了Swing提供的各事件監

聽者與各事件類成員方法之間的關系。請讀者務必注意:對應

不同僚件需要不同的事件監聽者,而每個事件監聽者都有相應

的成員方法,我們處理事件的程式代碼要寫在對應的成員方法

體中。

表9.2 Swing

中元件、事件及事件監聽者之間的對應關系

組 件

可激發的事件

(Event) 事件監聽者(EventListener)

AbstractButton

(JButton,JToggleButton,

JCheckBox,JRadioButton

)

ActionEvent

ChangeEvent

ItemEvent

ActionListener

ChangeListener

ItemListener

JFileChooser ActionEvent ActionListener

JTextField

JPasswordField

ActionEvent

CaretEvent

DocumentEvent

UndoableEvent

ActionListener

CaretListener

DocumentListener

UndoableListener

表9.2 Swing

中元件、事件及事件監聽者之間的對應關系

JTextArea

CaretEvent

DocumentEvent

UndoableEvent

CaretListener

DocumentListener

UndoableListener

JTextPane

JEditorPane

CaretEvent

DocumentEvent

UndoableEvent

HyperlinkEvent

CaretListener

DocumentListener

UndoableListener

HyperlinkListener

JComboBox ActionEvent

ItemEvent

ActionListener

ItemListener

JList ListSelectionEvent

ListDataEvent

ListSelectionListener

ListDataListener

表9.2 Swing

中元件、事件及事件監聽者之間的對應關系

JMenuItem

ActionEvent

ChangeEvent

ItemEvent

MenuKeyEvent

MenuDragMouseEvent

ActionListener

ChangeListener

ItemListener

MenuKeyListener

MenuDragMouseListener

JMenu MenuEvent MenuListener

JPopupMenu PopupMenuEvent PopupMenuListener

JProgressBar ChangeEvent ChangeListener

JSlider ChangeEvent ChangeListener

JScrollBar AdjustmentEvent AdjustmentListener

表9.2 Swing

中元件、事件及事件監聽者之間的對應關系

JTable

ListSelectionEvent

TableModeEvent

TableColumnModelEvent

CellEditorEvent

ListSelectionListener

TableModeListener

TableColumnModelListener

CellEditorListener

JTabbedPane ChangeEvent ChangeListener

JTree

TreeSelectionEvent

TreeExpansionEvent

TreeWillExpandEvent

TreeModeEvent

TreeSelectionListener

TreeExpansionListener

TreeWillExpandListener

TreeModeListener

JTimer ActionEvent ActionListener

表9.3 Swing

提供的各監聽者與各事件類成員方法之間的關系

事件監聽者成 員 方 法

CaretListener caretUpdate(CaretEvent e)

CellEditorListener editingCanceled(ChangeEvent e)

editingStopped(ChangeEvent e)

ChangeListener stateChanged(ChangeEvent e)

DocumentListener

changedUpdate(DocumentEvent e)

insertUpdate(DocumentEvent e)

removeUpdate(DocumentEvent e)

HyperlinkListener hyperlinkUpdate(HyperlinkEvent e)

表9.3 Swing

提供的各監聽者與各事件類成員方法之間的關系

ListDataListener

contentsChanged(ListDataEvent e)

intervalAdded(ListDataEvent e)

intervalRemoved(ListDataEvent e)

ListSelectionListener valueChanged(ListSelectionEvent e)

MenuDragMouseListener

menuDragMouseDragged(MenuDragMouseEvent e)

menuDragMouseEntered(MenuDragMouseEvent e)

menuDragMouseExited(MenuDragMouseEvent e)

menuDragMouseReleased(MenuDragMouseEvent e)

MenuKeyListener

menuKeyPressed(MenuKeyEvent e)

menuKeyReleased(MenuKeyEvent e)

menuKeyTyped(MenuKeyEvent e)

MenuListener

menuCanceled(MenuEvent e)

menuDeselected(MenuEvent e)

menuSelected(MenuEvent e)

PopupMenuListener

popupMenuCanceled(PopupMenuEvent e)

popupMenuWillBecomelavisible(PopupMenuEvent e)

popupMenuWillB ecomeVisible(PopupMenuEvent e)

表9.3 Swing

提供的各監聽者與各事件類成員方法之間的關系

TableColumnModelListener

columnAdded(TableColumnModelEvent e)

columnMarginChanged(ChangeEvent e)

columnMoved(TableColumnModelEvent e)

columnRemoved(TableColumnModelEvent e)

columnSelectionChanged(ListSelectionEvent e)

TableModelListener tableChanged(TableModelEvent e)

表9.3 Swing

提供的各監聽者與各事件類成員方法之間的關系

9.2.3

Java.awt

事件類繼承關系

Java語言提供了一組事件類來處理不同對象産生的事件。

Java.awt事件類的繼承關系如下:

java.awt.Object

java.util.Event

Java.util.Event.Object

. java.awt.AWTEvent

java.awt.event.ActionEvent.

java.awt.event.AdjustmentEvent

java.awt.event.InvocationEvent

java.awt.event.ItemEvent

java.awt.event.TextEvent

java.awt.event.ComponentEvent

java.awt.event.ContainerEvent

java.awt.event.FocusEvent

java.awt.event.PaintEvent

java.awt.event.WindowEvent

java.awt.event.InputEvent

java.awt.event.KeyEvent

java.awt.event.MouseEvent

9.2.4 AWT

中的事件與事件監聽者

Swing并不是用來取代原有的AWT的,事實上當我們使用

Swing元件時常常還是需要使用AWT功能的。例如,滑鼠和鍵盤

操作、視窗的變化、元件的增加或删除等都是比較低層的事

件,對于這些事件我們必須使用AWT包提供的處理方法來處理。

所有的Swing元件都是java.awt.Component的子類,它們具有

如下繼承關系:

java.lang.Object

java.awt.Component

java.awt.Container

javax.swing.JComponent

javax.swing的各種swing元件

是以,可以利用java.awt.Component類與java.awt.Container

類提供的事件及事件監聽者來處理諸如滑鼠和鍵盤操作等低層

事件。

表9.4列出了java.awt.Component與java.awt.Container類提供

的事件與事件監聽者之間的關系。表9.5列出了各事件監聽者與

各成員方法之間的對應關系。同理,對于AWT中的不同僚件需

要不同的事件監聽者,而每個監聽者都有相應的成員方法,我

們處理事件的程式代碼要寫在對應的成員方法體中。

表9.4 Component

類與Container

類提供的事件

與事件監聽者之間的關系

事 件

(Event) 事件監聽者(Listener) 說 明

ComponentEvent ComponentListener 主要處理元件大小的改變,位置的改變

及可見與不可見狀态等

ContainerEvent ContainerListener 主要處理元件的加入或移出容器

FocusEvent FocusListener 主要處理取得焦點或移開焦點等操作

KeyEvent KeyListener 主要處理鍵盤的操作

MouseEvent MouseListener 主要處理滑鼠是否在某個元件上、是否

按下滑鼠等操作

MouseMotionEve

nt

MouseMotionListene

r 主要追蹤滑鼠的位置

WindowEvent WindowListener 主要處理視窗問題,如打開、關閉、最

大或最小化等

表9.5 AWT

的各事件監聽者與各成員方法之間的關系

AWT事件監聽者成 員 方 法

ActionListener actionPerformed(ActionEvent e)

WindowListener

windowActivated(WindowEvent e)

windowClosed(WindowEvent e)

windowClosing(WindowEvent e)

windowDeactivated(WindowEvent e)

windowDeiconified(WindowEvent e)

windowIconified(WindowEvent e)

windowOpened(WindowEvent e)

MouseListener

mouseClicked(MouseEvent e)

mouseEntered(MouseEvent e)

mouseExited(MouseEvent e)

mousePressed(MouseEvent e)

mouseReleased(MouseEvent e)

表9.5 AWT

的各事件監聽者與各成員方法之間的關系

MouseMotionListener

mouseDragged(MouseEvent e)

mouseMoved(MouseEvent e)

ContainerListener

componentAdded(ContainerEvent e)

componentRemoved(ContainerEvent e)

ComponentListener

componentHidden(ComponentEvent e)

componentMoved(ComponentEvent e)

componentResized(ComponentEvent e)

componentShown(ComponentEvent e)

FocusListener

focusGained(FocusEvent e)

focusLost(FocusEvent e)

ItemListener itemStateChanged(ItemEvent e)

KeyListener

keyPressed(KeyEvent e)

keyReleased(KeyEvent e)

keyTyped(KeyEvent e)

AdjustmentListener adjustmentValueChanged(AdjustmentEvent e)

9.3

JLable

JLable元件被稱為标簽,它是一個靜态元件,也是标準組

件中最簡單的一個元件。每個标簽用一個标簽類的對象表示,

可以顯示一行靜态文本。标簽隻起資訊說明的作用,而不接受

使用者的輸入,也無事件響應。

建立标簽JLable類對象的構造方法如表9.6所示。

表9.6

JLable

類對象的構造方法構

構 造 方 法功能及參數說明

JLable( ) 建立一個空标簽

JLable(Icon icon) 建立圖示為icon的标簽

JLable(Icon icon,int halig)

建立圖示為icon的标簽,并指定水準排列方式(LEFT、

CENTER、RIGHT、LEADING和TRAILING)

JLable(String text) 建立一個含有文字的标簽

JLable(String text,int halig) 建立一個含有文字的标簽,并指定水準排列方式

JLable(String text,Icon icon,int halig) 建立一個含有文字及圖示的标簽,并指定水準排列方

表9.7

JLable

類常用成員方法

成 員 方 法功 能 說 明

Icon getIcon( ) 擷取此标簽的圖示

void setIcon(Icon icon) 設定标簽的圖示

String getText( ) 擷取此标簽的文本

void setText(String lable) 設定标簽的文本

void setHorizontalAlignment(int alig) 設定标簽内元件的水準對齊方式

void setVerticalAlignment(int alig) 設定标簽内元件的垂直對齊方式

void setHorizontalTextPosition(int tp) 設定标簽内文字與圖示的水準相對位

void setVerticalTextPosition (int tp) 設定标簽内文字與圖示的垂直相對位

9.4

JButton

元件與JToggleButton

元件

JButton元件與JToggleButton元件通常被稱為按鈕,它是一個

具有按下、擡起兩種狀态的元件。使用者可以指定按下按鈕(單擊事

件)時所執行的操作(事件響應)。按鈕上通常有一行文字(标簽)或

一個圖示以表明它的功能。此外,Swing元件中的按鈕還可以實作

下述效果:

(1) 改變按鈕的圖示,即一個按鈕可以有多個圖示,可根據

Swing按鈕所處的狀态而自動變換不同的圖示。

(2) 為按鈕加入提示,即當滑鼠在按鈕上稍做停留時,在按鈕

邊可出現提示,當滑鼠移出按鈕時,提示自動消失。

(3) 在按鈕上設定快捷鍵。

(4) 設定預設按鈕,即通過Enter鍵運作此按鈕的功能。

9.4.1

AbstractButton

類的常用成員方法

表9.8

AbstractButton

類常用成員方法

成 員 方 法功 能 說 明

Icon getIcon( ) 擷取預設圖示

void setIcon(Icon icon) 設定此按鈕的預設圖示

String getLabel( ) 擷取标簽文本

void setLabel(String lable) 設定标簽的文本

void setHorizontalAlignment(int alig) 設定文本與圖示的水準對齊方式(CENTER,LEFT,

RIGHT,LEADING,TRAILING)

void setVerticalAlignment(int alig) 設定文本與圖示的垂直對齊方式(CENTER,TOP,

BOTTOM)

表9.8

AbstractButton

類常用成員方法

void setHorizontalTextPosition(int tp)

設定文本與圖示的水準相對位置CENTER,LEFT,

RIGHT,LEADING,TRAILING)

void setVerticalTextPosition (int tp)

設定文本與圖示的垂直相對位置(CENTER,TOP,

BOTTOM)

String getText( ) 擷取此按鈕的文本

void addChangeListener(Change

Listener I) 給按鈕添加指定的ChangeListener

void addActionListener(ActionListener I) 給按鈕添加指定的ActionListener

void addItemListener(ItemListener I) 給按鈕添加指定的ItemListener

void removeActionListener(ActionListener

I)

從按鈕中删除指定的ActionListener

void remove

ChangeListener(ChangeListener I)

從按鈕中删除指定的ChangeListener

表9.8

AbstractButton

類常用成員方法

void remove

ItemListener(ItemListener I) 從按鈕中删除指定的ItemListener

void setPressedIcon(Icon pricon) 設定按鈕按下時的圖示

void setRolloverIcon(Icon roicon) 設定滑鼠經過時按鈕的圖示

void setRolloverEnabled(boolean b) 設定翻轉效果是否有效

void setRolloverSelectedIcon(Icon

seicon) 設定按鈕的翻轉并選擇圖示

void setEnabled(boolean b) 設定按鈕是否禁用

void setSelected(boolean b) 設定按鈕的狀态

void setText(String text) 設定按鈕的文本

boolean isSelected( ) 擷取按鈕的狀态

Icon getSelectedIcon( ) 擷取按鈕的圖示

9.4.2

JButton

類的構造方法

按鈕可分為有、無标簽的和有、無圖示的等幾種情況,因

此,系統提供了表9.9所示的JButton類的構造方法來建立這幾種

按鈕對象。

表9.9

JButton

類構造方法

構 造 方 法功 能 說 明

JButton( ) 建立一個無标簽的按鈕

JButton(String text) 建立一個有标簽的按鈕

JButton(Icon icon) 建立一個有圖示的按鈕

JButton(String text, Icon icon) 建立一個有标簽和圖示的按鈕

9.4.3

JToggleButton

類的構造方法

JToggleButton按鈕與JButton按鈕的差別僅在于:當按下

JButton按鈕并釋放滑鼠後,按鈕會自動彈起;按下

JToggleButton按鈕并釋放滑鼠後,按鈕不會自動彈起,除非再

按一次。表9.10列出了JToggleButton類的構造方法。

表9.10

JToggleButton

類構造方法

構 造 方 法功 能 說 明

JToggleButton( ) 建立一個無标簽的按鈕

JToggleButton(String text) 建立一個标簽為text的按鈕

JToggleButton(String text, boolean selected) 建立一個有标簽的按鈕,且初始狀态為false

JToggleButton(Icon icon) 建立一個圖示為icon的按鈕

JToggleButton(Icon icon, boolean selected) 建立一個有圖示的按鈕,且初始狀态為false

JToggleButton(String text, Icon icon) 建立一個既有标簽又有圖示的按鈕

JToggleButton(String text, Icon icon, boolean selected) 建立一個有标簽和圖示的按鈕,且初始狀态為

false

9.4.4

ActionEvent

事件及其響應

按照Java的委托事件模型,當我們在所設計的使用者界面上

按下一個按鈕時會激發一個事件,這個事件稱為動作事件。動

作事件由AWT的ActionEvent類的方法來處理。

1

.動作事件

ActionEvent類含有ACTION_PERFORMED事件,它是引

發某個動作的執行事件。能觸發這個事件的動作包括:單擊按

鈕;輕按兩下一個清單中的選項;選擇菜單項;在文本框中輸入回

車等。

2

.ActionEvent

類可使用的主要方法

getSource( )方法:用來擷取引發事件的對象名。

getActionCommand( )方法:用來擷取對象的标簽或事先為

這個對象設定的指令名。

getSource( )方法是EventObject類提供的,

getActionCommand( )方法是ActionEvent類提供的。由于

ActionEvent類繼承了EventObject類,是以,ActionEvent類可以

使用這兩個方法。

3

.事件響應

當使用者點選對象時,就會引發ActionEvent類代表的動作事件。

例如,下面的語句:

對象名.addActionListener(this);

注冊事件源對象的監聽者對象為this,而且要求this對象的類

必須聲明該類并實作ActionListener接口。當事件發生時,引發

的事件将被此事件的監聽者監聽到,并引用ActionListener的

actionPerformed(ActionEvent e)方法響應動作事件。在此方法體

中可以引用ActionEvent事件的getSource( )方法來擷取引發事件

的對象,也可以引用getActionCommand( )方法來擷取對象标簽

或事先為這個對象設定的指令名。使用者可在actionPerformed( )方

法體中寫入處理此事件的程式代碼。

9.4.5

應用舉例

【示例程式c9_1.java】 編寫一個單擊按鈕時改變标簽文本與按

鈕文本的内容的程式。

import java.awt.*;

import javax.swing.*;

import java.awt.event.*;

//聲明該類實作ActionListener 接口,監聽者對象是c9_1類的對象

public class c9_1 extends JApplet implements ActionListener

//JApplet是Applet的子類

{ Container cp=getContentPane( ); //建立視窗容器對象

Icon ro=new ImageIcon("g1.gif"); //建立圖示對象

Icon ge=new ImageIcon("g2.gif");

Icon pr=new ImageIcon("g3.gif");

JButton bt=new JButton( ); //建立按鈕對象

Icon icon=new ImageIcon("g4.jpg");

JLabel lb=new JLabel("Java",icon,JLabel.CENTER); //建立标簽對象

public void init( )

{

bt.setRolloverEnabled(true); //将按鈕圖示變化功能打開

bt.setText("OK"); //添加按鈕文本

bt.setHorizontalTextPosition(JLabel.CENTER); //将按鈕文字放在圖示中間

bt.setVerticalTextPosition(JLabel.BOTTOM); //設定按鈕文字在圖示下方

cp.add(lb,BorderLayout.NORTH); //添加标簽在JApple界面的北部位置上

cp.add(bt,BorderLayout.SOUTH);

bt.setIcon(ge); //設定滑鼠離開按鈕的圖示

bt.setRolloverIcon(ro); //設定滑鼠在按鈕上的圖示

bt.setPressedIcon(pr); //設定滑鼠按下按鈕的圖示

bt.addActionListener(this); //注冊bt的監聽者對象this

}

// actionPerformed( )方法在單擊bt時被系統自動調用

public void actionPerformed(ActionEvent e)

{ if(e.getSource( )==bt) //判斷動作事件是否由bt1引發的

{

if(lb.getText( )=="Hello") //修改标簽文本

lb.setText(“你好!”);

else

lb.setText("Hello");

if(bt.getText( )=="OK") //修改按鈕文本

bt.setText("确定");

else

bt.setText("OK");

}

}

}

圖9.2 程式c9_1的運作結果

程式說明:

(1) javax.swing.JApplet是java.awt.Applet的子類,當向

JApplet中添加Swing元件時要使用JApplet的getContentPane( )方

法獲得一個Container對象,再引用這個Container對象的add( )方

法将JComponent及其子類對象添加到JApplet中。

(2) 程式中建立的按鈕有一個圖示,根據滑鼠的移動來改

變圖示。

(3) 當單擊一個按鈕時,按鈕為監聽者對象發送一個稱為“動

作事件”的事件對象。産生事件的按鈕是事件源,通常說這個按

鈕激活一個事件。在這個程式中,bt是事件源,為了能夠讓按鈕

知道為哪個監聽對象發送動作事件對象,必須注冊按鈕的監聽

者對象。我們通過調用按鈕對象的addActionListener( )方法來實

現,即bt.addActionListener(this),其中this為監聽者對象,即

c9_1類的對象(通常把包含事件源的對象作為監聽對象)。為了把

c9_1類指定為一個動作監聽對象,必須聲明該類實作

ActionListener接口,即

public class c9_1 extends JApplet implements ActionListener

其中,ActionListener 接口僅僅包含了一個抽象方法

actionPerformed( )。ActionEvent的對象e代表一個動作事件,并

且支援那些用來發現所産生事件的特征的方法。

當按鈕激活一個動作事件時,則此按鈕引發的事件将被此

事件的監聽者監聽到并調用actionPerformed(ActionEvent e)方法

對該事件進行處理。

在方法體中調用e.getSource( )方法來擷取引發事件的按鈕對

象。

(4) 把元件放到使用者希望的位置,在Java語言中是通過布局

來實作的。JApplet界面上的預設布局是BordLayout布局,它将

界面劃分為東、南、西、北、中五個區域,我們把元件添加到

JApplet界面時,可以将元件放在這五個區域的任一位置上。更

複雜的内容我們将在後面的章節介紹。

(5) 程式中使用了AbstractButton類的成員方法,較長的描述見

表9.8。

9.5

JCheckBox

和JRadioButton

元件

JCheckBox元件被稱為複選框(也稱檢測框),它提供 “選中

/ON”和“未選中/OFF”兩種狀态。使用者點選某複選框就會改變該

複選框原有的狀态。

JRadioButton元件被稱為選項按鈕,在Java中JRadioButton組

件與JCheckBox元件功能完全一樣,隻是圖形不同,複選框為方

形圖示,選項按鈕為圓形圖示。由于目前所使用軟體的

RadioButton多為單選按鈕,即在同類的一組元件中,使用者隻能選

擇其中之一為ON,其餘為OFF。

Java為了與其他系統一緻,專門

提供了javax.swing.ButtonGroup類,這個類的功能就是實作諸如

JRadioButton、JRadioButtonMenuItem與JToggleButton等元件的多

選一功能。ButtonGroup類可被AbstractButton類的子類所使用。

9.5.1

JCheckBox

類的構造方法

表9.11

JCheckBox

類構造方法

構 造 方 法功 能 說 明

JCheckBox( ) 建立一個無标簽的複選框對象

JCheckBox(String text) 建立一個有标簽的複選框對象

JCheckBox(String text,boolean selected) 建立一個有标簽的複選框對象,且初始狀态為

false

JCheckBox(Icon icon) 建立一個有圖示的複選框對象

JCheckBox(Icon icon,boolean selected) 建立一個有圖示的複選框對象,且初始狀态為

false

JCheckBox(String text, Icon icon) 建立一個有标簽和圖示的複選框對象

JCheckBox(String text, Icon icon,boolean

selected)

建立一個有标簽和圖示的複選框對象,且初始

狀态為false

9.5.2

JRadioButton

的構造方法

表9.12

JRadioButton

類構造方法

構 造 方 法功 能 說 明

JRadioButton( ) 建立一個無标簽的JRadioButton對象

JRadioButton(String text) 建立一個有标簽的JRadioButton對象

JRadioButton(String text,boolean selected) 建立一個有标簽的JRadioButton對象,且初始

狀态為false

JRadioButton(Icon icon) 建立一個有圖示的JRadioButton對象

JRadioButton(Icon icon,boolean selected) 建立一個有圖示的JRadioButton對象,且初始

狀态為false

JRadioButton(String text, Icon icon) 建立一個有标簽和圖示的JRadioButton對象

JRadioButton(String text, Icon icon,boolean

selected)

建立一個有标簽和圖示的JRadioButton對象,

且初始狀态為false

9.5.3

ItemEvent

事件

1

.選擇事件

ItemEvent類隻包含一個事件ITEM_STATE_CHANGED,引

發這類事件的動作包括:

(1) 改變複選框JCheckbox對象的選中或不選中狀态;

(2) 改變單選按鈕JRadioButton對象的選中或不選中狀态;

(3) 改變下拉清單框JComboBox對象中選項的選中或不選中狀

态;

(4) 改變菜單項JMenuItem對象中選項的選中或不選中狀态;

(5) 改變JCheckboxMenuItem對象中選項的選中或不選中狀态。

2

.ItemEvent

類的主要方法

(1) ItemSelectable getItemSelectable( )。getItemSelectable( )

方法傳回引發選中狀态變化的事件源,例如JCheckbox對象。能

引發選中狀态變化的事件都必須是實作了ItemSelectable接口類

的對象,該方法的傳回值就是這些類的對象的引用。此外,

ItemEvent類的事件也可以使用其父類EventObject類提供的

getSource( )方法傳回引發選中狀态變化的事件源。

(2) Object getItem( )。getItem( )方法傳回引發選中狀态變化

事件的具體選擇項,例如JComboBox中的具體item。通過調用這

個方法可以知道使用者選中了哪個選項。

(3) int getStateChange( )。getStateChange( )方法傳回此元件

到底有沒有被選中。它的傳回值是一個整型值,通常用

ItemEvent類的靜态常量SELECTED(代表選項被選中)和

DESELECTED(代表選項被放棄或不選)來表達。

3

.事件響應

當使用者點選對象使其選中狀态發生變化時,就會引發

ItemEvent類代表的選擇事件。例如下面的語句:

對象名.addItemListener(this);

注冊事件源對象的監聽者對象為this,而且要求this對象的類必須

聲明該類實作ItemListener接口。當事件發生時,引發的事件将被

此事件的監聽者監聽到,并引用ItemListener中的

itemStateChanged(ItemEvent e)方法響應對象的狀态改變。在此方

法體中,引用ItemEvent事件的e.getItemSelectable( )方法以獲得引

發選擇事件的事件源對象,再引用getStateChange( )方法擷取選

擇事件之後的狀态。使用者在itemStateChanged( )方法體中編寫處

理事件的程式代碼。

9.5.4

應用舉例

【示例程式c9_2.java】 根據複選框及選擇按鈕來改變标簽

元件的文本大小及顔色。

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

public class c9_2 extends JApplet implements

ItemListener,ActionListener

{ int i1=0,i2=0,i3=0;

int fonti=10;

Font font;

Container ctp=getContentPane( );

JLabel lb=new JLabel("請選擇");

JCheckBox cb1,cb2,cb3; //聲明複選框對象

JRadioButton r1,r2,r3; //聲明按鈕對象

ButtonGroup bg=new ButtonGroup( ); //建立按鈕組對象,實作JRadioButton

多選一功能

public void init( )

{ ctp.setLayout(new FlowLayout( )); //設定布局方式為流式布局

cb1=new JCheckBox("紅色",false); //建立複選框

cb1.addItemListener(this); //注冊cb給監聽者this

ctp.add(cb1); //添加複選框在界面上

cb2=new JCheckBox("綠色",false);

cb2.addItemListener(this);

ctp.add(cb2);

cb3=new JCheckBox("藍色",false);

cb3.addItemListener(this);

ctp.add(cb3);

r1=new JRadioButton("10");

r1.addActionListener(this);

ctp.add(r1); //加載按鈕到界面上

r2=new JRadioButton("16");

r2.addActionListener(this);

ctp.add(r2);

r3=new JRadioButton("24");

r3.addActionListener(this);

ctp.add(r3);

bg.add(r1); //加載按鈕到按鈕組

bg.add(r2);

bg.add(r3);

ctp.add(lb); //加載标簽到界面上

}

public void itemStateChanged(ItemEvent e)

{ JCheckBox cbx=(JCheckBox)e.getItem( );

if (cbx.getText( )=="紅色")

{ if(e.getStateChange( )==e.SELECTED)i1=255; //判斷元件是否被選

else i1=0;}

if (cbx.getText( )=="綠色")

{if(e.getStateChange( )==e.SELECTED)i2=255;

else i2=0; }

if (cbx.getText( )=="藍色")

{if(cbx.isSelected( ))i3=255; //判斷元件是否被選

else i3=0; }

font=new Font("宋體",Font.BOLD,fonti);

lb.setFont(font);

lb.setForeground(new Color(i1,i2,i3));

}

public void actionPerformed(ActionEvent e)

{ String rbt=e.getActionCommand( );

if (rbt=="10") fonti=10;

else if (rbt=="16") fonti=16;

else fonti=24;

font=new Font("宋體",Font.BOLD,fonti);

lb.setFont(font);

lb.setForeground(new Color(i1,i2,i3));

}

}

圖9.3 程式c9_2的運作結果

9.6

JComboBox

元件

9.6.1

JComboBox

類的構造方法及成員方法

表9.13

JComboBox

類的構造方法和常用成員方法

方 法說 明

JComboBox(Vector items) 使用向量表items構造一個JComboBox對象

JComboBox( )

JComboBox(ComboBoxModel

a Model)

從已有的Model擷取選項,構造

JComboBox對象

JComboBox(Object[ ] items) 使用數組構造一個JComboBox

對象

構造一個空的JComboBox對象。必要時可使用addItem方法

添加選項

表9.13

JComboBox

類的構造方法和常用成員方法

方 法說 明

void

addActionListener(ActionListener e) 添加指定的ActionListener

void addItemListener(ItemListener

aListener) 添加指定的ItemListener

void addItem(Object anObject) 給選項表添加選項

String getActionCommand( ) 擷取動作指令

Object getItemAt(int index) 擷取指定下标的清單項

int getItemCount( ) 擷取清單中的選項數

int getSelectedIndex( ) 擷取目前選擇的下标

int getSelectedItem( ) 擷取目前選擇的項

9.6.2

事件響應

JComboBox元件能夠響應的事件分為選擇事件與動作事件。

若使用者選取下拉清單中的選擇項時,則激發選擇事件,使用

ItemListener事件監聽者進行處理;若使用者在JComboBox上直接

輸入選擇項并回車時,則激發動作事件,使用ActionListener事

件監聽者進行處理。

下面通過一個具體的程式來說明按鈕的事件響應。

【示例程式c9_3.java】 在JComboBox元件中添加4個學生的

名字選項,當點選下拉清單選擇項時得到學生的名字,将他的

成績用标簽文本顯示。

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

public class c9_3 extends JApplet implements ItemListener

{

Container ctp=getContentPane( );

JLabel lb1=new JLabel("姓名:"),

lb2=new JLabel("英語:"),

lb3=new JLabel(" ");

String name[ ]={"李林","趙欣","張揚","童梅"},

score[ ]={"80","94","75","87"};

JComboBox cbx=new JComboBox( ); //建立下拉式清單框對象

public void init( )

{

ctp.setLayout(new FlowLayout( )); //設定流式布局

for (int j=0;j<name.length;j++) //添加選項到下拉式清單框對象中

cbx.addItem(name[j]);

ctp.add(lb1);

ctp.add(cbx); //添加下拉式清單框對象到容器上

cbx.addItemListener(this); //注冊cbx給監聽對象

ctp.add(lb2);

ctp.add(lb3);

}

public void itemStateChanged(ItemEvent e)

{

int c=0;

String str=(String)e.getItem( ); //擷取所選項給str

for(int i=0;i<name.length;i++)

if(str==name[i]) //判斷str是否是name數組中某個元素的内容

c=cbx.getSelectedIndex( ); //将該選項的下标給c

lb3.setText(score[c]); //擷取該學生的成績

}

}

程式說明:

下拉式清單框産生ItemEvent代表的選擇事件。該程式中的

語句cbx.addItemListener(this);表示注冊JComboBox類的對象cbx

給監聽者對象。當使用者單擊下拉清單的某個選項時,系統自動

産生一個包含這個事件有關資訊的ItemEvent類的對象e,并把該

對象作為實際參數傳遞給被自動調用的監聽者的選擇事件響應

方法:itemStateChanged(ItemEvent e)。在這個方法中通過調用

ItemEvent 事件的方法e.getItem( )獲得引發目前選擇事件的下拉

清單事件源(被選中的項),再調用getSelectedIndex( )擷取該選項的

下标值,進而得到name數組的下标值,最終将這個元素的内容

作為新的标簽文本輸出。

圖9.4 c9_3運作結果

9.7

JList

JList稱為清單元件,它将所有選項放入清單框中。如果将

JList放入滾動面闆(JScrollPane)中,則會出現滾動菜單效果。利

用JList提供的成員方法,使用者可以指定顯示在清單框中的選項

個數,而多餘的選項則可通過清單的上下滾動來顯現。

JList元件與JComboBox元件的最大差別是:JComboBox組

件一次隻能選擇一項,而JList元件一次可以選擇一項或多項。

選擇多項時可以是連續區間選擇(按住Shift鍵進行選擇),也可以

是不連續的選擇(按住Ctrl鍵進行選擇)。

9.7.1

JList

類的構造方法及成員方法

表9.14

JList

類的構造方法和成員方法

方 法說 明

JList(Vectorl istData) 使用包含元素的向量構造JList對象

JList( ) 使用空的模式構造JList對象

JList(ListModel dataModel) 使用dataModel模式構造JList對象

JList(Object[ ] listData) 使用指定的數組構造JList對象

void

addListSelectionListener(ListSelectionListener e) 添加指定的ListSelectionListener

int getSelectedIndex( ) 擷取所選項的第一個下标

int getSelectedIndices( ) 擷取所有選項的下标

void setSelection Background(Color c) 設定單元格的背景顔色

void setSelection Foreground(Color c) 設定單元格的前景顔色

int getVisibleRowCount( ) 得到可見的清單選項值

void setVisibleRowCount (int num) 設定可見的清單選項

9.7.2

ListSelectionEvent

事件

JList元件的事件處理一般可分為兩種:一種是當使用者單擊列

表框中的某一個選項并選中它時,将産生ListSelectionEvent類的

選擇事件,此事件是Swing的事件;另一種是當使用者輕按兩下清單框

中的某個選項時,則産生MouseEvent類的動作事件。JList類通過

locatToindex( )方法來得知是單擊還是輕按兩下。

若希望實作JList的ListSelectionEvent事件,首先必須聲明實

現監聽者對象的類接口ListSelectionListener,并通過JList類的

addListSelectionListener( )方法注冊文本框的監聽者對象,再在

ListSelectionListener接口的valueChanged (ListSelectionEvent e)方

法體中寫入有關代碼,就可以響應ListSelectionEvent事件了。下

面通過示例程式來加以說明。

【示例程式c9_4.java】 設定一個JLabel元件和JList元件,

點選清單框中的選項,将所選項的值作為JLabel元件的文本輸出。

import java.awt.*;

import java.awt.event.*;

import javax.swing.*;

import javax.swing.event.*;

public class c9_4 extends JApplet implements ListSelectionListener

{ JList lis=null;

JLabel lb=null;

String[ ] s={"國小","國中","高中","大學","研究所學生"};

public void init( )

{ Container cp=getContentPane( );

cp.setLayout(new BorderLayout( ));

lb=new JLabel( );

lis=new JList(s);

lis.setVisibleRowCount(3); //設定清單框的可見選項行數,

選項超過則出現滾動條

lis.setBorder(BorderFactory.createTitledBorder("請選擇"));//

設定清單框的邊框文本

lis.addListSelectionListener(this); //注冊lis給監聽者對象

cp.add(lb,BorderLayout.NORTH);

//将lis對象放入滾動容器,再将此容器加載到界面上。

cp.add(new JScrollPane(lis),BorderLayout.CENTER);

}

public void valueChanged(ListSelectionEvent e)

{ int m=0;

String str="選取的是:";

//取得所有選項的下标值給index數組

int[ ] index = lis.getSelectedIndices( );

for(int i=0;i<index.length;i++)

{ //根據取得的下标值,找到相應的數組元素

m=index[i];

str=str+s[m]+" ";

}

lb.setText(str);//輸出選中項的值

}

}

上述程式中的語句:

lis.addListSelectionListener(this);

表示把lis注冊給ListSelectionEvent的監聽者

ListSelectionListener。當使用者單擊某個選項時,系統會自動引用

ListSelectionListener的valueChanged( )方法來處理選項的改變。

程式c9_4的運作結果見圖9.5。

圖9.5 程式c9_4的運作結果

9.8

JTextField

與JTextArea

元件

9.8.1

JTextField

元件的構造方法及成員方法

JtextField被稱為文本框。它定義了一個單行條形文本區,

可以輸出任何基于文本的資訊,也可以接受使用者的輸入。表9.15

列出了JTextField類的構造方法和成員方法。

表9.15

JTextField

類構造方法和成員方法

JTextField( )

JTextField(int n)

JTextField(String s)

JTextField(String s,int n)

JTextField(Document doc,String s, int n)

int getColumns( )

void setColumns(int Columns)

void addActionListener(ActionListener e)

void setFont(Font f)

void setHorizontalAlignment(int alig)

void setActionCommand(String com)

功 能 說 明

建立一個JTextField對象

建立一個列寬為n的空JTextField對象

建立一個JTextField對象,并顯示字元串s

建立一個JTextField對象,并以指定的字寬n顯示字元串s

使用指定的檔案存儲模式建立一個JTextField對象,并以指定的

字寬n顯示字元串s

擷取此對象的列數

設定此對象的列數

添加指定的動作事件監聽程式

設定字型

設定文本的水準對齊方式(LEFT、CENTER、RIGHT)

設定動作事件使用的指令字元串

9.8.2

JTextArea

元件的構造方法及成員方法

JTextArea被稱為文本域。它與文本框的主要差別是:文本

框隻能輸入/輸出一行文本,而文本域可以輸入/輸出多行文本。

表9.16列出了JTextArea類的構造方法和成員方法。

表9.16

JTextArea

類構造方法和成員方法

方 法功 能 說 明

JTextArea ( ) 建立一個JTextArea對象

JTextArea (int n,int m) 建立一個具有n行m列的空JTextArea對

JTextArea(String s) 建立一個JTextArea對象,并顯示字元

串s

JTextArea(String s,int n,int m) 建立一個JTextArea對象并以指定的行

數n和列數m顯示字元串聯s

JTextArea(String s,int n,int m,

int k)

建立一個JTextArea對象,并以指定的

行數n、列數m和滾動條的方向顯示字

符串s

JTextArea(Document doc) 使用指定的檔案存儲模式建立一個

JTextArea對象

JTextArea(Document doc,String s,int

n)

使用指定的檔案存儲模式建立一個

JTextArea對象,并以指定的字寬n顯

示字元串s

void setFont(Font f) 設定字型

void insert(String str,int pos) 在指定的位置插入指定的文本

void append(String str) 将指定的文本添加到末尾

void replaceRange(String str,int

start,int end)

将指定範圍的文本用指定的新文

本替換

public int getRows( ) 傳回此對象的行數

public void setRows(int rows) 設定此對象的行數

public int getColumns( ) 擷取此對象的列數

public void setColumns(int

Columns) 設定此對象的列數

9.8.3

事件處理

JTextField類隻引發ActionEvent事件,當使用者在文本框中按

Enter鍵時引發。JTextArea的事件響應由JTextComponent類決定。

JTextComponent類可以引發兩種事件:DocumentEvent事件與

UndoableEditEvent事件。當使用者修改了文本區域中的文本,如

做文本的增、删、改等操作時,TextComponent類将引發

DocumentEvent事件;當使用者在文本區域上撤消所做的增、删、

改時,TextComponent類将引發UndoableEditEvent事件。

(1) 實作文本框的ActionEvent事件。當監聽者對象的類聲明

實作了ActionListener接口,并且通過

textField.addActionListener(this)語句注冊文本框的監聽者對象

後,監聽程式内部動作事件的actionPerformed(ActionEvent e) 方

法就可以響應動作事件了。

(2) 實作文本區域的DocumentEvent事件。當監聽者對象的

類聲明實作了DocumentEditListener接口,并且通過

textArea.addDocumentListener(this)語句注冊文本區域的監聽者

對象後,監聽程式内部的DocumentListener接口的下列三個方法

之一就可以響應DocumentEvent事件了。

changedUpdate(DocumentEvent e); //修改文本操作

inset Update(DocumentEvent e); //增加文本操作

remove Update(DocumentEvent e); //删除文本操作

(3) 實作文本區域的UndoableEditEvent事件。當監聽者對

象的類聲明實作了UndoableEditListener接口,并且通過

textArea.addUndoableEditListener(this)語句注冊文本區域的監聽

者對象後,監聽程式内部的UndoableEditListener接口的

UndoableEditHappened

(UndoableEditEvent e)方法就可以響應UndoableEditEvent事件了。

9.8.4

應用舉例

【示例程式c9_5.java】 文本框和文本域元件的使用。

import javax.swing.*;

import java.awt.*;

import java.awt.event.*;

public class c9_5 extends JApplet implements ActionListener

{

Container ctp=getContentPane( );

ImageIcon icon1=new ImageIcon("g1.gif"),

icon2=new ImageIcon("g2.gif");

JLabel lb1=new JLabel("輸入文字後按回車:",icon1,JLabel.CENTER),

lb2=new JLabel("輸出結果:",icon2,JLabel.CENTER);

JTextField tf1=new JTextField(10); //建立文本框對象

JTextArea tf2=new JTextArea(5,10); //建立文本區域對象

public void init( )

{

ctp.setLayout(new FlowLayout( ));

ctp.add(lb1);

ctp.add(tf1);

ctp.add(lb2);

ctp.add(tf2);

tf1.addActionListener(this);

}

public void actionPerformed(ActionEvent e)

{

String str;

str=tf1.getText( ); //獲得文本框的文本給str(此方法是

JTextComponent類的方法)

// tf2.setText(str);

tf2.append(str+"/n"); //将str添加到文本區域中(append方法是

JTextArea類的方法)

}

}

圖9.6 程式c9_5的運作結果