日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

Java实现简易文本编辑器

發布時間:2023/12/10 java 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java实现简易文本编辑器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據結構課設要求完成一個簡易文本編輯器,以下記錄完成過程中的思路,學習到的新知識,遇到的問題和解決方案等。

要求至少實現以下要求:
1)具有圖形菜單界面
2)查找,替換(等長, 不等長),插入(插串,文本塊的插入)、快移動(行塊,列塊移動),刪除
3)可正確存盤、取盤
4)正確顯示總行數

新學到的方法:

  • ActionEvent 的 getSource()
    繼承自 EventObject;返回最初發生 Event 的對象。

  • public int getlineofoffset(int offset) throws badlocationexception
    將文本中的偏移量offset轉化為行號

  • public int getCaretPosition()
    返回文本插入符的位置。插入符的位置被限制在 0 和文本最后一個字符(包括)之間。如果沒有設置文本或插入符,則默認插入符的位置為 0。

  • indexOf() 方法有以下四種形式:
    public int indexOf(int ch): 返回指定字符在字符串中第一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
    public int indexOf(int ch, int fromIndex): 返回從 fromIndex 位置開始查找指定字符在字符串中第一次出現處的索引,如果此字符串中沒有這樣的字符,則返回-1。
    int indexOf(String str): 返回指定字符在字符串中第一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1。
    int indexOf(String str, int fromIndex): 返回從 fromIndex 位置開始查找指定字符在字符串中第一次出現處的索引,如果此字符串中沒有這樣的字符,則返回 -1
    同樣的,還有lastIndexOf()返回最后一次出現的位置,反向搜索

  • getDocument()

  • public component getfocusowner()
    如果此窗口為焦點窗口,則返回是焦點窗口的子組件;
    否則(即該窗口不是焦點窗口)返回 null。

  • public boolean isfocused()
    返回:此窗口是否為焦點窗口。如果存在焦點所有者,則焦點窗口就是(或者包含)焦點所有者的窗口。如果不存在焦點所有者,則沒有作為焦點的窗口。
    如果焦點窗口是一個 frame 或 dialog,那么它同時也是一個活動窗口。否則,活動窗口將是擁有焦點窗口的第一個 frame 或 dialog。

出現的問題及解決方案

  • 使用BufferedReader出現中文亂碼的情況
    解決:文件保存的時候設置編碼為“ANSI”

  • 完成選擇文本用鍵盤的左右鍵實現左右移動的時候

input.replaceSelection("");String text = input.getText();text = text.substring(0,position)+sText+text.substring(position,text.length());input.setText(text);input.setCaretPosition(position+sText.length()-1);input.select(input.getCaretPosition()-sText.length()+1, input.getCaretPosition()+1);

我想要實現可以持續進行左右移動的效果,也就是觸發鍵盤監聽器實現左/右移動后仍然選擇該文本,使用input.select(…)其中input是JTextArea文本輸入區域,但是出現的狀況是文本并沒有被選擇中,但是通過調試可以發現文本是被選擇了的只是沒有被高亮,因此思路轉到焦點上,可以發現JTextArea是焦點Componet,但該窗口不是焦點窗口(getFocusOwner()==null)。但是加入System.out.println(getFocusOwner().getX());會報NullPointerException,但是也能實現窗口聚焦的功能,現在還沒解決問題。

完成思路

  • 需要動態地獲取當前光標所在位置
