JavaJavaコンソールアプリ

【Java】コンソールで操作するメモ帳アプリを作成(1/2)

Javaメモ帳アプリ解説ページ1のアイキャッチ画像 Java

Javaを使用してコンソールで操作するメモ帳アプリケーションを作成する方法を解説します。この記事では、オブジェクト指向プログラミングの原則を活用し、ファイル操作ユーザー入力処理を含む実践的なアプリケーション開発のプロセスを紹介します。

はじめに

この記事のコードをコピペしてEclipseで出力結果を確認してみよう

コンソールで操作するメモ帳アプリ作成

以下のメモ帳アプリを作成します。

=== メモ帳アプリ ===
現在のメモ: なし
------------------------
1. 新規メモ作成
2. 既存のメモを開く
3. 現在のメモを保存
4. 現在のメモを編集
5. 終了
選択してください: 

メモ帳アプリ操作ガイド

アプリケーションの起動:

  1. Javaがインストールされている環境で、メモ帳アプリケーションを実行します。
  2. コンソールにメニューが表示されます。
操作選択肢操作手順結果
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メモデータの構造基本操作を実装

Java
/**
 * メモを表すクラス
 */
public record Note(String content) {
	/**
	 * コンストラクタ
	 * @param content メモの内容
	 */
	public Note {
		if (content == null) {
			throw new IllegalArgumentException("Content cannot be null");
		}
	}
}

NotePadApp.javaメインアプリケーションロジックユーザーインターフェースを実装

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メモの管理機能を実装し、ファイル操作の基本

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で開始地点を実装

Java
/**
 * メモ帳アプリケーションのメインクラス
 */
public class Main {
	/**
	 * アプリケーションのエントリーポイント
	 * @param args コマンドライン引数(使用しない)
	 */
	public static void main(String[] args) {
		NotePadApp app = new NotePadApp();
		app.run();
	}
}

Note.javaの解説

クラスの定義

Java
public record Note(String content) {
    // ...
}
  • この行はNoteという名前のレコードクラスを定義しています。
  • recordはJava 14以降で導入された新しい機能で、データを保持するためのクラスを簡潔に定義できます。
  • (String content)は、このレコードが1つのString型フィールドcontentを持つことを示しています。

コンストラクタ

Java
public Note {
    if (content == null) {
        throw new IllegalArgumentException("Content cannot be null");
    }
}
  • これはコンパクトコンストラクタと呼ばれる特別なコンストラクタです。
  • レコードクラスでは、通常のコンストラクタの代わりにこの形式を使用できます。
  • このコンストラクタは、contentnullでないことを確認しています。
  • nullの場合、IllegalArgumentExceptionという例外をスローします。

JavaDoc コメント

Java
/**
 * メモを表すクラス
 */
Java
/**
 * コンストラクタ
 * @param content メモの内容
 */
  • これらはJavaDocコメントと呼ばれる特別なコメントです。
  • クラスやメソッドの説明を記述するために使用され、ドキュメント生成ツールで利用されます。

重要なポイント

  1. レコードクラスの使用:データを保持するための簡潔な方法を提供します。
  2. null チェック:コンストラクタでnullチェックを行い、無効なデータの作成を防いでいます。
  3. 例外処理:不正な引数に対して適切な例外をスローしています。
  4. ドキュメンテーション:JavaDocを使用して、コードの目的と使用方法を明確に説明しています。

このコードは、シンプルながら堅牢なデータ構造を作成する良い例です。null安全性を確保し、適切にドキュメント化されています。

NotePadApp.javaの解説

インポート文

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: ファイル選択時のフィルタリングに使用

クラス定義

Java
/**
 * メモ帳アプリケーションのメインクラス
 */
public class NotePadApp {
    // ...
}

これはNotePadAppクラスの定義です。JavaDocコメントでクラスの目的を説明しています。

フィールド

Java
private final NoteManager noteManager;
private final Scanner scanner;
private final JFileChooser fileChooser;

