第7章 圖形用戶界面
《第7章 圖形用戶界面》由會員分享,可在線閱讀,更多相關(guān)《第7章 圖形用戶界面(68頁珍藏版)》請在裝配圖網(wǎng)上搜索。
1、第7章 圖形用戶界面 圖形用戶界面(Graphics User Interface, GUI),是指用圖形的方式實現(xiàn)用戶與計算機之間的交互。它通過圖形的方式,借助菜單、按鈕等標(biāo)準(zhǔn)界面元素和鼠標(biāo)操作,幫助用戶方便地向計算機發(fā)出命令,啟動程序,并將程序的運行結(jié)果同樣以圖形的形式顯示給用戶。 GUI通常由GUI組件(有時稱為控件或窗口小部件)構(gòu)成。GUI組件是用戶通過鼠標(biāo)、鍵盤或其它諸如聲音識別等輸入形式與應(yīng)用程序進行交互的對象。學(xué)習(xí)Java的GUI設(shè)計就必須了解幾個概念:容器、組件、容器布局、事件處理機制。本章將通過實例剖析Swing常用組件的功能、如何在組件中繪圖、各種事件的應(yīng)用、以及各
2、種布局的設(shè)置等問題。 7.1 Java GUI概述 隨著JDK1.2(現(xiàn)改名為Java 2)的發(fā)布,Java的API有兩套完整的按鈕、菜單、文本域以及其它GUI組件:抽象窗口工具集(Abstract Window Toolkit ,AWT)和Swing組件集。AWT從JDK1.0開始就是Java的一部分,由AWT擴展而來的Swing組件集,是Java1.2引入的新的GUI組件庫。二者均包括在JFC(Java Foundation Classes,Java基礎(chǔ)類)中,JFC是一組支持在流行平臺的客戶端應(yīng)用程序中創(chuàng)建GUI和圖形功能的Java類庫,作為J2SE的一個有機部分,主要包含五
3、個部分,即AWT、Java2D、Accessibility、Drag&Drop、Swing,它是一套幫助開發(fā)人員設(shè)計復(fù)雜應(yīng)用程序的開發(fā)包。 7.1.1 AWT與Swing AWT是Java2版本之前的Java平臺提供的一套圖形用戶界面組件類型。AWT庫最重要的特征之一是,它與運行Java程序的計算機窗口系統(tǒng)(經(jīng)常被稱作本地窗口系統(tǒng),native windowing system)底層相結(jié)合。AWT組件建立在對等模型(peer model)的基礎(chǔ)上。每個AWT組件有一個相應(yīng)的用本地系統(tǒng)的代碼編寫的對等類,對等類充當(dāng)Java代碼與本地窗口系統(tǒng)之間的接口,對等類里的方法是用本地代碼編寫的
4、。例如,若要顯示Button類型的對象時,需用java.awt.Button類,它有一個名為java.awt.peer.Button的對等類,在運行微軟的Windows 操作系統(tǒng)的計算機上,該Button對象將具有與其它Windows應(yīng)用程序相同的外觀和感覺;同樣,在運行Apple公司的Mac OS操作系統(tǒng)的計算機上,該Button對象將具有與其它Macintosh應(yīng)用程序相同的外觀和感覺。因此,AWT組件天生就是平臺相關(guān)的,AWT組件被認(rèn)為是重量級組件,它們直接映射到本地組件,需要由本地窗口系統(tǒng)提供資源。 注意:本地方法封裝了用非Java語言(通常是C或者C++)編寫的代碼的調(diào)用,使JVM
5、的功能獲得擴展。 Swing組件從根本上來說建立在AWT上,它的四個頂層的窗口類(JApplet, JDialog, JFrame與JWindow)是由AWT重量級組件派生而來,如圖7.1所示。它們本身也依賴于本地窗口,除此以外,所有Swing組件都是輕量級組件。Swing的一個顯著特點是用Swing實現(xiàn)的圖形界面外觀可以按需更換,而無需重寫任何代碼。這就讓Swing程序能自動適應(yīng)于它所運行的計算機的常規(guī)風(fēng)格和外觀,不需要程序員為特定的計算機開發(fā)特定的界面。事實上,這些外觀不限于常見的幾種機器,Swing可以開發(fā)新的外觀風(fēng)格。Swing中內(nèi)置了幾個觀感包。例如,javax.swing.pla
6、f.motif包里有實現(xiàn)Motif界面的類。Motif界面是一種常用的基于UNIX的界面。這些類知道如何畫出每個組件,也知道如何響應(yīng)鼠標(biāo)、鍵盤以及其它和這些組件聯(lián)系在一起的事件。javax.swing.plaf.windows包則負(fù)責(zé)實現(xiàn)Windows風(fēng)格的界面。Java缺省的設(shè)計風(fēng)格是“Java外觀”(被稱為“Metal”),它獨立于任何一種窗口系統(tǒng)的Java外觀。 圖7.1 AWT與Swing頂層窗口類之間的關(guān)系 Swing改善了AWT包沒有彈性、缺乏效率的缺點,提供了更豐富的視覺感受,人們越來越多地使用Swing組件構(gòu)建圖形用戶界面,在本書中給出的有關(guān)GUI程序中均使用Swing
7、組件。 7.1.2 Swing組件 輕量級組件不是依靠本地組件來支持它的顯示,而是完全由Java代碼來繪制并顯示。Swing平臺無關(guān)的觀感,是通過把所有負(fù)責(zé)畫出一個組件的代碼從組件中抽出來形成一個單獨的類而實現(xiàn)的。例如,除了定義按鈕控件的JButton類之外,還有一個單獨的類負(fù)責(zé)把按鈕在屏幕上畫出來。畫圖的這個類將控制按鈕的顏色、形狀以及其它外面上的特征。構(gòu)建輕量級組件的一種方法是擴展抽象的java.awt.Component 類,然后改寫它的paint()方法: public class LightWeightButton extends Component{ public
8、 void paint(Graphics g){ /*在此寫繪制組件的Java代碼*/ } } 抽象類JComponent是能夠出現(xiàn)在屏幕上的大多數(shù)組件的父類。Java GUI的基本組件都是JComponent類的子類,因此,每個組件都繼承了JComponent的所有方法和數(shù)據(jù)字段。JComponent直接從Container類派生而來,它和它的所有Swing子類都是輕量級組件(見圖7.2)。 圖7.2 Swing部分輕量級組件 Swing提供了若干包,在程序中,若使用Swing必須導(dǎo)入javax.swing包。swing包是Swing提供的最大包,它包含將近100個類和25個
9、接口,幾乎所有的Swing組件都在swing包中。 Swing組件從功能上可分為容器組件和原子組件。又可細(xì)分為:頂層容器、中間層容器、特殊容器、基本組件、不可編輯組件以及可編輯組件,如表7.1所示。原子組件必須加在容器組件中,容器組件用來容納其它容器組件或原子組件,并在其可視區(qū)域內(nèi)顯示這些組件。以下稱容器組件為容器,原子組件為組件。 表7.1 Swing組件分類表 GUI類別 組件 Swing類名 基本組件 按鈕 JButton, JCheckBox, JRadioButton 組合框 JComboBox 列表 JList 菜單 JMenu, JMenuBar, J
10、MenuItem, JPopupMenu 滑塊 JSlider 工具欄 JToolBar 文本區(qū) JTextField, JPasswordField, JTextArea, JFormattedTextField 不可編輯的顯示組件 標(biāo)簽 JLabel 工具提示 JToolTip 進度條 JProgressBar 可編輯的顯示組件 表 JTable 文本 JTextPane, JEditorPane 樹 JTree 顏色選擇器 JColorChooser 文件選擇器 JFileChooser 數(shù)值選擇器 JSpinner 頂層容器 窗體
11、 JFrame,JWindow applet JApplet 對話框 JDialog,JOptionPane 中間層容器 面板 JPanel 滾動窗格 JScrollPane, JScrollBar 拆分窗格 JSplitPane 索查標(biāo)簽窗格 JTabbedPane 特殊容器 內(nèi)部窗體 JInternalFrame 分層窗格 JLayeredPane 根窗格 JRootPane 7.1.3 Swing容器 AWT中的Container類是容器組件的超類,其目的是容納其它若干組件。一個窗口實際上指的是屏幕上的一個矩形區(qū)域,允許程序員將若干獨
12、立的組件作為一個整體處理。我們不能直接顯示組件,而是需要把它們加到容器中,由容器進行顯示。 容器也提供一些方法,用于獲取和設(shè)置許多屬性、增加和從自身中刪除組件等。在屏幕上顯示容器之前,必須調(diào)用容器的pack()方法,或者設(shè)置其初始尺寸。設(shè)置尺寸時可以使用容器的setSize方法: public void setSize(int width,int height) 其中的參數(shù)以像素(屏幕上的點)為單位。 由于輕量級組件和重量級組件之間的差別,為使輕量級組件能夠正確地工作,必須使用Swing容器容納Swing組件。Swing容器按其用途分為頂層容器、中間層容器以及特殊容器。頂層容器(Top
13、 Level Container)是一個窗口容器對象,在這樣的一個對象里可以再加入其它的窗口對象。JFrame、JApplet、JDialog、JWindow等就可以作為頂層容器,其余的Swing組件都必須依附在此四組件之一上才能顯示出來。 容器本身具有層次性,每一層都是一種特殊容器,這些特殊容器實際上是在GUI上起特殊作用的中間層。Swing容器具有獲取和調(diào)整這些面板層的方法。在簡單編程過程中主要涉及到將組件加到容器的內(nèi)容面板中。 Swing容器的層次結(jié)構(gòu)如圖7.3所示。 JFrame JDialog JApplet JWindow JLayeredPane JRootPane
14、JContentPane JGlassPane JMenuBar 圖7.3 Swing容器層次結(jié)構(gòu) (1) 根面板JRootPane 根面板是頂層容器中所包含的最內(nèi)層,四個頂層容器均實現(xiàn)RootPaneContainer這個接口,此接口定義了各種容器取得與設(shè)置。根面板并不是真實的容器,它是由層次面板(JLayeredPane)與玻璃面板(JGlassPane)所組成,不能在JRootPane上加入任何的組件,因為它只是一個虛擬的容器,通常無法在這一層做操作與處理。若要在最上層組件上加入組件,必須加在JLayeredPane或是JLayeredPane里的內(nèi)容面板上。 需要注意的是,
15、只有頂層容器才有根面板,其它中間層容器沒有根面板。 (2) 層次面板JLayeredPane JLayeredPane用于管理JMenuBar和內(nèi)容面板JContentPane,并維護一個層次疊放順序(Z-order)標(biāo)記數(shù)據(jù),可以對加入在層次面板中的對象設(shè)定層次,而不會被內(nèi)容面板中的對象屏蔽。一般程序會提供良好的Z-order自動管理機制,當(dāng)然java也不例外,大部分情況我們不會使用到Z-order,因為系統(tǒng)會自動幫我們管理好。用戶只需將所需的組件直接加入內(nèi)容面板即可,不需要知道它們之間的順序關(guān)系。JMenuBar是一個對象,用于跟蹤與容器相關(guān)聯(lián)的任何菜單。JMenuBar是可選的,如果
16、沒有,內(nèi)容面板就會充滿整個頂層容器。 (3) 內(nèi)容面板JContentPane 與AWT組件不同,Swing組件不能直接添加到頂層容器中,它必須添加到頂層Swing容器的內(nèi)容面板(JContentPane)上。JContentPane是Swing容器中一個對象,可以把Swing組件加到其中,并設(shè)置布局策略。大部分的可視對象都放在內(nèi)容面板中,一般在程序中必須用getContentPane()方法來獲取內(nèi)容面板,然后將其加到這一層中。內(nèi)容面板是頂層容器包含的一個普通容器,它是一個輕量級組件,應(yīng)避免在其上添加非Swing的重量級組件。 (4) 玻璃面板JGlassPane 在玻璃面板這一層次
17、上主要用來產(chǎn)生繪圖效果,以及觸發(fā)窗口程序的各種事件。 中間層容器主要有JPanel、JScrollPane、JSplitPane、JTabbedPane等,它們沒有根面板,不能在桌面上浮動,必須填加到頂層容器中才能顯示。 下面介紹一些常用的Swing容器。 1.框架窗口JFrame 窗口是最基本的用戶界面元素??蚣艽翱谑且环N窗體,其中帶有邊框、標(biāo)題欄及用于關(guān)閉和最大/最小化窗口的圖標(biāo)等。在GUI的應(yīng)用程序中,一般至少應(yīng)使用一個框架窗口。通常將框架窗口簡稱為窗口。 JFrame類是由Container類派生而來的,是一種頂層容器類,可用于創(chuàng)建框架窗口。JFrame作為最頂層容器存
18、在,不能被其它容器所包含。它可將加到其內(nèi)容面板的組件顯示在屏幕上,每個加到窗口中的組件需要明確它的大小和位置,以及在窗口中如何顯示。 JFrame構(gòu)造方法主要有: JFrame(),建立一個無標(biāo)題的JFrame。 JFrame(String title),建立一個標(biāo)題為title的JFrame。 窗口的基本操作: (1) 創(chuàng)建窗口 直接生成一個JFrame類的實例即可建立一個窗口,或通過繼承JFrame類來定義子類,再建立窗口。 例如,創(chuàng)建一個無標(biāo)題的窗口,語句如下: JFrame frame=new JFrame(); (2) 設(shè)置標(biāo)題 通過super(String ti
19、tle)調(diào)用基類的構(gòu)造方法,或通過setTitle(String title)方法來設(shè)置窗口標(biāo)題。 例如: JFrame frame=new JFrame(“JFrame testing”); 或者: JFrame frame=new JFrame(); frame.setTitle(“JFrame testing”); (3) 設(shè)置初始位置 通過setLocation(int x,int y)方法設(shè)置窗口初始位置。其中x,y是窗口左上角在屏幕上的坐標(biāo)值。 (4) 設(shè)置大小 通過setSize(int width,int height)方法設(shè)置窗口初始大小。 (5) 設(shè)置圖
20、標(biāo) 通過setIconImage(Icon icon)方法設(shè)置窗口圖標(biāo)。 (6) 定義關(guān)閉行為 通過setDefaultCloseOperation(int operation)方法設(shè)置窗口關(guān)閉行為。其中operation的取值可以是以下幾種: DO_NOTHING_ON_CLOSE:當(dāng)窗口關(guān)閉時,不做任何處理; HIDE_ON_CLOSE:當(dāng)窗口關(guān)閉時,隱藏這個窗口; DISPOSE_ON_CLOSE:當(dāng)窗口關(guān)閉時,隱藏并處理這個窗口; EXIT_ON_CLOSE:當(dāng)窗口關(guān)閉時,退出程序。 operation默認(rèn)值是HIDE_ON_CLOSE。 (7) 添加組件 創(chuàng)建好J
21、frame之后,就可以向它的內(nèi)容面板中添加組件。對Jframe添加組件有兩種方式: 第一種方式,用getContentPane( )方法獲得JFrame的內(nèi)容面板,再對其加入組件,語句如下: frame.getContentPane().add(childComponent) 第二種方式,先建立一個JPanel或 JDesktopPane之類的中間容器,把組件添加到容器中,用窗口對象的setContentPane()方法把該容器置為JFrame的內(nèi)容面板: JPanel conPane=new JPanel(); …… // 把其它組件添加到JPanel
22、中 frame.setContentPane(conPane); //把conPane對象設(shè)置成為窗口對象frame的內(nèi)容面板 這里需要注意的是,Swing容器都可以用來容納其他組件,但除了JPanel及其子類可以直接添加組件以外,其它Swing容器都不允許把組件直接加進去,添加方法和JFrame中添加組件一樣。 【例7.1】 建立一個標(biāo)題為“Swing窗口”,大小為(300,200),圖標(biāo)為javalogo.gif,位置居中的窗口。屏幕效果如圖7.4所示。 圖7.4 Swing窗口 源程序如下: //JFrameDemo.java import javax.swing.*
23、; import java.awt.*; public class JFrameDemo extends JFrame // 定義一個窗口子類 { JFrameDemo() { setIconImage(new ImageIcon("javalogo.gif").getImage()); // 設(shè)置圖標(biāo) setSize(300,200); // 設(shè)置窗口大小 setTitle("Swing窗口"); // 設(shè)置窗口標(biāo)題 // 取得屏幕尺寸 Dimension screen=Toolkit.getDefaultTo
24、olkit().getScreenSize(); Dimension mySize=this.getSize(); // 取得窗口尺寸 //設(shè)置初始位置于屏幕中央 setLocation((screen.width-mySize.width)/2, (screen.height-mySize.height)/2); setVisible(true); // 使窗口可見 } public static void main(String args[]) { JFrameDemo myFrame=new J
25、FrameDemo(); // 創(chuàng)建窗口 myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 設(shè)置關(guān)閉行為 } } 2. 無邊框的窗口JWindow JWindow可以構(gòu)造無邊框的窗口。主要構(gòu)造方法有: JWindow():創(chuàng)建一個無邊界的窗口; JWindow(Frame owner):創(chuàng)建一個依賴Frame對象的窗口。 3.對話框JDialog 對話框與框架窗口類似,是有邊框、有標(biāo)題、可獨立存在的頂級容器。對話框分為無模態(tài)對話框和模態(tài)對話框。模態(tài)對話框只讓程序響應(yīng)對話框內(nèi)部的事件,對于對話框以
26、外的事件程序不響應(yīng),并且在該對話框被關(guān)閉之前,其他窗口無法接受任何形式的輸入;而無模態(tài)對話框可以讓程序響應(yīng)對話框以外的事件,沒有限制。 JDialog的構(gòu)造方法有: JDialog(Frame owner); JDialog(Frame owner,Boolean modal); JDialog(Frame owner,String title); JDialog(Frame owner,String title,Boolean modal); 其中,參數(shù)owner指明對話框隸屬哪個窗口,參數(shù)title指明對話框的標(biāo)題。參數(shù)modal為true時,指明對話框是模態(tài)的;如果modal
27、為false,則指明對話框是無模態(tài)的。 用JDialog來作對話框,必須實現(xiàn)對話框中的每一個組件,但有時候?qū)υ捒蛑灰@示一段文字,或是作一些簡單的選擇,這時候可以利用JOptionPane類,從而大大的減少了程序代碼的編寫。JOptionPane類也在javax.swing包內(nèi)。要利用JOptionPane類來輸出對話框,通常不使用new創(chuàng)建一個JOptionPane對象出來,而是使用JOptionPane所提供的一些靜態(tài)方法,這些方法都是以showXxxxxDialog的形式出現(xiàn)。例如,建立一個消息對話框可使用JOptionPane.showMessageDialog();另外,JOpti
28、onPane.showConfirmDialog()會建立一個確認(rèn)對話框,JOptionPane.showInputDialog()會建立一個輸入對話框。 4.面板JPanel Swing的JPanel,它替代了AWT的畫布(Canvas)和面板(Panel),兼有二者的功能。JPanel是一個非頂級的通用容器,總是處于其它一些容器中。JPanel不能象JFrame那樣能夠在桌面上浮動。利用JPanel可以使版面的排列方式更生動,對于復(fù)雜GUI,通常由多個面板組成,而每個面板以特定的布局來排列組件。 JPanel的構(gòu)造方法有: JPanel(); JPanel(boolean isD
29、oubleBuffered); JPanel(LayoutManager layout); JPanel(LayoutManager layout,boolean isDoubleBuffered); 其中,isDoubleBuffered指明是否具有雙緩沖,layout指明布局方式。JPanel默認(rèn)是非雙緩沖,布局為流式布局(FlowLayout)。 5. 分割面板JSplitPane JSplitPane一次可將兩個組件同時顯示在兩個顯示區(qū)中,若想要同時在多個顯示區(qū)顯示組件,便必須同時使用多個JSplitPane。JSplitPane提供兩個常數(shù):HORIZONTAL_SPLIT
30、、VERTICAL_SPLIT,用來設(shè)置水平分割或是垂直分割。 6. JTabbedPane 如果一個窗口的功能有幾項,可以給每項設(shè)置一個標(biāo)簽,每個標(biāo)簽下面包含為完成此功能專用的若干組件。用戶要使用哪項功能,只要單擊相應(yīng)的標(biāo)簽,就可以進入相應(yīng)的頁面。這種選項卡功能的實現(xiàn)就需要使用JTabbedPane這個中間層容器。 7. 滾動面板JScrollPane 當(dāng)容器內(nèi)要容納的內(nèi)容大于容器時,希望容器能夠有一個滾動條,通過拖動滑塊,就可以看到更多的內(nèi)容。JScrollPane就是能夠?qū)崿F(xiàn)這種功能的容器。 8. JInternalFrame 使用JInternalFrame容器類可以實現(xiàn)在
31、一個主窗口中打開很多個文檔,每個文檔各自占用一個新的窗口。JInternalFrame的使用跟JFrame幾乎一樣,可以最大化、最小化、關(guān)閉窗口、加入菜單;唯一不同的是JInternalFrame是輕量級組件,它只能是中間容器,必須依附于頂層容器上。 7.1.4 基于Swing的Java GUI設(shè)計思路 構(gòu)造用戶界面會涉及到一些基本概念,包括前面已經(jīng)提到的組件、容器,還有后面要說明的布局管理器和事件處理等。Java GUI編程,一般可依據(jù)下面的設(shè)計思路: 1. 設(shè)置頂層容器。通常是JFrame或Japplet,用于設(shè)計Java應(yīng)用程序或Java小應(yīng)用程序。 2. 創(chuàng)建組件。組件
32、包括按鈕、菜單以及選項等。 3. 使用某種布局把組件加到某個容器中。對于復(fù)雜的用戶界面,通常會使用若干中間層容器,這樣便于對組件的管理,在編程時先將組件置于中間層容器中,之后再將中間層容器加到頂層容器中。對于組件在容器中的位置和大小,也可交給布局管理器全權(quán)負(fù)責(zé)。 4. 實現(xiàn)事件處理程序,以便響應(yīng)點擊按鈕、菜單選擇、窗口縮放以及其它活動等。 7.2 圖形與繪圖 7.2.1 繪圖表面 為了在Java程序里進行繪圖和繪畫,需要有一個可以操作的表面。在抽象窗口工具包(AWT)中,這個繪圖表面通常是一個Canvas組件。在Swing程序中可以直接在頂層窗口(通常是JApplet和J
33、Frame)上繪圖,或者在JPanel的子類上繪圖。 7.2.2 圖形環(huán)境和圖形對象 要在Java中繪圖,還需理解Java的坐標(biāo)系統(tǒng),如圖7.5所示。GUI組件(諸如applet或窗口)的左上角坐標(biāo)默認(rèn)為(0,0),坐標(biāo)對由一個x坐標(biāo)(水平坐標(biāo))和一個y坐標(biāo)(垂直坐標(biāo))組成。x坐標(biāo)是從左上角向右移動的水平距離,y坐標(biāo)是從左上角向下移動的垂直距離。坐標(biāo)的單位是像素,它是顯示器分辨率的最小單位。 圖7.5 以像素為單位的Java坐標(biāo)系統(tǒng) 在屏幕上繪圖要使用Java圖形環(huán)境,每個Java組件(包括Swing組件),都有一個與之關(guān)聯(lián)的圖形環(huán)境,也稱圖形上下文,用java.awt.G
34、raphics類的一個對象來表示。Graphics對象用于管理圖形環(huán)境,并在屏幕上繪制代表文本或其它圖形對象(如線條、橢圓、矩形或其它多邊形)的像素。Graphics 類是所有圖形上下文的抽象基類,這個上下文允許應(yīng)用程序?qū)D形繪制到由不同設(shè)備實現(xiàn)的組件上,以及繪制到空閑屏幕的映像中。 java.awt.Graphics類是一個抽象類,不能直接創(chuàng)建一個Graphics對象,這是由Java的可移植性決定的,因為在支持Java的各個平臺上,執(zhí)行的繪圖操作是不同的,例如運行Microsoft Windows的PC機繪制矩形的圖形功能不同于UNIX工作站上繪制矩形的圖形功能,而且它們也不同于Maci
35、ntosh系統(tǒng)中繪制矩形的圖形功能。在各個平臺實現(xiàn)Java時,系統(tǒng)將創(chuàng)建Graphics的一個子類,以實現(xiàn)繪圖功能。 一個 Graphics 對象封裝有 Java 所支持的基本繪圖操作所需的狀態(tài)信息。此狀態(tài)信息包括下列屬性: (1) 要被繪制到其上的組件對象; (2) 繪制和剪貼坐標(biāo)的平移原點。; (3) 當(dāng)前的剪貼區(qū); (4) 當(dāng)前顏色; (5) 當(dāng)前的字體; (6) 當(dāng)前的邏輯像素操作函數(shù) (XOR 或 Paint) ; (7) 當(dāng)前的 XOR 替換顏色。 其中XOR模式稱為位異或模式,它符合邏輯操作異或。在XOR模式下,當(dāng)在背景色和前景色上執(zhí)行一個異或操
36、作時,像素點的前景色是由畫筆的顏色來決定的。在黑白繪圖方式下,如果畫筆是黑色的,在背景為白色的任何位置,繪圖都是黑色的;如果背景已經(jīng)是黑色的,那么繪圖就會是白色的。這樣,在這種情況下XOR模式會對背景色進行反色操作。在有顏色的背景下,也能獲得類似的效果。 Graphics類中定義了許多方法,包含用于改變上述屬性默認(rèn)值的訪問方法,以及各種繪圖方法,分別如表7.2和表7.3所示。 表7.2 Graphics類的部分獲取和設(shè)置屬性默認(rèn)值的方法 名稱 說明 Shape getClip() 返回表示當(dāng)前剪貼區(qū)域的 Shape 對象 Color getColor() 返回該圖形上下文的當(dāng)前
37、顏色 Font getFont() 返回該圖形上下文的當(dāng)前字體 FontMetrics getFontMetrics() 返回該圖形上下文當(dāng)前字體的字體度量 void setClip(Shape?clip) 將當(dāng)前的剪貼域設(shè)置為任意剪貼形狀 void setColor(Color?c) 將該圖形上下文的當(dāng)前顏色設(shè)置為指定的顏色 void setFont(Font?font) 將指定的字體設(shè)置為該圖形上下文的字體。 void translate(int?x,int?y) 將圖形上下文的原點平移到當(dāng)前坐標(biāo)系的 (x ,y) 點處。修改該圖形的上下文,使得它的新原點與該圖形上
38、下文原先坐標(biāo)系中的 (x,y) 點相一致 表7.3 Graphics類的繪圖方法 方法 說明 void drawString(String str,int x,int y) 使用該圖形上下文的當(dāng)前字體和顏色,從坐標(biāo)點(x,y)位置處開始繪制由指定的字符串給出的文本 void drawLine(int?x1,int?y1,int?x2,int?y2) 繪制一條在點(x1,y1) 和(x2,y2) 之間的線 void drawRect(int x,int y,int width,int height) 畫一矩形,左上角坐標(biāo)為(x,y),寬width ,高h(yuǎn)eight void
39、fillRect(int x,int y,int width,int height) 繪制一個使用當(dāng)前顏色填充的指定矩形 void clearRect(int?x, int?y, int?width, int?height) 通過用當(dāng)前繪圖表面的背景顏色填充的方法來清除指定的矩形。 void drawRoundRect(int x, int y, int width, int height, int arcWidth, int arcHeight) 使用當(dāng)前顏色繪制圓角矩形。圓角是一個橢圓的1/4弧,此橢圓由arcWidth,arcHeight確定兩軸長 void fillRoun
40、dRect(int x, int y, int width,int height, int arcWidth, int arcHeight) 用當(dāng)前顏色填充指定的圓角矩形 void draw3DRect(int x, int y, int width, int height, boolean raised) 繪制指定矩形的一個突出顯示的三維輪廓。raised為true時,該矩形為凸的,反之為凹的 void fill3DRect(int x, int y, int width, int height, boolean raised) 繪制一個用當(dāng)前顏色填充的三維矩形 void dra
41、wOval(int x,int y,int width,int height) 繪制橢圓形的輪廓。結(jié)果是一個圓或橢圓,并適合由 x ,y ,width 和 height 參數(shù)指定的矩形 void fillOval(int x, int y, int width, int height) 用當(dāng)前顏色填充由指定矩形限定的橢圓 void drawArc(int x, int y, int width, int height, int startAngle, int arcAngle) 繪制一個覆蓋指定矩形的圓或橢圓弧的輪廓 void fillArc(int x, int y, int
42、width, int height, int startAngle, int arcAngle) 填充一個覆蓋了指定矩形的圓或橢圓弧 void drawPolyline(int xPoints[],int yPoints[],int nPoints) 繪制由 x 和 y 坐標(biāo)數(shù)組定義的連接線序列。每對 (x,y)坐標(biāo)定義一個點 void drawPolygon(int xPoints[],int yPoints[],int nPoints) 繪制由 x 和 y 坐標(biāo)數(shù)組定義的閉合多邊形。每對 (x,y) 坐標(biāo)定義一個點 void drawPolygon(Polygon p) 繪制
43、由指定的 Polygon 對象定義的多邊形的輪廓 void fillPolygon(int xPoints[],int yPoints[], int nPoints) 填充由 x 和 y 坐標(biāo)數(shù)組定義的閉合多邊形 void fillPolygon(Polygon p) 用圖形上下文的當(dāng)前顏色填充由指定的 Polygon 對象定義的多邊形。多邊形內(nèi)的區(qū)域使用奇偶填充規(guī)則和交替填充規(guī)則來定義 boolean drawImage(Image img, int x,int y, ImageObserver observer) 繪制指定圖像的當(dāng)前可用部分。繪制的圖像,其左上角位于坐標(biāo)(x,y
44、) 位置。如果圖像沒有被完全裝入,那么 drawImage 方法將返回 false 7.2.3 顏色 顏色美化了程序的外觀,并有助于信息的表達(dá)。Java的顏色是根據(jù)RGB值來建立的,RGB值是用于指定紅色、綠色和藍(lán)色量的3個數(shù)字的組合,這些顏色組件混合在一起形成了最終的顏色。java.awt.Color類聲明了用于操作Java程序中顏色的方法,同時Color類定義了一些標(biāo)準(zhǔn)顏色,作為類常量使用,這些常量共有13個,它們的名稱有小寫名稱也有大寫名稱,表7.4中采用大寫形式,這樣符合常量的命名約定。表7.5給出了一些Color類的構(gòu)造函數(shù)和常用方法。 表7.4 Color類的常量
45、顏色常量 顏色 public final static Color BLACK 黑色 public final static Color BLUE 藍(lán)色 public final static Color CYAN 藍(lán)綠色 public final static Color DARKGRAY 深灰色 public final static Color GRAY 灰色 public final static Color GREEN 綠色 public final static Color LIGHT_GRAY 淺灰色 public final static Col
46、or MAGENTA 紫紅色 public final static Color ORANGE 橙色 public final static Color PINK 粉紅色 public final static Color RED 紅色 public final static Color WHITE 白色 public final static Color YELLOW 黃色 表7.5 Color類的方法 方法 說明 Color(int r,int g,int b) 用指定的紅、綠和藍(lán)色成分創(chuàng)建一個顏色。三個參數(shù)都必須在 0-255 范圍內(nèi) Color(int
47、 rgb) 用指定的 RGB 值創(chuàng)建一個顏色,其中參數(shù)的 16-23 位表示紅色成分,8-15 位表示綠色成分,0-7 位表示藍(lán)色成分。0 表示這個基色成分沒有參與顏色構(gòu)成 Color(float r, float g, float b) 用指定的紅、綠和藍(lán)色值創(chuàng)建一個顏色,其中每個值在 0.0-1.0 范圍內(nèi)。0.0 值表示這個基色成分沒有貢獻(xiàn)。值 1.0 表示這個基色成分的最大飽和度 int getRed() 獲取這個顏色的紅色成分。返回結(jié)果是一個0 - 255 之間的整數(shù) int getGreen() 獲取這個顏色的綠色成分。返回結(jié)果是一個 0 - 255 之間的整數(shù) i
48、nt getBlue() 獲取這個顏色的藍(lán)色成分。返回結(jié)果是一個 0 - 255 之間的整數(shù) 設(shè)計使用顏色的程序時必須要小心,因為顏色的表示是與系統(tǒng)有關(guān)的。在理論上講,可能指定256*256*256=16 777 216種不同的顏色。但是在實際系統(tǒng)中,真正能夠顯示的不同顏色的數(shù)目,取決于系統(tǒng)顯示器的質(zhì)量。如果顯示只允許使用8位顏色來表示每個像素,則最多可以表示28=256種顏色,在這種情況下,操作系統(tǒng)會決定顯示16 777 216種顏色中的哪256種顏色,如果程序需要這256種顏色之外的顏色,系統(tǒng)會選擇最相近的顏色。 7.2.4 字體 為了創(chuàng)建有吸引力的界面,常常需要選擇和控制
49、所用的字體。Java中有關(guān)字體控制的類是Font類,有關(guān)字體度量的類是FontMetrics,它們都在java.awt包中。前面已經(jīng)提到,每個圖形上下文都有一個相關(guān)的字體Font對象和字體度量FontMetrics對象,F(xiàn)ont對象包括字體名、字號和風(fēng)格等屬性,F(xiàn)ontMetrics對象封裝了字體的許多重要數(shù)據(jù),如字體的高度和寬度等。表7.6給出了Font類的一些常量和常用方法。 表7.6 Font類的方法和常量 常量或方法 說明 public final static int PLAIN 一個代表普通字體風(fēng)格的常量 public final static int BOLD 一個
50、代表粗體字體風(fēng)格的常量 public final static int ITALIC 一個代表斜體字體風(fēng)格的常量 Font(String name,int style,int size) 利用指定的字體、風(fēng)格和大小創(chuàng)建一個Font對象 int getStyle() 返回一個表示當(dāng)前字體風(fēng)格的整數(shù)值 int getSize() 返回一個表示當(dāng)前字體大小的整數(shù)值 String getName() 以字符串形式返回當(dāng)前字體名稱 String getFamily() 以字符串形式返回當(dāng)前字體族名稱 Boolean isPlain() 測試一個字體是否是普通字體風(fēng)格 Boo
51、lean isBold() 測試一個字體是否是粗體字體風(fēng)格 Boolean isItalic() 測試一個字體是否是斜體字體風(fēng)格 Font類的構(gòu)造函數(shù)有3個參數(shù):字體名稱、字體風(fēng)格和字體大小。字體名稱可以是運行程序的當(dāng)前系統(tǒng)所支持的任何字體,在Java1.1和以后的版本中,所支持的字體名字有Monospaced、SansSerif、Serif、Dialog和DialogInput。字體風(fēng)格可以是表7.6已列出的三個之一,也可以是Font.ITALIC+Font.BOLD組合。字體大小以磅為度量單位,一磅等于1/72英寸。這些名字和風(fēng)格是平臺無關(guān)的,當(dāng)用于程序中時,會映射成本地系統(tǒng)可用的
52、實際字體。如果本地系統(tǒng)沒有與指定字體確切相匹配的字體,就會提供一個替代字體。 7.2.5 使用Graphics類繪圖 當(dāng)在AWT組件和Swing頂層窗口(JApplet和JFrame,是java.awt.Component的子類)上繪圖時,需要重寫組件的paint()方法;當(dāng)在Swing的JComponent的子類組件上繪圖時,則需重寫paintComponent()方法。在這兩種情況(Swing和AWT)下,都是以一個Graphics對象作為參數(shù)。在某個組件需要進行繪圖操作時,系統(tǒng)會將Graphics對象傳遞給paint方法或paintComponent方法。paint方法和pa
53、intComponent方法的頭部分別為: public void paint(Graphics g ) public void paintComponent(Graphics g ) 程序員很少直接調(diào)用paint方法,因為繪制圖形是一個事件驅(qū)動過程。在執(zhí)行applet(在第九章對此進行詳細(xì)說明)時,applet的容器調(diào)用paint方法,要再次調(diào)用paint方法,必須產(chǎn)生一個事件(如隱藏或重新顯示applet的窗口)。類似地,在顯示任何組件對象時,將調(diào)用該組件對象的paint方法。 如果程序員需要強制執(zhí)行paint方法,一般是調(diào)用repaint()方法(此方法不應(yīng)重寫,因為該方法執(zhí)行一
54、些與系統(tǒng)相關(guān)的任務(wù)),該方法自動調(diào)用Component類的update(Graphics g)方法以清除Component背景中的舊圖,然后update方法直接調(diào)用paint方法。 【例7.2】 使用各種顏色繪制文字及各種圖形。屏幕效果如圖7.6所示。源程序如下: // Graphic.java import java.awt.*; import javax.swing.*; public class Graphic extends JFrame{ public Graphic(){ super("字體、顏色與繪圖示例"); // 調(diào)用超類的構(gòu)造方法,設(shè)置窗口標(biāo)題
55、 setSize(480,240); // 設(shè)置窗口大小 setVisible(true); // 使窗口可見 } public void paint(Graphics g) // 重寫paint方法 { super.paint(g); g.setFont(new Font("Serif",Font.BOLD,12));/*設(shè)置圖形環(huán)境的字體,名為Serif, 黑體,12號*/ g.setColor(Color.BLACK); // 設(shè)置顏色 g.drawString("字體Serif,粗體,12號
56、,黑色",20,50); // 繪制字符串 g.setFont(new Font("SansSerif",Font.BOLD+Font.ITALIC,15)); g.setColor(new Color(255,0,0)); g.drawString("字體SansSerif,粗斜體,15號,紅色",200,50); g.drawLine(20,60,450,60); // 繪制直線 g.setColor(Color.BLUE); g.drawRect(20,70,100,50); // 繪制矩形 g.fillRect(1
57、30,70,100,50); // 繪制實心矩形 g.setColor(Color.YELLOW); g.draw3DRect(20,130,100,50,true); // 繪制三維凸起矩形 g.fill3DRect(130,130,100,50,false); // 繪制三維凹陷實心矩形 g.setColor(Color.pink); g.drawOval(240,80,100,50); // 繪制橢圓 g.fillOval(350,80,100,50); // 繪制實心橢圓 g.setColor(Color.MAG
58、ENTA); int xValues[]={250,280,290,300,330,310,320,290,260,270}; int yValues[]={160,160,140,160,160,170,180,170,180,170}; g.drawPolygon(xValues,yValues,10); // 根據(jù)給定的10個坐標(biāo)點,繪制空心多邊形 int xValues2[]={360,390,400,410,440,420,430,400,370,380}; g.fillPolygon(xValues2,yValues,10); // 根據(jù)給定的
59、10個坐標(biāo)點,繪制實心多邊形 } public static void main(String args[]) { // 設(shè)置窗口的外觀和感覺為Java默認(rèn) JFrame.setDefaultLookAndFeelDecorated(true); Graphic myGraphic=new Graphic(); // 產(chǎn)生Graphic類的一個實例 myGraphic.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 關(guān)閉窗口 } } 圖7.6 使用Graphics類繪圖 7.3事件
60、處理與Swing常用組件 聲明組件、處理事件以及將組件置于容器內(nèi)這三個問題聯(lián)系得非常緊密,在后續(xù)小節(jié)中我們將分別進行說明,而在所有基于GUI的程序中,其核心是事件處理,下面對此先進行說明。 GUI是事件驅(qū)動的(即用戶與GUI進行交互時,GUI將產(chǎn)生事件)。一些常見的事件包括單擊鼠標(biāo)按鈕、移動鼠標(biāo)、單擊按鈕、在文本字段內(nèi)進行輸入、在菜單中選擇菜單項、關(guān)閉窗口等。若發(fā)生了一次用戶交互,就將一個消息發(fā)送給程序。GUI事件信息存儲在擴展AWTEvent的類的一個對象中。AWT組件和Swing組件都可以使用java.awt.event包中的事件類型。javax.swing.event包還聲明了其
61、它一些事件類型,這些事件類型是專用于Swing組件的。 7.3.1 Java事件處理機制 事件處理機制是一種事件處理框架,其設(shè)計目的是把GUI交互動作(鼠標(biāo)點擊、菜單選擇等)轉(zhuǎn)變?yōu)檎{(diào)用相關(guān)的事件處理程序進行處理。JDK1.1以后Java采取了授權(quán)處理機制(Delegation-based Model),事件源可以把在其自身所有可能發(fā)生的事件分別授權(quán)給不同的事件處理者來處理。 由于窗口管理器無法直接調(diào)用開發(fā)人員提供的事件處理程序,必須在運行時告訴事件模型,哪一個例程用于處理事件。因此,為了獲取任何事件,開發(fā)人員必須事先通知窗口系統(tǒng),令其將事件發(fā)送給自己提供的事件處理程序,把事件處理
62、程序注冊為窗口管理器中的一個回調(diào)例程,使之連接到產(chǎn)生事件的組件上。 要實現(xiàn)這個過程,就要用到事件處理機制中的三個對象:事件源、事件對象和事件監(jiān)聽器。 事件源是與用戶進行交互的特定組件。事件源提供注冊監(jiān)聽器或取消監(jiān)聽器的方法,它維護一個已注冊的監(jiān)聽器列表,如有事件發(fā)生,就會通知每個已注冊的監(jiān)聽器。一個事件源可以注冊多個事件監(jiān)聽器。 事件對象封裝了有關(guān)已發(fā)生的事件的信息,這些信息包括事件源的一個引用和事件專用信息,事件監(jiān)聽器需要這些信息來處理事件。 事件監(jiān)聽器也是一個對象,該對象所屬的類實現(xiàn)了java.awt.event或javax.swing.event包中的一個或多個事件監(jiān)聽器的接口。
63、每個監(jiān)聽器可以對多種事件進行響應(yīng)。事件監(jiān)聽器負(fù)責(zé)監(jiān)聽事件,它監(jiān)視所有事件類型,當(dāng)有事件發(fā)生時,事件監(jiān)聽器會接收到事件源產(chǎn)生的事件對象,一旦該事件類型與自己所負(fù)責(zé)處理的事件類型一致,就會以該事件對象作為參數(shù)自動調(diào)用相應(yīng)的事件處理程序作出響應(yīng)。 許多事件監(jiān)聽器類型是Swing組件和AWT組件所共有的。這樣的事件監(jiān)聽器類型聲明在java.awt.event包中,并且其中許多都顯示在表7.7中。不同的組件會產(chǎn)生不同的事件,不同的事件處理程序要實現(xiàn)不同的接口,表7.7概括了三者之間的關(guān)系。每個接口所承諾的方法可查閱Java doc的API。 表7.7 類別、事件與接口 一般類別 產(chǎn)生的事件 事
64、件處理程序?qū)崿F(xiàn)的接口 鼠標(biāo) 拖曳、移動鼠標(biāo)產(chǎn)生的MouseEvent, 點擊、選擇、釋放鼠標(biāo)引起的MouseEvent MouseMotionListener MouseListener 鼠標(biāo)滾輪 鼠標(biāo)滾輪事件 MouseWheelListener 鍵盤 按鍵或釋放產(chǎn)生的KeyEvent KeyListener 選擇(列表、復(fù)選框等的某一項) 選擇某一選項時產(chǎn)生的ItemEvent ItemListener 文本輸入組件 輸入換行符時產(chǎn)生的TextEvent TextListener 滾動控件 滾動條滑動時引起的AdjustmentEvent Adjus
65、tmentListener 其它組件(按鈕、菜單等) 點擊組件時或文本框中按下Enter鍵時產(chǎn)生的ActionEvent ActionListener 窗口變動 打開、關(guān)閉窗口以及把窗口縮小為圖標(biāo)時產(chǎn)生的WindowEvent WindowListener 鍵盤焦點變動 使用制表鍵轉(zhuǎn)到下一個字段,或者要求聚焦時引起的FocusEvent。組件必須在獲得聚焦時才能產(chǎn)生事件 FocusListener 組件變動 縮放、隱藏、顯露或移動組件時產(chǎn)生的ComponentEvent ComponentListener 容器變動 加入或撤銷容器中的組件引起的ContainerEv
66、ent ContainerListener 要使程序能夠處理圖形用戶界面的事件,程序員必須完成2項關(guān)鍵任務(wù):為產(chǎn)生事件的GUI組件注冊一個事件監(jiān)聽器;實現(xiàn)一個事件處理方法(或一組事件處理方法)。事件處理方法通常稱為事件處理程序。下面以“關(guān)閉窗口”事件為例,來說明Java事件處理框架。 【例7.3】 關(guān)閉窗口事件處理。 源程序如下: // CloseDemo1.java import javax.swing.*; import java.awt.event.*; public class CloseDemo1{ public static void main(String args[]){ JFrame jframe=new JFrame("關(guān)閉窗口例");// 創(chuàng)建一個窗口 jframe.setSize(400,100); // 設(shè)置窗口大小 jframe.setVisible(true); // 使窗口可見 myWinClose handler=new myWinClose();
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。