From 35671ad119d7349c2ae2aa82a1685d1c195088ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=88=B4=E6=9C=A8=E3=80=80=E7=9A=93=E4=BB=8B?= <26-k-suzuki-avnz@it-college.co.jp> Date: Fri, 23 Oct 2026 16:08:49 +0900 Subject: [PATCH] =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E6=A9=9F=E8=83=BD=EF=BC=88?= =?UTF-8?q?=E8=89=B2=E4=BB=98=E3=81=91=EF=BC=86=E3=82=BD=E3=83=BC=E3=83=88?= =?UTF-8?q?=EF=BC=89=E5=AE=9F=E8=A3=85=E5=AE=8C=E4=BA=86=E6=B8=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 6 + .gitignore | 1 + .project | 23 ++++ file/tasks.csv | 7 ++ src/App.java | 60 +++++++++ src/Color.java | 70 +++++++++++ src/Main.java | 26 ++++ src/Sort.java | 143 +++++++++++++++++++++ src/Task.java | 7 ++ src/TaskItem.java | 196 +++++++++++++++++++++++++++++ src/TaskManager.java | 139 ++++++++++++++++++++ src/View.java | 32 +++++ src/testcolor.java | 17 +++ タスク管理システム実行例/tasks.csv | 1 + 14 files changed, 728 insertions(+) create mode 100644 .classpath create mode 100644 .gitignore create mode 100644 .project create mode 100644 file/tasks.csv create mode 100644 src/App.java create mode 100644 src/Color.java create mode 100644 src/Main.java create mode 100644 src/Sort.java create mode 100644 src/Task.java create mode 100644 src/TaskItem.java create mode 100644 src/TaskManager.java create mode 100644 src/View.java create mode 100644 src/testcolor.java diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..fb50116 --- /dev/null +++ b/.classpath @@ -0,0 +1,6 @@ + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ae3c172 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/bin/ diff --git a/.project b/.project new file mode 100644 index 0000000..02e36be --- /dev/null +++ b/.project @@ -0,0 +1,23 @@ + + + development-taskmanager + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.wst.common.project.facet.core.builder + + + + + + org.eclipse.wst.common.project.facet.core.nature + org.eclipse.jdt.core.javanature + + diff --git a/file/tasks.csv b/file/tasks.csv new file mode 100644 index 0000000..0a080a9 --- /dev/null +++ b/file/tasks.csv @@ -0,0 +1,7 @@ +1,研修内容振り返り,False,2026-09-24,2 +2,旅行の買いだし,True,2027-08-08,3 +3,試験勉強,True,2026-09-24,2 +4,テスト勉強,False,2026-10-30,1 +5,test,True,2026-10-22,1 +6,test1week,False,2026-10-25,3 +7,sort,False,2026-10-23,2 diff --git a/src/App.java b/src/App.java new file mode 100644 index 0000000..076d8f5 --- /dev/null +++ b/src/App.java @@ -0,0 +1,60 @@ +import java.util.List; +import java.util.Scanner; + +public class App { + + static List allData; + + // csvファイルを読み込んでタスク情報を保持する + public static void init() { + View.clearConsole(); // ANSI not work on Eclipse console + allData = TaskManager.readCSV(); + View.print(allData); + } + // 管理機能を選択する + public static String select() { + View.standby(); + Scanner sc = new Scanner(System.in); + String mode = sc.nextLine(); + return mode; + } + // 管理機能を実行する + public static void execute(String mode) throws invalidInputException,PastDateException { + switch (mode) { + case "1": + allData = TaskManager.register(allData); // 登録 + break; + case "2": + allData = TaskManager.changeStatus(allData); // 更新 + break; + case "3": + allData = TaskManager.remove(allData); // 削除 + break; + case "4": + allData = TaskManager.sort(allData); // ソート + break; + case "5": + System.exit(0); // 終了 + default : + throw new invalidInputException(); + } + System.out.println(); + } + // 不正入力時 + public static void invalid() { + System.out.println("正しい番号を入力してください。Enterキーを押してください。"); + Scanner sc = new Scanner(System.in); + sc.nextLine(); + } + // 過去日付指定時 + public static void past() { + System.out.println("過去の日付を登録できません。Enterキーを押してください。"); + Scanner sc = new Scanner(System.in); + sc.nextLine(); + } + // 後処理(ファイル書き込み+コンソール画面クリア) + public static void fin() { + TaskManager.writeCSV(allData); + } + +} diff --git a/src/Color.java b/src/Color.java new file mode 100644 index 0000000..d2bc0f3 --- /dev/null +++ b/src/Color.java @@ -0,0 +1,70 @@ +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class Color { + + // ANSIエスケープ:色指定 + final static String RED = "\033[00;31m"; + final static String GREEN = "\033[00;32m"; + final static String YELLOW = "\033[00;33m"; + final static String BACK_RED = "\033[00;41m"; + final static String GRAY = "\033[00;90m"; + final static String DEFAULT = "\033[00m"; + + // デフォルトに戻す + public static String reset() { + return DEFAULT; + } + // 完了時グレーアウト + public static String[] setColorCompleted() { + String[] colorList = new String[5]; + colorList[0] = GRAY; + colorList[1] = GRAY; + colorList[2] = GRAY; + colorList[3] = GRAY; + colorList[4] = GRAY; + return colorList; + } + // 優先度 + public static String setColorPrior(int prior) { + String color; + switch (prior) { + case 1: + color = GREEN; + break; + case 2: + color = YELLOW; + break; + case 3: + color = RED; + break; + default: + color = YELLOW; + break; + } + return color; + } + // 期限 + public static String setColorDeadline(String input) { + String color = ""; + try { + SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); + Date date = sdf.parse(input); // 指定年月日(0時0分0秒)を取得する + Date now = new Date(); + Date today = sdf.parse(sdf.format(now)); // 現在年月日(0時0分0秒)を取得する + Calendar calendar = Calendar.getInstance(); + calendar.setTime(today); + calendar.add(Calendar.DAY_OF_MONTH,7); + Date nextweek = calendar.getTime(); // 1週間後の日付(0時0分0秒)を取得する + if (date.compareTo(today)<0) { + color = BACK_RED; // 期限超過=背景赤 + } else if (date.compareTo(nextweek)<0) { + color = YELLOW; // 期限1週間以内=黄 + } + } catch (ParseException err) {} + return color; + } + +} diff --git a/src/Main.java b/src/Main.java new file mode 100644 index 0000000..7156000 --- /dev/null +++ b/src/Main.java @@ -0,0 +1,26 @@ +public class Main { + + public static void main(String[] args) { + // TODO 自動生成されたメソッド・スタブ + + while (true) { + App.init(); + try { + App.execute(App.select()); + } catch (invalidInputException err) { + App.invalid(); + continue; + } catch (PastDateException err) { + App.past(); + continue; + } catch (Exception err) { + System.out.println("不明なエラーが検出されました"); + err.printStackTrace(); + System.exit(-1); + } + App.fin(); + } + + } + +} diff --git a/src/Sort.java b/src/Sort.java new file mode 100644 index 0000000..70ea663 --- /dev/null +++ b/src/Sort.java @@ -0,0 +1,143 @@ +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class Sort { + + //====================TaskItem sort==================== + // taskID + public static List sortID(List allData, String input) { + if (isReverse(input)) { + Collections.sort(allData,new Sort.revIDComparator()); // 降順 + } else { + Collections.sort(allData,new Sort.IDComparator()); // 昇順 + } + return allData; + } + // isComplete + public static List sortStatus(List allData, String input) { + if (isReverse(input)) { + Collections.sort(allData,new Sort.revStatusComparator()); // 降順 + } else { + Collections.sort(allData,new Sort.StatusComparator()); // 昇順 + } + return allData; + } + // priority + public static List sortPriority(List allData, String input) { + if (isReverse(input)) { + Collections.sort(allData,new Sort.revPriorityComparator()); // 降順 + } else { + Collections.sort(allData,new Sort.PriorityComparator()); // 昇順 + } + return allData; + } + // deadline + public static List sortDeadline(List allData, String input) { + if (isReverse(input)) { + Collections.sort(allData,new Sort.revDeadlineComparator()); // 降順 + } else { + Collections.sort(allData,new Sort.DeadlineComparator()); // 昇順 + } + return allData; + } + // taskName + public static List sortName(List allData, String input) { + if (isReverse(input)) { + Collections.sort(allData,new Sort.revNameComparator()); // 降順 + } else { + Collections.sort(allData,new Sort.NameComparator()); // 昇順 + } + return allData; + } + // ソート順指定フラグを生成する + public static boolean isReverse(String input) { + boolean isReverse = false; + try { + int order = Integer.parseInt(input); + switch (order) { + case 1: + break; + case 2: + isReverse = true; // 2:降順 + break; + default: + break; + } + } catch (NumberFormatException err) {} + return isReverse; + } + + //====================TaskItemフィールド比較条件定義==================== + // ID比較(昇順) + public static class IDComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return Integer.compare(((TaskItem)t1).getTaskID(),((TaskItem)t2).getTaskID()); + } + } + // ID比較(降順) + public static class revIDComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return Integer.compare(((TaskItem)t2).getTaskID(),((TaskItem)t1).getTaskID()); + } + } + // isComplete比較(昇順) + public static class StatusComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return Boolean.compare(((TaskItem)t1).getIsComplete(),((TaskItem)t2).getIsComplete()); + } + } + // isComplete比較(降順) + public static class revStatusComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return Boolean.compare(((TaskItem)t2).getIsComplete(),((TaskItem)t1).getIsComplete()); + } + } + // priority比較(昇順)=優先度"高"→"低" + public static class PriorityComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return Integer.compare(((TaskItem)t2).getPriority(),((TaskItem)t1).getPriority()); + } + } + // priority比較(降順)==優先度"低"→"高" + public static class revPriorityComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return Integer.compare(((TaskItem)t1).getPriority(),((TaskItem)t2).getPriority()); + } + } + // deadline比較(昇順) + public static class DeadlineComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return ((TaskItem)t1).getDeadline().compareTo(((TaskItem)t2).getDeadline()); + } + } + // deadline比較(降順) + public static class revDeadlineComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return ((TaskItem)t2).getDeadline().compareTo(((TaskItem)t1).getDeadline()); + } + } + // taskName比較(辞書昇順) + public static class NameComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return ((TaskItem)t1).getTaskName().compareTo(((TaskItem)t2).getTaskName()); + } + } + // taskName比較(辞書降順) + public static class revNameComparator implements Comparator { + @Override + public int compare(Task t1,Task t2) { + return ((TaskItem)t2).getTaskName().compareTo(((TaskItem)t1).getTaskName()); + } + } + +} diff --git a/src/Task.java b/src/Task.java new file mode 100644 index 0000000..1624624 --- /dev/null +++ b/src/Task.java @@ -0,0 +1,7 @@ + +public interface Task { + + String toString(); + String toCSV(); + +} diff --git a/src/TaskItem.java b/src/TaskItem.java new file mode 100644 index 0000000..c60e84e --- /dev/null +++ b/src/TaskItem.java @@ -0,0 +1,196 @@ +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +public class TaskItem implements Task { + + private int taskID; + private String taskName; + private boolean isComplete; + private String deadline; + private int priority; + static int MaxTaskID = 0; + + //====================getter/setter==================== + public int getTaskID() { + return taskID; + } + public void setTaskID(int taskID) { + this.taskID = taskID; + } + public String getTaskName() { + return taskName; + } + public void setTaskName(String taskName) { + this.taskName = taskName; + } + public boolean getIsComplete() { + return isComplete; + } + public void setIsComplete(boolean isComplete) { + this.isComplete = isComplete; + } + public String getDeadline() { + return deadline; + } + public void setDeadline(String deadline) { + this.deadline = deadline; + } + public int getPriority() { + return priority; + } + public void setPriority(int priority) { + this.priority = priority; + } + + //====================コンストラクタ==================== + // コンストラクタ(登録時) + public TaskItem(String taskName, String deadline, String priority) throws PastDateException { // 文字列入力を受け取る + MaxTaskID++; + this.setTaskID(MaxTaskID); // 消去したタスクIDは使い回さない→最大ID+1のタスクとして登録する + this.setTaskName(taskName); + this.setDeadline(this.getValidDeadline(deadline)); + this.setPriority(this.getPriorityIndex(priority)); + } + // コンストラクタ(csv読み取り時) + public TaskItem(String taskID, String taskName,String isComplete, String deadline, String priority) { // 文字列入力を受け取る + this.setTaskID(Integer.parseInt(taskID)); + this.setTaskName(taskName); + this.setIsComplete(this.getIsCompleteBool(isComplete)); + this.setDeadline(deadline); // csv読み取り時に不正入力判定は行わない + this.setPriority(this.getPriorityIndex(priority)); + if (MaxTaskID register(List allData) throws PastDateException { + Scanner sc = new Scanner(System.in); + System.out.print("タスク名を入力: "); + String name = sc.nextLine(); + System.out.print("期限を入力 (例: 2026/09/20) [未入力:今日]: "); + String deadline = sc.nextLine(); + System.out.print("優先度を入力(1:低, 2:中, 3:高)[デフォルト:2]: "); + String priority = sc.nextLine(); + Task newTask = new TaskItem(name,deadline,priority); + allData.add(newTask); + return allData; + } + // 完了/未完了の切り替え + public static List changeStatus(List allData) throws invalidInputException { + Scanner sc = new Scanner(System.in); + System.out.print("状態を変更するタスクIDを入力: "); + String id = sc.nextLine(); + boolean currentStatus = ((TaskItem)(allData.get(getIndex(allData,id)))).getIsComplete(); + ((TaskItem)(allData.get(getIndex(allData,id)))).setIsComplete(!currentStatus); // 状態を反転させる + return allData; + } + // 削除 + public static List remove(List allData) throws invalidInputException { + Scanner sc = new Scanner(System.in); + System.out.print("削除するタスクIDを入力: "); + String id = sc.nextLine(); + allData.remove(getIndex(allData,id)); + return allData; + } + // ID照合→該当タスク配列インデックス取得 + public static int getIndex(List allData,String id) throws invalidInputException { + boolean isMatched = false; + int index = 0; + for (Task data : allData) { + try { + if (((TaskItem)data).getTaskID()==Integer.parseInt(id)) { + isMatched = true; + break; + } + } catch (NumberFormatException err) { + throw new invalidInputException(); // 不正入力→例外 + } + index++; + } + if (isMatched==false) { + throw new invalidInputException(); // ID照合失敗→例外 + } + return index; + } + // ソート + public static List sort (List allData) { + Scanner sc = new Scanner(System.in); + System.out.print("並び替え時に参照する項目を入力(1:ID, 2:状態, 3:優先度, 4:期限, 5:タスク名)[デフォルト:1]:"); + String mode = sc.nextLine(); + System.out.print("並び替え順を入力(1:昇順, 2:降順)[デフォルト:1]"); + String order = sc.nextLine(); + switch (mode) { + case "1": + allData = Sort.sortID(allData,order); + break; + // 同一条件はID昇順に並べる + case "2": + allData = Sort.sortID(allData,"1"); + allData = Sort.sortStatus(allData,order); + break; + case "3": + allData = Sort.sortID(allData,"1"); + allData = Sort.sortPriority(allData,order); + break; + case "4": + allData = Sort.sortID(allData,"1"); + allData = Sort.sortDeadline(allData,order); + break; + case "5": + allData = Sort.sortID(allData,"1"); + allData = Sort.sortName(allData,order); + break; + default : + allData = Sort.sortID(allData,"1"); + break; + } + return allData; + } + + //====================ファイル入出力==================== + // csvファイルからタスク情報を読み込む + public static List readCSV() { + List allData = new ArrayList(); + File f = new File(PATH); + try (BufferedReader br = new BufferedReader(new InputStreamReader(new FileInputStream(f),"UTF-8"))) { + String line = ""; + while ((line=br.readLine())!=null) { + String[] data = line.split(",",0); + Task task = new TaskItem(data[0],data[1],data[2],data[3],data[4]); + allData.add(task); + } + } catch (IOException err) { + System.out.println("ファイルの読み込みに失敗しました"); + err.printStackTrace(); + System.exit(-1); + } + return allData; + } + // csvファイルにタスク情報を書き込む + public static void writeCSV(List allData) { + File f = new File(PATH); + try (FileWriter fr = new FileWriter(f)) { + for (Task data : allData) { + fr.append(data.toCSV()+"\n"); + } + } catch (IOException err) { + System.out.println("ファイルの書き込みに失敗しました"); + err.printStackTrace(); + System.exit(-1); + } + } + +} + +// ID照合失敗エラークラス +class invalidInputException extends Exception { + +} diff --git a/src/View.java b/src/View.java new file mode 100644 index 0000000..738f315 --- /dev/null +++ b/src/View.java @@ -0,0 +1,32 @@ +import java.util.List; + +public class View { + + // コンソール画面クリア + public static void clearConsole() { +// System.out.print("\033[0;0J"+"\033[2J"); // not work on Eclipse conasole + // 空行を出力して前回の表示を隠す + for (int i=0;i<100;i++) { System.out.println(); } + } + + // タスク一覧を画面出力する + public static void print(List allData) { + System.out.println( + "============================================================\n" + + " Task Manager\n" + + "============================================================\n" + + "ID | 状態    | 優先度 | 期限 | タスク名\n" + + "------------------------------------------------------------\n"); + for (Task data : allData) { + System.out.println(data); + } + System.out.println(); + } + + // 入力待機表示を画面出力する + public static void standby() { + System.out.println("[1] タスク追加 [2] 完了/未完了の切り替え [3] 削除 [4] ソート [5] 終了"); + System.out.print("番号を入力してください > "); + } + +} diff --git a/src/testcolor.java b/src/testcolor.java new file mode 100644 index 0000000..33620a9 --- /dev/null +++ b/src/testcolor.java @@ -0,0 +1,17 @@ + +public class testcolor { + + public static void main(String[] args) { + // TODO 自動生成されたメソッド・スタブ + + for (int i = 0; i < 11; i++) { + for (int j = 0; j < 10; j++) { + int v = i*10+j; + System.out.printf("\033[%dm"+"%03d"+"\033[0m ",v,v); + } + System.out.printf("\n"); + } + + } + +} diff --git a/タスク管理システム実行例/tasks.csv b/タスク管理システム実行例/tasks.csv index 225f37c..fa8d637 100644 --- a/タスク管理システム実行例/tasks.csv +++ b/タスク管理システム実行例/tasks.csv @@ -2,3 +2,4 @@ 2,旅行の買いだし,False,2027-08-08,3 3,試験勉強,True,2026-09-24,2 4,テスト勉強,False,2026-10-30,1 +5,test,False,2026-10-23,2