《疯狂Java讲义》读书笔记(七):Swing编程
第十二章 Swing編程
?1、Swing開發(fā)圖形界面比AWT更加優(yōu)秀,它是一種輕量級(jí)組件,采用100%的Java實(shí)現(xiàn),不依賴于本地平臺(tái)的圖形界面,對(duì)跨平臺(tái)支持比較出色。依賴于本地平臺(tái)的AWT組件被稱為重量級(jí)組件。通常在AWT組件的組件名前添加“J”就變成了對(duì)應(yīng)的Swing組件。
Swing中包含了4個(gè)組件直接集成了AWT組件,而不是從JComponent派生的,它們分別是:JFrame、JWindow、JDialog和JApplet。它們是重量級(jí)組件,需要部分委托給運(yùn)行平臺(tái)上的GUI組件的對(duì)等體。Swing除了Canvas之外的所有AWT組件都提供了相應(yīng)的實(shí)現(xiàn)。
①使用setToolTipText()為組件設(shè)置對(duì)用戶有幫組的提示信息;②ImageIcon該實(shí)現(xiàn)類代表一個(gè)圖像圖標(biāo);③支持拔插式的外觀風(fēng)格,每個(gè)JComponent對(duì)象都有一個(gè)對(duì)應(yīng)的ComponentUI對(duì)象,完成所有的繪畫、事件處理、決定尺寸大小等工作。每個(gè)Swing組件都有一個(gè)對(duì)應(yīng)的UI類,例如JButton組件就有一個(gè)對(duì)應(yīng)的ButtonUI類來(lái)作為UI代理。一般是將Swing組件類名去掉J,后面添加UI后綴。
frame.setLocationRelativeTo(null);//默認(rèn)窗口居中位置
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//關(guān)閉窗口,點(diǎn)擊右上角的 X 即可關(guān)閉窗口。
Swing菜單不允許使用add(new JMenuItem("-"))的方式來(lái)添加菜單分隔符,只能使用addSeparator()方法來(lái)添加菜單分隔符。
Swing組件添加右鍵菜單無(wú)須像AWT那樣繁瑣,只需要調(diào)用setComponentPopupMenu()方法來(lái)設(shè)置右鍵菜單即可。簡(jiǎn)而言之,如果希望讓JTextArea、JTable組件有滾動(dòng)效果支持,只要將該組件放入JScrollPane中,再將該JScrollPane容器添加到窗口中即可。
JScrollPane對(duì)于JTable組件尤其重要,通常需要把JTable放在JScrollPane容器中才可以顯示出JTable組件的標(biāo)題欄。
?Swing組件的雙緩沖和鍵盤驅(qū)動(dòng):所有的Swing組件默認(rèn)還有如下兩個(gè)功能:默認(rèn)的雙緩沖繪圖技術(shù)和簡(jiǎn)單的鍵盤驅(qū)動(dòng)。JComponent組件默認(rèn)啟用雙緩沖,無(wú)須自己實(shí)現(xiàn),如果想關(guān)閉,可以在組件上調(diào)用setDoubleBuffered(false)方法。JComponent類提供了getInputMap、getActionMap兩個(gè)方法,getInputMap返回一個(gè)關(guān)聯(lián),該對(duì)象用于將KeyStroke對(duì)象(代表鍵盤或其他類似輸入設(shè)備的一次輸入事件)和名字關(guān)聯(lián);getActionMap返回一個(gè)ActionMap對(duì)象,該對(duì)象用于將指定名字和Action(Action接口是ActionListener的子接口,可以作為一個(gè)事件監(jiān)聽(tīng)器使用)關(guān)聯(lián),從而允許用戶通過(guò)鍵盤操作來(lái)代替鼠標(biāo)驅(qū)動(dòng)GUI上的Swing組件,即快捷鍵。典型用法例子:
// 添加事件監(jiān)聽(tīng)器
button.addActionListener(senMessage);
// 將Ctrl+Enter作為鍵和 send關(guān)聯(lián)
textField.getInputMap().put(KeyStroke.getKeyStroke('\n',java.awt.event.InputEvent.CTRL_MASK), "send");
//將send和senMessage Action關(guān)聯(lián)
textField.getActionMap().put("send", senMessage);
//監(jiān)聽(tīng)事件實(shí)現(xiàn)
Action senMessage = new?AbstractAction()?{
public?void?actionPerformed(ActionEvent?e) {Date?date = new?Date();
SimpleDateFormat?simpleDateFormat = new?SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss");
String?sendTime = simpleDateFormat.format(date);textArea.append(textField.getText() + " ?"?+ sendTime + "\n");
textField.setText("");}};
?使用JToolBar創(chuàng)建工具條:創(chuàng)建JToolBar對(duì)象時(shí)可以指定如下兩個(gè)參數(shù):name指定工具條的名稱和orientation指定工具條的方向。一旦創(chuàng)建了JToolBar對(duì)象之后,JToolBar對(duì)象還有如下幾個(gè)常用方法:
JButton add(Action a)通過(guò)Action對(duì)象為JToolBar添加對(duì)應(yīng)的工具按鈕;void addSeparator(Dimension size):向工具條中添加指定大小的分隔符,可以使用默認(rèn)大小的分隔符;void setFloatable(boolean b):設(shè)置該工具條是否可以浮動(dòng),即該工具條是否可以拖動(dòng);void setMargin(Insets m)設(shè)置工具條邊框和工具按鈕之間的頁(yè)邊距;void setOrientation(int o)設(shè)置工具條的方向。
Clipboard clipboard=Toolkit.getDefaultToolkit().getSystemClipboard();//獲取系統(tǒng)剪貼板
Action pasteAction=new AbstractAction("粘貼",new ImageIcon("ico/paste.png")){
public void actionPerformed(ActionEvent e){
if(clipboard.isDataFlavorAvailable(DataFlavor.stringFlavor))//如果剪貼板中包含stringFlavor內(nèi)容
{try{
//取出剪貼板中的stringFlavor內(nèi)容 ?
String content=(String)clipboard.getData(DataFlavor.stringFlavor);
//將選中內(nèi)容替換成剪貼板內(nèi)容 ?
jta.replaceRange(content,jta.getSelectionStart(),jta.getSelectionEnd());}catch()
}}}
//復(fù)制的主要代碼
StringSelection contents=new StringSelection(jta.getSelectedText());//將StringSelection對(duì)象放入剪貼板中
clipboard.setContents(contents,null); ??//如果剪貼板中包含stringFlavor內(nèi)容,則激活“粘貼”按鈕事件
if(clipboard.isDateFlavorAvailable(DataFlavor.stringFlavor)){
pasteAction.setEnabled(true);}
?
?JFileChooser的功能與AWT中的FileDialog基本相似,與FileDialog不同的是,JFileChooser無(wú)需依賴本地平臺(tái)的GUI,由100%純Java實(shí)現(xiàn)。JFileChooser先創(chuàng)建一個(gè)對(duì)話框?qū)嵗?#xff0c;有多個(gè)構(gòu)造器,包含兩個(gè)參數(shù)currentDirectory、FileSystemView。JFileChooser并不是JDialog的子類,所以不能使用setVisible(true)方法來(lái)顯示該文件對(duì)話框,而是使用showXXXDialog()方法來(lái)顯示文件對(duì)話框。創(chuàng)建JFileChooser對(duì)象時(shí)可以指定初始化路徑,如下代碼:
JFileChooser chooser=new JFileChooser(".");表示以當(dāng)前路徑創(chuàng)建文件選擇器。
?JFileChooser大致有如下幾個(gè)常用方法:
setSelectedFile/setSelectedFiles指定該文件選擇器默認(rèn)選擇的文件(也可以默認(rèn)選擇多個(gè)文件):chooser.setSelectedFile(new File("123.jpg")); ???
setMultiSelectionEnabled(boolean b)默認(rèn)情況下,該文件選擇器只能選擇一個(gè)文件,通過(guò)該方法可以設(shè)置允許選擇多個(gè)文件(設(shè)置b為true即可)。 ??
setFileSelectionMode(int mode)在默認(rèn)情況下,該文件選擇器只能選擇一個(gè)文件,該方法可以設(shè)置允許選擇文件、路徑、文件與路徑,設(shè)置參數(shù)值為:JFileChooser.FILES_ONLY、JFileChooser.DIRECTORIES_ONLY、JFileChooser.FILES_AND_DIRECTORIES。
?如果讓文件對(duì)話框?qū)崿F(xiàn)文件過(guò)濾功能,則需要結(jié)合FileFilter類來(lái)實(shí)現(xiàn)文件過(guò)濾。JFileChooser提供了兩個(gè)方法來(lái)安裝文件過(guò)濾器:addChoosableFileFilter(FileFilter filter)添加文件過(guò)濾器,該方法允許該文件對(duì)話框有多個(gè)文件過(guò)濾器。
setFileFilter(FileFilter filter):設(shè)置文件過(guò)濾器,一旦調(diào)用該方法,將導(dǎo)致文件對(duì)話框只有一個(gè)文件過(guò)濾器。
?FileView類可以改變文件對(duì)話框的外觀視圖。
?調(diào)用showXXXDialog()方法可以打開文件對(duì)話框,通常有三個(gè)方法可以用:
int showDialog(Component parent,String approveButtonText)彈出文件對(duì)話框,該對(duì)話框的標(biāo)題、“同意”按鈕的文本(默認(rèn)是 保存 或 取消 按鈕)由approveButtonText指定。?
int showOpenDialog(Component parent)彈出文件對(duì)話框,有默認(rèn)標(biāo)題,“同意”按鈕的文本是“打開”。 ?
int showSaveDialog(Component parent)彈出文件對(duì)話框,該對(duì)話框具有默認(rèn)標(biāo)題,“同意”按鈕的文本是“保存”。
?JFileChooser提供了兩個(gè)方法來(lái)獲取用戶選擇的文件或文件集:File getSelectedFile()返回用戶選擇的文件。File[] getSelectedFiles()返回多個(gè)文件。
默認(rèn)情況下,JFileChooser總會(huì)在文件對(duì)話框的“文件類型”下拉列表中增加“所有文件”選項(xiàng),但可以調(diào)用JFileChooser的setAcceptAllFileFilterUsed(flase)來(lái)取消顯示該選項(xiàng)。
?
?使用JOptionPane可以非常方便的創(chuàng)建一些簡(jiǎn)單的對(duì)話框,有4個(gè)方法:
①showMessageDialog/showInternalMessageDialog:消息對(duì)話框,告知用戶某事已經(jīng)發(fā)生,用戶只能點(diǎn)擊“確定”按鈕,類似JavaScript的alert函數(shù)。
②showConfirmDialog/showInternalConfirmDialog:確認(rèn)對(duì)話框,用戶可以選擇yes、no、cancel選項(xiàng)。該方法返回用戶單擊了哪個(gè)按鈕;
③showInputDialog/showInternalInputDialog:輸入對(duì)話框,該方法返回用戶輸入的字符串;④showOptionDialog/showInternalInputDialog:自定義選項(xiàng)對(duì)話框,允許使用自定義選項(xiàng),可以取代showConfirmDialog所產(chǎn)生的對(duì)話框,只是用起來(lái)復(fù)雜。JOptionPane產(chǎn)生的所有對(duì)話框都是模式的,在用戶完成對(duì)話框的交互之前,showXXXDialog方法都將一直阻塞當(dāng)前線程。
(1)輸入?yún)^(qū):輸入?yún)^(qū)組件可以是普通文本框組件,也可以是下拉列表框組件;
(2)圖標(biāo)區(qū):左上角的圖標(biāo)會(huì)隨創(chuàng)建的對(duì)話框所包含消息類型的不同而不同,JOptionPane提供5種消息類型:
?ERROR_MESSAGE:錯(cuò)誤消息,其圖標(biāo)是一個(gè)紅X;?INFORMATION_MESSAGE:普通消息,藍(lán)色的感嘆號(hào);?WARNING_MESSAGE:警告消息,黃色感嘆號(hào);?QUESTION_MESSAGE:問(wèn)題消息,綠色問(wèn)號(hào);?PLAIN_MESSAGE:普通消息,沒(méi)有默認(rèn)圖標(biāo)。
(3)消息區(qū):不管哪種對(duì)話框,其消息區(qū)總是存在的,消息區(qū)的內(nèi)容通過(guò)message參數(shù)來(lái)指定,該message參數(shù)可以是以下幾種:
①String類型:系統(tǒng)將該字符串對(duì)象包裝成JLabel對(duì)象,然后顯示在對(duì)話框中;②Icon:該Icon被包裝成JLabel后作為對(duì)話框的消息;③Component:將該Component在對(duì)話框的消息區(qū)中顯示出來(lái);④Object[] :對(duì)象數(shù)組被解釋為在縱向排列的一系列message對(duì)象,每個(gè)message對(duì)象根據(jù)其實(shí)際類型又可以是字符串、圖標(biāo)、組件、對(duì)象數(shù)組等。⑤其它類型:系統(tǒng)調(diào)用該對(duì)象的toString方法返回字符串。
(4)按鈕區(qū):對(duì)話框底部的按鈕區(qū)也是一定存在的,底部總是包含“確定”和“取消”兩個(gè)標(biāo)準(zhǔn)按鈕,該參數(shù)可以取如下幾個(gè)值:①DEFAULT_OPTION:按鈕只包含一個(gè)“確定”按鈕;②YES_NO_OPTION:按鈕包含“是”、“否”兩個(gè)按鈕;③YES_NO_CANCEL_OPTION:按鈕包含“是”、“否”、“取消”三個(gè)按鈕;④OK_CANCEL_OPTION:按鈕包含“確定”、“取消”2個(gè)按鈕。
int?str1 = JOptionPane.showConfirmDialog(frame, "這是彈出來(lái)的信息");?System.out.println(str1);
是:返回0。否:返回1。取消:返回2。右上角紅X:返回-1。
String[] aa = { "深圳", "廣州", "北京", "上海"?};????
Object?str = JOptionPane.showInputDialog(frame, "想去哪里發(fā)展?","彈框的標(biāo)題",?
JOptionPane.WARNING_MESSAGE, null, aa, aa[0]);??
System.out.println(str.toString());
其中JOptionPane.WARNING_MESSAGE可以使用數(shù)字1,2,3等表示,但是數(shù)字表示不直觀,不利于代碼閱讀。倒數(shù)第一個(gè)參數(shù)表示選中的默認(rèn)值。
?
Swing簡(jiǎn)化的拖放功能:
textArea.setDragEnabled(true);//啟動(dòng)文本域和單行文本框的拖放支持
frame.add(new?JScrollPane(textArea));//滾動(dòng)條,簡(jiǎn)潔的代碼編寫風(fēng)格
?
使用JProgressBar、ProgressMonitor和BoundedRangeModel創(chuàng)建進(jìn)度條:
使用JProgressBar可以非常方便的創(chuàng)建進(jìn)度條,步驟有仨:①創(chuàng)建JProgressBar對(duì)象,可以指定3個(gè)參數(shù),用于設(shè)置進(jìn)度條的排列方向(豎直和水平)、進(jìn)度條的最大值和最小值。②調(diào)用該對(duì)象的常用方法設(shè)置進(jìn)度條的普通屬性,JProgressBar除了提供設(shè)置排列方向、最小最大值的setter和getter方法之外,還提供了3個(gè)方法:setBorderPainted(boolean b)設(shè)置該進(jìn)度條是否使用邊框;setIndeterminate(boolean newValue),設(shè)置該進(jìn)度條是否是進(jìn)度不確定的進(jìn)度條,如果指定一個(gè)進(jìn)度條的進(jìn)度不確定,將看到一個(gè)滑塊在進(jìn)度條中左右移動(dòng);setStringPainted(boolean newValue):設(shè)置是否在進(jìn)度條中顯示完成的百分比。③當(dāng)程序中工作進(jìn)度改變時(shí),調(diào)用JProgressBar對(duì)象的setValue方法,當(dāng)進(jìn)度條的完成進(jìn)度發(fā)生改變時(shí),程序還可以調(diào)用進(jìn)度條對(duì)象的如下2個(gè)方法:double getPercentComplete返回進(jìn)度條的百分比,String getString()返回進(jìn)度條字符串的當(dāng)前值。
使用匿名內(nèi)部類來(lái)使用Timer,創(chuàng)建進(jìn)度條:
import?java.awt.FlowLayout;
import?java.util.Timer;
import?java.util.TimerTask;
import?javax.swing.JFrame;
import?javax.swing.JProgressBar;
public?class?TestProgressBar?{
JFrame?jframe?= new?JFrame("測(cè)試");
JProgressBar?bar?= new?JProgressBar(JProgressBar.HORIZONTAL);//水平的
public?void?init() {
jframe.setLayout(new?FlowLayout());
jframe.add(bar);bar.setStringPainted(true);// 繪制百分比
final?SimulateClass?target = new?SimulateClass(100);
new?Thread(target).start();
// 啟動(dòng)一條線程的方式來(lái)執(zhí)行一個(gè)耗時(shí)任務(wù)
bar.setMinimum(0);
bar.setMaximum(target.getAmount());
Timer?timer=new?Timer();
timer.schedule(new?TimerTask() {
@Override
public?void?run() {
bar.setValue(target.getCurrent());
System.out.println("完成了工作量的:"+target.getCurrent());}},?
1000, 2000);
//實(shí)際上,Java實(shí)時(shí)性很差,如果調(diào)用Timer的scheduleAtFixedRate方法,那么Timer會(huì)盡量讓Task執(zhí)行頻率保持在2秒一次,如果某一次延遲,Timer會(huì)記錄下這個(gè)延遲,并嘗試在下一個(gè)任務(wù)時(shí)彌補(bǔ)這個(gè)延遲。
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);jframe.pack();
jframe.setVisible(true);}
public?static?void?main(String[] args) {new?TestProgressBar().init();}}
class?SimulateClass?implements?Runnable {
private?volatile?int?current;
private?int?amount;
public?int?getCurrent() {
return?current;}
public?int?getAmount() {return?amount;}
public?SimulateClass(int?amount) {current?= 0;this.amount?= amount;}
@Override
public?void?run() {
while(current<amount){
try?{
Thread.sleep(150);}?
catch?(Exception?e) {
e.printStackTrace();}
current++;}}}
?
注:自定義的class?SimulateClass?implements?Runnable實(shí)現(xiàn)了Runnable接口,這是一個(gè)特殊的接口,實(shí)現(xiàn)該接口可以實(shí)現(xiàn)多線程功能。
?
創(chuàng)建進(jìn)度對(duì)話框:
ProgressMonitor的用法與ProgressBar的用法基本相似,只是ProgressMonitor可以直接創(chuàng)建一個(gè)進(jìn)度對(duì)話框,構(gòu)造器如下:ProgressMonitor(Component parentCom,Object message,String note,int min,int max):該構(gòu)造器中的parentCom參數(shù)用于設(shè)置該進(jìn)度對(duì)話框的父組件,message用于設(shè)置該進(jìn)度條對(duì)話框的描述信息,note用于設(shè)置該進(jìn)度條的提示文本,min和max用于設(shè)置對(duì)話框所包含進(jìn)度條的最小值和最大值。
final?ProgressMonitor?dialog=new?ProgressMonitor(null, "等待任務(wù)的完成...", "已完成:", 0, target.getAmount());
?
使用JTable和TableModel創(chuàng)建表格:
使用JTable創(chuàng)建表格非常容易,JTable可以把一個(gè)二維數(shù)據(jù)包裝成一個(gè)表格,數(shù)據(jù)既可以是二維數(shù)組,也可也是集合元素為Vector的對(duì)象,為了給表格的每一列指定列標(biāo)題,還需要傳入一個(gè)一維數(shù)據(jù)作為列標(biāo)題,一維數(shù)據(jù)既可以是一維數(shù)組,也可也是Vector對(duì)象。
JFrame?frame?= new?JFrame("測(cè)試表格");JTable?table;
Object[][] tableData?= { new?Object[] { "張三", 28, "男", "沒(méi)有列名嗎"?},
new?Object[] { "哈哈", 20, "女", "沒(méi)有列名嗎"?},new?Object[] { "么么噠", 22, "女", "沒(méi)有列名嗎"?},
new?Object[] { "lili", 28, "男", "沒(méi)有列名嗎"?},new?Object[] { "斯諾克", 30, "男", "沒(méi)有列名嗎"?}, };
Object[] columnTitle?= { "姓名", "年齡", "性別", "數(shù)據(jù)可以多,但是標(biāo)題不能多"?};
public?void?init() {
// 以二維數(shù)組和一維數(shù)組來(lái)創(chuàng)建一個(gè)JTable對(duì)象
table?= new?JTable(tableData, columnTitle);
// 將表放入JScrollPane中
frame.add(new?JScrollPane(table));
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);}
?
注:表頭只能少,不能多出一列,表頭少的僅僅顯示前面的數(shù)據(jù),而后面的數(shù)據(jù)將不能正常顯示。如果不把JTable放在JScrollPane中顯示,JTable默認(rèn)不會(huì)顯示列標(biāo)題。
?
使用JPasswordField:JPasswordField是JTextField的一個(gè)子類,當(dāng)用戶向JPasswordField輸入內(nèi)容時(shí),JPasswordField會(huì)顯示星號(hào)或者黑點(diǎn)來(lái)代替用戶輸入的字符串。除此之外,JPasswordField重寫了JTextComponent的getText()方法,并且不再推薦使用getText()方法返回字符串密碼框的字符串,因?yàn)?/span>getText()方法返回的字符串會(huì)一直停留在虛擬機(jī)中,直到垃圾回收,這可能導(dǎo)致一些安全隱患,所以JPasswordField提供了一個(gè)getPassword()方法,有更好的機(jī)制。
總結(jié)
以上是生活随笔為你收集整理的《疯狂Java讲义》读书笔记(七):Swing编程的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 日文つ的浊音怎样打
- 下一篇: java美元兑换,(Java实现) 美元