摘要
通過本章的學習,讀者應能知道GUI(圖形用戶界面)的概念,並且能夠使用Java語言來構建一個令人心曠神怡的GUI界面,使你的程序更具有感召力。把握標簽、按鈕、文本框、選擇框、滾動條……等等各種GUI部件的使用方法。
--------------------------------------------------------------------------------
本章目標:
通過本章的學習,讀者應能知道GUI(圖形用戶界面)的概念,並且能夠使用Java語言來構建一個令人心曠神怡的GUI界面,使你的程序更具有感召力。把握標簽、按鈕、文本框、選擇框、滾動條……等等各種GUI部件的使用方法。
9.1 用什麼構建GUI
傳授新知
早期,電腦向用戶提供的是單調、枯燥、純字符狀態的“命令行界面(CLI)”。就是到現在,我們還可以依稀看到它們的身影:在Windows中開個DOS窗口,就可看到歷史的足跡。
後來,Apple公司率先在電腦的操作系統中實現了圖形化的用戶界面(Graphical User Interface,簡稱GUI),但由於Apple公司封閉的市場策略,自己完成電腦硬件、操作系統、應用軟件一條龍的產品,與其它PC不兼容。這使得Apple公司錯過了一次一統全球PC的好機會。
後來,聞名的Microsoft公司推出了風靡全球的Windows操作系統,它憑借著優秀的圖形化用戶界面,一舉奠定了操作系統標准的地位。這也造就了世界首富---比爾.蓋茨和IT業的泰山北斗微軟公司。
在這圖形用戶界面風行於世的今天,一個應用軟件沒有良好的GUI是無法讓用戶接受的。而Java語言也深知這一點的重要性,它提供了一套可以輕松構建GUI的工具。在本章和下一章中,我們將向你充分證實這一點。
在Java語言提供的GUI構建工具中,可以分為“部件”(component)和“容器”(container)兩種。
在Java語言中,提供了以下部件:
§ 按鈕
§ 標簽
§ 復選框
§ 單選按鈕
§ 選擇框
§ 列表框
§ 文本框
§ 滾動條
§ 畫布
§ 菜單
這些部件,我們在使用Windows操作系統時都碰到過,你通過操作它們來實現與程序的交互。
而光有“部件”就組不成程序,我們必須使用“容器”將這些“部件”裝配起來,使其成為一個整體。Java語言還提供了以下“容器”:
§ 程序的啟動封面
§ 窗體(form)
§ 對話框(Dialog)
Java語言是通過AWT(抽象窗口化工具包)和Java基礎類(JFC或更常用的Swing)來提供這些GUI部件的。
其中Java.awt是最原始的GUI工具包,存放在java.awt包中。現在有許多功能被已被Swing取代並得到了很大的增加與提高,因此一般我們很少再使用Java.awt,但是AWT中還是包含了最核心的功能,通常,一個Java的GUI程序至少還要使用下面幾個類:
§ java.awt.Color:基本顏色定義
§ java.awt.Font:基本字體定義
§ java.awt.Cursor:光標操作定義
而Swing則存放在javax.swing包中。
我們可以在Java的GUI程序的最前面加上以下兩句就可以了:
import java.awt.*;
import javax.swing.*;
這樣就可以一勞永逸了。
用Java開發一個GUI程序,通常需要以下幾步:
1) 構建一個頂層容器;
2) 構建一個部件;
3) 用容器的add方法將部件加入到這個容器中;
我們馬上就開始!
自測練習
1) 在Java語言中,用來構建GUI的工具可以分為________和__________。
a.控件 b.部件 c.窗體 d.容器
2) 下面不屬於“部件”的是__________。
a.選擇框 b.窗體 c.菜單
3) 下面不屬於“容器”的是__________。
a.文本框 b.對話框 c.窗體
4) 容器可以被添加到其它容器中去。________
a.正確 b.不正確
5) 部件可以被添加到容器中去。_______
a.正確 b.不正確
6) 容器可以被添加到部件中去。_______
a.正確 b.不正確
7) 部件可以被添加到其它部件中去。_______
a.正確 b.不正確
練習答案
1)b、d 在Java語言中,GUI構建工具可以分為部件與容器。
2)b 窗體是一種容器,不是部件。
3)a 文本框是一種部件,不是容器。
4)a 有些容器可以被包含到其它容器中去。
5)a 容器就是用來放置各種部件的。
6)b 將部件裝到容器去,就象“把桶裝到水中”一樣可笑。
7)b “把水裝到水中”也是可笑的呀。
9.2 使用Button(按鈕)
實例說明
1.首先,我們使用文字編輯軟件輸入下源程序。
源程序:useButton.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class useButton extends JApplet
{
JButton button1;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
button1=new JButton(“Beep!”);
panel1.add(button1);
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
Toolkit.getDefaultToolkit().beep();
}
});
}
}
2.執行以下命令,編譯這個程序:
c:javastudy> javac useButton.java
由於,這是一個Java Applet(小應用程序),需要在網頁上顯示,所以我們需要編輯一個包含這個小應用程序的Html文件。形如:
源程序:useButton.html
<html><body>
<applet code="useButton.class" WIDTH=150 HEIGHT=100>
</applet>
</body></html>
3.然後使用appletviewer來運行這個程序:
c:javastudy> appletviewer useButton.html
程序輸出如下圖所示:
圖9-1 程序useButton的運行結果
你試著按一下“Beep!”這個按鈕,每按一下就會響一聲。
傳授新知
我們一起來看一下這個冗長而且令人費解的程序段。
1)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
這一段程序是用來將構建GUI程序所需的包包含進來。
2)
public class useButton extends JApplet
這一句用來聲明類useButton,說明它是從JApplet中繼續而來的子類。JApplet是Applet類的一種增強類。因此,從這裡可以看出這個程序是Java小應用程序,而不是Java應用程序。
3)
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
這一段程序創建了一個Jpanel(面板)容器:panel1,然後調用setLayout方法顯示它。
4)
button1=new JButton(“Beep!”);
panel1.add(button1);
這一段程序創建了一個新的部件:button1按鈕,並將按鈕上顯示標簽“Beep!”。然後調用容器panel1的add方法將這個按鈕添加到這個面板上。
5)
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
Toolkit.getDefaultToolkit().beep();
}
});
這是一個非凡的事件,它為按鈕buuton1添加上一個ActionListener(action:行動、事件;Listener:監聽者),也就是事件監視器。這個監視器做什麼呢?
當actionPerformed(action:行動、事件;Performed:執行,表演),就是當這個事件執行時(什麼事件呢?ActionEvent evt,按下按鈕時),將執行:Toolkit.getDefaultToolkit().beep()
也就是響鈴。
自測練習
1)按鈕類中提供了一個方法,可以修改按鈕文本的顏色。以下就是一個應用實例:
button1.setForeground(Color.green);
其中button1是按鈕名,setForeground則方法名,set就是設置,Foreground就是前景,也就是設置前景色。參數是Color.green,綠色。相對應的,紅色就是Color.red,藍色就是Color.blue。
請編寫一個程序,在面板上顯示三個按鈕,按鈕上的標簽分別是:set red,set green,set blue(顏色為黑色)。當按下set red按鈕,則三個按鈕的標簽都變成紅色;而按下set green則變成綠色;按下set blue則變成藍色。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
2)按鈕類中還提供了一個方法,可以修改按鈕標簽。以下就是一個應用實例:
button1.setText(“OK”);
其中button1是按鈕名,setText是方法名,set就是設置,Text就是文本,也就是設置按鈕上的文本色。參數是”OK”。這樣就會將button1的標簽改為”OK”。
請使用這個方法修改程序useButton,使得按鈕上顯示按過的次數,假如沒有按下,則仍顯示“Beep!”。只需寫出修改的部分。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
練習答案
1) 以下就是一個實現實例:
源程序:lianxi901.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi901 extends JApplet
{
JButton buttonRed;
JButton buttonGreen;
JButton buttonBlue;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
buttonRed=new JButton(“set red”);
buttonGreen=new JButton(“set green”);
buttonBlue=new JButton(“set blue”);
panel1.add(buttonRed);
panel1.add(buttonGreen);
panel1.add(buttonBlue);
buttonRed.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
buttonRed.setForeground(Color.red);
buttonGreen.setForeground(Color.red);
buttonBlue.setForeground(Color.red);
}
});
buttonGreen.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
buttonRed.setForeground(Color.green);
buttonGreen.setForeground(Color.green);
buttonBlue.setForeground(Color.green);
}
});
buttonBlue.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
buttonRed.setForeground(Color.blue);
buttonGreen.setForeground(Color.blue);
buttonBlue.setForeground(Color.blue);
}
});
}
}
通過構建一個HTML文件,使其包含這個Applet後,以下就是一個運行效果之一:
圖9-2 練習的輸出
2) 要實現這個功能很簡單,只需做兩個修改:
a. 在變量定義處加入一個新的變量定義:
int counter=0;
b.在button1的addActionListener方法中的actionPerformed中加入一行:
Button1.setText(String.valueOf(++counter));
9.3 使用Label(標簽)
實例說明
1.首先,我們使用文字編輯軟件輸入下源程序。
源程序:useLabel.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class useLabel extends JApplet
{
JLabel label1;
public void init()
{
label1=new JLabel(“This is a java label!”);
label1.setHorizontalAlignment(SwingConstants.CENTER);
label1.setVerticalAlignment(SwingConstants.TOP);
label1.setBackground(Color.red);
label1.setOpaque(true);
label1.setForeground(Color.white);
label1.setToolTipText(“Hello,I am a Java Label!”);
panel1.add(label1);
}
}
2.使用javac編譯這個程序。
3.編輯一個顯示這個Java Applet的頁面:
源程序:useLabel.html
<html><body>
<applet code="useLabel.class" WIDTH=150 HEIGHT=100>
</applet>
</body></html>
4.最後使用appletviewer來運行這個程序:
c:javastudy> appletviewer useLabel.html
程序輸出如下圖所示:
圖9-3 程序useLabel的運行結果
傳授新知
我們可以看到這一段程序,與useButton.java十分類似,在類的前面,包含了編寫GUI程序要使用的包:javax.swing.*、java.awt.*和java.awt.event.*。
接著,通過使用“extends JApplet”說明useLabel類也是一個小應用程序(Applet)。在init方法中,首先創建了一個容器---Panel,用來放置後面創建的“標簽”。我們下面就認真地看一下關於Label的語句:
1)
label1=new JLabel(“This is a java label!”);
類似的,我們使用new來創建一個Label實例,參數“This is a java label!”就是標簽要顯示的內容。假如省略這個標簽,將創建一個空標簽,什麼也不會顯示。
一些提示:
在Java語言中,標簽提供了一個setText方法,可以用來設置它顯示的內容。
2)
label1.setHorizontalAlignment(SwingConstants.CENTER);
label1.setVerticalAlignment(SwingConstants.TOP);
Label類提供兩個設置其對齊方式的方法:
§ setHorizontalAlignment:設置水平對齊方式;
它的有效參數是:
¨ SwingConstants.LEFT:左對齊;(默認值,也就是不設置時則左對齊)
¨ SwingConstants.CENTER:居中對齊;
¨ SwingConstants.RIGHT:右對齊;
§ setVerticalAlignment:設置垂直對齊方式;
它的有效參數是:
¨ SwingConstants.TOP:向上對齊;
¨ SwingConstants.CENTER:居中對齊;(默認值,也就是不設置時居中對齊)
¨ SwingConstants.BOTTOM:向下對齊;
3) label1.setBackground(Color.red);
label1.setOpaque(true);
setBackground方法用來設置標簽的背景色。但是Java的Swing部件默認狀態下是不透明的,在這種狀態下是無法顯示背景色的。因此,我們還需使用setOpaque(true)方法使該部件變為透明的。
4)
label1.setForeground(Color.white);
與按鈕一樣,我們可以使用setForeground方法來設置字符顏色。
5)
label1.setToolTipText(“Hello,I am a Java Label!”);
在Windows的界面中,許多工具按鈕都提供了一個這樣的功能:當你將鼠標放在這個按鈕上面一會兒,就會出現一個幫助性的提示。在Java語言中,我們可以很簡單地使用:
部件.setToolTipText(“提示信息”)
來實現這個功能。
一些提示:
其實“按鈕”部件也可以使用這個方法來顯示提示信息。
6)
panel1.add(label1);
最後,我們使用容器panel的add方法,將這個標簽放置到容器中。
自測練習
1) 標簽Label上顯示的文本信息一經定後,就不能在程序中動態修改。________
a. 錯 b.對
2) 對於一個Label來說,默認的水平對齊方式是:________。
a.SwingConstants.CENTER b.SwingConstants.RIGHT
c.SwingConstants.LEFT
3) 對於一個Label來說,默認的垂直對齊方式是:________。
a.SwingConstants.CENTER b.SwingConstants.BOTTOM
c.SwingConstants.TOP
4) 要獲得一個Label上顯示的文本信息,應使用_________方法。
a.setText b.getText c.getContent
5)標簽類中提供了一個方法,可以修改標簽上顯示的文本。以下就是一個 應用實例:
label1.setText(“new text!”);
請編寫一個程序,在面板左邊顯示一個標簽,右邊顯示一個按鈕,按鈕上顯示“Plus one”,標簽顯示為“0”。每按一次按鈕,標簽上顯示的數字就加1.
一些提示:
在Java中,我們還可以使用getText來獲得標簽上顯示的文本信息。
程序顯示如下圖所示:
圖9-4 練習輸出
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
練習答案
1)a 在程序中可以使用setText方法動態修改Label顯示的文本信息。
2)c 默認是水平左對齊。
3)a 默認是垂直居中對齊。
4)b setText方法是設置文本,getText是獲取文本,並沒有getContent方法。
5)以下就是一個實現該功能的程序實例:
源程序:lianxi902.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi902 extends JApplet
{
JButton button1;
JLabel label1;
int counter=0;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
label1=new JLabel(String.valueOf(counter));
label1.setIcon("winupd.ico");
button1=new JButton("Plus one");
panel1.add(label1);
panel1.add(button1);
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
label1.setText(String.valueOf(++counter));
}
});
}
}
9.4 復選框與單選按鈕
實例說明
1.首先,我們使用文字編輯軟件輸入下源程序。
源程序:useCheckbox.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class useCheckbox extends JApplet
{
JButton button1;
int counter=0;
Checkbox setbeep,setcounter,red,green,blue;
CheckboxGroup colorSel;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
setbeep=new Checkbox("Beep when press button");
setcounter=new Checkbox("Counter press time");
panel1.add(setbeep);
panel1.add(setcounter);
colorSel=new CheckboxGroup();
red=new Checkbox("Set red",colorSel,true);
green=new Checkbox("Set green",colorSel,false);
blue=new Checkbox("Set blue",colorSel,false);
panel1.add(red);
panel1.add(green);
panel1.add(blue);
red.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
if(evt.getStateChange()==ItemEvent.SELECTED)
button1.setForeground(Color.red);
}
});
green.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
if(evt.getStateChange()==ItemEvent.SELECTED)
button1.setForeground(Color.green);
}
});
blue.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
if(evt.getStateChange()==ItemEvent.SELECTED)
button1.setForeground(Color.blue);
}
});
button1=new JButton("Press me");
panel1.add(button1);
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
doButton1Action();
}
});
}
public void doButton1Action()
{
if (setbeep.getState())
Toolkit.getDefaultToolkit().beep();
if (setcounter.getState())
button1.setText("press: "+String.valueOf(++counter));
else
button1.setText("Press me");
}
}
2.使用javac編譯這個程序,然後編輯一個顯示這個Java Applet的頁面:
源程序:useCheckbox.html
<html><body>
<applet code="useCheckbox.class" width=320 height=150>
</applet>
</body></html>
4.最後使用appletviewer來運行這個程序,這個程序的輸出如下圖所示:
圖9-5 程序useCheckbox的運行結果
傳授新知
從我們學習Java開始,這個示例程序是大家碰到的最長的一個。大家不要被它嚇退,這個程序閱讀起來一樣並不困難。下面,我們就對程序做一些點評。
1)
setbeep=new Checkbox("Beep when press button");
setcounter=new Checkbox("Counter press time");
panel1.add(setbeep);
panel1.add(setcounter);
在這一段程序中,我們定義了兩個Checkbox:setbeep和setcounter。什麼是Checkbox呢?如下圖所示:
圖9-6 復選框
在Java語言中,Checkbox類定義了復選框。復選框用來讓用戶做出某種選擇,正如上圖所示,答應選中多個復選框。
在前兩句中,我們使用new創建了這兩個復選框;而在後兩句中,我們使用容器Panel的add方法將它們裝入Panel。
2)
colorSel=new CheckboxGroup();
red=new Checkbox("Set red",colorSel,true);
green=new Checkbox("Set green",colorSel,false);
blue=new Checkbox("Set blue",colorSel,false);
panel1.add(red);
panel1.add(green);
panel1.add(blue);
而這一段程序則是用來定義red、green和blue三個單選按鈕。在Java語言中,單選按鈕被看作是一組非凡的復選框。我們使用一個CheckboxGroup將它們組成一個組,這樣就只答應這個組裡的“復選框”只能有一定被選中,這就形成了單選按鈕。
單選按鈕與復選框在外觀上也不同:復選框是一個正方形的小框,而單選按鈕則是一個小小的圓,如下圖所示:
圖9-7 單選按鈕
在上面的程序中,我們首先定義了一個組:colorSel。接下來的三條語句使用new操作符創建了三個Checkbox,並在參數列表中指定了它所在的組,其語法格式為:
單選按鈕名=new Checkbox(“提示文本”,所在組名,初值);
其中初值是布爾型的:true表示選中,false表示未選中。
注重:
一組單選按鈕中僅能有一個按鈕的初值是true,因為是“單選”嘛。
最後,我們再次調用了panel的add方法,將它們裝入容器panel中。
3)
red.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
if(evt.getStateChange()==ItemEvent.SELECTED)
button1.setForeground(Color.red);
}
});
這段程序用到了許多我們沒有碰到過的東西!不過不要緊,做為初學者還是要學會“黑盒子”學習方法,也就是在學習的初級階段要將某些東西當作一個整體來接受,而不是每一個都要剖析清楚,那樣就會影響學習效果的。正如這段程序,大家只要會用,會理解就行了,不一定要搞懂為什麼這麼寫。
第一行中red.addItemListener用來為單選按鈕red增加一個監測器。監測什麼呢?第3行說明監測itemStateChanged(狀態改變時)。第5行說明當監測到狀態改變時,就判定改變後的狀態是不是“選中”的。假如是,就執行第6行,將按鈕button1的前景色設置為紅色。
在後面的兩段中,我們采用相同的方法為單選按鈕green和blue分別創建了一個監測器,使得當其被“選中”時,就將按鈕button1的前景色設置為相應的顏色(綠色和藍色)。
4)
button1.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
doButton1Action();
}
});
這一段程序,我們在9.2小節中就碰到過。它是用來為按鈕button1創建一個監測器。不同的是,當時我們是直接說明了當按鈕按下時所要執行的語句。而在此,我們則是讓其去執行一個doButton1Action方法。這個方法,是在我們後面的程序中定義的。
5)
public void doButton1Action()
{
if (setbeep.getState())
Toolkit.getDefaultToolkit().beep();
if (setcounter.getState())
button1.setText("press: "+String.valueOf(++counter));
else
button1.setText("Press me");
}
這就是當按下按鈕button1時,執行的方法doButton1Action。整個方法可以分為兩個部分的工作:
其一是:
if (setbeep.getState())
Toolkit.getDefaultToolkit().beep();
即,首先判定復選框setbeep否被選中(使用復選框的getState方法獲得其狀態,假如被選中,返回true;假如未被選中,返回false)。假如被選中,就響鈴。
把整個程序邏輯串起來講就是:當按鈕button1按下時,將檢查復選框setbeep是否被選中,假如被先中,就響鈴,否則無任何反應。
其二是:
if (setcounter.getState())
button1.setText("press: "+String.valueOf(++counter));
else
button1.setText("Press me");
即,首先判定復選框setcounter是否被選中。假如被選中,則改變按鈕button1的顯示文本,將其改為press:按下總次數;否則,讓其顯示最初的“Press me”。
自測練習
1) 在Java語言中,復選框類名是____________。
a.Button b.Checkbox c.checkBox d.Label
2) 在Java語言中,單選框類名是____________。
a.Label b.checkBox c.Button d.Checkbox
3) 假設有cb1、cb2、cb3三個對象,屬於同一個CheckboxGroup,則它們是________。
a.單選按鈕 b.復選框
4) 復選框的外觀是________。
a.一個小正方形 b.一個小圓形 c.一個小三角形
5) 單選框的外觀是________。
a.一個小正方形 b.一個小圓形 c.一個小三角形
6) 編寫一段程序,使其運行結果如下圖所示:
圖9-8 練習903題圖
並且,當選中了NO.1,則按鈕顯示為NO.1;選中了NO.2,則按鈕顯示為NO.2。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
練習答案
1)b 復選框類名為Checkbox,第一個字母“C”是大寫字母。
2)d 單選按鈕也是Checkbox,與復選框的不同是,單選按鈕是屬於一個CheckboxGroup的。
3)a 加入了同一個CheckboxGroup,就成為一組,一組中僅有一個能夠被選中,稱為單選按鈕。
4)a 請參看圖9-6。
5)b 請參看圖9-7。
6)以下是一個實現實例:
源程序:lianxi903.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi903 extends JApplet
{
JButton button1;
Checkbox theOne,theTwo;
CheckboxGroup cbg1;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
cbg1=new CheckboxGroup();
theOne=new Checkbox("NO.1",cbg1,true);
theTwo=new Checkbox("NO.2",cbg1,false);
button1=new JButton("Button");
panel1.add(theOne);
panel1.add(theTwo);
panel1.add(button1);
theOne.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
if(evt.getStateChange()==ItemEvent.SELECTED)
button1.setText("NO.1");
}
});
theTwo.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
if(evt.getStateChange()==ItemEvent.SELECTED)
button1.setText("NO.2");
}
});
}
}
9.5 使用列表框
實例說明
1.首先,我們使用文字編輯軟件輸入下源程序。
源程序:useList.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class useList extends JApplet
{
Label label1;
List colorList;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
colorList=new List();
colorList.add("red");
colorList.add("green");
colorList.add("blue");
colorList.select(0);
panel1.add(colorList);
label1=new Label("You selected red");
label1.setForeground(Color.red);
panel1.add(label1);
colorList.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
String selString;
String sel;
int selNum;
if(evt.getStateChange()==ItemEvent.SELECTED)
{
selNum=colorList.getSelectedIndex();
sel=colorList.getItem(selNum);
selString="You selected "+sel;
label1.setText(selString);
switch(selNum)
{
case 0:
label1.setForeground(Color.red);
break;
case 1:
label1.setForeground(Color.green);
break;
case 2:
label1.setForeground(Color.blue);
break;
}
}
}
});
}
}
2.使用javac編譯這個程序,然後編輯一個顯示這個Java Applet的頁面:
3.最後使用appletviewer來運行這個程序,這個程序的輸出如下圖所示:
圖9-9 程序useList的運行結果
當你選擇green後,標簽將以綠色顯示You selected green;而若你選擇blue後,標簽將以藍色顯示You selected blue。
傳授新知
這一節中,我們將碰到一個新的部件---列表框。下面,就對剛才這個程序做一些點評。
1)
colorList=new List();
colorList.add("red");
colorList.add("green");
colorList.add("blue");
colorList.select(0);
panel1.add(colorList);
在這一段程序中,我們定義了一個列表框List:colorList。列表框用來將多個表項列出來,以供用戶選擇,如下圖所示:
圖9-10 列表框
首先,我們使用new操作符創建一個colorList,然後調用列表框的add方法,增加可供選擇的表項(red、green和blue)。最後,使用select方法,使得缺省選擇是red(第0項)。
最後使用容器Panel的add方法將它們裝入Panel。
一些提示:
假如要讓缺省選擇的是blue,則應該使用colorList.select(2)。
為列表框的指定位置上增加項目,可以使用方法:
public synchronized void add(String item,int index)
其中,item是一個字符串,用來存放要顯示的標簽文本。而index則是添加的位置。列表框的位置是一個從0開始的數,所以,假如用戶在位置0處增加項目,那麼該項目將增加在列表框的頂部。假如用戶試圖在-1處或大於列表框中項目數(甚至象例子中,不給出index參數)的位置上增加項目,那麼將增加到列表框的末尾。
假如你想刪除某一項,則可以使用方法:
public synchronized void remove(int position)
其中position就是你要刪除項目的位置。假如你想刪除掉所有的項,則可調用方法:
public synchronized void removeAll()
2)
colorList.addItemListener(new ItemListener()
{
public void itemStateChanged(ItemEvent evt)
{
……
}
});
與其它部件一樣,可以使用addItemListener方法為其設置一個監測器,當列表框選擇項改變時就會激活這個監測器。
3)
if(evt.getStateChange()==ItemEvent.SELECTED)
{
selNum=colorList.getSelectedIndex();
sel=colorList.getItem(selNum);
selString="You selected "+sel;
label1.setText(selString);
在這一段程序中,我們首先調用了列表框的getSelectedIndex ()方法取得你所選擇項目的編號。這個項目返回的是一個整型的索引號。
接著,我們再使用這個索引號調用列表框的getItem方法獲取該項目的標簽文本。
為了讓標簽中顯示的文本更加清楚、易懂,我們在標簽文本的前面加上了“You Selected”,然後調用標簽label1的setText方法改變標簽所顯示的文本。
4)
switch(selNum)
{
case 0:
label1.setForeground(Color.red);
break;
case 1:
label1.setForeground(Color.green);
break;
case 2:
label1.setForeground(Color.blue);
break;
}
這是一個多分支結構,它根據所選擇的項目編號(前面,我們已經調用getSelectedIndex ()方法取得了項目編號,存放在變量selNum中)來做相應的操作。
<1> case 0:假設selNum=0,那麼就執行
label1.setForeground(Color.red);
break;
也就是,將標簽label1的前景色(字的顏色)設置為紅色,然後退出switch-case語句。
<2> case 1:假設selNum=1,那麼就執行
label1.setForeground(Color.green);
break;
將標簽label1的前景色設置為綠色,然後退出switch-case語句。
<3> case 2:假設selNum=2,那麼就執行
label1.setForeground(Color.blue);
break;
將標簽label1的前景色設置為藍色,然後退出switch-case語句。
文本,將其改為press:按下總次數;否則,讓其顯示最初的“Press me”。
自測練習
1) 在程序中要構建一個列表框,要使用_________類。
a.Checkbox b.Listbox c.List d.Label
2) 列表框中第一項的項目編號(也稱索引)是________。
a.0 b.1 c.-1 d.10
3) 假設有一個列表框listbox1,要在其最後添加一項,應使用________________語句。
a.listbox.add(“The end item”,0) b. listbox.add(“The end item”,10)
c. listbox.add(“The end item”,-1) d. listbox.add(“The end item”, 1)
4) 我們可以使用__________________方法,取得當前選擇的項目的索引值。
a. getSelectedIndex() b. getItem() c. getNumber()
5) 編寫一段程序,使其運行結果如下圖所示:
圖9-11 練習903題圖
當按下Add按鈕,就在列表框上增加一項:No.x(x是順序號),當按下Remove按鈕,就刪除最後一項。
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
練習答案
1)c 在Java中,類List實現了列表框。
2)a 從0開始,而不是1。
3)c 要在這後一項添加有三種方法。其一:以-1為位置參數;其二:以大於最大項目索引數的數為位置參數;其三:不帶位置參數。因此在此,只有c。
4)a getItem是獲得顯示的內容。
5)下面,我們給出一個實現的實例。
源程序:lianxi904.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi904 extends JApplet
{
List listbox1;
JButton buttonAdd,buttonRemove;
int counter=0;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
listbox1=new List();
buttonAdd=new JButton("Add");
buttonRemove=new JButton("Remove");
panel1.add(listbox1);
panel1.add(buttonAdd);
panel1.add(buttonRemove);
buttonAdd.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
listbox1.add("NO."+String.valueOf(counter++));
}
});
buttonRemove.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
listbox1.remove(counter-1);
counter-=1;
}
});
}
}
9.6 使用文本部件
9.6.1 普通文本框
實例說明
1.編輯以下源程序,生成useText.java文件。
源程序:useTextfield.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class useTextfield extends JApplet
{
JButton buttonOK;
JTextField text1;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
buttonOK=new JButton("OK");
text1=new JTextField(20);
panel1.add(text1);
panel1.add(buttonOK);
buttonOK.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
showStatus(text1.getText());
}
});
}
}
2.使用javac編譯這個程序,然後編輯一個顯示這個Java Applet的頁面:
3.最後使用appletviewer來運行這個程序,這個程序的輸出如下圖所示:
圖9-12 程序useTextfield.java的運行結果(1)
正如上圖所示,屏幕上出現了一個寬度為20的文本框和一個OK按鈕。我們可以在這個文本框內寫入字符。我們輸入“Haha,I’m writing to Java’s TextField!!”,然後單擊OK按鈕,這時屏幕變為:
圖9-13 程序useTextfield.java的運行結果(2)
也就是,我們按下OK按鈕後,在狀態欄上出現了我們輸入的文本信息。
傳授新知
多次閱讀Java語言源程序,應該為大家積累了不少經驗,我想大家在閱讀這個程序的時候,因為不再覺得那麼費勁了吧。假如你還是覺得讀程序是一件痛苦的事的話,我希望你還是好好反省一下,看前面的章節時是不是走馬觀花了。
好了,言歸正傳,我們一起來看一下上面的這個程序。這個程序中的大部分語句,大家應該都耳熟能詳了,生疏的只有關於本小節的主人公---文本框TextField的語句了:
1)
JTextField text1;
……
text1=new JTextField(20);
首先,我們定義了一個JTextField類的對象text1,然後使用new操作符來創建這個對象text1(也就是一個文本框)
大家還記得new後面的這個與類名相同的方法稱為什麼嗎?對,構造器。這個類有三種帶不同參數的構造器。
A. JTextField(int columns)
第一種構造器,就是我們在本例中調用的那個,它帶了一個整型參數columns,這個單詞的中文意思是列,也就是說,這個參數指定了我們要創建的TextField的列寬。這裡的列寬指長度,而不是可包含的字符數。
那麼20,到底是多少寬呢?Java是這樣定義的:
能夠顯示20個小寫“m”(當前選擇的字體)的寬度。
注重:
得再次強調一下,這裡的列寬是一種長度,而不是字符數。你可以試一試,在我們這個程序執行後,再這個文本框中輸入小寫字母“m”,看一看能夠輸入多少個。但大家也應該注重到,我們在例子中輸入的字符數遠不止20個。
B. JTextField(String text)
第二種構造器則帶的是一個字符串型參數text,這個字符串將會在程序一執行時就顯示在文本框中。
C.JTextField(String text,int columns)
而假如你既想設置默認的字符串,又想設置它的寬度,就可以調用第三種構造器。
注重:
調用JTextField的構造器時,一定要帶上參數,否則將會出錯。
2)
buttonOK.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
showStatus(text1.getText());
}
});
大家看到這個語句,應該不會感到生疏吧!它為按鈕buttonOK增加一個監測器,監測是否按下按鈕。假如按下按鈕,就執行:showStatus(text1.getText())語句。
這個語句中,有兩個新的知識。
其一是:showStatus(String test)方法,它用來在狀態欄上顯示字符串。
其二是:getText()方法,它是JTextField類的一個成員方法,用來獲取文本框內的文本。例如本例中text1.getText()就將獲得文本框text1中的文本。也就是我們輸入的那些東西。
整個串起來,得到:
當我們按下OK按鈕時,程序將獲取文本框text1中的文本,然後將它們顯示到狀態欄上。
用getText()方法可以獲取文本框中的文本,相應的,我們可以使用setText()方法設置文本框中的文本。其語法是:
文本框對象.setText(String text)
這樣,就將文本框中的文本改成了字符串text。
除此之外,我們還可以使用setHorizontalAlignment方法來設置字符串中文本的對齊方式,具體來說:
setHorizontalAlignment(Swing constants.CENTER) 居中對齊
setHorizontalAlignment(Swing constants.LEFT) 左對齊
setHorizontalAlignment(Swing constants.RIGHT) 右對齊
9.6.2 口令文本框
傳授新知
口令文本框(JPassWordField)是一種非凡的文本框,在口令文本框中輸入任何字符串都將顯示成為“*”,這樣就可以不讓別人知道你輸入的是什麼,這種文本框比較適合與密碼、口令的輸入,所以稱之為口令文本框。
為了安全起見,獲取口令文本框中的密碼(口令)使用的方法與普通文本框不同。它使用方法:getPassword()。
“越麻煩越安全”,所以,Java語言中為你獲取口令再添加了一層麻煩(我看來是一種不必要的麻煩),getPassword()方法將返回一個char數組,我們還得將其轉換成為字符串。以下就是一個轉換的實例:
String passwd=new String(passwdTextField.getPassword())
9.6.3 文本區
實例說明
正如我們看到的一樣,普通文本框TextField只能輸入一行,假如要提供一個多行的輸入界面,那怎麼辦呢?下面我們就看一下下面這個程序:
源程序:useTextArea.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class useTextarea extends JApplet
{
JButton buttonClear;
JTextArea textarea1;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
buttonClear=new JButton("Clear all");
textarea1=new JTextArea("Enter new text",5,15);
panel1.add(textarea1);
panel1.add(buttonClear);
buttonClear.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
textarea1.setText("");
}
});
}
}
2.使用javac編譯這個程序,然後編輯一個顯示這個Java Applet的HTML頁面,建議高度為100,寬度為300。
3.最後我們再使用appletviewer來運行這個程序,這個程序的輸出如下圖所示:
圖9-14 程序useTextarea.java的運行結果
接著,我們就可以在這個文本區內寫多行文本了。大家在按下“Clear all”按鈕之前,想一下,會發現什麼結果?
傳授新知
這個程序中,主要需要說明的只有關於TextArea部件(文本區)的一些語句:
1)
JTextArea textarea1;
……
textarea1=new JTextArea("Enter new text",5,15);
首先,我們定義了一個JTextArea類的對象textarea1,然後使用new操作符來創建這個對象textarea1(也就是一個文本區)。與文本框類似,文本區的構造器也有三種:
A. JTextField(int rows,int columns)
在這個構造器中,有兩個整型參數rows(這個單詞的中文意思是行)和columns(這個單詞的中文意思是列),也就是說,這兩參數用來指令文本區的行數,與列寬。
這裡的列寬與文本框一樣,是一種長度,用能夠顯示多少個個小寫“m”(當前選擇的字體)來衡量的寬度。而行數,就很好理解了,就是能夠輸入的行數。
要注重的是,這裡的行數、列數都是只顯示出來的框的大小。假如一行中超過了列寬,將會使文本區變得越來越寬,如下圖所示:
圖9-15 超過了列寬
由於輸入的文本超過了文本區原來的寬度,使得文本區變得越來越寬,把按鈕都擠到下一行中去了。
注重:
假如把多出來的文本刪除掉後,文本區將變成原來的大小。
同樣的,假如輸入太多行,將引起如下圖所示的情況:
圖9-16 超過了行數
B. JTextArea(String text)
也可以只帶一個字符串型參數text調用構造器方法,這個字符串將會在程序一執行時就顯示在文本區中。
C. JTextField(String text ,int rows,int columns)
而假如你既想設置默認的字符串,又想設置它的寬度,就可以調用第三種構造器。在本例中,我們就是調用這個構造器,構建了一個5行,15個“m”寬的文本區,讓其一啟動就顯示一段文本:“Enter new text”。
注重:
同樣的,調用JTextArea的構造器時,一定要帶上參數,否則將會出錯。
2)
buttonClear.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
textarea1.setText("");
}
});
在這一段程序中,我們為按鈕buttonClear增加了一個監測器,使得當這個按鈕按下時就執行:textarea1.setText(“”)。與文本框TextField一樣,文本區TextArea也提供了設置顯示文本的方法:setText(String text)。
大家想想,將顯示文本設置為“”,意味著什麼,對!就是讓其什麼也不顯示,這也就是前面那個問題(大家在按下“Clear all”按鈕之前,想一下,會發現什麼結果?)的答案。
到現在,我們已經讀懂了這個程序,但通過執行程序時,我們發現了一個十分不好的問題,那就是在文本區內不會自動換行。我們並不希望文本區變得越來越寬!
怎麼辦呢?Java為文本區TextArea提供了一個方法,使得自動換行成為可能:
textarea1.setLineWrap(true)
只需將這條語句加入程序,就會使得我們編輯到右邊時會自動換行。假如我們要恢復成不自動換行,就調用:
textarea1.setLineWrap(false)
自測練習
1) 部件____________適合於提供密碼輸入界面。
a. JTextArea b.JTextField c.JPasswordField
2) 在文本區中________輸入超過程序中定義的行數。
a.能 b.不能
3) 我們可以使用______________來清除文本框text1中的文本。
a.text1.clearText() b.text1.setText(“”)
c.text1.deleteText() d.以上都可以
4) 假如我們調用____________來獲得口令文本框passwd1中的文本。
a.passwd1.getText() b.passwd1.getPassword()
5) 在程序中_______________,就能夠防止因為在一行中輸入過多的文本,而使文本區textarea1變寬。
a.不需要做任何考慮 b.textarea1.setLineWrap(true)
c.textarea1.setLineWrap(false) d.textarea1.noWrap()
6) 假如我們使用textfield1=new JTextField(“TEST”)來創建一個文本框,那麼這個文本框的寬度有多大?
____________________________________________________________________
7) 請在程序useTextarea.java中加入textarea1.setLineWrap(true),然後再執行這個程序,發現一下,還存在什麼樣的問題。
____________________________________________________________________
____________________________________________________________________
8) 根據以下要求,編寫程序
設置兩個文本框,一個用來輸入UserName,另一個用來輸入Password;再設置一個按鈕OK和一個文本區。
假如我們按下OK按鈕,則右邊的文本區中就會顯示:
UserName:用戶名
Password:密碼
其中用戶名、密碼就是用戶輸入的內容,假如沒有輸入則不顯示。程序輸出如下圖所示:
圖9-17 程序lianxi905.java的輸出
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
____________________________________________________________________
練習答案
1)c 由於輸入密碼的地方,應該不能明文顯示,否則輕易被邊上的人從偷看到,我們可以借助Java中提供的口令文本框PasswordField來實現。這樣,你輸入的內容就變成了星號,不怕被人偷看到了。
2)a 能,而且會使得文本區的行數增加。
3)b 一個文本框並不存在cleatText()方法,也沒有提供delete()方法,但我們可以通過調用setText(“”)來實現,這是因為,我們讓它顯示的文本變成了“”。也就空文本,這難道不是清除所有文本嗎?
4)b 口令文本框要使用非凡的方法getPassword()來獲得口令文本。
5)b 通過使文本區自動換行,就可以有效地避免這個問題。
6)這個文本框的寬度就是字符串“TEST”的大小。如下圖所示:
圖9-18 練習答案參考圖(1)
7)還存在一個問題,那就是這個程序十分愚笨,它雖然會自動換行,但是卻常把一個單詞分在兩行裡,如下圖所示:
圖9-19 練習答案參考圖(2)
一些提示:
其實文本區部件還提供了一個方法來解決這個問題,那就是:
public void setWrapStyleWord(boolean word)
假如在程序中,加入textarea1.setWrapStyleWord(true),那麼程序輸入則是:
圖9-20 練習答案參考圖(3)
怎麼樣,效果是不是更好了!
8) 請參考以下實現實例:
源程序:lianxi905.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class lianxi905 extends JApplet
{
Label label1,label2;
JTextField username;
JPasswordField passwd;
JButton buttonOK;
JTextArea showResult;
String out;
public void init()
{
JPanel panel1=(JPanel)getContentPane();
panel1.setLayout(new FlowLayout());
label1=new Label("Please input your name:");
username=new JTextField(15);
label2=new Label("Please input your password:");
passwd=new JPasswordField(15);
buttonOK=new JButton("OK");
showResult=new JTextArea(2,15);
panel1.add(label1);
panel1.add(username);
panel1.add(label2);
panel1.add(passwd);
panel1.add(buttonOK);
panel1.add(showResult);
buttonOK.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
out="Username: "+username.getText()+" ";
out=out+"Password: "+new String(passwd.getPassword());
showResult.setText(out);
}
});
}
}
請大家注重到,我們是如何生成在文本區showResult顯示的文本信息(存放在字符串變量out中)的:
out="Username: "+username.getText()+" ";
out=out+"Password: "+new String(passwd.getPassword());
先讓out等於“Username:”+username.getText(),這就使其包含了提示字符“Username:”,而後面的內容是另一部分的,所以我們在這個後面加上了“ ”,這是一個轉義符,代表回車(也就是另起一行)。
然後再將其加上提示字符“Password:”,最後是調用了getPassword()方法,然後將其轉換為字符串型。