圖形用戶界面或圖形用戶接口(Graphical User Interface,GUI)是指采用圖形方式,借助菜單、按鈕等標準界面元素,用戶可以通過鼠標等外設向計算機系統發出指令、啟動操作,并將系統運行的結果同樣以圖形方式顯示給用戶的技術。
GUI是事件驅動的,常見交互包括移動鼠標、單擊鼠標按鈕、在文字段輸入、從菜單選擇一個選項以及關閉一個窗口等。
從Java 1.2版開始,Sun公司推出了新的圖形界面工具包:Swing。相應的工具包都以Swing來命名,例如javax.swing、javax .swing.event。相對AWT而言,Swing更為輕便,更容易編程,而且功能也更為靈活、強大,是Java基礎類(Java Foundation Classes, JFC)的主要組成部分.
Java繪圖
Java在圖形處理方面有豐富的類庫和方法,使用這些方法可以便捷的繪圖,基本的繪圖方法包括點、線、矩形和圓等。繪制這些圖形要用到Graphics類。
Java中的任何一個圖形組件,小到文本框、標簽,大到一個框架,一個對話框,都有一個專門負責顯示其界面的方法,這個方法名稱是固定的:paint(),它的原型為:
public void paint(Graphics g)
{
……
}
- 畫直線
void drawLine(int startX,int startY,int endX,int endY);
四個參數分別為:起始點的x坐標和y坐標以及終點的x坐標和y坐標,該方法用于在起點(startX,startY)和終點(endX,endY)之間畫一條直線。坐標參數是相對的,他們相對于左上角的坐標為(0,0),以像素為單位,向右向下延伸,直線如果超出窗口,則超出的部分不會顯示。
- 畫矩形
void drawRect(int x,int y,int width,int height);
繪制一個左上角坐標為(x,y),寬為width,高為height的直角矩形。void fillRect(int x,int y,int width,int height);
繪制一個左上角坐標為(x,y),寬為width,高為height的有填充效果的直角矩形。void drawRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight);
繪制一個左上角坐標為(x,y),寬為width,高為height,在x軸方向上圓邊半徑為arcWidth,在y軸方向上圓邊半徑為arcHeight的圓角矩形。void fillRoundRect(int x,int y,int width,int height,int arcWidth,int arcHeight);
繪制一個左上角坐標為(x,y),寬為width,高為height,在x軸方向上圓邊半徑為arcWidth,在y軸方向上圓邊半徑為arcHeight的,有填充效果的圓角矩形。
- 畫多邊形:多邊形是不限邊數的圖形,而這些邊實際上是由一組點連接而成的,所以繪制多邊形需要一組x,y坐標對。繪圖的原理是從第一個x,y坐標對開始,向第二坐標對畫一條直線,然后向第三個x,y坐標對畫一條直線,依次類推,可以畫出多邊形。下面有方法繪制和填充多邊形:
void drawPloygon(int []xPoints,int []yPoints,int numPoints);
void fillPloygon(int []xPoints,int []yPoints,int numPoints);
xPoints代表x坐標的整形數組,yPoints代表y坐標的整形數組,numPoints代表所有點數的整數,當然,x數組和y數組應該具有相同數目的元素。通過規定Polygon對象或者x,y數組值來設置多邊形的點。
Java字體顏色
任何顏色都是三原色組成(RGB),Java中支持24位彩色,即紅綠藍色分量取值介于0…255之間。
Color的構造函數: public Color(int r,int g,int b);
使用舉例:如果想構造一個灰色對象,則用下面的句子:
Color gray=new Color(205,205,205);
設置畫筆顏色語法
g.setColor(color); //color是一個Color對象
每修改一次顏色它影響的就是下面所有的繪圖語句,一直影響到再次碰到setColor函數才以新的顏色代替。
框架和面板
框架
框架是GUI應用程序的主窗口,是頂層容器。所謂容器是指能夠容納其他組件的特殊組件,由于容器也是組件的一種,因此容器中也能容納容器。框架可重定義尺寸大小,能最大化最小化,帶邊框,可以指定標題、圖標和窗口光標。框架可包菜單,使用對話框。在Java中每個GUI程序至少要有一個框架,Applet有時也會使用框架。
Frame的構造方法:
Frame();
構造一個框架,標題為空,使用缺省布局管理器;Frame(GraphicsConfiguration gc)
構造一個使用特定圖形配置的框架;Frame(string title)
構造一個帶標題的框架Frame(string title , GraphicsConfiguration gc)
構造一個使用特定圖形配置帶標題的框架
package 實驗九;import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{public Test (){ super("演示字體、顏色、繪圖"); //調用基類構造方法 setVisible( true ); //顯示窗口setSize( 480, 250 ); //設置窗口大小 }public void paint( Graphics g ) {super.paint( g ); // call superclass's paint methodg.setFont( new Font( "SansSerif", Font.BOLD, 12 ) ); g.setColor(Color.blue); //設置顏色g.drawString("字體ScanSerif,粗體,12號,藍色",20,50); g.setFont( new Font( "Serif", Font.ITALIC, 14 ) );g.setColor(new Color(255,0,0));g.drawString( " 字體Serif,斜體,14號,紅色", 250, 50 );g.drawLine(20,60,460,60); //繪制直線g.setColor(Color.green);g.drawRect(20,70,100,50); //繪制空心矩形g.fillRect(130,70,100,50); //繪制實心矩形g.setColor(Color.yellow);g.drawRoundRect(240,70,100,50,50,50); //繪制空心圓角矩形g.fillRoundRect(350,70,100,50,50,50); //繪制實心圓角矩形g.setColor(Color.cyan);g.draw3DRect(20,130,100,50,true); //繪制突起效果空心矩形g.fill3DRect(130,130,100,50,false); //繪制凹陷效果實心矩形g.setColor(Color.pink);g.drawOval(240,130,100,50); //繪制空心橢圓g.fillOval(350,130,100,50); //繪制實心橢圓g.setColor(new Color(0,120,20));g.drawArc(20,190,100,50,0,90); //繪制一段圓弧 g.fillArc(130,190,100,50,0,90); //繪制扇形g.setColor(Color.black);int xValues[]={250,280,290,300,330,310,320,290,260,270};int yValues[]={210,210,190,210,210,220,230,220,230,220};g.drawPolygon(xValues,yValues,10); //繪制空心多邊形int xValues2[]={360,390,400,410,440,420,430,400,370,380};g.fillPolygon(xValues2,yValues,10); //繪制實心多邊形}public static void main( String args[] ) { Test application = new Test (); application.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE );}
}
Swing基礎
前面介紹了如何在屏幕上繪制普通的圖形,但如果需要繪制一個按鈕,并使其可以對點擊事件作出響應,就需要使用java Swing提供的組件
其實前面我們已經用到的JFrame、JApplet都是Swing組件,它們分別代表窗口組件和Applet容器組件
JFC
Java Foundation Classes(Java基礎類)的縮寫
是關于組件和服務的完整集合
Swing
JFC 的一部分
提供按鈕、窗口、表格等所有的組件
純Java組件(完全用Java寫的)
- 文本標簽(label)顯示靜態文本,用于提示和說明
- 文本框(text box)接收單行字符串輸入
- 文本區域(text area)接收多行字符串輸入
- 組合框(combo box)用于選擇單個值,也可直接輸入值
- 復選框(check box)接收yes/no值的數據,可選擇多個
- 單選按鈕(radio button)從一組選項中選擇單個選項
- 按鈕(button)觸發一個操作
容器:存放上述組件的窗口稱為容器(Container)。每個組件都可以繼承其父容器的性質,如字體和顏色。同時,容器也可以控制放置其中的組件位置。
容器包含在框架窗口(frame window)中。框架窗口是頂層窗口,沒有父容器。
按鈕 JButton
構造方法:
JButton()
創建不帶有設置文本或圖標的按鈕JButton(Icon icon)
創建一個帶圖標的按鈕JButton(String text)
創建一個帶文本的按鈕JButton(String text, Icon icon)
創建一個帶初始文本和圖標的按鈕
package 實驗九;
import java.awt.*;
import javax.swing.*;
public class Test extends JFrame //創建一個框架窗體
{ public Test(String str){super(str);}public static void main(String args[]){ Test f=new Test("框架");JPanel panelObject=new JPanel(); //創建一個面板f.getContentPane().add(panelObject); //添加面板到框架上JButton b=new JButton("login");panelObject.add(b); //在面板上添加按鈕f.setSize(200,200); f.setBackground(Color.red);f.setVisible(true);}
}
從本例來看,創建的用戶界面可以理解為實際上由三層內容組成:框架Frame為基層,面板Panel為第二層,按鈕Button為第三層。
JPanel是一個構件,是JComponent類的子類,也是一個簡單的容器類。
JPanel類的對象必須放在JFrame中才能可見,提供了添加其他組件的空間,即使添加另一個面板也可以。
標簽JLabel
構造方法:
JLabel():
創建無圖像并且其標題為空字符串的 JLabelJLabel(Icon image)
創建具有指定圖像的 JLabel 實例Label(Icon image, int horizontalAlignment)
創建具有指定圖像和水平對齊方式的 JLabel 實例。JLabel(String text)
創建具有指定文本的 JLabel 實例JLabel(String text, Icon icon, int horizontalAlignment)
創建具有指定文本、圖像和水平對齊方式的 JLabel 實例。
package 實驗九;import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{public Test(String str){ super(str); }public static void main(String args[]){ Test f=new Test("框架");JPanel panelObject=new JPanel();f.getContentPane().add(panelObject);JButton b1=new JButton("login");JButton b2=new JButton("exit");JLabel CustomerName=new JLabel("Customer Name"); panelObject.add(b1);panelObject.add(b2);panelObject.add(CustomerName); //添加標簽到面板上panelObject.setBackground(Color.red);f.setSize(200,200); f.setVisible(true);}
}
文本字段 JTextField
構造方法:
JTextField()
構造一個新的 TextField。創建一個默認的模型,初始字符串為 null,列數設置為 0。JTextField(int columns)
構造一個具有指定列數的新的空 TextField。JTextField(String text)
構造一個用指定文本初始化的新 TextField。JTextField(String text, int columns)
構造一個用指定文本和列初始化的新 TextField。
package 實驗九;import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{public Test(String str){super(str);}public static void main(String args[]){ Test f=new Test("框架");JPanel panelObject=new JPanel();f.getContentPane().add(panelObject);JButton b=new JButton("login");JButton b2=new JButton("exit");JLabel CustomerName=new JLabel("Customer Name"); JTextField CustNameText=new JTextField(10); //創建文本框,長度為10 panelObject.add(b);panelObject.add(b2);panelObject.add(CustomerName);panelObject.add(CustNameText); //添加文本框到面板上f.setSize(200,200); f.setVisible(true);}
}
文本列表框 JList
構造方法:
JList()
構造一個具有空的、只讀模型的JList。JList(Object[] listData)
構造一個 JList,使其顯示指定數組中的元素。
package 實驗九;import java.awt.*;
import javax.swing.*;
public class Test extends JFrame
{public Test(String str){ super(str); }public static void main(String args[]){ JFrame f=new JFrame("List Demo");JPanel p=new JPanel();String listArray[]={"The first list", "The second list","The three list","The four list"};JList list=new JList(listArray); list.setFixedCellWidth(100);list.setVisibleRowCount(4);p.add(list);f.getContentPane().add(p);f.setSize(200,200); f.setVisible(true); }
}
菜單
創建一個菜單系統由JMenuBar,JMenu,JMenuItem三個類共同實現。位于窗口的菜單欄包括下拉菜單的名字,當點擊該名字時就能打開包含菜單項及子菜單項的菜單。
JmenuBar:菜單欄的實現。將 JMenu 對象添加到菜單欄以構造菜單。當用戶選擇 JMenu 對象時,就會顯示其關聯的 JPopupMenu,允許用戶選擇其上的某一個 JMenuItem。構造方法 JMenuBar() 用于創建新的菜單欄。
JMenu:菜單的實現,是一個包含 JMenuItem 的彈出窗口,用戶選擇 JMenuBar 上的項時會顯示該 JMenuItem。除 JMenuItem 之外,JMenu 還可以包含 JSeparator。 菜單本質上是帶有關聯 JPopupMenu 的按鈕。當按下“按鈕”時,就會顯示 JPopupMenu。
其構造方法有:
JMenu():構造沒有文本的新 JMenu。
JMenu(String s):構造一個新 JMenu,用提供的字符串作為其文本。
JMenuItem:菜單中的項的實現。菜單項本質上是位于列表中的按鈕。當用戶選擇“按鈕”時,則執行與菜單項關聯的操作。JPopupMenu 中包含的 JMenuItem 正好執行該功能。
構造方法有:
JMenuItem():創建不帶有設置文本或圖標的 JMenuItem。
JMenuItem(Icon icon):創建帶有指定圖標的 JMenuItem。
JMenuItem(String text):創建帶有指定文本的 JMenuItem。
JMenuItem(String text, Icon icon):創建帶有指定文本和圖標的 JMenuItem。
事件處理
基于窗口的,事件驅動程序的流程:
在事件處理的過程中,主要涉及三類對象:
- 事件源: 能夠接收外部事件的源體, 產生事件的地方(單擊鼠標, 按按鈕, 選擇項目等產生動作的對象)。
- 監聽器: 能夠接收事件源通知的對象。監聽程序必須注冊一個事件源, 才能接收這個事件, 這個過程是自動的, 監聽程序必須實現接受和處理這個事件的方法。
- 事件處理方法: 用于處理事件的對象, 事件源產生一個事件, 并把這個事件發送到一個或多個監聽程序, 監聽程序只是等待這個事件并處理它, 然后返回. 即程序把事件的處理“委托”給一段“代碼”。這段代碼就是事件處理方法, 也叫事件處理程序。
Java中事件模型處理機制:
- 監聽器對象是一個實現了專門監聽接口的類的實例;
- 可以向事件源注冊相應事件的監聽器;
- 當事件發生時, 事件源能夠把事件對象發給已注冊的相應監聽器;
- 監聽器對象中的事件處理方法會使用事件中的信息決定對事情的反應;
授權處理模型處理時間的一般方法:
- 對于某種類型的事件XXXEvent, 要想接收并處理這類事件,必須定義相應的事件監聽器類,該類需要實現與該事件相對應的接口XXXListener;
- 事件源實例化以后,必須進行授權,注冊該類事件的監聽器,使用addXXXListener(XXXListener ) 方法來注冊監聽器。
例如:按鈕單擊改變頁面背景顏色的界面
package 實驗九;import java.awt.*;
import java.awt.event.*;
public class Test extends Frame implements ActionListener
{static Test frm=new Test(); static Button btn=new Button("Click Me");public static void main(String args[]){ btn.addActionListener(frm); // 把frm向btn注冊frm.setLayout(new FlowLayout());frm.setTitle("Action Event");frm.setSize(200,150);frm.add(btn);frm.setVisible(true);}public void actionPerformed(ActionEvent e) // 事件發生的處理操作{ frm.setBackground(Color.red); }
}
運行結果:
事件類
與AWT有關的所有事件類都由java.awt.AWTEvent類派生,它也是EventObject類的子類。AWT事件共有10類。
低級事件
ComponentEvent
( 組件事件:組件尺寸的變化,移動)ContainerEvent
( 容器事件:組件增加,移動)WindowEvent
( 窗口事件:關閉窗口,窗口閉合)FocusEvent
( 焦點事件:焦點的獲得和丟失)KeyEvent
( 鍵盤事件:鍵按下、釋放)MouseEvent
( 鼠標事件:鼠標單擊,移動)
高級事件(語義事件)ActionEvent
(動作事件:按鈕按下,按Enter鍵)AdjustmentEvent
(調節事件:在滾動條上移動滑塊)ItemEvent
(項目事件:選擇項目,不選擇"項目改變")TextEvent
(文本事件,文本對象改變)
事件監聽器
每類時間都有相應的事件監聽器,根據動作來定義相應的方法。
如與鍵盤事件KeyEvent相對應的接口是:
public interface KeyListener extends EventListener
{public void keyPressed(KeyEvent ev);//鍵盤剛按下public void keyReleased(KeyEvent ev);//鍵盤抬起來public void keyTyped(KeyEvent ev);//鍵盤敲擊一次
}
常用的事件監聽器:
AcionListener
Button,List,MenuItem,TextField接收Acion_Event事件。ItemLisener
Choice,ChectBox接收Acion_Event事件,接收所有的List_事件FocusListener
接收Got_focus和Lost_Focus事件KeyListener
接收所有的Key_事件MouseMotionLisener
接收Mouse_Drag和Mouse_Move事件AdjustmentLisener
接收所有的Scroll_事件
實現事件處理的方法:
- 實現事件監聽器接口:需要實現接口中的所有方法。不需要進行處理的事件方法也要列出來,可以用一堆空的花括號
- 繼承事件監聽器類:只需要重寫我們感興趣的事件
例:創建一窗口,當鼠標在窗口中點擊時,在窗口標題欄中顯示點擊位置坐標
package 實驗九;import java.awt.event.*; //載入MouseListener類所在的包
import javax.swing.*; //載入JFrame所在的包
public class Test implements MouseListener
{JFrame f; public Test () {f=new JFrame(); //新建一窗口f.setSize(300,150);f.show();f.addMouseListener(this); //為窗口增加鼠標事件監聽器f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); }public void mousePressed(MouseEvent e){} public void mouseReleased(MouseEvent e){}public void mouseEntered(MouseEvent e){} public void mouseExited(MouseEvent e){}public void mouseClicked(MouseEvent e){f.setTitle("點擊坐標為 ("+e.getX()+", "+e.getY());}public static void main(String[] args){ new Test ();}
}
運行結果: