想要有簡單如意好用的 Java 程式開發工具,又不想花錢去買,怎麼辦呢?
乾脆自己動手用 Java 來寫它幾個吧!
本文介紹的幾個 Java 應用程式和軟體開發工具,都是 Do It Yourself 地用 Java 寫成的,
簡單、好用而且又是完全免費的喔!
本文全文見 HOPE NET 光碟月刊第 29 期,1996 年十月號。
工具之一:影像展示器
記得在上一期的本欄之中,筆者介紹了一個可以展示影像圖形的 Applet ,它可以 將一個寫在 Java 程式之中的圖形檔案展示到 Web 的頁面上,如果在我們的電腦硬碟上 面,有一大堆 .gif 和 .jpg 的圖形檔案,我們想要看看這些圖形檔案的展示效果,以 便選取合適的圖形去用,這時只用那個展示影像圖形的 Applet 就非常不方便了。現在 ,讓我們把這個展示影像的 Applet 改為一個獨立的 Java 應用程式,並且將所欲觀看 的圖形以指令參數的型態輸入,就會是一個很實用的工具。 例如,這個獨立的應用程式的類別名稱叫做 ShowImage.class ,那麼打入下面的指 令就可以看到名叫 test5.gif 的圖形效果了。 java ShowImage test5.gif程式執行的結果:
程式的全文如下:
/* 一個簡單影像的 Application @author: Symon Chang 09-20-96 E-mail: symonchang@earthlink.net URL: http://home.earthlink.net/~symonchang copyright(c) 1996 Symon Chang, Symon & Associates */ import java.applet.*; import java.awt.*; import java.awt.image.*; import java.net.*; import java.io.*; public class ShowImage extends Frame { Image myImage; // 宣告一個影像圖形物件 public ShowImage(String sImage) { // 建構函式 super("Display " + sImage); // 設標題 myImage=getImage(getURL(sImage)); // 抓取影像檔案 pack(); // 照尺寸去放置 show(); // 顯示到螢幕上 } public URL getURL(String sFileName) { String sDirName; File fInput = new File(sFileName); // 檔案物件 if (fInput.isAbsolute()) { sDirName = sFileName; } else { // 加入子目錄 sDirName = (System.getProperty("user.dir")+ "\\" + sFileName); } String urlDirName = sDirName.replace( File.separatorChar, '/' ); try { // 建立新的 URL return new URL( "file:" + urlDirName ); } catch ( MalformedURLException e ) // 捕捉錯誤 { System.out.println(e); return null; } } public Image getImage( URL url ) { Toolkit tk = Toolkit.getDefaultToolkit(); try { // Toolkit 中的方法 ImageProducer imgProd = (ImageProducer) url.getContent(); return tk.createImage( imgProd ); } catch ( IOException e ) { // 捕捉錯誤 System.out.println(e); return null; } } public void paint(Graphics g) { // 繪圖方法 g.drawImage(myImage, 0, 0, this); // 畫影像到螢幕上 } public boolean imageUpdate(Image img, int infoflags, int x, int y, int w, int h) { if (infoflags == ALLBITS) { // 齊了後調整尺寸 resize(myImage.getWidth(this)+8,myImage.getHeight(this)+28); repaint(); // 呼叫繪圖方法 return false; } else return true; } public boolean handleEvent(Event evt) { // 處理事件的方法 switch(evt.id) { case Event.WINDOW_DESTROY: // 銷毀視窗 this.dispose(); return true; default: return super.handleEvent(evt); // 交上級處理 } } public static void main(String args[]) { // 主程式入口 if (args.length <= 0) { System.out.println("Usage: java ShowImage"); System.exit(0); } new ShowImage(args[0]); // 呼叫自己 } } 工具之二:影像觀察器
寫了上面的這個視窗元件以後,可利用它來開發一個影像的觀察器 (ImageViewer)。 觀察器是一個選取圖檔來觀看的工具,它繼承 Frame 的獨立應用程式,和前面的兩個應 用程式一般,它一共有四大部分:程式內部的一些物件和變數的宣告、建構函式、處理 事件的方法,以及main() 這個主程式的進入點。
這個採用 ShowImage 類別所開發而成的影像觀察器 ImageViewer.java 程式如下:
/* Imager Viewer Application @author: Symon Chang 09-20-96 E-mail: symonchang@earthlink.net URL: http://home.earthlink.net/~symonchang copyright(c) 1996 Symon Chang, Symon & Associates */ import java.awt.*; import java.io.*; public class ImageViewer extends Frame { private List listFile; // 宣告一個列表物件 private Button bQuit; // 宣告一個按鍵物件 private File fileDir; // 宣告一個檔案物件 static final int LIST_MAX = 20; public ImageViewer(String sDirName, FilenameFilter myFilter) throws IOException { // 建構函式 super("Image Viewer "); // 設標題 setLayout(new FlowLayout(FlowLayout.CENTER,10,10)); // 設外觀管理員 listFile = new List(LIST_MAX, false); // 設列表物件 fileDir = new File(sDirName); // 設檔案物件 if (!fileDir.isDirectory()) { throw new IllegalArgumentException("ImageViewer: no such directory"); } String[] sFileList = fileDir.list(myFilter); // 檔案名稱過濾 for(int i = 0; i < sFileList.length; i++) listFile.addItem(sFileList[i]); // 加到列表物件中 add(listFile); // 加入列表物件 bQuit = new Button("Quit"); // 宣告一個按鍵 add(bQuit); // 加入按鍵物件 pack(); // 照尺寸去放置 resize(165, 370); // 調整尺寸 show(); // 顯示到螢幕上 } public boolean handleEvent(Event evt) { // 處理事件的方法 if (evt.target == bQuit) System.exit(0); switch(evt.id) { case Event.WINDOW_DESTROY: // 銷毀視窗 System.exit(0); case Event.ACTION_EVENT: // 有活要幹了 String selFile = new File(fileDir, (String)evt.arg).getAbsolutePath(); new ShowImage(selFile); // 呼叫秀影像 return true; default: return super.handleEvent(evt); // 交上級處理 } } public static void main(String args[]) // 主程式入口 throws IOException { FilenameFilter gifFilter =new ImageFilter(); // 檔案名稱過濾物件 String sDirName = null; if (args.length > 0) sDirName = args[0]; else sDirName = System.getProperty("user.dir"); // Working Dir try { new ImageViewer(sDirName, gifFilter); // 呼叫自己 } catch ( Exception e) { System.out.println(e); } } } class ImageFilter implements FilenameFilter { // 檔案名稱過濾物件 public boolean accept(File fDir, String name) { if ((name.endsWith("gif")) || (name.endsWith("GIF")) || (name.endsWith("jpg")) || (name.endsWith("JPG"))) return true; else return false; } }影像觀察器的妙用
這個 ImageViewer 的 Java 應用程式可以用來觀看任何指定子目錄下面的所有用 GIF 或 JPEG 格式的影像圖檔。如果用 java ImageViewer 這個指令時,它會展列所有 在目前工作的子目錄下面的相關圖檔;如果在指令後面再加上一個子目錄的全名時,它 就會展示在該子目錄下面的所有相關圖檔的名字,以供選看其內容。 例如我的瀏覽器將所有從 Internet 上面看過的檔案都暫存在硬式磁碟的緩衝區上 ,但是它所用的檔案名稱都是一些由八位字母和數字所組成的怪名字,利用這個影像觀 察器就可以將最近瀏覽器所看過的影像圖檔的怪名字一一列出,並且只要用滑鼠一指點 ,就可以看到影像圖檔的內容。![]()
工具之三:選項的主程式
下面的這一個簡單的程式就展示如何在一個 Java 的視窗應用程式之中呼叫出一些在 Windows 95 上面的現成應用程式,例如計算器或是筆記本之類的附屬程式。在程式中的 那兩個欲呼叫的子目錄名稱,一個用雙斜線,另一個用單斜線是用來展示這兩種寫法在 Windows 95 的環境之下都可以被接受。 程式執行的結果:
程式的全文如下:
import java.awt.*; public class MyMenu2 extends Frame { String sExe[] = { "c:\\windows\\calc.exe" , "c:/windows/notepad.exe" } ; public MyMenu2() { super("選 單 的 程 式"); // 建構函式 setLayout(new FlowLayout()); // 設標題 add(new Button("小計算機")); // 加入宣告的按鍵 add(new Button("小筆計本")); pack(); // 照尺寸去放置 resize(200,60); // 調整尺寸 show(); // 顯示到螢幕上 } public boolean handleEvent(Event evt) { // 處理事件的方法 int myExe = 0; switch(evt.id) { case Event.WINDOW_DESTROY: // 銷毀視窗 System.exit(0); case Event.ACTION_EVENT: // 有活要幹了 if (evt.arg.equals("小計算機")) myExe = 1; if (evt.arg.equals("小筆計本")) myExe = 2; if (myExe != 0) { } default: return super.handleEvent(evt); // 交上級處理 } } public static void main(String args[]) { // 主程式入口 new MyMenu2(); // 呼叫自己 } }
工具之四: Java 的程式開發屏風
一個簡單的 Java 程式開發屏風![]()
在這個屏風之中,會列出一個子目錄之下所有和 Java 程式開發相關的檔案名稱, 可以利用滑鼠去選擇所欲執行的檔案。當選好檔案名稱之後,只要按各個不同的指令按鍵, 就可以去編輯、編譯或是執行 Java 的應用程式,也可以呼叫 appletviewer 去測試 Java 的 Applet,這些都是在 Windows 95 之下開發 Java 程式常用的指令。
在開發的過程之中,常常會有新的檔案產生,例如新的 .class 檔或是新的 Java 原始 程式 .java 檔,為了使這些新增加的檔案能夠納入的視窗的檔案列表之中,我又加了一個 刷新檔案名稱的功能。當使用者按下了「Refresh」的按鍵時,程式會將子目錄下的相關 檔案重新列表展示出來。
整個程式只有一百多行程式碼,程式的全文如下:
import java.awt.*; import java.io.*; public class MakeJava extends Frame { private List listFile; // 宣告一個列表物件 private TextField txtMessage; // 宣告一個文字物件 private Button myButton[]; // 宣告一個按鍵物件 static final int B_REFESH = 4; static final int B_QUIT = 5; static final int JAVACLASS = 2; private FilenameFilter myFilter; // 宣告檔名過濾物件 private String myDirectory = null; // 子目錄名稱 private String[] sFileList; static final String CMDS[] = { "notepad", "javac", "java", "appletviewer" }; static final String B_LABEL[] = { " Edit ","Compile","Execute","Applet Viewer","Refesh","Quit" }; private String sItemSelected = null; public MakeJava(String sDirectory, FilenameFilter myFilter) throws IOException { // 建構函式 super("Make Java Programs"); // 設標題 setFont(new Font("Dialog", Font.BOLD, 14)); // 設字型 setBackground(Color.white); // 設背景色 setForeground(Color.blue); // 設前景色 this.myFilter = myFilter; // 檔案名稱過濾 this.myDirectory = sDirectory; // 子目錄名稱 listFile = new List(12, false); // 設列表物件 setLayout(new BorderLayout(10,10)); // 設外觀管理員 Panel pButtons = new Panel(); // 宣告按鍵物件屏 myButton = new Button[B_QUIT+1]; // 宣告按鍵矩陣 for (int i=0; i< myButton.length; i++) { myButton[i] = new Button(B_LABEL[i]); // 宣告一個按鍵 pButtons.add(myButton[i]); // 加入按鍵物件 } txtMessage = new TextField(); // 文字信息 txtMessage.setEditable(false); // 禁改 this.add("North", txtMessage); // 加入文字物件 getDirFlist(sDirectory); // 抓檔案名 this.add("Center", listFile); // 加入列表物件 this.add("South", pButtons); // 加入按鍵物件屏 this.resize(550, 480); // 調整尺寸 this.pack(); // 照尺寸去放置 this.show(); // 顯示到螢幕上 } public void getDirFlist(String sDirName) // 抓檔案名 throws IOException { File fDir = new File(sDirName); // 檔案物件 if (!fDir.isDirectory()) // 非子目錄? throw new IllegalArgumentException( "MakeJava: no such directory"); listFile.clear(); // 洗清列表 txtMessage.setText("Directory = " + sDirName); sFileList = fDir.list(myFilter); // 檔案名稱過濾 for(int i = 0; i < sFileList.length; i++) listFile.addItem(sFileList[i]); // 加到列表物件中 } public boolean handleEvent(Event e) { // 處理事件的方法 Process p = null; // Process 物件 String sCommand; String sNameOnly = null; if ((e.target == myButton[B_QUIT]) || (e.id == Event.WINDOW_DESTROY)) // 銷毀視窗 System.exit(0); if ((e.target == myButton[B_REFESH]) ) { try { // 更換人選 getDirFlist(myDirectory); } catch ( Exception ex) { txtMessage.setText("Invalid Selection: " + ex); sItemSelected = null; } return true; } if (e.target == listFile) { try { // 雀屏中選? sItemSelected = sFileList[((Integer)e.arg).intValue()]; } catch (Exception ex) { txtMessage.setText("Invalid Selection"); sItemSelected = null; } txtMessage.setText(sItemSelected); // 雀屏中選者 return true; } if (sItemSelected == null) return false; // 沒有活可幹了 for (int i=0; i < B_REFESH; i++) { if (e.target == myButton[i]) { // 有活要幹了 if (i == JAVACLASS) { // class ? try { sNameOnly = sItemSelected.substring(0, sItemSelected.lastIndexOf('.')); } catch (Exception ex) { txtMessage.setText("Error in substring"); } sCommand = CMDS[i]+" "+sNameOnly; // 要執行的指令 } else { // 非 class sCommand = CMDS[i] + " " + sItemSelected; } txtMessage.setText("Executing " + sCommand); String saveSelected = sItemSelected; // 暫存 sItemSelected = null; // 暫停 try { p = Runtime.getRuntime().exec(sCommand); // 執行 p.waitFor(); // 稍候 } catch (Exception ex) { // 錯了 txtMessage.setText("Error executing " + sCommand); } txtMessage.setText(sCommand+" returned "+p.exitValue()); sItemSelected = saveSelected ; // 存回 return true; } } return super.handleEvent(e); // 交上級處理 } public static void main(String args[]) // 主程式入口 throws IOException { FilenameFilter myFilter = new JavaRelatedFilter(); try { // 呼叫自己 new MakeJava(System.getProperty("user.dir"),myFilter); } catch ( Exception e) { System.out.println(e); } } } class JavaRelatedFilter implements FilenameFilter { // 檔案名稱過濾物件 public boolean accept(File dir, String name) { if ((name.endsWith("java")) || (name.endsWith("class")) || (name.endsWith("html")) || (name.endsWith("HTM")) || (name.endsWith("htm"))) return true; else return false; } }
歡迎對本站內容提出您的寶貴意見, E-mail: symonchang@earthlink.net