第七章 用JBuilder9開發一個文本編輯器
一、概述
文本編輯器是一種最常用的應用程序,下麵我們利用Jbuilder9集成開發環境,用java語言實現一個簡單的文本編輯器。該文本編輯器具有讀出、寫入、編輯文本文件,可以設定文字顏色、字形和編輯區域背景顏色等基本功能。
我們首先通過Jbuilder9項目向導和應用向導創建項目,然後應用可視化設計工具,修改UI設計,連接事件,編輯源碼以及常用控件和任務諸如菜單項、工具條、文本區域和係統事件等常用控件和任務的處理。涉及到具體技術有:
用JFileChooser對話框讓用戶選擇文本文件。
用JtextArea讀、寫和處理文本文件中的文字。
設置前景色和背景色。
用dbSwingFontChooser對話框設置字型。
在狀態欄和窗口標題欄顯示信息。
手工添加處理UI事件的代碼。
通過將代碼放在一個可被菜單項和按鈕兩個事件處理器調用的新的"幫助"方法中,使得菜單項和按鈕執行相同的代碼。
給JtextArea控件增加一個右擊菜單。
保持對文件的位置以及文件是否活動過的跟蹤,展示對文件|新建,文件|打開,文件|保存,文件|另存為,編輯和退出等邏輯的處理。
將"TextEditor"應用程序展開為JAR文件。
二、開發文本編輯器java源程序說明
文本編輯器程序包含三個java源程序即TextEditFrame.java、TextEditclass.java和TextEditFrame_AboutBox.java程序,下麵將分別介紹如下:
1、TextEditFrame.java的源程序代碼(節選部分):
packagetexteditor;
//TextEditFrame.java
importjava.awt.*;//導入類
importjava.awt.event.*;
importjavax.swing.*;
importcom.borland.dbswing.*;
importjava.io.*;
importjavax.swing.text.*;
importjavax.swing.event.*;
publicclassTextEditFrameextendsJFrame{
IntlSwingSupportintlSwingSupport1=newIntlSwingSupport();
//Swing控件互聯網化:即本地化應用程序,需要添加一行代碼以便Swing控件JfileChooser//和JcolorChooser出現在程序運行的語言中
JPanelcontentPane;//設置內容窗(contentPane)的JPanel控件
JMenuBarmenuBar1=newJMenuBar();//創建菜單條並加入到框架窗體中
JMenumenuFile=newJMenu();//創建File菜單和相應的菜單項
JMenuItemmenuFileExit=newJMenuItem();
JMenumenuHelp=newJMenu();//創建Help菜單和相應的菜單項
JMenuItemmenuHelpAbout=newJMenuItem();
JToolBartoolBar=newJToolBar();//創建工具條組件
JButtonjButton1=newJButton();//創建按鈕組件
JButtonjButton2=newJButton();
JButtonjButton3=newJButton();
ImageIconimage1;//定義圖標
ImageIconimage2;
ImageIconimage3;
JLabelstatusBar=newJLabel();//創建標簽組件
BorderLayoutborderLayout1=newBorderLayout();//創建BorderLayout布局器
JScrollPanejScrollPane1=newJScrollPane();//創建滾動窗控件
JTextAreajTextArea1=newJTextArea();//創建多行文本域組件
JMenuItemjMenuItem1=newJMenuItem();//創建菜單項
JMenuItemjMenuItem2=newJMenuItem();
JMenuItemjMenuItem3=newJMenuItem();
JMenuItemjMenuItem4=newJMenuItem();
FontChooserfontChooser1=newFontChooser();//創建字型選擇對話框
JMenujMenu1=newJMenu();
JMenuItemjMenuItem5=newJMenuItem();
JMenuItemjMenuItem6=newJMenuItem();
JMenuItemjMenuItem7=newJMenuItem();
JFileChooserjFileChooser1=newJFileChooser();//創建文本選擇對話框
StringcurrFileName=null;//Fullpathwithfilename.nullmeansnew/untitled.
booleandirty=false;
Documentdocument1;//文本
DBTextDataBinderdBTextDataBinder1=newDBTextDataBinder();
//Truemeansmodifiedtext.
//構造架框
publicTextEditFrame(){
enableEvents(AWTEvent.WINDOW_EVENT_MASK);
try{
jbInit();
updateCaption();
}
catch(Exceptione){
e.printStackTrace();
}
}
//組件初始化
privatevoidjbInit()throwsException{
//三個工具欄按鈕圖標
image1=newImageIcon(TextEditFrame.class.getResource("openFile.gif"));
image2=newImageIcon(TextEditFrame.class.getResource("closeFile.gif"));
image3=newImageIcon(TextEditFrame.class.getResource("help.gif"));
contentPane=(JPanel)this.getContentPane();//內容創格
document1=jTextArea1.getDocument();//多行文本域文檔
contentPane.setLayout(borderLayout1);//borderLayout布局器
this.setSize(newDimension(400,300));//窗口大小
this.setTitle("TextEditor");//窗口標題
statusBar.setText("");
menuFile.setText("File");
menuFileExit.setText("Exit");
menuFileExit.addActionListener(newTextEditFrame_menuFileExit_ActionAdapter(this));
//添加事件監聽器
menuHelp.setText("Help");
menuHelpAbout.setText("About");
menuHelpAbout.addActionListener(newTextEditFrame_menuHelpAbout_ActionAdapter(this));
jButton1.setIcon(image1);//設置三個工具欄按鈕圖標,添加事件監聽器
jButton1.addActionListener(newTextEditFrame_jButton1_actionAdapter(this));
jButton1.setToolTipText("OpenFile");
jButton2.setIcon(image2);
jButton2.addActionListener(newTextEditFrame_jButton2_actionAdapter(this));
jButton2.setToolTipText("CloseFile");
jButton3.setIcon(image3);
jButton3.addActionListener(newTextEditFrame_jButton3_actionAdapter(this));
jButton3.setToolTipText("About");
jTextArea1.setLineWrap(true);
jTextArea1.setWrapStyleWord(true);
jTextArea1.setBackground(Color.white);
jMenuItem1.setText("New");//設置菜單,添加事件監聽器
jMenuItem1.addActionListener(newTextEditFrame_jMenuItem1_actionAdapter(this));
jMenuItem2.setText("Open");
jMenuItem2.addActionListener(newTextEditFrame_jMenuItem2_actionAdapter(this));
jMenuItem3.setText("Save");
jMenuItem3.addActionListener(newTextEditFrame_jMenuItem3_actionAdapter(this));
jMenuItem4.setText("SaveAs");
jMenuItem4.addActionListener(newTextEditFrame_jMenuItem4_actionAdapter(this));
fontChooser1.setFrame(this);
fontChooser1.setTitle("Font");
jMenu1.setText("Edit");
jMenuItem5.setText("Font");
jMenuItem5.addActionListener(newTextEditFrame_jMenuItem5_actionAdapter(this));
jMenuItem6.setText("ForegroundColor");
jMenuItem6.addActionListener(newTextEditFrame_jMenuItem6_actionAdapter(this));
jMenuItem7.setText("BackgroundColor");
jMenuItem7.addActionListener(newTextEditFrame_jMenuItem7_actionAdapter(this));
document1.addDocumentListener(newTextEditFrame_document1_documentAdapter(this));
dBTextDataBinder1.setJTextComponent(jTextArea1);
//Turnoffright-clickfileOpen...menuitem.
dBTextDataBinder1.setEnableFileLoading(false);
//Turnoffright-clickfileSave...menuitem.
dBTextDataBinder1.setEnableFileSaving(false);
toolBar.add(jButton1);//工具組件添加按鈕
toolBar.add(jButton2);
toolBar.add(jButton3);
menuFile.add(jMenuItem1);//菜單組件添加菜單項
menuFile.add(jMenuItem2);
menuFile.add(jMenuItem3);
menuFile.add(jMenuItem4);
menuFile.addSeparator();//采單組件添加分隔線
menuFile.add(menuFileExit);
menuHelp.add(menuHelpAbout);
menuBar1.add(menuFile);
menuBar1.add(jMenu1);
menuBar1.add(menuHelp);
this.setJMenuBar(menuBar1);
contentPane.add(toolBar,BorderLayout.NORTH);
//內容窗設置borderLayout布局器
contentPane.add(statusBar,BorderLayout.SOUTH);
contentPane.add(jScrollPane1,BorderLayout.CENTER);
jScrollPane1.getViewport().add(jTextArea1,null);
jMenu1.add(jMenuItem5);
jMenu1.add(jMenuItem6);
jMenu1.add(jMenuItem7);
}
//DisplaytheAboutbox.
voidhelpAbout(){
TextEditFrame_AboutBoxdlg=newTextEditFrame_AboutBox(this);
DimensiondlgSize=dlg.getPreferredSize();
DimensionfrmSize=getSize();
Pointloc=getLocation();
dlg.setLocation((frmSize.width-dlgSize.width)/2+loc.x,(frmSize.height-dlgSize.height)/2+loc.y);
dlg.setModal(true);
dlg.show();
}
.........
.........
TextEditFrame.java是實現文本編輯器的主要程序,它有下麵6點編程技巧說明:
1)製作一個完全充滿用戶界麵頂部菜單欄和底部狀態欄之間區域的文本區
主用戶界麵容器的布局管理器需要采用邊界布局(Borderlayout)。在主容器中,含有一個叫做內容窗(contentPane)的JPanel控件,被改變成邊界布局,需要做的隻是在內容窗添加一個文本區控件。為此,先在內容窗添加一個滾動窗,再在滾動窗內放上文本區控件(jTextArea)。滾動窗提供一個帶滾動棒(JScollPane)的文本區。
一個邊界布局的容器被分成五個區域:北、南、東、西、中。每個區域隻能有一個控件,所以最多可有五個控件(注:含有多個控件的麵板被認為是一個控件)。放進中心區域的控件完全占滿該容器控件,不被含有控件的任何其他區域所占據。例如,在本例中,工具欄占據北區(頂),狀態欄占據南區(低步),由於東西兩個區域沒有安排控件,這樣滾動窗控件占據中心區域並擴展到容器的左(西)右(東)的邊緣。
2)創建菜單File(包含New、Open、Save、Saveas和Exit菜單項),菜單Edit{包含Font(字體)、Foreground(前景色)和Background(背景色)菜單項}和菜單Help(包含About幫助說明)
①菜單Edit的Font(字體)、Foreground(前景色)和Background(背景色)菜單項:
添加字型選擇對話框
給菜單掛上事件,從Edit|Font菜單項開始,該菜單將引出一個FontChooser(字型選擇)對話框。
給FontChooser附加一個菜單項事件(源程序)如下:
voidjMenuItem5_actionPerformed(ActionEvente){
//Handlethe"EditFont"menuitem
//Pickuptheexistingfontfromthetextarea
//andputitintotheFontChooserbeforeshowing
//theFontChooser,sothatweareeditingthe
//existing/previousfont.
fontChooser1.setSelectedFont(jTextArea1.getFont());
//ObtainthenewFontfromtheFontChooser.
//FirsttestthereturnvalueofshowDialog()to
//seeiftheuserpressedOK.
if(fontChooser1.showDialog()){
//SetthefontofjTextArea1tothefont
//theuserselectedbeforepressingtheOKbutton
jTextArea1.setFont(fontChooser1.getSelectedFont());
}
//repaintsmenuafteritemisselected
this.repaint();
//Repaintstextproperlyifsometextishighlightedwhenfontischanged.
jTextArea1.repaint();
}
給JcolorChooser(顏色選擇)附加一個菜單項事件
創建Edit|ForegroundandEdit|Background兩個菜單事件,並將它們與Swing中的JcolorChooser對話控件連接起來。
voidjMenuItem6_actionPerformed(ActionEvente){
//Handlethe"ForegroundColor"menuitem
Colorcolor=JColorChooser.showDialog(this,"ForegroundColor",jTextArea1.getForeground());
if(color!=null){
jTextArea1.setForeground(color);
}
//repaintsmenuafteritemisselected
this.repaint();
}
voidjMenuItem7_actionPerformed(ActionEvente){
//Handlethe"BackgroundColor"menuitem
Colorcolor=JColorChooser.showDialog(this,"Background
Color",jTextArea1.getBackground());