これらはクラスのメンバー変数(フィールド)です:

  • noteManager: メモの管理を担当
  • scanner: ユーザー入力の読み取りに使用
  • fileChooser: ファイル選択ダイアログを表示するために使用

コンストラクタ

Java
/**
 * NotePadAppのコンストラクタ
 * 必要なオブジェクトの初期化を行う
 */
public NotePadApp() {
    this.noteManager = new NoteManager();
    this.scanner = new Scanner(System.in);
    this.fileChooser = createCustomJFileChooser();
}

このコンストラクタは、アプリケーションの初期化を行います:

  • NoteManagerのインスタンスを作成
  • Scannerを標準入力で初期化
  • カスタマイズされたJFileChooserを作成

カスタムJFileChooserの作成

メソッド定義

Java
/**
 * カスタマイズされたJFileChooserを作成する
 */
private JFileChooser createCustomJFileChooser() {
    // ...
}
  • これはcreateCustomJFileChooserというプライベートメソッドです。
  • JFileChooserオブジェクトを返します。
  • JavaDocコメントでメソッドの目的を説明しています。

JFileChooserのカスタマイズ

Java
JFileChooser chooser = new JFileChooser() {
    @Override
    public void approveSelection() {
        // ...
    }
};
  • 新しいJFileChooserインスタンスを作成しています。
  • 無名内部クラスを使用してJFileChooserを拡張しています。
  • approveSelectionメソッドをオーバーライドして、カスタム動作を追加しています。

ファイル上書き確認ロジック

Java
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;
    }
}
  • 選択されたファイルが既に存在するかチェックします。
  • 存在する場合、確認ダイアログを表示します。
  • ユーザーが「はい」を選択しない場合、メソッドを終了します。

親クラスのメソッド呼び出し

Java
super.approveSelection();
  • 親クラス(JFileChooser)のapproveSelectionメソッドを呼び出します。
  • これにより、標準の選択承認処理が実行されます。

ファイルフィルターの設定

Java
FileNameExtensionFilter filter = new FileNameExtensionFilter("テキストファイル", "txt");
chooser.setFileFilter(filter);
  • FileNameExtensionFilterを作成し、.txtファイルのみを表示するよう設定しています。
  • このフィルターをJFileChooserに適用しています。

カスタマイズされたJFileChooserの返却

Java
return chooser;
  • カスタマイズされたJFileChooserオブジェクトを返します。

重要なポイント:

  1. カスタム動作: 標準のJFileChooserに、ファイル上書き確認機能を追加しています。
  2. 無名内部クラス: JFileChooserを拡張するために使用され、柔軟なカスタマイズを可能にしています。
  3. ユーザーインターフェース: JOptionPaneを使用して、ユーザーに確認ダイアログを表示しています。
  4. ファイルフィルタリング: FileNameExtensionFilterを使用して、特定の拡張子(.txt)のファイルのみを表示するようにしています。
  5. メソッドのオーバーライド: approveSelectionメソッドをオーバーライドして、標準の動作を拡張しています。

このコードは、ファイル選択ダイアログをカスタマイズする高度な例を示しています。ユーザー体験を向上させるために、標準のコンポーネントを拡張し、追加機能を実装しています。

アプリケーションのメインループ

メソッド定義

Java
/**
 * アプリケーションのメインループを実行する
 */
public void run() {
    // ...
}
  • これはrunというパブリックメソッドです。
  • アプリケーションのメインループを実行します。
  • JavaDocコメントでメソッドの目的を説明しています。

無限ループ

Java
while (true) {
    // ...
}
  • while (true)無限ループを作成します。
  • これにより、ユーザーが明示的に終了するまでアプリケーションが継続して実行されます。

メニュー表示とユーザー入力

Java
displayMenu();
int choice = scanner.nextInt();
scanner.nextLine(); // 改行文字を消費
  • displayMenu()メソッドを呼び出して、メニューを表示します。
  • scanner.nextInt()ユーザーの選択を読み取ります。
  • scanner.nextLine()は、入力後の改行文字を消費します。

