package proe; 
import java.awt.*; import javax.swing.*; import java.awt.event.*; import java.io.*; import javax.swing.text.*; import javax.swing.event.*; import javax.swing.undo.*; import java.util.*; 
/**  *<p>Title: 程序编辑器</p>  *<p>Description: 增强的文本编辑程序</p>  *<p>Copyright: Copyright (c) 2005</p>  *<p>Company: </p>  *@author 红色彼岸  *@version 0.1  */ class ProEFrame extends JFrame{     private JFileChooser fileChooser = new JFileChooser(); 
    private JMenuBar menuBar;     private JMenu file, edit, format, help;     private JMenuItem newItem, openItem, saveItem, saveAsItem, pageSetItem, printItem, exitItem;     private JMenuItem undoItem, redoItem, cutItem, copyItem, pasteItem, deleteItem, findItem, findNextItem, replaceItem, goToLineItem, selectAllItem, timeItem;     private JMenuItem autoNextLineItem, fontItem;     private JMenuItem helpItem, aboutItem;     private JTextArea textArea;     private JScrollPane scrollPane;     private final int TAB_SIZE = 4; 
    private File fileName;     private boolean isChange = false; 
    private final UndoManager undo = new UndoManager(); 
    public ProEFrame(String title) {  //设置窗体的标题栏和默认关闭操作      super(title);  setDefaultCloseOperation(DO_NOTHING_ON_CLOSE); 
 //设置菜单栏和菜单的内容  menuBar = new JMenuBar();  file  = new JMenu("文件(F)");  edit  = new JMenu("编辑(E)");  format = new JMenu("格式(O)");  help  = new JMenu("帮助(H)");  setQuickKey(file, 'F');  setQuickKey(edit, 'E');  setQuickKey(format, 'O');  setQuickKey(help, 'H');  newItem = new JMenuItem("新建(N)");  openItem = new JMenuItem("打开(O)...");  saveItem = new JMenuItem("保存(S)");  saveAsItem = new JMenuItem("另存为...");  pageSetItem = new JMenuItem("页面设置(U)...");  printItem = new JMenuItem("打印(P)...");  exitItem = new JMenuItem("退出");  setQuickKey(newItem, 'N');  setQuickKey(openItem, 'O');  setQuickKey(saveItem, 'S');  setQuickKey(pageSetItem, 'U');  setQuickKey(printItem, 'P');    file.add(newItem);  file.add(openItem);  file.add(saveItem);  file.add(saveAsItem);  file.addSeparator();  file.add(pageSetItem);  file.add(printItem);  file.addSeparator();  file.add(exitItem); 
 undoItem = new JMenuItem("撤销(Z)");  redoItem = new JMenuItem("恢复(R)");  cutItem = new JMenuItem("剪切(X)");  copyItem = new JMenuItem("复制(C)");  pasteItem = new JMenuItem("粘贴(V)");  deleteItem = new JMenuItem("删除");  findItem = new JMenuItem("查找(F)...");  findNextItem = new JMenuItem("查找下一个");  replaceItem = new JMenuItem("替换...");  goToLineItem = new JMenuItem("转到(G)...");  selectAllItem = new JMenuItem("全选(A)");  timeItem = new JMenuItem("时间/日期"); 
 setQuickKey(undoItem, 'Z');  setQuickKey(redoItem, 'R');  setQuickKey(cutItem, 'X');  setQuickKey(copyItem, 'C');  setQuickKey(pasteItem, 'V');  setQuickKey(findItem, 'F');  setQuickKey(goToLineItem, 'G');  setQuickKey(selectAllItem, 'A');    edit.add(undoItem);  edit.add(redoItem);  edit.addSeparator();  edit.add(cutItem);  edit.add(copyItem);  edit.add(pasteItem);  edit.add(deleteItem);  edit.addSeparator();  edit.add(findItem);  edit.add(findNextItem);  edit.add(replaceItem);  edit.add(goToLineItem);  edit.addSeparator();  edit.add(selectAllItem);  edit.add(timeItem); 
 autoNextLineItem = new JMenuItem("自动换行(W)");  fontItem = new JMenuItem("字体..."); 
 setQuickKey(autoNextLineItem, 'W'); 
 format.add(autoNextLineItem);  format.add(fontItem); 
 helpItem = new JMenuItem("帮助主题(H)");  aboutItem = new JMenuItem("关于ProE"); 
 setQuickKey(helpItem, 'H'); 
 help.add(helpItem);  help.add(aboutItem); 
 menuBar.add(file);  menuBar.add(edit);  menuBar.add(format);  menuBar.add(help);  setJMenuBar(menuBar); 
 textArea = new JTextArea();  textArea.setTabSize(TAB_SIZE);  //支持撤销/恢复操作的监听方法  textArea.getDocument().addUndoableEditListener(new UndoableEditListener() {      public void undoableEditHappened(UndoableEditEvent evt) {       undo.addEdit(evt.getEdit());      }  });  //监听文档内容是否发生变化  textArea.getDocument().addDocumentListener(   new DocumentListener() {    public void changedUpdate(DocumentEvent de) {     isChange = true;    }    public void insertUpdate(DocumentEvent de) {     isChange = true;    }    public void removeUpdate(DocumentEvent de) {     isChange = true;    }   }  );  scrollPane = new JScrollPane(textArea);  this.getContentPane().add(scrollPane, BorderLayout.CENTER); 
 //测试用的方法  MenuItemEventHandler menuItemHandler = new MenuItemEventHandler();  newItem.addActionListener(menuItemHandler);  openItem.addActionListener(menuItemHandler);  saveItem.addActionListener(menuItemHandler);  saveAsItem.addActionListener(menuItemHandler);  pageSetItem.addActionListener(menuItemHandler);  printItem.addActionListener(menuItemHandler);  exitItem.addActionListener(menuItemHandler);  undoItem.addActionListener(menuItemHandler);  redoItem.addActionListener(menuItemHandler);  cutItem.addActionListener(menuItemHandler);  copyItem.addActionListener(menuItemHandler);  pasteItem.addActionListener(menuItemHandler);  deleteItem.addActionListener(menuItemHandler);  findItem.addActionListener(menuItemHandler);  findNextItem.addActionListener(menuItemHandler);  replaceItem.addActionListener(menuItemHandler);  goToLineItem.addActionListener(menuItemHandler);  selectAllItem.addActionListener(menuItemHandler);  timeItem.addActionListener(menuItemHandler);  autoNextLineItem.addActionListener(menuItemHandler);  fontItem.addActionListener(menuItemHandler);  helpItem.addActionListener(menuItemHandler);  aboutItem.addActionListener(menuItemHandler); 
 addWindowListener(new WindowAdapter() {   public void windowClosing(WindowEvent we) {    exitPerformed();   }  });     } 
    //辅助方法:为菜单或者菜单项设定快捷键     private void setQuickKey(AbstractButton button, char quickKey) {  String type = button.getClass().getSimpleName();  if(type.equals("JMenu"))   button.setMnemonic(quickKey);  else if(type.equals("JMenuItem")) {   JMenuItem menuItem = (JMenuItem)button;   menuItem.setAccelerator(KeyStroke.getKeyStroke(quickKey, InputEvent.CTRL_MASK));  }     } 
    //辅助方法:测试JTextArea中文本是否有变化     private boolean hasChange() {  return isChange;     } 
    //内部方法:响应菜单事件     private void newPerformed() {  int value = -1;  if(hasChange())    if(fileName != null && fileName.exists()) {    String[] buttonTexts = {"保存", "不保存", "取消"};    value = JOptionPane.showOptionDialog(this, "源程序已经改变,请确认是否保存!", "保存更改?", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, buttonTexts, buttonTexts[0]);    if(value == JOptionPane.YES_OPTION)     savePerformed();    else if(value == JOptionPane.NO_OPTION) {     fileName = null;     textArea.setText("");     setTitle("程序编辑器");     return;    }    else if(value == JOptionPane.CANCEL_OPTION)     return;   }   else {    saveAsPerformed();    fileName = null;    textArea.setText("");    setTitle("程序编辑器");    return;   }  fileName = null;  textArea.setText("");  setTitle("程序编辑器");  isChange = false;  return;     } 
    private void openPerformed() {  BufferedReader input = null;  String text;  int ret = fileChooser.showOpenDialog(this);  if(ret != JFileChooser.APPROVE_OPTION)     return;  newPerformed();  fileName = fileChooser.getSelectedFile();  if(fileName.exists() && fileName.canRead()) {      setTitle("程序编辑器: " + fileName.getName());       try{          input = new BufferedReader(new FileReader(fileName));          while((text = input.readLine()) != null)       textArea.append(text + "\n");          input.close();      }      catch(IOException e) {          JOptionPane.showMessageDialog(this, "文件打开错误,没有打开");      }      finally {   input = null;      }  }  isChange = false;     }     private void savePerformed() {   if(!hasChange())   return;  PrintWriter output = null;  if(fileName != null && fileName.exists()) {      try{      output = new PrintWriter(fileName);      output.write(textArea.getText());      }      catch(IOException e)      {          JOptionPane.showMessageDialog(this, "文件写入错误,没有保存");      }      finally {          output.close();          output = null;      }      isChange = false;  }  else       saveAsPerformed();     }     private void saveAsPerformed() {   if(!hasChange())      return;  PrintWriter output = null;  int ret = fileChooser.showSaveDialog(this);  if(ret != JFileChooser.APPROVE_OPTION) {         isChange = true;       return;  } 
 fileName = fileChooser.getSelectedFile();  setTitle("程序编辑器: " + fileName.getName());   try{      output = new PrintWriter(fileName);           output.write(textArea.getText());    }  catch(IOException e){   JOptionPane.showMessageDialog(this, "文件写入错误,没有保存");   }  finally{      output.close();      output = null;  }  isChange = false;     }     private void pageSetPerformed() {  System.out.println("显示页面设置对话框");     }     private void printPerformed() {  System.out.println("显示打印对话框");     }     private void exitPerformed() {  String[] buttonTexts = {"保存退出", "不保存退出", "取消"};  int value = -1;  if(hasChange()) {      value = JOptionPane.showOptionDialog(this, "源程序已经改变,请是否选择保存或直接退出!", "退出程序", JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, buttonTexts, buttonTexts[0]);      switch(value)      {          case JOptionPane.YES_OPTION:   savePerformed();   break;          case JOptionPane.NO_OPTION:   System.exit(0);   break;          case JOptionPane.CANCEL_OPTION:   isChange = true;   return;      }  }  else      System.exit(0);     }     private void undoPerformed() {  try{   if(undo.canUndo())    undo.undo();  }catch(CannotUndoException e) {   JOptionPane.showMessageDialog(this, "无法执行撤销操作", "撤销异常", JOptionPane.WARNING_MESSAGE);  }     }     private void redoPerformed() {  try{   if(undo.canRedo())    undo.redo();  }catch(CannotRedoException e) {   JOptionPane.showMessageDialog(this, "无法执行恢复操作", "恢复异常", JOptionPane.WARNING_MESSAGE);  }     }     private void cutPerformed() {  textArea.cut();     }     private void copyPerformed() {  textArea.copy();     }     private void pastePerformed() {  textArea.paste();     }     private void deletePerformed() {  textArea.replaceRange(null, textArea.getSelectionStart(), textArea.getSelectionEnd());     }     private void findPerformed() {  String findString = JOptionPane.showInputDialog(this, );     }     private void findNextPerformed() {  System.out.println("查找下一个");     }     private void replacePerformed() {  System.out.println("替换");     }     private void goToLinePerformed() {  System.out.println("转到");     }     private void selectAllPerformed() {  textArea.selectAll();     }     private void timePerformed() {  textArea.insert((new Date()).toString(), textArea.getSelectionEnd());     }     private void autoNextLinePerformed() {  System.out.println("自动换行");     }     private void fontPerformed() {  System.out.println("字体");     }     private void helpPerformed() {  System.out.println("帮助主题");     }     private void aboutPerformed() {  System.out.println("关于程序");     } 
   /**     *<p>Title: </p>     *<p>Description: 处理菜单出发的事件</p>     *<p>Copyright: Copyright (c) 2005</p>     *<p>Company: </p>     *@author 红色彼岸     *@version 0.1     */     class MenuItemEventHandler implements ActionListener{  public void actionPerformed(ActionEvent e) {      JMenuItem item = (JMenuItem)e.getSource();      if(item == newItem)   newPerformed();      else if(item == openItem)   openPerformed();      else if(item == saveItem)   savePerformed();      else if(item == saveAsItem)   saveAsPerformed();      else if(item == pageSetItem)   pageSetPerformed();      else if(item == printItem)   printPerformed();      else if(item == exitItem)   exitPerformed();      else if(item == undoItem)   undoPerformed();      else if(item == redoItem)   redoPerformed();      else if(item == cutItem)   cutPerformed();      else if(item == copyItem)   copyPerformed();      else if(item == pasteItem)   pastePerformed();      else if(item == deleteItem)   deletePerformed();      else if(item == findItem)   findPerformed();      else if(item == findNextItem)   findNextPerformed();      else if(item == replaceItem)   replacePerformed();      else if(item == goToLineItem)   goToLinePerformed();      else if(item == selectAllItem)   selectAllPerformed();      else if(item == timeItem)   timePerformed();      else if(item == autoNextLineItem)   autoNextLinePerformed();      else if(item == fontItem)   fontPerformed();      else if(item == helpItem)   helpPerformed();      else if(item == aboutItem)   aboutPerformed();  }     } }
   
 
  |