1 Commits
main ... suzuki

Author SHA1 Message Date
35671ad119 追加機能(色付け&ソート)実装完了済 2026-10-23 16:08:49 +09:00
14 changed files with 728 additions and 0 deletions

6
.classpath Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>

1
.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
/bin/

23
.project Normal file
View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>development-taskmanager</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.wst.common.project.facet.core.builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.wst.common.project.facet.core.nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

7
file/tasks.csv Normal file
View File

@@ -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
1 1 研修内容振り返り False 2026-09-24 2
2 2 旅行の買いだし True 2027-08-08 3
3 3 試験勉強 True 2026-09-24 2
4 4 テスト勉強 False 2026-10-30 1
5 5 test True 2026-10-22 1
6 6 test1week False 2026-10-25 3
7 7 sort False 2026-10-23 2

60
src/App.java Normal file
View File

@@ -0,0 +1,60 @@
import java.util.List;
import java.util.Scanner;
public class App {
static List<Task> 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);
}
}

70
src/Color.java Normal file
View File

@@ -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;
}
}

26
src/Main.java Normal file
View File

@@ -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();
}
}
}

143
src/Sort.java Normal file
View File

@@ -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<Task> sortID(List<Task> 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<Task> sortStatus(List<Task> 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<Task> sortPriority(List<Task> 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<Task> sortDeadline(List<Task> 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<Task> sortName(List<Task> 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<Task> {
@Override
public int compare(Task t1,Task t2) {
return Integer.compare(((TaskItem)t1).getTaskID(),((TaskItem)t2).getTaskID());
}
}
// ID比較(降順)
public static class revIDComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return Integer.compare(((TaskItem)t2).getTaskID(),((TaskItem)t1).getTaskID());
}
}
// isComplete比較(昇順)
public static class StatusComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return Boolean.compare(((TaskItem)t1).getIsComplete(),((TaskItem)t2).getIsComplete());
}
}
// isComplete比較(降順)
public static class revStatusComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return Boolean.compare(((TaskItem)t2).getIsComplete(),((TaskItem)t1).getIsComplete());
}
}
// priority比較(昇順)=優先度"高"→"低"
public static class PriorityComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return Integer.compare(((TaskItem)t2).getPriority(),((TaskItem)t1).getPriority());
}
}
// priority比較(降順)==優先度"低"→"高"
public static class revPriorityComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return Integer.compare(((TaskItem)t1).getPriority(),((TaskItem)t2).getPriority());
}
}
// deadline比較(昇順)
public static class DeadlineComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return ((TaskItem)t1).getDeadline().compareTo(((TaskItem)t2).getDeadline());
}
}
// deadline比較(降順)
public static class revDeadlineComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return ((TaskItem)t2).getDeadline().compareTo(((TaskItem)t1).getDeadline());
}
}
// taskName比較(辞書昇順)
public static class NameComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return ((TaskItem)t1).getTaskName().compareTo(((TaskItem)t2).getTaskName());
}
}
// taskName比較(辞書降順)
public static class revNameComparator implements Comparator<Task> {
@Override
public int compare(Task t1,Task t2) {
return ((TaskItem)t2).getTaskName().compareTo(((TaskItem)t1).getTaskName());
}
}
}

7
src/Task.java Normal file
View File

@@ -0,0 +1,7 @@
public interface Task {
String toString();
String toCSV();
}

196
src/TaskItem.java Normal file
View File