switch文による選択処理

Java
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は、無効な選択に対するフォールバックです。

重要なポイント:

  1. 無限ループ: アプリケーションを継続的に実行し、ユーザーが明示的に終了するまで動作し続けます。
  2. ユーザー入力: Scannerクラスを使用して、ユーザーからの入力を受け取ります。
  3. メニュー駆動型インターフェース: ユーザーの選択に基づいて異なる操作を実行する、典型的なコンソールアプリケーションの構造を示しています。
  4. モジュール化: 各操作(新規作成、開く、保存、編集)が別々のメソッドとして実装されており、コードの整理と保守性を向上させています。
  5. エラー処理: 無効な選択に対して適切なメッセージを表示し、ユーザーに再試行を促しています。
  6. アプリケーションの終了: ユーザーが特定の選択(ここでは5)をした場合に、アプリケーションを適切に終了する方法を示しています。

このコードは、シンプルながら効果的なコンソールアプリケーションの中心的な制御構造を示しています。ユーザーとの対話、異なる操作の実行、そしてアプリケーションのライフサイクル管理の基本的な概念を含んでいます。

メニュー表示

Java
/**
 * メインメニューを表示する
 */
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("選択してください: ");
}

このメソッドはメインメニューを表示します。

現在のメモ情報の表示

メソッド定義

Java
/**
 * 現在のメモの情報を表示する
 */
private void displayCurrentNoteInfo() {
    // ...
}
  • これはdisplayCurrentNoteInfoというプライベートメソッドです。
  • 現在のメモの情報を表示する役割を持ちます。
  • JavaDocコメントでメソッドの目的を説明しています。

現在のメモとファイル名の取得

Java
Note currentNote = noteManager.getCurrentNote();
String fileName = noteManager.getCurrentFileName();
  • noteManagerから現在のメモファイル名を取得しています。
  • これらの情報はNoteManagerクラスで管理されています。

メモの存在チェックと情報表示

Java
if (currentNote != null) {
    // ...
} else {
    // ...
}
  • if文を使用して、現在のメモが存在するかどうかをチェックしています。

メモが存在する場合の処理

Java
System.out.println("現在のメモ:");
System.out.println("ファイル名: " + (fileName != null ? fileName : "未保存"));
System.out.println("内容:");
System.out.println(currentNote.content());
System.out.println("------------------------");
  • メモが存在する場合、以下の情報を表示します:
  1. “現在のメモ:” というヘッダー
  2. ファイル名(ファイル名がnullの場合は “未保存” と表示)
  3. “内容:” というラベル
  4. メモの実際の内容currentNote.content()
  5. 区切り線
  • (fileName != null ? fileName : "未保存")三項演算子を使用しています。これは以下のif文と同等です:
Java
  if (fileName != null) {
      System.out.println("ファイル名: " + fileName);
  } else {
      System.out.println("ファイル名: 未保存");
  }

メモが存在しない場合の処理

Java
System.out.println("現在のメモ: なし");
System.out.println("------------------------");
  • メモが存在しない場合(currentNotenullの場合)、
    “現在のメモ: なし” というメッセージと区切り線を表示します。

重要なポイント:

  1. Null チェック: currentNotenullかどうかをチェックして、適切な情報を表示しています。
  2. 条件付き表示: ファイル名の表示に三項演算子を使用して、コードを簡潔にしています。
  3. 情報の構造化: メモの情報を見やすく構造化して表示しています(ヘッダー、ファイル名、内容)。
  4. 区切り線の使用: 情報の前後に区切り線を表示して、視覚的に情報を分離しています。
  5. メソッドの単一責任: このメソッドは「現在のメモの情報を表示する」という単一の責任を持っています。

このコードは、ユーザーに現在の状態を明確に伝えるための情報表示の良い例です。条件分岐を使って異なるシナリオ(メモが存在する場合と存在しない場合)を適切に処理し、ユーザーフレンドリーな出力を生成しています。

