首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 實作記事本程式:選單、檔案操作、尋找取代與右鍵選單

     編輯:Java 程式設計入門

本文展示一個基於 Swing 的完整記事本程式原始碼,包含選單列 (檔案/編輯/格式/說明)、工具列、狀態列、右鍵彈出選單、檔案新增/開啟/儲存/另存新檔、編輯剪貼簿操作、尋找/取代對話框、字型/顏色選擇、自動換行、日期時間插入 等功能。僅「復原」功能待實作。

核心架構

  • 主類別 Jsb:繼承無、包含所有 UI 元件與事件處理邏輯。
  • 元件:JFrame 視窗、JTextArea 編輯區、JScrollPane 捲軸、JMenuBar 選單列、JPopupMenu 右鍵選單、JFileChooser 檔案選擇器、JColorChooser 顏色選擇器。
  • 事件處理:採用適配器類別命名慣例 (如 File_new_actionAdapter) 分離事件邏輯,主類別提供具體實作方法 (如 File_new_actionPerformed)。
  • 資料狀態:dirty 標記內容是否修改、filename 記錄目前檔案路徑。

關鍵功能實作片段

1. 選單與右鍵選單建構

// 主選單列
JMenuBar mbar = new JMenuBar();
JMenu fileMenu = new JMenu("檔案"); fileMenu.setMnemonic('F');
JMenu editMenu = new JMenu("編輯"); editMenu.setMnemonic('E');
// ... 加入選單項、設定加速鍵 (Ctrl+N, Ctrl+O, Ctrl+S 等)
// 右鍵選單
JPopupMenu popup = new JPopupMenu();
JMenuItem pUndo = new JMenuItem("復原"); pUndo.addActionListener(e -> undo());
// ... 加入剪下、複製、貼上、刪除
textArea.addMouseListener(new MouseAdapter() {
    public void mousePressed(MouseEvent e) { checkPopup(e); }
    public void mouseReleased(MouseEvent e) { checkPopup(e); }
    private void checkPopup(MouseEvent e) {
        if (e.isPopupTrigger()) popup.show(textArea, e.getX(), e.getY());
    }
});

2. 檔案操作 (開啟/儲存)

private void openFile() {
    if (jFileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION) {
        File f = jFileChooser.getSelectedFile();
        try (BufferedReader br = new BufferedReader(new FileReader(f))) {
            textArea.read(br, null); // JTextComponent 內建讀取
            filename = f.getAbsolutePath();
            dirty = false;
            frame.setTitle("記事本 - " + f.getName());
        } catch (IOException ex) { showError(ex); }
    }
}

private void saveFile() {
    if (filename.isEmpty()) saveAsFile();
    else writeToFile(new File(filename));
}

private void saveAsFile() {
    if (jFileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION) {
        writeToFile(jFileChooser.getSelectedFile());
    }
}

private void writeToFile(File f) {
    try (BufferedWriter bw = new BufferedWriter(new FileWriter(f))) {
        textArea.write(bw); // 內建寫入
        filename = f.getAbsolutePath();
        dirty = false;
        frame.setTitle("記事本 - " + f.getName());
    } catch (IOException ex) { showError(ex); }
}

3. 尋找 / 取代對話框

// 尋找
private void find() {
    FindDialog dlg = new FindDialog(frame, "尋找", true);
    dlg.setVisible(true);
    if (dlg.isFound()) {
        String target = dlg.getFindText();
        int start = textArea.getCaretPosition();
        int end = textArea.getText().length();
        if (dlg.isForward()) findForward(target, start, end);
        else findBackward(target, start);
    }
}

private void findForward(String target, int start, int end) {
    String text = textArea.getText();
    int pos = text.indexOf(target, start);
    if (pos >= 0) {
        textArea.setCaretPosition(pos + target.length());
        textArea.moveCaretPosition(pos); // 反向選取
    } else { showMessage("找不到:" + target); }
}

// 取代
private void replace() {
    ReplaceDialog dlg = new ReplaceDialog(frame, "取代", true);
    dlg.setVisible(true);
    if (dlg.isConfirmed()) {
        String find = dlg.getFindText(), repl = dlg.getReplaceText();
        String text = textArea.getText();
        int pos = text.indexOf(find, textArea.getCaretPosition());
        while (pos >= 0) {
            textArea.select(pos, pos + find.length());
            textArea.replaceSelection(repl);
            pos = text.indexOf(find, pos + repl.length());
        }
    }
}

4. 字型與顏色選擇

private void chooseFont() {
    // 簡易字型選擇對話框 (可用 JFontChooser 第三方或自行組合)
    String[] fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
    String fontName = (String) JOptionPane.showInputDialog(frame, "選擇字型", "字型", 
        JOptionPane.PLAIN_MESSAGE, null, fonts, textArea.getFont().getFamily());
    if (fontName != null) {
        textArea.setFont(new Font(fontName, textArea.getFont().getStyle(), textArea.getFont().getSize()));
    }
}

private void chooseColor() {
    Color c = JColorChooser.showDialog(frame, "選擇文字顏色", textArea.getForeground());
    if (c != null) textArea.setForeground(c);
}

5. 視窗關閉與髒資料檢查

frame.addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) { exitApp(); }
});

private void exitApp() {
    if (dirty) {
        int opt = JOptionPane.showConfirmDialog(frame, "檔案已修改,是否儲存?", "確認", 
            JOptionPane.YES_NO_CANCEL_OPTION);
        if (opt == JOptionPane.YES_OPTION) saveFile();
        else if (opt == JOptionPane.CANCEL_OPTION) return;
    }
    System.exit(0);
}

待完善項目與改進建議

  1. 復原/重做:使用 UndoManager 監聽 Document 事件,undoManager.addEdit(),選單項綁定 undoManager.undo()/redo()。
  2. 行號顯示:自訂 JTextComponent 左側行號區 (JComponent.setBorder + paintComponent)。
  3. 語法高亮:實作 DocumentFilter 或使用 RSyntaxTextArea 第三方元件。
  4. 編碼支援:開啟/儲存時提供編碼選擇 (UTF-8, Big5, GBK 等),使用 InputStreamReader/OutputStreamWriter 指定編碼。
  5. 多文件分頁:改用 JTabbedPane,每個分頁一個 JTextArea + 狀態。
  6. 拖放開啟:實作 DropTargetListener 處理檔案拖放。

完整原始碼結構

原始碼約 600 行,單一檔案 Jsb.java,包含主類別、7 個適配器內部類別、2 個對話框內部類別 (FindDialog, ReplaceDialog)。編譯執行:

javac Jsb.java
java jeason.Jsb

套件宣告為 package jeason;,請對應目錄結構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved