Javaを使用してコンソールで操作するメモ帳アプリケーションを作成する方法を解説します。この記事では、オブジェクト指向プログラミングの原則を活用し、ファイル操作やユーザー入力処理を含む実践的なアプリケーション開発のプロセスを紹介します。
- 【Java】コンソールで操作するメモ帳アプリを作成(1/2)
- 【Java】コンソールで操作するメモ帳アプリを作成(2/2)
はじめに
この記事のコードをコピペしてEclipseで出力結果を確認してみよう!
コンソールで操作するメモ帳アプリ作成
以下のメモ帳アプリを作成します。
=== メモ帳アプリ ===
現在のメモ: なし
------------------------
1. 新規メモ作成
2. 既存のメモを開く
3. 現在のメモを保存
4. 現在のメモを編集
5. 終了
選択してください:
メモ帳アプリ操作ガイド
アプリケーションの起動:
- Javaがインストールされている環境で、メモ帳アプリケーションを実行します。
- コンソールにメニューが表示されます。
操作 | 選択肢 | 操作手順 | 結果 |
---|---|---|---|
1. 新規メモ作成 | 1 | ・1を入力してEnterキーを押す ・新しいメモの内容をコンソールに入力 ・空行を入力してEnterキーを押す(Enterキーを2回押す) | 新しいメモが作成される |
2. 既存のメモを開く | 2 | ・2を入力してEnterキーを押す ・ファイル選択ダイアログからファイルを選択 | 選択したファイルの内容が読み込まれ、コンソールに表示される |
3. 現在のメモを保存 | 3 | ・3を入力してEnterキーを押す ・ファイル保存ダイアログで保存先とファイル名を指定 | 現在のメモが指定した場所に保存される |
4. 現在のメモを編集 | 4 | ・4を入力してEnterキーを押す ・表示された内容を編集 ・編集終了後、空行を入力してEnterキーを押す(Enterキーを2回押す) ※ 最初の行に’cancel’と入力でキャンセル可能 | メモが更新される (キャンセル時は変更が反映されない) |
5. アプリケーションの終了 | 5 | ・5を入力してEnterキーを押す | アプリケーションが終了する |
このガイドに従って、簡単にメモ帳アプリケーションをご利用いただけます。必要に応じて新しいメモを作成したり、既存のメモを開いて編集・保存できます。
コード例
- クリックするとコードが表示されます。
Note.javaでメモデータの構造と基本操作を実装
/**
* メモを表すクラス
*/
public record Note(String content) {
/**
* コンストラクタ
* @param content メモの内容
*/
public Note {
if (content == null) {
throw new IllegalArgumentException("Content cannot be null");
}
}
}
NotePadApp.javaでメインアプリケーションロジックとユーザーインターフェースを実装
import java.io.File;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
/**
* メモ帳アプリケーションのメインクラス
*/
public class NotePadApp {
private final NoteManager noteManager;
private final Scanner scanner;
private final JFileChooser fileChooser;
/**
* NotePadAppのコンストラクタ
* 必要なオブジェクトの初期化を行う
*/
public NotePadApp() {
this.noteManager = new NoteManager();
this.scanner = new Scanner(System.in);
this.fileChooser = createCustomJFileChooser();
}
/**
* カスタマイズされたJFileChooserを作成する
*/
private JFileChooser createCustomJFileChooser() {
JFileChooser chooser = new JFileChooser() {
@Override
public void approveSelection() {
File selectedFile = getSelectedFile();
if (selectedFile.exists()) {
int response = JOptionPane.showConfirmDialog(this,
"ファイル '" + selectedFile.getName() + "' はすでに存在します。\n上書きしますか?",
"ファイルの上書き確認",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
if (response != JOptionPane.YES_OPTION) {
return;
}
}
super.approveSelection();
}
};
FileNameExtensionFilter filter = new FileNameExtensionFilter("テキストファイル", "txt");
chooser.setFileFilter(filter);
return chooser;
}
/**
* アプリケーションのメインループを実行する
*/
public void run() {
while (true) {
displayMenu();
int choice = scanner.nextInt();
scanner.nextLine(); // 改行文字を消費
switch (choice) {
case 1 -> createNewNote();
case 2 -> openExistingNote();
case 3 -> saveCurrentNote();
case 4 -> editCurrentNote();
case 5 -> {
System.out.println("アプリケーションを終了します。");
return;
}
default -> System.out.println("無効な選択です。もう一度お試しください。");
}
}
}
/**
* メインメニューを表示する
*/
private void displayMenu() {
System.out.println("\n=== メモ帳アプリ ===");
displayCurrentNoteInfo();
System.out.println("1. 新規メモ作成");
System.out.println("2. 既存のメモを開く");
System.out.println("3. 現在のメモを保存");
System.out.println("4. 現在のメモを編集");
System.out.println("5. 終了");
System.out.print("選択してください: ");
}
/**
* 現在のメモの情報を表示する
*/
private void displayCurrentNoteInfo() {
Note currentNote = noteManager.getCurrentNote();
String fileName = noteManager.getCurrentFileName();
if (currentNote != null) {
System.out.println("現在のメモ:");
System.out.println("ファイル名: " + (fileName != null ? fileName : "未保存"));
System.out.println("内容:");
System.out.println(currentNote.content());
System.out.println("------------------------");
} else {
System.out.println("現在のメモ: なし");
System.out.println("------------------------");
}
}
/**
* 新規メモを作成する
*/
private void createNewNote() {
System.out.println("新しいメモの内容を入力してください。入力が終わったら空行を入力してEnterキーを押してください:");
StringBuilder content = new StringBuilder();
String line;
while (!(line = scanner.nextLine()).isEmpty()) {
content.append(line).append("\n");
}
noteManager.setCurrentNote(new Note(content.toString().trim()));
noteManager.setCurrentFileName(null);
System.out.println("新しいメモが作成されました。");
}
/**
* 既存のメモを開く
*/
private void openExistingNote() {
int result = fileChooser.showOpenDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
try {
noteManager.loadNote(selectedFile.getAbsolutePath());
noteManager.setCurrentFileName(selectedFile.getName());
System.out.println("メモを開きました: " + selectedFile.getName());
} catch (Exception e) {
System.out.println("エラー: " + e.getMessage());
}
}
}
/**
* 現在のメモを保存する
*/
private void saveCurrentNote() {
if (noteManager.getCurrentNote() == null) {
System.out.println("保存するメモがありません。");
return;
}
int result = fileChooser.showSaveDialog(null);
if (result == JFileChooser.APPROVE_OPTION) {
File selectedFile = fileChooser.getSelectedFile();
// ファイル名に .txt 拡張子を追加(必要な場合)
if (!selectedFile.getName().toLowerCase().endsWith(".txt")) {
selectedFile = new File(selectedFile.getParentFile(), selectedFile.getName() + ".txt");
}
try {
noteManager.saveNote(selectedFile.getAbsolutePath());
noteManager.setCurrentFileName(selectedFile.getName());
System.out.println("メモを保存しました: " + selectedFile.getName());
} catch (Exception e) {
System.out.println("エラー: " + e.getMessage());
}
}
}
/**
* 現在のメモを編集する
*/
private void editCurrentNote() {
if (noteManager.getCurrentNote() == null) {
System.out.println("編集するメモがありません。新規メモを作成するか、既存のメモを開いてください。");
return;
}
System.out.println("現在のメモ内容を編集します。編集が終わったら空行を入力してください。");
System.out.println("編集をキャンセルする場合は、最初の行に 'cancel' と入力してください。");
System.out.println("現在の内容:");
System.out.println(noteManager.getCurrentNote().content());
StringBuilder newContent = new StringBuilder();
String line = scanner.nextLine();
if ("cancel".equalsIgnoreCase(line.trim())) {
System.out.println("編集をキャンセルしました。");
return;
}
newContent.append(line).append("\n");
while (!(line = scanner.nextLine()).isEmpty()) {
newContent.append(line).append("\n");
}
noteManager.setCurrentNote(new Note(newContent.toString().trim()));
System.out.println("メモが更新されました。");
}
}
NoteManager.javaでメモの管理機能を実装し、ファイル操作の基本
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
/**
* メモの管理を行うクラス
*/
public class NoteManager {
private Note currentNote;
private String currentFileName;
/**
* 現在のメモを取得
* @return 現在のメモ
*/
public Note getCurrentNote() {
return currentNote;
}
/**
* 現在のメモを設定
* @param note 設定するメモ
*/
public void setCurrentNote(Note note) {
this.currentNote = note;
}
/**
* 現在のファイル名を取得
* @return 現在のファイル名
*/
public String getCurrentFileName() {
return currentFileName;
}
/**
* 現在のファイル名を設定
* @param fileName 設定するファイル名
*/
public void setCurrentFileName(String fileName) {
this.currentFileName = fileName;
}
/**
* メモをファイルから読み込む
* @param fileName 読み込むファイル名
* @throws IOException ファイル読み込みエラー時
*/
public void loadNote(String fileName) throws IOException {
Path path = Paths.get(fileName);
String content = Files.readString(path);
this.currentNote = new Note(content);
this.currentFileName = path.getFileName().toString();
}
/**
* 現在のメモをファイルに保存
* @param fileName 保存するファイル名
* @throws IOException ファイル書き込みエラー時
*/
public void saveNote(String fileName) throws IOException {
if (currentNote == null) {
throw new IllegalStateException("No note to save");
}
Path path = Paths.get(fileName);
Files.writeString(path, currentNote.content());
this.currentFileName = path.getFileName().toString();
}
}
Main.javaで開始地点を実装
/**
* メモ帳アプリケーションのメインクラス
*/
public class Main {
/**
* アプリケーションのエントリーポイント
* @param args コマンドライン引数(使用しない)
*/
public static void main(String[] args) {
NotePadApp app = new NotePadApp();
app.run();
}
}
Note.javaの解説
クラスの定義
public record Note(String content) {
// ...
}
- この行は
Note
という名前のレコードクラスを定義しています。 record
はJava 14以降で導入された新しい機能で、データを保持するためのクラスを簡潔に定義できます。(String content)
は、このレコードが1つのString
型フィールドcontent
を持つことを示しています。
コンストラクタ
public Note {
if (content == null) {
throw new IllegalArgumentException("Content cannot be null");
}
}
- これはコンパクトコンストラクタと呼ばれる特別なコンストラクタです。
- レコードクラスでは、通常のコンストラクタの代わりにこの形式を使用できます。
- このコンストラクタは、
content
がnull
でないことを確認しています。 null
の場合、IllegalArgumentException
という例外をスローします。
JavaDoc コメント
/**
* メモを表すクラス
*/
/**
* コンストラクタ
* @param content メモの内容
*/
- これらはJavaDocコメントと呼ばれる特別なコメントです。
- クラスやメソッドの説明を記述するために使用され、ドキュメント生成ツールで利用されます。
重要なポイント
- レコードクラスの使用:データを保持するための簡潔な方法を提供します。
- null チェック:コンストラクタで
null
チェックを行い、無効なデータの作成を防いでいます。 - 例外処理:不正な引数に対して適切な例外をスローしています。
- ドキュメンテーション:JavaDocを使用して、コードの目的と使用方法を明確に説明しています。
このコードは、シンプルながら堅牢なデータ構造を作成する良い例です。null安全性を確保し、適切にドキュメント化されています。
NotePadApp.javaの解説
インポート文
import java.io.File;
import java.util.Scanner;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
これらは必要なクラスをインポートしています:
File
: ファイル操作に使用Scanner
: ユーザー入力の読み取りに使用JFileChooser
: ファイル選択ダイアログを表示JOptionPane
: メッセージダイアログを表示FileNameExtensionFilter
: ファイル選択時のフィルタリングに使用
クラス定義
/**
* メモ帳アプリケーションのメインクラス
*/
public class NotePadApp {
// ...
}
これはNotePadApp
クラスの定義です。JavaDocコメントでクラスの目的を説明しています。
フィールド
private final NoteManager noteManager;
private final Scanner scanner;
private final JFileChooser fileChooser;
これらはクラスのメンバー変数(フィールド)です:
noteManager
: メモの管理を担当scanner
: ユーザー入力の読み取りに使用fileChooser
: ファイル選択ダイアログを表示するために使用
コンストラクタ
/**
* NotePadAppのコンストラクタ
* 必要なオブジェクトの初期化を行う
*/
public NotePadApp() {
this.noteManager = new NoteManager();
this.scanner = new Scanner(System.in);
this.fileChooser = createCustomJFileChooser();
}
このコンストラクタは、アプリケーションの初期化を行います:
NoteManager
のインスタンスを作成Scanner
を標準入力で初期化- カスタマイズされた
JFileChooser
を作成
カスタムJFileChooserの作成
メソッド定義
/**
* カスタマイズされたJFileChooserを作成する
*/
private JFileChooser createCustomJFileChooser() {
// ...
}
- これは
createCustomJFileChooser
というプライベートメソッドです。 JFileChooser
オブジェクトを返します。- JavaDocコメントでメソッドの目的を説明しています。
JFileChooserのカスタマイズ
JFileChooser chooser = new JFileChooser() {
@Override
public void approveSelection() {
// ...
}
};
- 新しい
JFileChooser
インスタンスを作成しています。 - 無名内部クラスを使用して
JFileChooser
を拡張しています。 approveSelection
メソッドをオーバーライドして、カスタム動作を追加しています。
ファイル上書き確認ロジック
File selectedFile = getSelectedFile();
if (selectedFile.exists()) {
int response = JOptionPane.showConfirmDialog(this,
"ファイル '" + selectedFile.getName() + "' はすでに存在します。\n上書きしますか?",
"ファイルの上書き確認",
JOptionPane.YES_NO_OPTION,
JOptionPane.WARNING_MESSAGE);
if (response != JOptionPane.YES_OPTION) {
return;
}
}
- 選択されたファイルが既に存在するかチェックします。
- 存在する場合、確認ダイアログを表示します。
- ユーザーが「はい」を選択しない場合、メソッドを終了します。
親クラスのメソッド呼び出し
super.approveSelection();
- 親クラス(
JFileChooser
)のapproveSelection
メソッドを呼び出します。 - これにより、標準の選択承認処理が実行されます。
ファイルフィルターの設定
FileNameExtensionFilter filter = new FileNameExtensionFilter("テキストファイル", "txt");
chooser.setFileFilter(filter);
FileNameExtensionFilter
を作成し、.txtファイルのみを表示するよう設定しています。- このフィルターを
JFileChooser
に適用しています。
カスタマイズされたJFileChooserの返却
return chooser;
- カスタマイズされた
JFileChooser
オブジェクトを返します。
重要なポイント:
- カスタム動作: 標準の
JFileChooser
に、ファイル上書き確認機能を追加しています。 - 無名内部クラス:
JFileChooser
を拡張するために使用され、柔軟なカスタマイズを可能にしています。 - ユーザーインターフェース:
JOptionPane
を使用して、ユーザーに確認ダイアログを表示しています。 - ファイルフィルタリング:
FileNameExtensionFilter
を使用して、特定の拡張子(.txt)のファイルのみを表示するようにしています。 - メソッドのオーバーライド:
approveSelection
メソッドをオーバーライドして、標準の動作を拡張しています。
このコードは、ファイル選択ダイアログをカスタマイズする高度な例を示しています。ユーザー体験を向上させるために、標準のコンポーネントを拡張し、追加機能を実装しています。
アプリケーションのメインループ
メソッド定義
/**
* アプリケーションのメインループを実行する
*/
public void run() {
// ...
}
- これは
run
というパブリックメソッドです。 - アプリケーションのメインループを実行します。
- JavaDocコメントでメソッドの目的を説明しています。
無限ループ
while (true) {
// ...
}
while (true)
は無限ループを作成します。- これにより、ユーザーが明示的に終了するまでアプリケーションが継続して実行されます。
メニュー表示とユーザー入力
displayMenu();
int choice = scanner.nextInt();
scanner.nextLine(); // 改行文字を消費
displayMenu()
メソッドを呼び出して、メニューを表示します。scanner.nextInt()
でユーザーの選択を読み取ります。scanner.nextLine()
は、入力後の改行文字を消費します。
switch文による選択処理
switch (choice) {
case 1 -> createNewNote();
case 2 -> openExistingNote();
case 3 -> saveCurrentNote();
case 4 -> editCurrentNote();
case 5 -> {
System.out.println("アプリケーションを終了します。");
return;
}
default -> System.out.println("無効な選択です。もう一度お試しください。");
}
switch
文を使用して、ユーザーの選択に基づいて異なるアクションを実行します。- これはJava 14以降で導入された新しいswitch式の構文です。
- 各
case
は特定のメソッドを呼び出すか、特定のアクションを実行します。 case 5
では、アプリケーションを終了するメッセージを表示し、return
でメソッドを終了します。default
は、無効な選択に対するフォールバックです。
重要なポイント:
- 無限ループ: アプリケーションを継続的に実行し、ユーザーが明示的に終了するまで動作し続けます。
- ユーザー入力:
Scanner
クラスを使用して、ユーザーからの入力を受け取ります。 - メニュー駆動型インターフェース: ユーザーの選択に基づいて異なる操作を実行する、典型的なコンソールアプリケーションの構造を示しています。
- モジュール化: 各操作(新規作成、開く、保存、編集)が別々のメソッドとして実装されており、コードの整理と保守性を向上させています。
- エラー処理: 無効な選択に対して適切なメッセージを表示し、ユーザーに再試行を促しています。
- アプリケーションの終了: ユーザーが特定の選択(ここでは5)をした場合に、アプリケーションを適切に終了する方法を示しています。
このコードは、シンプルながら効果的なコンソールアプリケーションの中心的な制御構造を示しています。ユーザーとの対話、異なる操作の実行、そしてアプリケーションのライフサイクル管理の基本的な概念を含んでいます。
メニュー表示
/**
* メインメニューを表示する
*/
private void displayMenu() {
System.out.println("\n=== メモ帳アプリ ===");
displayCurrentNoteInfo();
System.out.println("1. 新規メモ作成");
System.out.println("2. 既存のメモを開く");
System.out.println("3. 現在のメモを保存");
System.out.println("4. 現在のメモを編集");
System.out.println("5. 終了");
System.out.print("選択してください: ");
}
このメソッドはメインメニューを表示します。
現在のメモ情報の表示
メソッド定義
/**
* 現在のメモの情報を表示する
*/
private void displayCurrentNoteInfo() {
// ...
}
- これは
displayCurrentNoteInfo
というプライベートメソッドです。 - 現在のメモの情報を表示する役割を持ちます。
- JavaDocコメントでメソッドの目的を説明しています。
現在のメモとファイル名の取得
Note currentNote = noteManager.getCurrentNote();
String fileName = noteManager.getCurrentFileName();
noteManager
から現在のメモとファイル名を取得しています。- これらの情報は
NoteManager
クラスで管理されています。
メモの存在チェックと情報表示
if (currentNote != null) {
// ...
} else {
// ...
}
- if文を使用して、現在のメモが存在するかどうかをチェックしています。
メモが存在する場合の処理
System.out.println("現在のメモ:");
System.out.println("ファイル名: " + (fileName != null ? fileName : "未保存"));
System.out.println("内容:");
System.out.println(currentNote.content());
System.out.println("------------------------");
- メモが存在する場合、以下の情報を表示します:
- “現在のメモ:” というヘッダー
- ファイル名(ファイル名が
null
の場合は “未保存” と表示) - “内容:” というラベル
- メモの実際の内容(
currentNote.content()
) - 区切り線
(fileName != null ? fileName : "未保存")
は三項演算子を使用しています。これは以下のif文と同等です:
if (fileName != null) {
System.out.println("ファイル名: " + fileName);
} else {
System.out.println("ファイル名: 未保存");
}
メモが存在しない場合の処理
System.out.println("現在のメモ: なし");
System.out.println("------------------------");
- メモが存在しない場合(
currentNote
がnull
の場合)、
“現在のメモ: なし” というメッセージと区切り線を表示します。
重要なポイント:
- Null チェック:
currentNote
がnull
かどうかをチェックして、適切な情報を表示しています。 - 条件付き表示: ファイル名の表示に三項演算子を使用して、コードを簡潔にしています。
- 情報の構造化: メモの情報を見やすく構造化して表示しています(ヘッダー、ファイル名、内容)。
- 区切り線の使用: 情報の前後に区切り線を表示して、視覚的に情報を分離しています。
- メソッドの単一責任: このメソッドは「現在のメモの情報を表示する」という単一の責任を持っています。
このコードは、ユーザーに現在の状態を明確に伝えるための情報表示の良い例です。条件分岐を使って異なるシナリオ(メモが存在する場合と存在しない場合)を適切に処理し、ユーザーフレンドリーな出力を生成しています。
新規メモ作成
メソッド定義
/**
* 新規メモを作成する
*/
private void createNewNote() {
// ...
}
- これは
createNewNote
というプライベートメソッドです。 - 新しいメモを作成する機能を提供します。
- JavaDocコメントでメソッドの目的を説明しています。
ユーザーへの指示
System.out.println("新しいメモの内容を入力してください。入力が終わったら空行を入力してEnterキーを押してください:");
- ユーザーに対して、新しいメモの入力方法を説明しています。
- 空行が入力の終了を示すことを伝えています。
入力内容の蓄積
StringBuilder content = new StringBuilder();
String line;
while (!(line = scanner.nextLine()).isEmpty()) {
content.append(line).append("\n");
}
StringBuilder
を使用して、入力された内容を効率的に蓄積します。while
ループを使用して、ユーザーが空行を入力するまで続けて入力を受け付けます。scanner.nextLine()
で1行ずつ読み取り、isEmpty()
で空行かどうかをチェックします。- 各行を
StringBuilder
に追加し、改行(\n
)も付け加えています。
新しいメモの作成
noteManager.setCurrentNote(new Note(content.toString().trim()));
StringBuilder
の内容を文字列に変換し、余分な空白を削除(trim()
)します。- この内容で新しい
Note
オブジェクトを作成し、noteManager
の現在のメモとして設定します。
ファイル名のリセット
noteManager.setCurrentFileName(null);
- 新しいメモはまだ保存されていないので、現在のファイル名を
null
に設定します。
完了メッセージ
System.out.println("新しいメモが作成されました。");
- ユーザーに対して、新しいメモが正常に作成されたことを通知します。
重要なポイント:
- ユーザーインターフェース: 明確な指示をユーザーに提供し、使いやすさを向上させています。
- 動的な入力処理:
while
ループを使用して、ユーザーが望む量の入力を受け付けられるようにしています。 - 効率的な文字列処理:
StringBuilder
を使用して、大量のテキスト入力を効率的に処理しています。 - 入力の終了条件: 空行を入力の終了条件として使用し、ユーザーが簡単に入力を完了できるようにしています。
- 状態管理:
NoteManager
を使用して、新しいメモの状態(内容とファイル名)を適切に管理しています。 - フィードバック: 操作の完了をユーザーに通知し、アプリケーションの状態を明確にしています。
このコードは、ユーザー入力の処理、文字列の効率的な操作、オブジェクト指向プログラミングの原則(NoteManager
の使用)を示す良い例です。また、ユーザーフレンドリーなインターフェースの設計も示しています。
既存のメモを開く
メソッド定義
/**
* 既存のメモを開く
*/
private void openExistingNote() {
// ...
}
- これは
openExistingNote
というプライベートメソッドです。 - 既存のメモファイルを開く機能を提供します。
- JavaDocコメントでメソッドの目的を説明しています。
ファイル選択ダイアログの表示
int result = fileChooser.showOpenDialog(null);
JFileChooser
を使用して、ファイル選択ダイアログを表示します。showOpenDialog(null)
は、ダイアログを表示し、ユーザーの操作結果を返します。null
は親コンポーネントがないことを示します(独立したダイアログとして表示)。
ユーザーの選択結果の確認
if (result == JFileChooser.APPROVE_OPTION) {
// ...
}
- ユーザーがファイルを選択して「開く」ボタンをクリックしたかどうかを確認します。
JFileChooser.APPROVE_OPTION
は、ユーザーが選択を承認したことを示す定数です。
選択されたファイルの取得
File selectedFile = fileChooser.getSelectedFile();
- ユーザーが選択したファイルの
File
オブジェクトを取得します。
ファイルの読み込みと例外処理
try {
noteManager.loadNote(selectedFile.getAbsolutePath());
noteManager.setCurrentFileName(selectedFile.getName());
System.out.println("メモを開きました: " + selectedFile.getName());
} catch (Exception e) {
System.out.println("エラー: " + e.getMessage());
}
- try-catchブロックを使用して、ファイル読み込み時の例外を処理します。
noteManager.loadNote()
メソッドを呼び出して、選択されたファイルを読み込みます。getAbsolutePath()
でファイルの絶対パスを取得します。- 読み込みが成功したら、現在のファイル名を設定し、成功メッセージを表示します。
- 例外が発生した場合、エラーメッセージを表示します。
重要なポイント:
- ユーザーインターフェース:
JFileChooser
を使用して、グラフィカルなファイル選択インターフェースを提供しています。 - ユーザーの選択の確認:
JFileChooser.APPROVE_OPTION
を使用して、ユーザーが実際にファイルを選択したかどうかを確認しています。 - 例外処理: try-catchブロックを使用して、ファイル読み込み時に発生する可能性のあるエラーを適切に処理しています。
- 状態管理:
NoteManager
を使用して、開いたメモの状態(内容とファイル名)を管理しています。 - フィードバック: ファイルを開いた後、またはエラーが発生した場合に、適切なメッセージをユーザーに表示しています。
- ファイル操作:
File
クラスを使用して、ファイルのパスと名前を取得しています。
このコードは、ファイル選択、例外処理、オブジェクト指向プログラミング(NoteManager
の使用)の良い例です。また、ユーザーフレンドリーなインターフェースとエラー処理を組み合わせて、堅牢なファイル操作機能を提供しています。
現在のメモを保存
メソッド定義
/**
* 現在のメモを保存する
*/
private void saveCurrentNote() {
// ...
}
- これは
saveCurrentNote
というプライベートメソッドです。 - 現在のメモをファイルに保存する機能を提供します。
- JavaDocコメントでメソッドの目的を説明しています。
保存するメモの存在確認
if (noteManager.getCurrentNote() == null) {
System.out.println("保存するメモがありません。");
return;
}
- 現在のメモが存在するかどうかをチェックします。
- メモがない場合は、メッセージを表示してメソッドを終了します。
ファイル保存ダイアログの表示
int result = fileChooser.showSaveDialog(null);
JFileChooser
を使用して、ファイル保存ダイアログを表示します。showSaveDialog(null)
は、保存ダイアログを表示し、ユーザーの操作結果を返します。
ユーザーの選択結果の確認
if (result == JFileChooser.APPROVE_OPTION) {
// ...
}
- ユーザーがファイル名を入力して「保存」ボタンをクリックしたかどうかを確認します。
選択されたファイルの取得と拡張子の確認
File selectedFile = fileChooser.getSelectedFile();
if (!selectedFile.getName().toLowerCase().endsWith(".txt")) {
selectedFile = new File(selectedFile.getParentFile(), selectedFile.getName() + ".txt");
}
- ユーザーが選択したファイルの
File
オブジェクトを取得します。 - ファイル名が.txt拡張子で終わっていない場合、自動的に追加します。
ファイルの保存と例外処理
try {
noteManager.saveNote(selectedFile.getAbsolutePath());
noteManager.setCurrentFileName(selectedFile.getName());
System.out.println("メモを保存しました: " + selectedFile.getName());
} catch (Exception e) {
System.out.println("エラー: " + e.getMessage());
}
- try-catchブロックを使用して、ファイル保存時の例外を処理します。
noteManager.saveNote()
メソッドを呼び出して、選択されたファイルにメモを保存します。- 保存が成功したら、現在のファイル名を更新し、成功メッセージを表示します。
- 例外が発生した場合、エラーメッセージを表示します。
重要なポイント:
- Null チェック: 保存するメモが存在するかどうかを最初に確認しています。
- ユーザーインターフェース:
JFileChooser
を使用して、グラフィカルなファイル保存インターフェースを提供しています。 - ファイル拡張子の自動追加: ユーザーが.txt拡張子を付け忘れた場合に自動的に追加する機能があります。
- 例外処理: try-catchブロックを使用して、ファイル保存時に発生する可能性のあるエラーを適切に処理しています。
- 状態管理:
NoteManager
を使用して、保存したメモの状態(ファイル名)を更新しています。 - フィードバック: ファイルの保存後、またはエラーが発生した場合に、適切なメッセージをユーザーに表示しています。
このコードは、ファイル保存操作、例外処理、ユーザーインターフェース設計の良い例です。また、ファイル名の自動修正など、ユーザーの利便性を考慮した機能も含まれています。
現在のメモを編集
メソッド定義
/**
* 現在のメモを編集する
*/
private void editCurrentNote() {
// ...
}
- これは
editCurrentNote
というプライベートメソッドです。 - 現在のメモを編集する機能を提供します。
- JavaDocコメントでメソッドの目的を説明しています。
編集するメモの存在確認
if (noteManager.getCurrentNote() == null) {
System.out.println("編集するメモがありません。新規メモを作成するか、既存のメモを開いてください。");
return;
}
- 現在のメモが存在するかどうかをチェックします。
- メモがない場合は、メッセージを表示してメソッドを終了します。
編集指示の表示
System.out.println("現在のメモ内容を編集します。編集が終わったら空行を入力してください。");
System.out.println("編集をキャンセルする場合は、最初の行に 'cancel' と入力してください。");
System.out.println("現在の内容:");
System.out.println(noteManager.getCurrentNote().content());
- ユーザーに編集方法を説明します。
- 現在のメモの内容を表示します。
編集内容の入力と処理
StringBuilder newContent = new StringBuilder();
String line = scanner.nextLine();
if ("cancel".equalsIgnoreCase(line.trim())) {
System.out.println("編集をキャンセルしました。");
return;
}
newContent.append(line).append("\n");
while (!(line = scanner.nextLine()).isEmpty()) {
newContent.append(line).append("\n");
}
StringBuilder
を使用して新しい内容を蓄積します。- 最初の行で‘cancel’が入力されたかチェックし、キャンセル処理を行います。
while
ループを使用して、空行が入力されるまで続けて入力を受け付けます。
編集内容の保存
noteManager.setCurrentNote(new Note(newContent.toString().trim()));
System.out.println("メモが更新されました。");
- 新しい内容で
Note
オブジェクトを作成し、noteManager
の現在のメモとして設定します。 - 更新完了のメッセージを表示します。
重要なポイント:
- Null チェック: 編集するメモが存在するかどうかを最初に確認しています。
- ユーザーガイダンス: 編集方法や現在の内容を明確に表示し、ユーザーをガイドしています。
- キャンセル機能: ユーザーが’cancel’を入力することで編集をキャンセルできる機能を提供しています。
- 動的な入力処理:
while
ループを使用して、ユーザーが望む量の入力を受け付けられるようにしています。 - 効率的な文字列処理:
StringBuilder
を使用して、大量のテキスト入力を効率的に処理しています。 - 状態管理:
NoteManager
を使用して、編集されたメモの状態を更新しています。 - フィードバック: 編集完了時にメッセージを表示し、操作の結果をユーザーに通知しています。
このコードは、ユーザー入力の処理、文字列操作、状態管理の良い例です。また、ユーザーフレンドリーなインターフェース設計も示しており、ユーザーに明確な指示を提供しながら、柔軟な編集機能を実現しています。
まとめ
- Note.javaでメモデータの構造と基本操作を実装
- NotePadApp.javaでメインアプリケーションロジックとユーザーインターフェースを実装
- ファイル操作(読み込み、保存)の実装方法
- 例外処理を通じて、堅牢なエラーハンドリングの実装方法
- JavaDocを使用した効果的なドキュメンテーションの作成方法
- カスタムJFileChooserの作成を通じて、GUIコンポーネントのカスタマイズ方法
このメモ帳アプリケーションの作成を通じて、Javaプログラミングの実践的なスキルと重要な概念を身につけることができます。クラス設計、ファイルI/O、ユーザー入力の処理、例外処理など、実際のアプリケーション開発で必要となる重要な要素を学ぶことができます。
特に、ファイル操作の実装は、多くのアプリケーション開発で必要とされる重要なスキルです。また、カスタムJFileChooserの作成を通じて、GUIプログラミングの基礎も学ぶことができます。
追加の機能(例:テキスト検索、自動保存、複数ファイルの同時編集など)を実装することで、さらに複雑なアプリケーションへと発展させることができます。
コメント