新規メモ作成

メソッド定義

Java
/**
 * 新規メモを作成する
 */
private void createNewNote() {
    // ...
}
  • これはcreateNewNoteというプライベートメソッドです。
  • 新しいメモを作成する機能を提供します。
  • JavaDocコメントでメソッドの目的を説明しています。

ユーザーへの指示

Java
System.out.println("新しいメモの内容を入力してください。入力が終わったら空行を入力してEnterキーを押してください:");
  • ユーザーに対して、新しいメモの入力方法を説明しています。
  • 空行が入力の終了を示すことを伝えています。

入力内容の蓄積

Java
StringBuilder content = new StringBuilder();
String line;
while (!(line = scanner.nextLine()).isEmpty()) {
    content.append(line).append("\n");
}
  • StringBuilderを使用して、入力された内容を効率的に蓄積します。
  • whileループを使用して、ユーザーが空行を入力するまで続けて入力を受け付けます。
  • scanner.nextLine()で1行ずつ読み取り、isEmpty()で空行かどうかをチェックします。
  • 各行をStringBuilderに追加し、改行(\n)も付け加えています。

新しいメモの作成

Java
noteManager.setCurrentNote(new Note(content.toString().trim()));
  • StringBuilderの内容を文字列に変換し、余分な空白を削除trim())します。
  • この内容で新しいNoteオブジェクトを作成し、noteManagerの現在のメモとして設定します。

ファイル名のリセット

Java
noteManager.setCurrentFileName(null);
  • 新しいメモはまだ保存されていないので、現在のファイル名をnullに設定します。

完了メッセージ

Java
System.out.println("新しいメモが作成されました。");
  • ユーザーに対して、新しいメモが正常に作成されたことを通知します。

重要なポイント:

  1. ユーザーインターフェース: 明確な指示をユーザーに提供し、使いやすさを向上させています。
  2. 動的な入力処理: whileループを使用して、ユーザーが望む量の入力を受け付けられるようにしています。
  3. 効率的な文字列処理: StringBuilderを使用して、大量のテキスト入力を効率的に処理しています。
  4. 入力の終了条件: 空行を入力の終了条件として使用し、ユーザーが簡単に入力を完了できるようにしています。
  5. 状態管理: NoteManagerを使用して、新しいメモの状態(内容とファイル名)を適切に管理しています。
  6. フィードバック: 操作の完了をユーザーに通知し、アプリケーションの状態を明確にしています。

このコードは、ユーザー入力の処理、文字列の効率的な操作、オブジェクト指向プログラミングの原則(NoteManagerの使用)を示す良い例です。また、ユーザーフレンドリーなインターフェースの設計も示しています。

既存のメモを開く

メソッド定義

Java
/**
 * 既存のメモを開く
 */
private void openExistingNote() {
    // ...
}
  • これはopenExistingNoteというプライベートメソッドです。
  • 既存のメモファイルを開く機能を提供します。
  • JavaDocコメントでメソッドの目的を説明しています。

ファイル選択ダイアログの表示

Java
int result = fileChooser.showOpenDialog(null);
  • JFileChooserを使用して、ファイル選択ダイアログを表示します。
  • showOpenDialog(null)は、ダイアログを表示し、ユーザーの操作結果を返します。
  • nullは親コンポーネントがないことを示します(独立したダイアログとして表示)。

ユーザーの選択結果の確認

Java
if (result == JFileChooser.APPROVE_OPTION) {
    // ...
}
  • ユーザーがファイルを選択して「開く」ボタンをクリックしたかどうかを確認します。
  • JFileChooser.APPROVE_OPTIONは、ユーザーが選択を承認したことを示す定数です。

選択されたファイルの取得

Java
File selectedFile = fileChooser.getSelectedFile();
  • ユーザーが選択したファイルのFileオブジェクトを取得します。

ファイルの読み込みと例外処理