input.addCaretListener(new CaretListener() {@Overridepublic void caretUpdate(CaretEvent e) {JTextArea editArea = (JTextArea)e.getSource();int lineNum = 1;int columnNum = 1;try{int caretpos = editArea.getCaretPosition();//獲取當前光標偏移量lineNum = editArea.getLineOfOffset(caretpos);//獲取當前光標所在位置的行偏移量columnNum = caretpos - editArea.getLineStartOffset(lineNum);//當前光標所在的列位置就是caretpos-這一行最初的列偏移量lineNum += 1;//然后再將行的數目加1(從0開始計算偏移量)}catch(Exception ex) { }updateStatus(lineNum, columnNum);//updateStatus是更新狀態欄的方法}});
  • 需要正確的獲取文本內容的總行數
    不能憑借光標的位置來判斷總行數,應該以最后有內容的一行的行數來作為文本內容的總行數。記錄光標到達過的最大行數maxCaretLine,從這一行開始判斷,如果這一行為空,則再往上一行判斷,如果這一行不為空,則為最后有內容的一行的行數。最初想到的判斷方法是
for(int i = maxCaretLine;i >= 0;i --){String value = input.getText().split("\r\n")[i];if(value != null){line = i;break;}}

但在換行的時候出現了問題,如果以分隔符來判斷,換行后本來maxCaretLine應該等于2了,但是由于換行后用分隔符分割開的數組大小仍然為1(此時換行后還未新增內容)并且中間無論跳多少行都算作一行,所以改用BufferReader來讀取每一行

  • 打開和保存文件的選擇路徑方法我最開始使用的是JFileChooser
int result = 0;String path = null;JFileChooser fileChooser = new JFileChooser();FileSystemView fsv = FileSystemView.getFileSystemView(); System.out.println(fsv.getHomeDirectory()); fileChooser.setCurrentDirectory(fsv.getHomeDirectory());fileChooser.setDialogTitle("打開");fileChooser.setApproveButtonText("確定");fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);fileChooser.addChoosableFileFilter(new FileFilter(){ @Overridepublic String getDescription() {return "文本文件"; }@Overridepublic boolean accept(File f) {if (f.getAbsolutePath().endsWith(".txt") || f.isDirectory()) return true; return false;}});result = fileChooser.showOpenDialog(openning);

但是后來找到了FileDialog(覺得更好看qaq)

  • 文本篩選器:篩選出文本文件
fileChooser.addChoosableFileFilter(new FileFilter() { @Overridepublic String getDescription() {return "文本文件"; }@Overridepublic boolean accept(File f) {if (f.getAbsolutePath().endsWith(".txt") || f.isDirectory()) return true; return false;}});

但是FileDialog對上面的方法不適用,并沒有適用。jdoc的原注釋為:Filename filters do not function in Sun’s reference implementation for Microsoft Windows.
所以就換了一種比較通俗的方法

FileDialog also = new FileDialog(openning,"另存為",FileDialog.SAVE); also.setFile("*.txt;");

直接將要查找的文件名設置為*.txt,就可以直接找到以txt為后綴的文件了。
暫時還沒有找到更合適的篩選器。

  • 實現移動整行和整列的效果:
    思路:【數組】需要標識行數和列數——【二維數組】將每一行的數據保存在一個數組中,每一行用“\n”分割開為數組,每一行的字串再用“”分開,形成二維數組:
String s = input.getText();String[][] a;String[] sFirst=s.split("\n");a=new String[sFirst.length][]; //sFirst.length表示有多少行for(int i=0;i<sFirst.length;i++){String[] sSecond= sFirst[i].split(""); a[i]=new String[sSecond.length];//sSecond.length分別表示每一行有多少列for(int j=0;j<sSecond.length;j++){a[i][j] = sSecond[j];if(maxColumn < a[i].length)maxColumn = a[i].length;}}

但在進行移動的時候,例如將第2行移動到第7行,那么第3-7行都要上移

String[] usedString = a[used-1];int i = used;for(;i < after; i++){a[i-1] = a[i]; }d[after-1] = usedString;

如果行數間隔大的話,for循環的時間就更長了,顯然沒有鏈表方便,【二維鏈表】將每一行的數據保存在一個單向鏈表中,將每一行的表頭保存在一個行鏈表中形成一個二維鏈表,這樣在移動的時候只需要更改一項就可以了。

總結

以上是生活随笔為你收集整理的Java实现简易文本编辑器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。