My TicketDesk System

Published: (January 19, 2026 at 06:36 AM EST)
6 min read
Source: Dev.to

Source: Dev.to

Intro

For my Intro to Programming module, I made a TicketDesk system in Java that can:

  • Track tickets
  • Track login information
  • Provide a role‑based authentication system

This devlog explores the main features and challenges I faced, along with useful comments on key points that I thought were worth mentioning.

Brief Description of the Program

The main goal of this TicketDesk system was to sort users into different roles, each receiving a different experience when interacting with the ticket desk:

RoleCapabilities
AdminDelete tickets, manage accounts
UserCreate and manage tickets (no account management)
GuestRead tickets only, with limited information

I’ll explain three key features of the program below.

Feature 1: User Input

The program relies on user input to navigate the system. Users constantly make menu selections and enter data so that tickets can be recorded.

  • I primarily used the Scanner class because it is simpler than BufferedReader, which requires handling a checked IOException.
  • The scanner variable is declared private in the Main class because it is only read from within that class.
private static Scanner sc = new Scanner(System.in);
int choice = Integer.parseInt(sc.nextLine());

The input captured through the Scanner drives the control flow of the ticket desk:

  • Integers navigate menus.
  • Strings populate ticket fields such as titles and descriptions.

Reference:
Scanner is skipping nextLine after using next/nextFoo – Stack Overflow

Feature 2: Methods

Methods separate functionality into reusable sections and allow code to be referenced across different classes (TicketManager, Authentication, Main).

Example – creating tickets (available to users and admins)

// method for creating tickets, for only users and admins
public void createTicket(Person loggedIn, Scanner sc) {
    loadTickets();
    if (loggedIn.isGuest()) { // if the user is a guest
        System.out.println("Unauthorised to create tickets. Returning to main menu...");
        return;
    }
    String title = getInput("Enter the ticket title (or 'CANCEL' to go back): ", sc);
    // ... additional logic ...
}
  • The createTicket() method centralises ticket‑creation logic, avoiding code duplication.
  • Permission checks are performed inside the method, so the menu only needs to call it once.

Reference:
How to apply the Single Responsibility Principle in Java – TheServerSide

Reflection:
The method currently handles loading tickets and checking permissions, which means it does not fully adhere to the Single Responsibility Principle. In future work I would separate those concerns to make the method more reusable.

Feature 3: Object‑Oriented Programming

OOP is used extensively, especially on the authentication side. The system defines three user roles—guest, user, admin—each with its own menu and accessible features.

Class Structure

public class Person {
    // private fields for better encapsulation (getters and setters used)
    private String username;
    private String password;
    private String role;

    public Person(String username, String password, String role) {
        this.username = username;
        this.password = password;
        this.role = role;
    }
    // getters / setters omitted for brevity
}
public class Admin extends Person {
    // constructor for admin class
    public Admin(String username, String password) {
        super(username, password, "admin");
    }
}
  • Encapsulation: Fields are private; access is provided via getters/setters.
  • Inheritance: Admin (and similarly User, Guest) extend Person.

Advantages of OOP in this project

  1. Flexibility: Adding a new role only requires creating a new subclass; no need to rewrite existing logic.
  2. Readability: Ticket information lives in a dedicated Ticket class, making the code intuitive.
  3. Hierarchy: Permissions naturally map to inheritance (admin > user > guest), demonstrating encapsulation and inheritance.

References:

Issues Encountered

Issue 1 – Delimiter Input

When admins or users create or modify tickets, typing a comma (,) in any field (e.g., the title) broke the display because the program used a comma as the data delimiter.

Solution – a helper method that rejects commas and empty input:

// very useful helper method to stop users from typing commas in the fields,
// as well as empty inputs
private String getInput(String prompt, Scanner sc) {
    while (true) {
        System.out.println(prompt);
        String userInput = sc.nextLine();

        if (userInput.contains(",")) {
            System.out.println("Commas cannot be entered! Please try again.");
        } else if (userInput.trim().isEmpty()) {
            System.out.println("Input cannot be empty, try again.");
        } else {
            return userInput;
        }
    }
}
  • The method is called wherever user input is required (e.g., editing ticket fields).
  • If a comma is detected, the loop repeats and asks again.
  • It also prevents empty strings, forcing the user to provide a valid value.

By using getInput() everywhere, the program no longer crashes due to stray commas.

Issue 2 – Console Output Overflow

When displaying large lists (all tickets, all accounts, etc.), the console immediately returned to the menu, causing the information to scroll off‑screen before the user could read it.

Solution – pause the output until the user presses ENTER:

System.out.println("\n========== Limited Ticket View ============");
for (int i = 0; i < ticketList.size(); i++) {
    Ticket t = ticketList.get(i);
    // formatted manually so it only displays these fields
    System.out.println("ID: " + t.getTicketId()
            + " | Title: " + t.getTitle()
            + " | Status: " + t.getStatus()
            + " | Tag: " + t.getTag());
}
System.out.println("==============================================");

System.out.println("\nTap ENTER to continue.."); // prevents immediate return to menu
sc.nextLine();
  • The prompt forces the user to acknowledge the output before the menu reappears.
  • It also works when listing users for deletion, giving admins time to locate the correct account.

In a GUI this would be handled automatically, but for a console‑based app the pause greatly improves usability across different IDEs.

Issue 3 – Ticket File Not Found

If the ticket storage file (ticketlist.txt) is missing or placed in the wrong directory, the program crashes because it cannot load or save tickets.

Solution – automatically create the file when it does not exist:

if (!myFile.exists()) {
    // You can also add your own files directly; they must be formatted
    // the same way as ticketlist.txt.
    System.out.println("There is currently no file to load tickets from... "
            + "A new file has been created called " + filename + " !");
    try {
        myFile.createNewFile();
        System.out.println("The file ticketlist.txt has now been created!");
        return;
    } catch (IOException e) { // need to handle this checked exception
        System.out.println("Error creating file, returning to main menu... "
                + e.getMessage());
        return;
    }
}
  • When a new file is created, the system reports “0 tickets loaded,” allowing the admin to edit the file manually if desired.
  • This prevents the entire application from breaking due to a missing file.

Closing Thoughts

These three issues—delimiter handling, console overflow, and missing‑file protection—represent the main challenges I tackled while building the ticket‑desk system. Addressing them made the code:

  • More readable for other developers.
  • More reliable, handling edge cases that could otherwise cause crashes.

Thanks for reading!

Back to Blog

Related posts

Read more »

Java Multithreading/Concurrency

What is multithreading in Java? Multithreading in Java is a feature that allows for the concurrent execution of two or more parts of a program, known as thread...