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