小蟲的天地

          Java SE | Java EE | NetBeans | Open Source World | Groovy | Grails | JavaScript | jQuery
          隨筆 - 10, 文章 - 0, 評(píng)論 - 225, 引用 - 0
          數(shù)據(jù)加載中……

          NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)

            上一篇博客介紹了NetBeans Java代碼編輯器,這一篇將介紹用NetBeans 開發(fā)基于Swing Application Framework (JSR 296) 的程序,Swing一直以來是飽受爭(zhēng)議的GUI庫(kù),特別是SWT與Swing的爭(zhēng)論,分別體現(xiàn)在了Eclipse與NetBeans的爭(zhēng)論上。

          在此,我無(wú)心討論SWT與Swing孰優(yōu)孰劣,你要是真的對(duì)這個(gè)感興趣,可以到williamchen博客里的Swing專欄看看,該專欄博主已經(jīng)對(duì)SWT和Swing分析得非常透徹:

          http://blog.sina.com.cn/swingjava

          Swing在1998年末作為Java 2的一部分發(fā)布了1.0,但是當(dāng)時(shí)發(fā)布的版本不管是性能還是外觀都足以令人失望。雖然當(dāng)時(shí)Swing小組的工程師使用了最前沿的技術(shù),如設(shè)計(jì)模式,但是時(shí)的Swing小組已經(jīng)被性能、本地化外觀一致性問題以及許多錯(cuò)誤深深陷住了,這些問題幾乎把整個(gè)項(xiàng)目拖垮。

          幸虧,Swing小組堅(jiān)持了下來,要不然今天我們就不會(huì)看到像NetBeans這樣的IDE了。自從JDK1.5后,Java的性能已經(jīng)有了巨大的改觀,現(xiàn)在1.6下,Swing的性能已經(jīng)完全不是問題。

          那么Swing的優(yōu)勢(shì)有那些呢?

          l         優(yōu)秀的設(shè)計(jì),正如剛才所說的,Swing從九十年代中期開始設(shè)計(jì)就用了當(dāng)時(shí)最前沿的開發(fā)方法學(xué)??梢哉fSwing在當(dāng)今各種GUI庫(kù)中,設(shè)計(jì)是非常優(yōu)雅的。

          l         輕量級(jí)

          l         官方的存在JRE中,發(fā)布程序不需要像SWT那樣還要捆綁自己的GUI庫(kù)

          l         真正的平臺(tái)獨(dú)立,Swing組件由Java 2D繪制

          l         輕易的更改面觀模式

          l         強(qiáng)大的IDE支持,現(xiàn)在用NetBeans做界面,幾乎不用你敲一行代碼。

          l         Swing現(xiàn)在又多了一個(gè)殺手級(jí)框架Swing Application Framework (JSR 296)

          下面開始我的第二篇Java博客

          NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)

          Swing Application Framework簡(jiǎn)介

          Swing Application Framework(以下簡(jiǎn)稱SAF)致力于簡(jiǎn)化Swing應(yīng)用程序的開發(fā),框架定義了對(duì)大多數(shù)桌面應(yīng)用程序的共有的基礎(chǔ)設(shè)施:

          l         應(yīng)用程序生命周期管理,特別是GUI的啟動(dòng)和關(guān)閉。

          l         對(duì)資源管理和載入的支持,這些資源是字符串,格式化的消息,圖像,顏色,字體以及桌面應(yīng)用程序共有的其他類型的資源。

          l         對(duì)動(dòng)作定義,管理和綁定的支持,其中包含了異步運(yùn)行的動(dòng)作(在后臺(tái)運(yùn)行)。

          l         持久化會(huì)話狀態(tài):支持自動(dòng)地,有選擇地保存應(yīng)用程序一次運(yùn)行到下次運(yùn)行的GUI狀態(tài)。比如頂層的窗口幾何位置。


          用NetBeans開發(fā)SAF

          SAF已經(jīng)定義了大多數(shù)桌面應(yīng)用程序的基礎(chǔ)設(shè)施,我們可以更方便的開發(fā)Swing程序了,但是手動(dòng)編碼開發(fā)GUI還是讓很多人抓狂。能不能提供一個(gè)像VB一樣的環(huán)境,讓程序員更加專注于功能的實(shí)現(xiàn)而不是界面的實(shí)現(xiàn)?答案是肯定的,NetBeans 6.0就為開發(fā)SAF提供了這樣一個(gè)環(huán)境,甚至比VB還要做得更好。

          那么到底NetBeans6.0SAF提供了什么樣的優(yōu)勢(shì)呢?

          l         生成基礎(chǔ)框架,不必每次新創(chuàng)建一個(gè)程序的時(shí)候都從頭開始

          l         唾手可得的國(guó)際化支持,在Netbeans里對(duì)SAF程序國(guó)際化,簡(jiǎn)單得不能再簡(jiǎn)單

          l         擁有Swing世界里的明星級(jí)UI設(shè)計(jì)工具模塊Matisse提供的免費(fèi)大餐

          l         NetBeans開發(fā)SAF,意味著你還可以使用Beans BindingJSR 295),數(shù)據(jù)綁定將問題變得更簡(jiǎn)單



          開始之前

          用NetBeans 6.0開發(fā)基于SAF,其實(shí)不用明白SAF,主要遵循一定的開發(fā)原則也可以開發(fā)出穩(wěn)定高效的SAF程序來

          但是為了你更深入的理解SAF,強(qiáng)烈建議看下面的文章

          l         Using the Swing Application Framework (JSR 296)

          http://java.sun.com/developer/technicalArticles/javase/swingappfr/

          l         Swing應(yīng)用程序框架(Swing Application Framework)API緒論(JSR-296)之一

          http://www.javaeye.com/topic/81326

          Swing應(yīng)用程序框架(Swing Application Framework)API緒論(JSR-296)之二

          http://www.javaeye.com/topic/81327

          l
             如果你有更多的時(shí)間,那么請(qǐng)看下面網(wǎng)址有關(guān)Swing的部分

          http://blog.sina.com.cn/swingjava



          開發(fā)環(huán)境準(zhǔn)備

          JDK1.6或以上版本

          NetBeans6.0或以上版本

          提示:Netbeans 網(wǎng)站上提供有六種捆綁包下載

          l         Web & Java EE

          l         Mobility

          l         Java SE

          l         Ruby

          l         C/C++

          l         All

          開發(fā)Swing Application Framework只需要Java SE下載包就行了

          這樣能真正發(fā)揮NetBeans的性能!



          創(chuàng)建項(xiàng)目

          我們新建一個(gè)項(xiàng)目,從Java種類里選擇 Java Desktop Application,如下圖

          點(diǎn)擊下一步,接著輸入項(xiàng)目名稱、項(xiàng)目存放地址和程序的主類

          在Choose Application Shell里面我們選擇Basic Application,單擊完成

          提示:我們?nèi)绻麆?chuàng)建基于Swing的數(shù)據(jù)庫(kù)程序,那么選擇BataBase Application將提供極大的便利。但是在這里我只是介紹Basic Application,也就是現(xiàn)在我們用SAF開發(fā)普通的桌面程序。



          生成的項(xiàng)目目錄結(jié)構(gòu)

          l         META-INF/services目錄

          該目錄一般存在一個(gè)JAR包里面

          META-INF/services目錄涉及一個(gè)模式:服務(wù)提供者模式

          引入該模式一般是為了程序松散耦合,而且是IoC(控制反轉(zhuǎn))的另一種實(shí)現(xiàn)方式

          服務(wù)提供者模式一般有兩個(gè)角色

          ²        服務(wù) :一般為一個(gè)抽象類

          ²        服務(wù)提供者 :抽象類的實(shí)現(xiàn)

          存在META-INF/services目錄的JAR包一般為一個(gè)“服務(wù)提供者”

          用NetBeans開發(fā)中小型程序不需要服務(wù)提供者概念,如果你要深入理解

          可以Baidu或Google一下META-INF/services

          l         foo

          foo包是我們創(chuàng)建程序的主類foo.FooApp時(shí),NetBeans自動(dòng)為我們生成的,

          我們來看看NetBeans為我們生成了什么基礎(chǔ)框架類:

          1、FooApp.java

          public class FooApp extends SingleFrameApplication {

              

          /**

               * 在啟動(dòng)的時(shí)候創(chuàng)建和顯示程序的主框架

               
          */


              @Override 
          protected void startup() {

                  show(
          new FooView(this));

              }


              
          /**

               *這個(gè)方法是用相應(yīng)的資源注入到特定的Window來初始化程序

               *因?yàn)槲覀冇肗etBeansk開發(fā),所以相應(yīng)的資源是通過Gui生成器來完成

               *也就是不用我們手動(dòng)編寫代碼

               *所以這個(gè)方法不是必須的

               
          */


              @Override 
          protected void configureWindow(java.awt.Window root) {

              }


              
          /**

               * 一個(gè)方便的靜態(tài)獲取器,用來獲取FooApp類的實(shí)例

               
          */


              
          public static FooApp getApplication() {

                  
          return Application.getInstance(FooApp.class);

              }


              
          /**

               * 程序的運(yùn)行入口點(diǎn)

               
          */


              
          public static void main(String[] args) {

                  launch(FooApp.
          class, args);

              }


          }

          FooApp.java里面的代碼是NetBean為我們生成的,開發(fā)簡(jiǎn)單的程序這里基本上不需要更改什么。


          2
          、FooAboutBox.java

          每個(gè)程序都應(yīng)該有一個(gè)關(guān)于界面,Netbeans為我們生成了關(guān)于的模板

          修改相應(yīng)文字就可以了,當(dāng)然也可以自己做個(gè)About界面


          3
          、FooView.java

          FooView.java是程序View部分的關(guān)鍵,由于生成的代碼比較多

          在解釋代碼之前,我先看看Design部分

          NetBenas給我們生成的框架非常簡(jiǎn)單明了

          需要注意的是圖上標(biāo)識(shí)的兩個(gè)地方

           標(biāo)有1的地區(qū)為消息地區(qū),我們的程序完成任務(wù)后,在這里提示消息

           標(biāo)有2的地區(qū)為任務(wù)進(jìn)度條,程序執(zhí)行任務(wù)時(shí)在這里現(xiàn)實(shí)任務(wù)進(jìn)度,當(dāng)然任務(wù)有確定模式和不確定模式,不確定模式的進(jìn)度條持續(xù)地顯示動(dòng)畫來表示正進(jìn)行的操作。

          接下來我們看看FooView.java的構(gòu)造器的代碼:

              public FooView(SingleFrameApplication app) {

                  
          super(app);

                  initComponents();

                  ResourceMap resourceMap 
          = getResourceMap();

                  
          int messageTimeout = resourceMap.getInteger("StatusBar.messageTimeout");

                  messageTimer 
          = new Timer(messageTimeout, new ActionListener() {

                      
          public void actionPerformed(ActionEvent e) {

                          statusMessageLabel.setText(
          "");

                      }


                  }
          );

                  messageTimer.setRepeats(
          false);

                  
          int busyAnimationRate = resourceMap.getInteger("StatusBar.busyAnimationRate");

                  
          for (int i = 0; i < busyIcons.length; i++{

                      busyIcons[i] 
          = resourceMap.getIcon("StatusBar.busyIcons[" + i + "]");

                  }


                  busyIconTimer 
          = new Timer(busyAnimationRate, new ActionListener() {

                      
          public void actionPerformed(ActionEvent e) {

                          busyIconIndex 
          = (busyIconIndex + 1% busyIcons.length;

                          statusAnimationLabel.setIcon(busyIcons[busyIconIndex]);

                      }


                  }
          );

                  idleIcon 
          = resourceMap.getIcon("StatusBar.idleIcon");

                  statusAnimationLabel.setIcon(idleIcon);

                  progressBar.setVisible(
          false);

                  
          // connecting action tasks to status bar via TaskMonitor

                  TaskMonitor taskMonitor 
          = new TaskMonitor(getApplication().getContext());

                  taskMonitor.addPropertyChangeListener(

                          
          new java.beans.PropertyChangeListener() {

                      
          public void propertyChange(java.beans.PropertyChangeEvent evt) {

                          String propertyName 
          = evt.getPropertyName();

                          
          if ("started".equals(propertyName)) {

                              
          if (!busyIconTimer.isRunning()) {

                                  statusAnimationLabel.setIcon(busyIcons[
          0]);

                                  busyIconIndex 
          = 0;

                                  busyIconTimer.start();

                              }


                              progressBar.setVisible(
          true);

                              progressBar.setIndeterminate(
          true);

                          }
           else if ("done".equals(propertyName)) {

                              busyIconTimer.stop();

                              statusAnimationLabel.setIcon(idleIcon);

                              progressBar.setVisible(
          false);

                              progressBar.setValue(
          0);

                          }
           else if ("message".equals(propertyName)) {

                              String text 
          = (String)(evt.getNewValue());

                              statusMessageLabel.setText((text 
          == null? "" : text);

                              messageTimer.restart();

                          }
           else if ("progress".equals(propertyName)) {

                              
          int value = (Integer)(evt.getNewValue());

                              progressBar.setVisible(
          true);

                              progressBar.setIndeterminate(
          false);

                              progressBar.setValue(value);

                          }


                      }


                  }
          );

          }

          一大段代碼,看起來是不是眼花繚亂啊,其實(shí)這么一大斷代碼是IDE給我們生成的用來初始發(fā)剛才所示的兩個(gè)區(qū)域的消息區(qū)和進(jìn)度條區(qū)域的。

          也就是初始化消息區(qū)域和進(jìn)度條區(qū)域,如果不想自定義消息現(xiàn)實(shí)和任務(wù)進(jìn)度條的實(shí)現(xiàn)方式,上面一大段代碼大可不必理會(huì)。

          我們?cè)賮砜匆欢未a:

              @Action

              
          public void showAboutBox() {

                  
          if (aboutBox == null{

                      JFrame mainFrame 
          = FooApp.getApplication().getMainFrame();

                      aboutBox 
          = new FooAboutBox(mainFrame);

                      aboutBox.setLocationRelativeTo(mainFrame);

                  }


                  FooApp.getApplication().show(aboutBox);

          }

          看到方法名我們就知道,這個(gè)是用來實(shí)現(xiàn)關(guān)于界面的

          我們運(yùn)行一下程序,在點(diǎn)擊菜單欄里面的 Help > About..

          結(jié)果,關(guān)于界面跳了出來。

          看到這里你也許會(huì)驚訝,因?yàn)榘凑諅鹘y(tǒng)的方法,相應(yīng)的菜單應(yīng)該有相應(yīng)的ActionListener事情監(jiān)聽器才能發(fā)生事件啊!

          別著急,你看showAboutBox()方法前不是有一個(gè)注解: @Action

          這個(gè)注解涉及到SAF對(duì)動(dòng)作的定義,我們后面將詳細(xì)講解

          l         foo.resources、foo.resources.busyicons包

          foo.resources、foo.resources.busyicons包是用來存放程序的圖像、文字等資源的地方

          后面講到程序的國(guó)際化的時(shí)候再作介紹。

           

           

          忘掉ActionListener事件監(jiān)聽器,擁抱@Action

          上面我們已經(jīng)提到,沒有相應(yīng)的ActionListener事件監(jiān)聽器,點(diǎn)擊菜單欄里面的 Help > About..也照樣能觸發(fā)事件,這是怎么回事?

          原來是SAF框架對(duì)有@Action注釋的方法進(jìn)行了管理。

          既然用原來的ActionListener已經(jīng)處理得非常好,為什么SAF專家組的人還弄個(gè)@Action,這不是沒事找事干嗎?呵呵,下面我們通過幾個(gè)例子來說明引入@Action的好處

          l         制作環(huán)境相關(guān)的按鈕

          我們經(jīng)常遇到這樣的按鈕或菜單,一般情況下它是不可用的,如上圖畫圈的三個(gè)按鈕,要等一定的條件他們自動(dòng)啟用。

          我舉例用@Action做這樣的按鈕看看,不用擔(dān)心,不必寫多少代碼,IDE幫我們完成了大部分的工作

          我們要做的功能如下

          點(diǎn)擊選擇CheckBox選項(xiàng)后,按鈕自動(dòng)開啟,取消選中后按鈕變灰色,不可用。

          在右邊的Palette屬性面板中拖出我們需要的兩個(gè)組件到程序主界面,并修改Text文字

          右鍵點(diǎn)擊按鈕,選擇 Set Action…

          在跳出來對(duì)話框中,在Action 選擇框中選中Create New Action

          接下填寫按鈕的相關(guān)信息,這里我做一下簡(jiǎn)單的說明

          Action’s Class :動(dòng)作方法存放在那個(gè)類中

          Action’s Method:動(dòng)作方法的名稱,比如上面提到的跳出關(guān)于對(duì)話框的方法showAboutBox()

          Background Task選項(xiàng):這個(gè)暫時(shí)不理它,后面將講到

          Attributes 1、Basic標(biāo)簽 設(shè)置按鈕的顯示文字、快捷鍵、按鈕圖像。

          2、Advanced標(biāo)簽可要注意了,因?yàn)檫@個(gè)和我們現(xiàn)在要做的例子關(guān)系非常大,我們?cè)?/span>Advanced標(biāo)簽里的Enabled Preproty 寫上 hasSelect(名字可以自己寫),如下面第二個(gè)圖

                      

           

          單擊OK,馬上看到IDE為我們生成的代碼

           

          這樣我們就可以通過setHasSelect()方法來設(shè)置按鈕的可用性,setHasSelect(ture) 時(shí)按鈕開啟,setHasSelect(false)時(shí)按鈕不可用。

          接下來選擇CheckBox組件,單擊右鍵,再選擇下圖所示

           

          出來代碼中寫上一行代碼:

           

          setHasSelect( ((JCheckBox)evt.getSource()).isSelected());

           

          最后是這樣子的

           

          private void jCheckBox1ItemStateChanged(java.awt.event.ItemEvent evt) {

              setHasSelect( ((JCheckBox)evt.getSource()).isSelected());

          }

           

          自此環(huán)境相關(guān)的按鈕就做完了,我們可以運(yùn)行代碼試試。

          從上面的例子中我們看到,做這個(gè)例子真正只寫了一行代碼:

           

          setHasSelect( ((JCheckBox)evt.getSource()).isSelected());

           

          其它都是通過IDE生成的,多虧IDESAFAction我們才能如此高效的制作程序。

          l         菜單和按鈕關(guān)聯(lián)

          菜單和按鈕經(jīng)常表現(xiàn)為同一個(gè)行為,我們當(dāng)然可以各自實(shí)現(xiàn)它,但是這樣就產(chǎn)生了冗余

          編寫程序最總要的一點(diǎn)就是不要重復(fù)代碼。在Design模式下右鍵單擊相應(yīng)的菜單,在Set Action…操作里面選擇相應(yīng)Action

          這樣菜單和按鈕就關(guān)聯(lián)起來了,該菜單和按鈕行為相同,SAF如此簡(jiǎn)單的為我們完成了任務(wù)。

          這又是Action解決了一大問題

          l         Background Task

          剛才在制作環(huán)境相關(guān)的按鈕時(shí),我們忽略一個(gè)選項(xiàng)

          現(xiàn)在我們來介紹這個(gè)非常重要的特性

          以前人們不斷抱怨Swing是如何慢,其實(shí)JRE1.5后,特別是1.6后Swing性能已經(jīng)完全不是問題,問題是開發(fā)Swing的程序員沒有處理好Swing的線程問題,比如本該在后臺(tái)運(yùn)行的任務(wù)卻直接寫在Swing中,造成Swing程序相應(yīng)緩慢。

          在以前你要非常熟練Swing和小心才能寫出高質(zhì)量的Swing程序來,但是現(xiàn)在你利用SAF提供的框架支持,處理后臺(tái)任務(wù)變得非常容易。

          我們 Set Action 的時(shí)候把Background Task選項(xiàng)選中,最后看一下IDE給我們生成了什么代碼:

          原來的代碼:

              @Action(enabledProperty = "hasSelect")

              
          public Task actionMethodName() {

             }

          Background Task選項(xiàng)選中后為如下代碼:

              @Action(enabledProperty = "hasSelect")

              
          public Task actionMethodName() {

                  
          return new ActionMethodNameTask(getApplication());

              }


              
          private class ActionMethodNameTask extends 

                      org.jdesktop.application.Task
          <Object, Void> {

                  ActionMethodNameTask(org.jdesktop.application.Application app) 
          {

                      
          // Runs on the EDT. Copy GUI state that

                      
          // doInBackground() depends on from parameters

                      
          // to ActionMethodNameTask fields, here.

                      
          super(app);

                  }


                  @Override 
          protected Object doInBackground() {

                      
          // Your Task's code here. This method runs

                      
          // on a background thread, so don't reference

                      
          // the Swing GUI from here.

                      
          return null// return your result

                  }


                  @Override 
          protected void succeeded(Object result) {

                      
          // Runs on the EDT. Update the GUI based on

                      
          // the result computed by doInBackground().

                  }


          }

          可以看到,actionMethodName()方法里運(yùn)行的代碼將在一個(gè)新線程中運(yùn)行

          如果你要徹底明白上面的代碼和EDT是什么概念,請(qǐng)瀏覽下面的博客地址

          http://blog.sina.com.cn/swingjava中有關(guān)Swing部分。

          如果您懶得瀏覽,那么請(qǐng)遵循下面的建議

          1、在ActionMethodNameTask構(gòu)造器中

          代碼運(yùn)行在EDT(事件分派進(jìn)程)中,在這里復(fù)制doInBackground() 方法中所需要的GUI 的狀態(tài)或參數(shù)到ActionMethodNameTask的成員變量中。

              2、doInBackground()方法中,不要存放處理GUI界面的代碼,該方法返回的值將自動(dòng)傳到后面succeeded(Object Result)中

              3、succeeded()運(yùn)行在EDT中,任務(wù)成功的執(zhí)行后才執(zhí)行該方法,該方法主要收集doInBackground()方法運(yùn)行后的結(jié)果以用來更新GUI程序。

          我們做一下試驗(yàn),為ActionMethodNameTask增加一些代碼:

              private class ActionMethodNameTask extends 

                      org.jdesktop.application.Task
          <Object, Void> {

                  ActionMethodNameTask(org.jdesktop.application.Application app) 
          {

                      
          super(app);

                  }


                  @Override 
          protected Object doInBackground() {

                      
          for(int i=0;i<1000000;i++){

                          System.out.println(i);

                      }


                      
          return null

                  }


                  @Override 
          protected void succeeded(Object result) {

                      setMessage(
          "運(yùn)行成功");

                  }


              }

          運(yùn)行程序后點(diǎn)擊按鈕

          任務(wù)開始:


          任務(wù)結(jié)束:

          注意提示信息只顯示一定時(shí)間,這個(gè)時(shí)間可以自己設(shè)定,一定時(shí)間后信息自動(dòng)消失。

          l         制作阻塞按鈕

          我經(jīng)常要做具有阻塞功能的按鈕,比如我們按一下按鈕,就跳出如上對(duì)話框,程序在后臺(tái)運(yùn)行任務(wù),但是我們不能進(jìn)行其它操作,除非我們點(diǎn)擊取消按鈕。

          制作這樣的按鈕,其實(shí)非常簡(jiǎn)單:

          在Set Action...進(jìn)行如下設(shè)置就可以了

           

          Blocking Type 可以選擇NONE,ACTION,COMPONENT,WINDOW,APPLICATION指定阻塞的范圍空間,你可以自己嘗試一下,效果是怎樣的。

          從上面幾個(gè)小例子可以看到引入@Action巨大好處了吧。



          國(guó)際化支持

          正如開始所說的,SAF本身就很好的支持了國(guó)際化,再加上NetBeans輔助,國(guó)際化簡(jiǎn)直易如反掌。

          我們知道一些企業(yè)框架比如StructsJSF是通過后綴名為properties的文件保存相關(guān)資源的。

          SAF也是,我們看看IDE為我們生成的properties文件

          從上圖可以看出,

          FooApp.java

          FooAboutBox.java

          FooView.java

           

          這三個(gè)類在foo.resources包分別對(duì)應(yīng)有后綴名為properties的文件

          FooApp. properties

          FooAboutBox. properties

          FooView. Properties

           

          也就是說,類里面用到文字資源,圖像資源集中放到了一起。這樣國(guó)際化就相當(dāng)簡(jiǎn)單了

          這時(shí)也許你會(huì)說,一開始就寫properties的文件,豈不是很麻煩?

          別忘了,我們NetBeans的支持,做這個(gè)工作幾乎不費(fèi)你任何力氣

          在可視化編輯頁(yè)面,我直接修改相應(yīng)文字,IDE會(huì)自動(dòng)為我們把相應(yīng)的文字保存到對(duì)應(yīng)的properties的文件中。

          根本不用自己手動(dòng)敲寫下面的文字

          jCheckBox1.text=選中按鈕開啟

           



          尾聲

          關(guān)于用NetBeans開發(fā)Swing Application Framework程序其實(shí)還有很多我沒有說清楚,有些也很難說清楚,關(guān)鍵還是要自己親身試驗(yàn)一下,正如大牛們所說的“理論看不懂就去實(shí)踐,實(shí)踐不懂就去看理論”。

          本文僅起到入門介紹的作用。開發(fā)需要的SAF JavaDoc文檔可以下面所示查看:



          為了你更好的理解,我用
          SAF做一個(gè)端口掃描程序,這個(gè)程序很不完善,僅做演示:


          點(diǎn)擊這里下載源代碼:
          PortScan.rar
          (提示:NetBeans6.X打開項(xiàng)目目錄即可)



          SAF
          做的更完整的程序:

          l         mp3在線搜索工具


          你可以到作者博客查看更詳細(xì)信息:

          http://www.aygfsteel.com/huliqing/archive/2008/03/26/188817.html

          l         單詞Mp3隨身寶DIY


          本人的英語(yǔ)成績(jī)一直不是很好,特別是詞匯量很低
          ,很多單詞不會(huì)發(fā)音。

          所以我就有個(gè)想法,能不能把自己想要背記的單詞做成MP3的形式,單詞和單詞的解釋放到對(duì)應(yīng).lrc文件中,隨意挑選單詞,

          制作成帶同步歌詞(LRC文件)的MP3文件,這樣在MP3機(jī)上就能邊聽單詞邊同步看單詞及其解釋,單詞先后次序、間隔多長(zhǎng),

          可以相應(yīng)自由地調(diào)整,讓我們的MP3機(jī)變成英語(yǔ)學(xué)習(xí)機(jī)!我通過網(wǎng)絡(luò)尋找這樣的軟件。

          但是找了好久就是找不到合適的軟件,只是有一個(gè)《我愛背單詞》的軟件有類似這樣的一個(gè)功能,但是該軟件是閉源收費(fèi)軟件,

          免費(fèi)版的語(yǔ)音是合成的,效果非常差。求人不如求自己,于是產(chǎn)生制作這個(gè)程序的想法。

          這個(gè)程序原本就是想開源的,但是我拿去參加學(xué)校的電腦作品賽了,比賽的作品先前不能發(fā)布。所以暫時(shí)不發(fā)布程序和源代碼,等比賽結(jié)束再上傳程序和源代碼。這個(gè)可能要一段時(shí)間,請(qǐng)大家耐心等待消息。

          l         NetBeans開發(fā)但是沒有用SAFYOYOPlayerMp3播放器


          詳細(xì)信息請(qǐng)看作者的博客:

          http://www.aygfsteel.com/hadeslee/archive/2007/12/31/171678.html

          通過上面幾個(gè)程序可以體現(xiàn)出NetBeans的強(qiáng)大特性來(不僅僅是做桌面程序哦)!SAF框架加上NetBeans,我們可以專注程序的功能而不是程序的基礎(chǔ)實(shí)施上,而且即使是初學(xué)者也可以編寫出高性能的Swing程序來。我相信隨著越來越多的人了解SAFNetBeans,后面會(huì)不斷涌現(xiàn)出新的Swing桌面程序來,讓我們拭目以待吧!

          由于水平有限,文中有些術(shù)語(yǔ)解釋可能不準(zhǔn)確,歡迎批評(píng)指正?。ㄟ@也是我寫博客的原因,通過他人認(rèn)識(shí)自己的不足)

          版權(quán)聲明:

          本文由令狐蟲原創(chuàng),歡迎轉(zhuǎn)載,轉(zhuǎn)載請(qǐng)保留博客地址:

          http://www.aygfsteel.com/linghuchong/

          posted on 2008-03-27 11:05 令狐蟲@qq.com 閱讀(10643) 評(píng)論(44)  編輯  收藏 所屬分類: NetBeans

          評(píng)論

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          又看到了博主的新聞?wù)?,很是受用,加油啊博主!我現(xiàn)在正在學(xué)習(xí)java的swing編程,希望有機(jī)會(huì)和博主交流交流!
          2008-03-27 11:15 | 日月雨林

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          呵呵,大家共同學(xué)習(xí)進(jìn)步!~
          2008-03-27 11:20 | 令狐蟲

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          博主對(duì)Netbeans的了解,值得學(xué)習(xí),我現(xiàn)在也在用NetBeans學(xué)習(xí)java,希望有機(jī)會(huì)能和博主 交流交流!
          2008-03-27 12:14 | 日月雨林

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          很不錯(cuò)的文章,我也是想學(xué)習(xí)Swing,但是現(xiàn)在工作太忙,只能晚上加班回家搞半個(gè)小時(shí),對(duì)著Netbeans一頓狂托....

          希望樓主將這個(gè)寫成一個(gè)序列,介紹如何使用NetBeans開發(fā)Swing程序.
          2008-03-27 13:16 | hcom

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)[未登錄]  回復(fù)  更多評(píng)論   

          嗯,的確netbeans 開發(fā)swing 不錯(cuò),可惜還有些問題,比如:
          1。netbeans自動(dòng)生成的代碼無(wú)法修改
          2。弄好的界面下次打開的時(shí)候,有時(shí)候控件會(huì)縮成一條,無(wú)法再次拖拉修改

          雖然總會(huì)有些問題,但不能掩飾俺對(duì)netbeans的喜歡
          2008-03-27 14:07 | fatbear

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @日月雨林
          隨時(shí)歡迎交流

          @hcom
          如果有時(shí)間的話,我正打算這么做

          @fatbear
          其實(shí)你那兩個(gè)問題都不是問題
          只是大家對(duì)NetBeans不夠了解而已
          NetBeans強(qiáng)大卻不失靈活
          下一篇文章我打算對(duì)你這兩個(gè)問題做個(gè)介紹。
          2008-03-27 14:17 | 令狐蟲

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @令狐蟲
          netbeans剛用不久,期待你的下一篇文章

          2008-03-27 17:29 | fatbear

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          很不錯(cuò),今年一定研究一下:)
          2008-03-27 17:42 | Masen

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          博主的文章很不錯(cuò)哦!
          eclipse與netbeans這兩個(gè)工具我都有用過段時(shí)間,因?yàn)橄矚g上JSF后我才使用netbeans,在netbeans5.5的時(shí)候還是有些不適應(yīng),而且還有不少bug,所以一直追蹤著netbeans的版本更新, 現(xiàn)在感覺使用netbeans已經(jīng)非常順手舒服。當(dāng)然eclipse也非常不錯(cuò),但我還是比較喜歡netbeans的便利,不喜歡到處去找插件。
          2008-03-27 19:07 | huliqing

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          是呀 感謝分享 以后看來可視化和基于標(biāo)注開發(fā)是大勢(shì)所趨啊 Eclipse RCP 這方面遠(yuǎn)遠(yuǎn)落后
          2008-03-27 22:02 | BeanSoft

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          支持java,支持swing
          2008-03-28 00:12 | zht

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)[未登錄]  回復(fù)  更多評(píng)論   

          樓主的文章給了我很大的幫助,期待你以后的文章。
          2008-05-08 09:51 | writegull

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)[未登錄]  回復(fù)  更多評(píng)論   

          我跟著lz的教程進(jìn)步中。。。寫一篇我學(xué)一篇。
          2008-05-11 11:55 | bk

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)[未登錄]  回復(fù)  更多評(píng)論   

          6.1版本突然沒有了“Set Action”菜單了,奇怪ing
          2008-05-21 12:08 | bk

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)[未登錄]  回復(fù)  更多評(píng)論   

          弄錯(cuò)了,只有在DesktopApplication程序中才有這個(gè)。java Application為什么沒有呢?奇怪
          2008-05-21 12:16 | bk

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          您好,想請(qǐng)教您一個(gè)問題

          用netbeansRCP生成的程序,標(biāo)題欄的咖啡圖標(biāo)要怎么改掉?

          我在窗口類的構(gòu)造器里面試著加了
          ImageIcon image = new ImageIcon("icon.ico");
          this.getFrame().setIconImage(image.getImage());

          this.getFrame().setIconImage((Toolkit.getDefaultToolkit().createImage("icon.ico")));

          都沒辦法改掉那個(gè)咖啡圖標(biāo)
          2008-05-29 10:26 | fcy

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @zht
          @writegull
          @bk
          感謝各位的支持!
          最近由于時(shí)間忙,抽不出時(shí)間來寫新教程,等忙過這段時(shí)間后
          我將陸續(xù)的介紹NetBeans其它方面的內(nèi)容!

          @fcy
          我以前軟件工程的課程設(shè)計(jì)就是用NetBeans RCP做的
          那時(shí)標(biāo)題欄不是你所說的咖啡圖標(biāo),而是方塊圖標(biāo)
          不知道現(xiàn)在是不是改為你所說的咖啡圖標(biāo)

          不過要修改這個(gè)圖標(biāo)很簡(jiǎn)單
          有兩種方法
          方法一:
          修改套件的的 Improtant Files->Project Properties文件
          app.icon=圖片地址(類路徑地址)

          方法二:
          右鍵點(diǎn)擊套件選擇Properties
          在Build選項(xiàng)里面選擇你自己的圖標(biāo)地址
          NetBeans會(huì)自動(dòng)把這個(gè)圖標(biāo)保存到branding/core/core.jar/org/netbeans/core/startup/里面
          不用手動(dòng)修改
          2008-05-29 13:04 | 令狐蟲@qq.com

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          剛才試了下,以上兩種方法,當(dāng)新建的項(xiàng)目為NetBeans Modules時(shí)才可以使用(標(biāo)題欄上的圖標(biāo)的確是方塊圖標(biāo))


          新建Java Desktop Application(就是按文章上說的基于SAF,這時(shí)候標(biāo)題欄上就是咖啡圖標(biāo)了),就沒辦法使用上面說的2種辦法了..還有其它的辦法可以更改標(biāo)題欄上的圖標(biāo)嗎?
          2008-05-29 15:42 | fcy

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @fcy
          原來你是說用基于SAF的圖標(biāo)啊

          你可以試一下在窗口類的構(gòu)造器寫下面這樣的代碼:
          getFrame().setIconImage(new ImageIcon(getClass().getResource("地址")).getImage());

          地址的形式如下:
          /desktopapplication/resources/ico.png
          ico.png存放在desktopapplication.resources包中
          2008-05-29 17:26 | 令狐蟲@qq.com

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @令狐蟲@qq.com

          使用this.getFrame().setIconImage(new ImageIcon(getClass().getResource("resources/icon.png")).getImage());
          可以改標(biāo)題欄圖標(biāo)了^_^

          謝謝了^_^


          ImageIcon image = new ImageIcon("resources/icon.png");
          this.getFrame().setIconImage(image.getImage());
          我原來用上面這種寫法怎么就改不了呢?一個(gè)功能啊?


          2008-05-29 23:32 | fcy

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @fcy
          只是ImageIcon的構(gòu)造參數(shù)不一樣而已
          getClass().getResource("resources/icon.png")獲取的是resources/icon.png的類路徑URL,一般圖片放在JAR包里面
          都應(yīng)該用這種方法



          2008-05-30 09:17 | 令狐蟲@qq.com

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          原來是這樣...明白了..謝謝了^_^
          2008-05-30 14:30 | fcy

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          不知道博主有沒有碰到下面的問題
          http://www.javaeye.com/problems/370
          請(qǐng)看鏈接內(nèi)容
          2008-06-07 15:16 | pp21

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @pp21
          很抱歉,你遇到的情況我沒有遇到過!
          你的問題也沒有說清楚,我沒有辦法去試驗(yàn)!
          2008-06-07 22:00 | 令狐蟲@qq.com

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          當(dāng)你寫過幾個(gè)SWING 的應(yīng)用程序,會(huì)發(fā)現(xiàn)matisse 純屬意淫。


          2008-06-18 11:55 | 管華

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          這個(gè)玩意只能用來教學(xué),給學(xué)生演示,學(xué)生看完之后會(huì)肯定會(huì)說:好強(qiáng)大。

          他的致命缺點(diǎn)是生成的代碼不能改,每個(gè)UI類會(huì)有個(gè)form文件,netbeans加載時(shí)首先打開的form文件,這個(gè)文件是XML格式的,本身也是天書,就算你把代碼改了,netbeans同樣會(huì)以XML文件里面的信息為主再把代碼更新。

          不改的代碼是可能的,往往界面有很多自定義的控件,包括日歷,一些自己業(yè)務(wù)上的component,比如某個(gè)設(shè)備樹等等。

          不可否認(rèn)就像SUN自己的說的的一樣,MATTISSE是當(dāng)前世界上無(wú)與倫比的可視化拖拽工具,也僅此而已。

          2008-06-18 12:06 | 管華

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @管華
          呵呵!這位兄弟對(duì)MATTISSE有很大的意見啊
          Swing Application Framework (JSR 296) 本來就是針對(duì)中小型程序的
          我相信沒有人會(huì)用Swing Application Framework開發(fā)大型軟件的吧?
          對(duì)于學(xué)生的課程設(shè)計(jì)、需要快速開發(fā)的中小軟件,Swing Application Framework (JSR 296)完全可以勝任
          對(duì)于開發(fā)超大型的Swing程序NetBeans RCP也完全可以勝任,在NetBeans RCP中,用MATTISSE也可以加速開發(fā)嘛。
          至于代碼不能改的問題,NetBeans還是提供修改的可能的。^_^

          不過令人欣慰的是,在這個(gè)流行B/S模式的時(shí)代,還有人關(guān)心Swing。
          2008-06-19 22:12 | 令狐蟲@qq.com

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          “this.getFrame().setIconImage(new ImageIcon(getClass().getResource("resources/icon.png")).getImage());”

          可用! 非常感謝——令狐蟲@qq.com 和fcy !!!
          2008-07-21 15:27 | syslover

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          呵呵,一點(diǎn)意見而已。

          我不搞SWING已經(jīng)好多年
          2008-08-05 17:47 | 管華

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          如何修改代碼呢?
          2008-08-10 20:18 | yanjc

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)[未登錄]  回復(fù)  更多評(píng)論   

          樓主是人才
          2008-08-18 13:56 | 1

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)[未登錄]  回復(fù)  更多評(píng)論   

          你好!對(duì)你的作品試用過,也學(xué)習(xí)了.作為一個(gè)JAVA忠實(shí)的學(xué)習(xí)者,你的設(shè)計(jì)使我深受鼓舞.看到大家都這么熱情的提問,在這里我也有一個(gè)小的想法.就是給界面上加一個(gè)"打開文件"這樣的功能.這也是我作為一個(gè)體驗(yàn)者第一次運(yùn)行程序所想到的.希望你的程序功能更加完善.謝謝!

          (我真誠(chéng)地希望與更多JAVA愛好者共同學(xué)習(xí)交流.QQ:719378618)
          2008-10-15 10:03 | JAVA學(xué)習(xí)者

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @JAVA學(xué)習(xí)者
          很高興自己的作品能被別人關(guān)注,你的想法也很好!
          有時(shí)間我會(huì)完善并且做一些新java桌面程序!
          2008-10-15 11:14 | 令狐蟲@qq.com

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          我就想要那個(gè)背單詞的阿!看起來很有用!
          2008-11-11 10:03 | 泥巴麒麟

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @泥巴麒麟
          源代碼已經(jīng)發(fā)在Subversion服務(wù)器上了
          你可以再下面的地址檢出代碼:
          svn://svnhost.cn/DictMp3ComposeApp
          2008-11-11 10:48 | 令狐蟲@qq.com

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          樓主,

          文章中是不是還有錯(cuò)誤阿?呵呵,以下是疑問

          原文有:
          從上面的例子中我們看到,做這個(gè)例子真正只寫了一行代碼:
          setHasSelect( ((JCheckBox)evt.getSource()).isSelected());

          是不是在setHasSelect(boolean b)里面還少了一行代碼
          jButton1.setEnabled(b);
          2009-04-19 01:27 | daan

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          原來上面看錯(cuò)了。。。。
          2009-04-19 11:59 | daan

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @管華
          右擊控件-》定制代碼
          基本上可定制的地方夠用了。
          自定義控件有個(gè)布局上的小BUG,因?yàn)樽詣?dòng)生成代碼的流程是:
          初始化
          設(shè)置布局
          而自定義的組件在創(chuàng)建的時(shí)候就布局了,結(jié)果是布局被覆蓋掉。
          實(shí)際上設(shè)置布局的自動(dòng)代碼只要先判斷一下panel有沒有布局管理器就能避免這個(gè)BUG。希望下個(gè)版本能解決這個(gè)問題。
          現(xiàn)在只要把自定義組件的布局放在父窗口布局后就可以了。
          2009-04-23 12:18 | sleepsaint

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          您好,您的mymusic源碼不知道怎么的,是空的,下不下來,請(qǐng)您加我qq254905352幫我傳一份,謝謝!
          2009-04-29 11:52 | 傷心太平洋

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)[未登錄]  回復(fù)  更多評(píng)論   

          很好很強(qiáng)大。
          @Action出來的標(biāo)簽不能決定何時(shí)Action可見,只有enable, selected屬性,郁悶中。。。。
          2009-05-18 16:08 | steeven

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          請(qǐng)問樓主阻塞功能的按鈕中間的pregressbar裡頭的文字是亂碼.有修正的方法嗎?
          2010-05-03 16:09 | oreio

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          @oreio

          假設(shè)@Action Task actionMethodName()
          那在
          foo.resources包中FooView. Properties中
          增加下面一行可以去掉亂碼文字

          actionMethodName.BlockingDialog.progressBar.stringPainted=false
          2010-05-04 00:48 | 令狐蟲@qq.com

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          寫得相當(dāng)?shù)馁潱。?
          2010-05-07 19:32 | leeing

          # re: NetBeans 6.0 提高生產(chǎn)力之Swing Application Framework (JSR 296)  回復(fù)  更多評(píng)論   

          SAF是很不錯(cuò),希望 Java 在 Oracle 手里能持續(xù)發(fā)展,別受 JAVA 7 影響
          2010-05-16 21:47 | kinzey
          主站蜘蛛池模板: 财经| 林西县| 广昌县| 庐江县| 江源县| 宁都县| 沾化县| 蒙山县| 平南县| 和林格尔县| 太康县| 镇康县| 林甸县| 宣化县| 吉木萨尔县| 招远市| 涞源县| 陆良县| 托克托县| 班戈县| 方正县| 阳山县| 绥中县| 蓬安县| 商南县| 体育| 顺平县| 绥芬河市| 湟源县| 敖汉旗| 徐水县| 广昌县| 沛县| 菏泽市| 桦南县| 宝坻区| 乳源| 北辰区| 东源县| 清丰县| 北宁市|