Java
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()ファイルの絶対パスを取得します。
  • 読み込みが成功したら、現在のファイル名を設定し、成功メッセージを表示します。
  • 例外が発生した場合、エラーメッセージを表示します。

重要なポイント:

  1. ユーザーインターフェース: JFileChooserを使用して、グラフィカルなファイル選択インターフェースを提供しています。
  2. ユーザーの選択の確認: JFileChooser.APPROVE_OPTIONを使用して、ユーザーが実際にファイルを選択したかどうかを確認しています。
  3. 例外処理: try-catchブロックを使用して、ファイル読み込み時に発生する可能性のあるエラーを適切に処理しています。
  4. 状態管理: NoteManagerを使用して、開いたメモの状態(内容とファイル名)を管理しています。
  5. フィードバック: ファイルを開いた後、またはエラーが発生した場合に、適切なメッセージをユーザーに表示しています。
  6. ファイル操作: Fileクラスを使用して、ファイルのパスと名前を取得しています。

このコードは、ファイル選択、例外処理、オブジェクト指向プログラミング(NoteManagerの使用)の良い例です。また、ユーザーフレンドリーなインターフェースとエラー処理を組み合わせて、堅牢なファイル操作機能を提供しています。

現在のメモを保存

メソッド定義

Java
/**
 * 現在のメモを保存する
 */
private void saveCurrentNote() {
    // ...
}
  • これはsaveCurrentNoteというプライベートメソッドです。
  • 現在のメモをファイルに保存する機能を提供します。
  • JavaDocコメントでメソッドの目的を説明しています。

保存するメモの存在確認

Java
if (noteManager.getCurrentNote() == null) {
    System.out.println("保存するメモがありません。");
    return;
}
  • 現在のメモが存在するかどうかをチェックします。
  • メモがない場合は、メッセージを表示してメソッドを終了します。

ファイル保存ダイアログの表示

Java
int result = fileChooser.showSaveDialog(null);
  • JFileChooserを使用して、ファイル保存ダイアログを表示します。
  • showSaveDialog(null)は、保存ダイアログを表示し、ユーザーの操作結果を返します。

ユーザーの選択結果の確認

Java
if (result == JFileChooser.APPROVE_OPTION) {
    // ...
}
  • ユーザーがファイル名を入力して「保存」ボタンをクリックしたかどうかを確認します。

選択されたファイルの取得と拡張子の確認

Java
File selectedFile = fileChooser.getSelectedFile();
if (!selectedFile.getName().toLowerCase().endsWith(".txt")) {
    selectedFile = new File(selectedFile.getParentFile(), selectedFile.getName() + ".txt");
}
  • ユーザーが選択したファイルのFileオブジェクトを取得します。
  • ファイル名が.txt拡張子で終わっていない場合、自動的に追加します。

ファイルの保存と例外処理

Java
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()メソッドを呼び出して、選択されたファイルにメモを保存します。
  • 保存が成功したら、現在のファイル名を更新し、成功メッセージを表示します。
  • 例外が発生した場合、エラーメッセージを表示します。

重要なポイント:

  1. Null チェック: 保存するメモが存在するかどうかを最初に確認しています。
  2. ユーザーインターフェース: JFileChooserを使用して、グラフィカルなファイル保存インターフェースを提供しています。
  3. ファイル拡張子の自動追加: ユーザーが.txt拡張子を付け忘れた場合に自動的に追加する機能があります。
  4. 例外処理: try-catchブロックを使用して、ファイル保存時に発生する可能性のあるエラーを適切に処理しています。
  5. 状態管理: NoteManagerを使用して、保存したメモの状態(ファイル名)を更新しています。
  6. フィードバック: ファイルの保存後、またはエラーが発生した場合に、適切なメッセージをユーザーに表示しています。

このコードは、ファイル保存操作、例外処理、ユーザーインターフェース設計の良い例です。また、ファイル名の自動修正など、ユーザーの利便性を考慮した機能も含まれています。