@@ -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<Integer.parseInt(taskID)) {
MaxTaskID = Integer.parseInt(taskID); // 最大IDを記録する
}
}
//====================メソッドforコンストラクタ(非公開)====================
// 完了フラグ入力文字列を真偽値に変換する
private boolean getIsCompleteBool(String input) {
boolean isComplete = false; // デフォルト=未完了(false)
if (input.equals("True")) {
isComplete=true;
}
else if (input.equals("False")) {
isComplete=false;
}
return isComplete;
}
// 期限の不正入力をチェックする(不正入力→現在年月日)
private String getValidDeadline(String input) throws PastDateException {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String now = sdf.format(new Date());
String deadline = now; // デフォルト=現在年月日
try {
// フォーマット照合
Date today = sdf.parse(now); // 現在年月日(0時0分0秒)を取得する
SimpleDateFormat inputsdf = new SimpleDateFormat("yyyy/MM/dd");
Date date = inputsdf.parse(input); // 指定年月日(0時0分0秒)を取得する(不正入力検出)
// 指定年月日が現在年月日より後であるかを確認する
if (date.compareTo(today)<0) {
throw new PastDateException();
}
String[] ymd = input.split("/",3); // 年月日取得
// 入力文字列が1月~12月を指定していることを確認する
boolean isUnderDec = Integer.parseInt(ymd[1])<=12;
// 入力文字列の指定日が指定月最終日より小さいことを確認する
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.YEAR,Integer.parseInt(ymd[0]));
calendar.set(Calendar.MONTH,Integer.parseInt(ymd[1])-1); // Calendar.MONTH:0_index
boolean isUnderLastday = Integer.parseInt(ymd[2])<=(calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
if (isUnderDec&&isUnderLastday) {
deadline = sdf.format(date); // 正常入力
}
} catch (ParseException err) {}
return deadline;
}
// 優先度入力文字列を整数に変換する
private int getPriorityIndex(String priority) {
int priorityIndex = 2; // デフォルト=2
try {
priorityIndex = Integer.parseInt(priority);
} catch (Exception e) {}
return priorityIndex;
}
//====================出力====================
// 文字列for画面出力
@Override
public String toString() {
// ID桁数を参照した空白文字列を生成する
int nMaxSpace = 4;
String space = "";
for (int i=0;i<nMaxSpace-String.valueOf(this.getTaskID()).length();i++) {
space += " ";
}
// 色付け
String[] colorList = setColor();
return colorList[0]+this.getTaskID() +Color.reset() +space
+"| "+colorList[1]+this.toStringComp() +Color.reset() +" "
+"|  "+colorList[2]+this.toStringPrior()+Color.reset()+"  "
+"| "+colorList[3]+this.getDeadline() +Color.reset() +" "
+"| "+colorList[4]+this.getTaskName() +Color.reset();
}
// 文字列forExcel出力
public String toCSV() {
return this.getTaskID()+","
+this.getTaskName()+","
+this.toStringCompCSV()+","
+this.getDeadline()+","
+this.getPriority();
}
//====================メソッドfor出力(非公開)====================
// 完了フラグを文字列に変換する(完了/未完了)
private String toStringComp() {
String strComp;
if (this.getIsComplete()) strComp = "[x] 完了 ";
else strComp = "[ ] 未完了";
return strComp;
}
// 完了フラグを文字列に変換する(True/False)
private String toStringCompCSV() {
String strComp;
if(this.getIsComplete()) strComp = "True";
else strComp = "False";
return strComp;
}
// 優先度フラグを文字列に変換する
private String toStringPrior() {
String strPrior;
switch (this.getPriority()) {
case 1:
strPrior="低";
break;
case 2:
strPrior="中";
break;
case 3:
strPrior="高";
break;
default:
strPrior="中";
break;
}
return strPrior;
}
// 色テンプレートを作成する
private String[] setColor() {
String[] colorList = {"","","","",""};
if (this.getIsComplete()) {
colorList = Color.setColorCompleted(); // 完了フラグ
} else {
colorList[2] = Color.setColorPrior(this.getPriority()); // 優先度
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
colorList[3] = Color.setColorDeadline(this.getDeadline()); // 期限
}
return colorList;
}
}
// 過去日付指定エラークラス
class PastDateException extends Exception {
}

139
src/TaskManager.java Normal file
View File

@@ -0,0 +1,139 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class TaskManager {
static final String PATH = "./file/tasks.csv";
//====================配列管理====================
// タスク追加
public static List<Task> register(List<Task> 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<Task> changeStatus(List<Task> 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<Task> remove(List<Task> 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<Task> 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<Task> sort (List<Task> 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<Task> readCSV() {
List<Task> allData = new ArrayList<Task>();
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<Task> 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 {
}

32
src/View.java Normal file
View File

@@ -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<Task> 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("番号を入力してください > ");
}
}

17
src/testcolor.java Normal file
View File

@@ -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");
}
}
}

View File

@@ -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
1 1 研修内容振り返り True 2026-09-24 2
2 2 旅行の買いだし False 2027-08-08 3
3 3 試験勉強 True 2026-09-24 2
4 4 テスト勉強 False 2026-10-30 1
5 5 test False 2026-10-23 2