From c57218ff7f132db5c0c99ff524813ba70de4cddd Mon Sep 17 00:00:00 2001 From: Hyewon Date: Fri, 12 Dec 2025 07:15:34 +0900 Subject: [PATCH] Make UI Consistent --- src/main/java/com/unitime/App.java | 11 ++- src/main/java/com/unitime/UI/ResultView.java | 2 +- src/main/java/com/unitime/feature/Editor.java | 57 +++++++------ .../com/unitime/feature/InputHandler.java | 79 +++++++++++-------- 4 files changed, 88 insertions(+), 61 deletions(-) diff --git a/src/main/java/com/unitime/App.java b/src/main/java/com/unitime/App.java index 387a3cf..0c30434 100644 --- a/src/main/java/com/unitime/App.java +++ b/src/main/java/com/unitime/App.java @@ -9,13 +9,22 @@ import com.unitime.feature.InputHandler; public class App { + public static final String RESET = "\u001B[0m"; + public static final String RED = "\u001B[31m"; + public static final String GREEN = "\u001B[32m"; + public static final String YELLOW = "\u001B[33m"; + public static final String BLUE = "\u001B[34m"; + public static final String PURPLE = "\u001B[35m"; + public static final String CYAN = "\u001B[36m"; + public static final String BLACK = "\u001B[30m"; + public static final String BOLD = "\u001B[1m"; public static void main(String[] args) { // Only one scanner!!!!! Scanner sc = new Scanner(System.in); IntroScreen.start(); - System.out.println("Press [ENTER] to start..."); + System.out.println("Press"+PURPLE+" [ENTER]"+RESET+" to start..."); sc.nextLine(); // get input diff --git a/src/main/java/com/unitime/UI/ResultView.java b/src/main/java/com/unitime/UI/ResultView.java index 8d389af..1cd4213 100644 --- a/src/main/java/com/unitime/UI/ResultView.java +++ b/src/main/java/com/unitime/UI/ResultView.java @@ -46,7 +46,7 @@ public static String printBatchAndGetInput(List> allSchedules, int // 2. Print Header (Print in each new page) System.out.println(CYAN + "\n========================= Timetable =========================" + RESET); - System.out.println(YELLOW + BOLD + " (*'▽ '*) Found " + totalSize + " timetables! Showing " + (currentIndex + 1) + "~" + endIndex + " (*'▽ '*)" + RESET); + System.out.println(YELLOW + BOLD + " (*'▽ '*) Found " + totalSize + " timetables! Showing " + (currentIndex + 1) + "~" + endIndex + " (*'▽ '*)" + RESET); System.out.println(CYAN + "=============================================================" + RESET); // 3. Print 5 timetables diff --git a/src/main/java/com/unitime/feature/Editor.java b/src/main/java/com/unitime/feature/Editor.java index 837dcf0..1455611 100644 --- a/src/main/java/com/unitime/feature/Editor.java +++ b/src/main/java/com/unitime/feature/Editor.java @@ -5,6 +5,15 @@ import com.unitime.algorthm.Scheduler; public class Editor { + public static final String RESET = "\u001B[0m"; + public static final String RED = "\u001B[31m"; + public static final String GREEN = "\u001B[32m"; + public static final String YELLOW = "\u001B[33m"; + public static final String BLUE = "\u001B[34m"; + public static final String PURPLE = "\u001B[35m"; + public static final String CYAN = "\u001B[36m"; + public static final String BLACK = "\u001B[30m"; + public static final String BOLD = "\u001B[1m"; private List> schedules; private List mandatoryList; @@ -38,7 +47,7 @@ public void route(String input, List> currentSchedules) { else if (input.equals("edit")) editList(); else if (input.equals("next")) viewLoop(5); else { - System.out.println("[Error] Invalid input. Going back to View Mode."); + System.out.println(RED+"[Error] Invalid input. Going back to View Mode."+RESET); viewLoop(0); } } @@ -60,7 +69,7 @@ private void viewLoop(int startIndex) { int nextIndex = startIndex; if(nextInput.equals("next")) { if (startIndex + 5 < schedules.size()) nextIndex += 5; - else System.out.println("[Info] Last page."); + else System.out.println(YELLOW+"[Info]"+RESET + " Last page."); } route(nextInput, this.schedules); @@ -69,7 +78,7 @@ private void viewLoop(int startIndex) { // 'edit': edit lists and send it back to InputHandler private void editList() { - System.out.println("[Edit Mode]"); + System.out.println(GREEN+"[Edit Mode]"+RESET); modifyCourse(this.mandatoryList, this.optionList); System.out.println("Re-calculating schedules..."); @@ -87,73 +96,73 @@ private void modifyCourse(List mandatory, List optional) { InputHandler ih = new InputHandler(); while (true) { - System.out.println("\n------------------------------------------"); - System.out.println(" Current Goal Credit: " + this.goalCredit); - System.out.println(" Mandatory: " + mandatory.size() + " courses"); - System.out.println(" Optional : " + optional.size() + " courses"); - System.out.println("------------------------------------------"); + System.out.println(CYAN+"\n------------------------------------------"+RESET); + System.out.println(" Current Goal Credit: " + this.goalCredit); + System.out.println(" Mandatory: " + mandatory.size() + " courses"); + System.out.println(" Optional : " + optional.size() + " courses"); + System.out.println(CYAN+"------------------------------------------"+RESET); System.out.println("1. Add/Edit MANDATORY Courses"); System.out.println("2. Add/Edit OPTIONAL Courses"); System.out.println("3. Remove a Course"); System.out.println("4. Change Goal Credit"); System.out.println("0. Finish Editing (Run Scheduler)"); - System.out.print("> Select: "); + System.out.print(YELLOW+"> (,,>∇<,,) Select: "+RESET); String choice = sc.nextLine().trim(); // Add if (choice.equals("1")) { - System.out.println("\n[Add to Mandatory] Type 'done' to finish."); + System.out.println(BLUE+"\n[Add to Mandatory]"+RESET+" Type 'done' to finish."); ih.inputLoop(sc, mandatory); } else if (choice.equals("2")) { - System.out.println("\n[Add to Optional] Type 'done' to finish."); + System.out.println(BLUE+"\n[Add to Optional]"+RESET+" Type 'done' to finish."); ih.inputLoop(sc, optional); } else if (choice.equals("3")) { removeCourseHelper(mandatory, optional); } else if (choice.equals("4")) { - System.out.print("Enter new max credit: "); + System.out.print("(*'▽ '*) Enter"+YELLOW+" new"+RESET+" max credit: "); try { int newCredit = Integer.parseInt(sc.nextLine().trim()); if (newCredit > 0) { this.goalCredit = newCredit; - System.out.println("Goal credit updated."); + System.out.println("Goal credit"+YELLOW+" updated."+RESET); } else { - System.out.println("Credit must be positive."); + System.out.println("Credit must be"+RED+" positive."+RESET); } } catch (Exception e) { - System.out.println("Invalid number."); + System.out.println(RED+"Invalid number."+RESET); } } else if (choice.equals("0")) { break; } else { - System.out.println("Invalid choice."); + System.out.println(RED+"Invalid choice."+RESET); } } } // helper of 'edit': remove private void removeCourseHelper(List mandatory, List optional) { - System.out.println("\n[Remove Course]"); + System.out.println(PURPLE+"\n(*'▽ '*) [Remove Course]"+RESET); System.out.println("1. From Mandatory"); System.out.println("2. From Optional"); - System.out.print("> Select list: "); + System.out.print(YELLOW+"> (,,>∇<,,) Select list: "+RESET); String listType = sc.nextLine().trim(); List target = null; if (listType.equals("1")) target = mandatory; else if (listType.equals("2")) target = optional; else { - System.out.println("Canceled."); + System.out.println(RED+"Canceled."+RESET); return; } if (target.isEmpty()) { - System.out.println("This list is empty."); + System.out.println(RED+"This list is empty."+RESET); return; } @@ -161,22 +170,22 @@ private void removeCourseHelper(List mandatory, List optional) { System.out.println("[" + i + "] " + target.get(i).getName()); } - System.out.print("Enter index to remove (or -1 to cancel): "); + System.out.print(RED+"(*'▽ '*) Enter index to remove "+RESET+" (or -1 to cancel): "); try { int idx = Integer.parseInt(sc.nextLine().trim()); if (idx >= 0 && idx < target.size()) { Course removed = target.remove(idx); System.out.println("Removed: " + removed.getName()); } else if (idx != -1) { - System.out.println("Invalid index."); + System.out.println(RED+"Invalid index."+RESET); } } catch (Exception e) { - System.out.println("Invalid input."); + System.out.println(RED+"Invalid input."+RESET); } } public void quit(){ - System.out.println("[Bye] Closing system..."); + System.out.println(BLUE+"[Bye] Closing system..."+RESET); System.exit(0); } } \ No newline at end of file diff --git a/src/main/java/com/unitime/feature/InputHandler.java b/src/main/java/com/unitime/feature/InputHandler.java index fe2af10..351e067 100644 --- a/src/main/java/com/unitime/feature/InputHandler.java +++ b/src/main/java/com/unitime/feature/InputHandler.java @@ -5,16 +5,25 @@ import java.util.Scanner; public class InputHandler { + public static final String RESET = "\u001B[0m"; + public static final String RED = "\u001B[31m"; + public static final String GREEN = "\u001B[32m"; + public static final String YELLOW = "\u001B[33m"; + public static final String BLUE = "\u001B[34m"; + public static final String PURPLE = "\u001B[35m"; + public static final String CYAN = "\u001B[36m"; + public static final String BLACK = "\u001B[30m"; + public static final String BOLD = "\u001B[1m"; private List mandatoryList = new ArrayList<>(); private List optionalList = new ArrayList<>(); private int maxCredit = 0; public void handle(Scanner sc) { - System.out.println("===== UniTime-Solver: Input Courses ====="); + System.out.println(CYAN +"===== UniTime-Solver: Input Courses ====="+ RESET); // Maximum credit - System.out.print("What is your MAXIMUM total credit? (positive number): "); + System.out.print(YELLOW+"(*'▽ '*) What is your MAXIMUM total credit?"+RESET+" ('"+RED+"positive"+RESET+"' number): "); while (true) { try { maxCredit = Integer.parseInt(sc.nextLine().trim()); @@ -22,20 +31,20 @@ public void handle(Scanner sc) { System.out.println("Maximum credit checked."); break; } - System.out.println("Please enter a positive number."); + System.out.println("Please enter a '"+RED+"positive"+RESET+"' number."); } catch (NumberFormatException e) { - System.out.println("Invalid number. Please try again."); + System.out.println(RED+"Invalid number. Please try again."+RESET); } } // Put into list // MandatoryList - System.out.println("\n[1] Enter MANDATORY Courses"); + System.out.println(BLUE+"\n[1] Enter MANDATORY Courses"+RESET); inputLoop(sc, mandatoryList); // OptionalList - System.out.println("\n[2] Enter OPTIONAL Courses"); + System.out.println(BLUE+"\n[2] Enter OPTIONAL Courses"+RESET); inputLoop(sc, optionalList); printSummary(); @@ -44,39 +53,39 @@ public void handle(Scanner sc) { // Show result public void printSummary() { - System.out.println("\n=========================================="); - System.out.println(" Check Input Summary "); - System.out.println("=========================================="); - System.out.println("Maximum Credit: " + maxCredit); + System.out.println(CYAN +"\n=========================================="+ RESET); + System.out.println(PURPLE+" (*>3<*) Check Input Summary "+RESET); + System.out.println(CYAN +"=========================================="+ RESET); + System.out.println(RED+"Maximum Credit: "+RESET + maxCredit); // Mandatory - System.out.println("\n[Fixed Courses] (" + mandatoryList.size() + " courses)"); + System.out.println(GREEN+"\n[Fixed Courses]"+RESET+" (" + mandatoryList.size() + " courses)"); if (mandatoryList.isEmpty()) System.out.println(" (None)"); for (Course c : mandatoryList) { System.out.println(" - " + c); } // Optional - System.out.println("\n[Optional Courses] (" + optionalList.size() + " courses)"); + System.out.println(GREEN+"\n[Optional Courses]"+RESET+" (" + optionalList.size() + " courses)"); if (optionalList.isEmpty()) System.out.println(" (None)"); for (Course c : optionalList) { System.out.println(" - " + c); } - System.out.println("=========================================="); - System.out.println("Finding timetables..."); - System.out.println("=========================================="); + System.out.println(CYAN +"=========================================="+ RESET); + System.out.println(" Finding timetables..."); + System.out.println(CYAN +"=========================================="+ RESET); } // Get user input public void inputLoop(Scanner sc, List targetList) { - System.out.println("------------------------------------------------------------------"); - System.out.println("Format: Name / Credit / Time"); - System.out.println("Example: Data Structure / 3 / Mon 12:30 14:00"); - System.out.println("------------------------------------------------------------------"); + System.out.println(PURPLE +"------------------------------------------------------------------"+ RESET); + System.out.println(" Format: Name / Credit / Time"); + System.out.println(" Example: Data Structure / 3 / Mon 12:30 14:00"); + System.out.println(PURPLE +"------------------------------------------------------------------"+ RESET); while (true) { - System.out.print("\nInput (or 'done'): "); + System.out.print(BLUE+"\nInput (or 'done'): "+RESET); String input = sc.nextLine().trim(); if (input.equalsIgnoreCase("done")) break; @@ -85,7 +94,7 @@ public void inputLoop(Scanner sc, List targetList) { // Split by '/' String[] parts = input.split("/"); if (parts.length != 3) { - throw new Exception("All 3 fields must be separated by '/'"); + throw new Exception(RED +"All 3 fields must be separated by '/'"+RESET); } // Trim and parse @@ -95,13 +104,13 @@ public void inputLoop(Scanner sc, List targetList) { // Validate credit if (credit <= 0) { - throw new Exception("Credit must be a positive number"); + throw new Exception(RED +"Credit must be a positive number"+RESET); } // Split time input String[] timeParts = timeString.split(" "); if (timeParts.length != 3) { - throw new Exception("Time format should be 'Day Start End'"); + throw new Exception(RED +"Time format should be 'Day Start End'"+RESET); } // Handle 'day' @@ -112,14 +121,14 @@ public void inputLoop(Scanner sc, List targetList) { else if (d.startsWith("w")) day = 2; else if (d.startsWith("th")) day = 3; else if (d.startsWith("f")) day = 4; - else throw new Exception("Invalid day (use Mon, Tue, Wed, Thu, or Fri)"); + else throw new Exception(RED +"Invalid day (use Mon, Tue, Wed, Thu, or Fri)"+RESET); // Parse time int startMin = parseMin(timeParts[1]); int endMin = parseMin(timeParts[2]); if (startMin >= endMin) { - throw new Exception("End time must be after start time"); + throw new Exception(RED +"End time must be after start time" +RESET); } // String for returning toString @@ -128,17 +137,17 @@ public void inputLoop(Scanner sc, List targetList) { // Add to list Course c = new Course(name, credit, day, startMin, endMin, timeRaw); targetList.add(c); - System.out.println(" -> [Added] " + name); + System.out.println(GREEN+" -> [Added] " +RESET+ name); } catch (NumberFormatException e) { - System.out.println("Error: Credit must be a valid number"); - System.out.println("Try again: Name / Credit / Day Start End"); + System.out.println(RED +"Error: Credit must be a valid number"+ RESET); + System.out.println(RED +"Try again: Name / Credit / Day Start End"+ RESET); } catch (ArrayIndexOutOfBoundsException e) { - System.out.println("Error: Invalid time format"); - System.out.println("Try again: Name / Credit / Day Start End"); + System.out.println(RED +"Error: Invalid time format"+ RESET); + System.out.println(RED +"Try again: Name / Credit / Day Start End"+ RESET); } catch (Exception e) { - System.out.println("Error: " + e.getMessage()); - System.out.println("Try again: Name / Credit / Day Start End"); + System.out.println(RED +"Error: "+ RESET + e.getMessage()); + System.out.println(RED +"Try again: Name / Credit / Day Start End"+ RESET); } } } @@ -148,18 +157,18 @@ public int parseMin(String t) throws Exception { try { String[] hhmm = t.split(":"); if (hhmm.length != 2) { - throw new Exception("Time must be in HH:MM format"); + throw new Exception(RED +"Time must be in HH:MM format"+ RESET); } int hours = Integer.parseInt(hhmm[0]); int minutes = Integer.parseInt(hhmm[1]); if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) { - throw new Exception("Invalid time range (hours: 0-23, minutes: 0-59)"); + throw new Exception(RED +"Invalid time range (hours: 0-23, minutes: 0-59)"+ RESET); } return hours * 60 + minutes; } catch (NumberFormatException e) { - throw new Exception("Time must contain valid numbers"); + throw new Exception(RED +"Time must contain valid numbers"+ RESET); } }