現在のメモを編集

メソッド定義

Java
/**
 * 現在のメモを編集する
 */
private void editCurrentNote() {
    // ...
}
  • これはeditCurrentNoteというプライベートメソッドです。
  • 現在のメモを編集する機能を提供します。
  • JavaDocコメントでメソッドの目的を説明しています。

編集するメモの存在確認

Java
if (noteManager.getCurrentNote() == null) {
    System.out.println("編集するメモがありません。新規メモを作成するか、既存のメモを開いてください。");
    return;
}
  • 現在のメモが存在するかどうかをチェックします。
  • メモがない場合は、メッセージを表示してメソッドを終了します。

編集指示の表示

Java
System.out.println("現在のメモ内容を編集します。編集が終わったら空行を入力してください。");
System.out.println("編集をキャンセルする場合は、最初の行に 'cancel' と入力してください。");
System.out.println("現在の内容:");
System.out.println(noteManager.getCurrentNote().content());
  • ユーザーに編集方法を説明します。
  • 現在のメモの内容を表示します。

編集内容の入力と処理

Java
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ループを使用して、空行が入力されるまで続けて入力を受け付けます。

編集内容の保存

Java
noteManager.setCurrentNote(new Note(newContent.toString().trim()));
System.out.println("メモが更新されました。");
  • 新しい内容でNoteオブジェクトを作成し、noteManagerの現在のメモとして設定します。
  • 更新完了のメッセージを表示します。

重要なポイント:

  1. Null チェック: 編集するメモが存在するかどうかを最初に確認しています。
  2. ユーザーガイダンス: 編集方法や現在の内容を明確に表示し、ユーザーをガイドしています。
  3. キャンセル機能: ユーザーが’cancel’を入力することで編集をキャンセルできる機能を提供しています。
  4. 動的な入力処理: whileループを使用して、ユーザーが望む量の入力を受け付けられるようにしています。
  5. 効率的な文字列処理: StringBuilderを使用して、大量のテキスト入力を効率的に処理しています。
  6. 状態管理: NoteManagerを使用して、編集されたメモの状態を更新しています。
  7. フィードバック: 編集完了時にメッセージを表示し、操作の結果をユーザーに通知しています。

このコードは、ユーザー入力の処理、文字列操作、状態管理の良い例です。また、ユーザーフレンドリーなインターフェース設計も示しており、ユーザーに明確な指示を提供しながら、柔軟な編集機能を実現しています。

まとめ

  • Note.javaメモデータの構造基本操作を実装
  • NotePadApp.javaメインアプリケーションロジックユーザーインターフェースを実装
  • ファイル操作(読み込み、保存)の実装方法
  • 例外処理を通じて、堅牢なエラーハンドリングの実装方法
  • JavaDocを使用した効果的なドキュメンテーションの作成方法
  • カスタムJFileChooserの作成を通じて、GUIコンポーネントのカスタマイズ方法

このメモ帳アプリケーションの作成を通じて、Javaプログラミングの実践的なスキル重要な概念を身につけることができます。クラス設計ファイルI/Oユーザー入力の処理例外処理など、実際のアプリケーション開発で必要となる重要な要素を学ぶことができます。

特に、ファイル操作の実装は、多くのアプリケーション開発で必要とされる重要なスキルです。また、カスタムJFileChooserの作成を通じて、GUIプログラミングの基礎も学ぶことができます。

追加の機能(例:テキスト検索、自動保存、複数ファイルの同時編集など)を実装することで、さらに複雑なアプリケーションへと発展させることができます。

未経験でもWEBスキルを取得したい方
  • Javaコース
    Javaプログラミングを基礎から応用まで、体系的に学べる実践的なカリキュラムが特徴です。「マインクラフト」を通じてJavaの基本文法とフレームワークの概念を学びます。また、実際のプロジェクト開発を通じて、データベース連携やWebアプリケーション開発のスキルを身につけることができます。

コメント

タイトルとURLをコピーしました