Code Sketch
graphic_7325
Category: Art
import javax.swing._
import java.awt._
import java.awt.event._
import java.awt.print.PrinterException
import java.net.{URI, URL, HttpURLConnection}
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import java.io.{BufferedReader, InputStreamReader}
import java.util.Base64
import scala.collection.mutable.ArrayBuffer
import scala.util.Random
object RailwayApp {
// ?. ??????? ??????? '7313' (Base64 Encoded)
val hiddenSecret = "NzMxMw=="
def getPassword(): String = {
new String(Base64.getDecoder.decode(hiddenSecret), "UTF-8")
}
val cloudHistoryKey = "railway_school_history_7313"
val cloudHistoryUrl = s"https://kvdb.io/4y9H7m5QzK7hS3qX9kH5Rz/$cloudHistoryKey"
val trainList = Vector(
("12124", "Deccan Queen", "Pune Jn - Mumbai CSMT", 450),
("12127", "Intercity Express", "Mumbai CSMT - Pune Jn", 350),
("11010", "Sinhagad Express", "Pune Jn - Mumbai CSMT", 250),
("11030", "Koyna Express", "Mumbai CSMT - Kolhapur", 400),
("12025", "Shatabdi Express", "Pune - Secunderabad", 600),
("11007", "Deccan Express", "Mumbai CSMT - Pune Jn", 300)
)
val bookingHistory = ArrayBuffer[String]()
val localHistory = ArrayBuffer[String]()
var currentUser: String = "Guest"
val random = new Random()
def fetchCloudData(urlStr: String): String = {
try {
val url = new URL(urlStr)
val conn = url.openConnection().asInstanceOf[HttpURLConnection]
conn.setRequestMethod("GET")
conn.setConnectTimeout(2000)
conn.setReadTimeout(2000)
if (conn.getResponseCode == 200) {
val in = new BufferedReader(new InputStreamReader(conn.getInputStream, "UTF-8"))
val sb = new StringBuilder
var line = in.readLine()
while (line != null) {
sb.append(line).append("\n")
line = in.readLine()
}
in.close()
sb.toString().trim
} else ""
} catch {
case _: Exception => ""
}
}
def logToCloudHistory(record: String): Unit = {
localHistory += record
new Thread(new Runnable {
def run(): Unit = {
try {
val oldLog = fetchCloudData(cloudHistoryUrl)
val updated = if (oldLog.isEmpty) record else oldLog + "\n" + record
val url = new URL(cloudHistoryUrl)
val conn = url.openConnection().asInstanceOf[HttpURLConnection]
conn.setRequestMethod("POST")
conn.setDoOutput(true)
conn.setConnectTimeout(2000)
conn.setRequestProperty("Content-Type", "text/plain; charset=UTF-8")
val os = conn.getOutputStream
os.write(updated.getBytes("UTF-8"))
os.flush()
os.close()
conn.getResponseCode
} catch {
case _: Exception =>
}
}
}).start()
}
def openWebsite(url: String): Unit = {
try {
if (Desktop.isDesktopSupported) Desktop.getDesktop.browse(new URI(url))
else JOptionPane.showMessageDialog(null, "Open this website:\n" + url)
} catch {
case _: Exception => JOptionPane.showMessageDialog(null, "Website could not be opened:\n" + url)
}
}
// ----------------------------------------
// 1. SPLASH SCREEN (TRAIN DESIGN)
// ----------------------------------------
def showSplash(): Unit = {
val splash = new JFrame()
splash.setUndecorated(true)
splash.setSize(600, 380)
splash.setLocationRelativeTo(null)
val logoPanel = new JPanel() {
override def paintComponent(g: Graphics): Unit = {
super.paintComponent(g)
val g2 = g.asInstanceOf[Graphics2D]
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
// Background
g2.setColor(new Color(15, 32, 67))
g2.fillRect(0, 0, getWidth, getHeight)
// Pantograph
g2.setColor(new Color(200, 200, 210))
g2.setStroke(new BasicStroke(3))
g2.drawLine(250, 42, 350, 42)
g2.drawLine(270, 42, 300, 68)
g2.drawLine(330, 42, 300, 68)
g2.drawLine(300, 68, 275, 78)
g2.drawLine(300, 68, 325, 78)
// Locomotive Body
g2.setColor(new Color(178, 34, 34))
g2.fillRoundRect(220, 78, 160, 130, 28, 28)
g2.setColor(new Color(139, 0, 0))
g2.fillRoundRect(225, 75, 150, 20, 15, 15)
// Windows
g2.setColor(new Color(190, 225, 255))
g2.fillRoundRect(235, 95, 60, 36, 10, 10)
g2.fillRoundRect(305, 95, 60, 36, 10, 10)
g2.setColor(new Color(40, 40, 40))
g2.setStroke(new BasicStroke(2))
g2.drawRoundRect(235, 95, 60, 36, 10, 10)
g2.drawRoundRect(305, 95, 60, 36, 10, 10)
// Yellow Stripe & Lights
g2.setColor(new Color(255, 193, 7))
g2.fillRect(220, 142, 160, 14)
g2.setColor(new Color(40, 40, 40))
g2.fillOval(282, 134, 36, 30)
g2.setColor(new Color(255, 255, 200))
g2.fillOval(286, 138, 13, 22)
g2.fillOval(301, 138, 13, 22)
g2.setColor(Color.RED)
g2.fillOval(235, 175, 12, 12)
g2.fillOval(353, 175, 12, 12)
// Buffers & Tracks
g2.setColor(new Color(30, 30, 30))
g2.fillRect(215, 205, 170, 12)
g2.fillOval(230, 202, 18, 18)
g2.fillOval(352, 202, 18, 18)
g2.setColor(new Color(200, 200, 210))
g2.setStroke(new BasicStroke(4))
g2.drawLine(150, 230, 450, 230)
g2.drawLine(120, 246, 480, 246)
g2.setColor(new Color(130, 110, 90))
g2.setStroke(new BasicStroke(3))
var sx = 140
while (sx <= 460) {
g2.drawLine(sx, 226, sx - 8, 250)
sx += 26
}
// Title Texts
g2.setColor(Color.WHITE)
g2.setFont(new Font("Arial", Font.BOLD, 26))
val title = "INDIAN RAILWAYS"
val fmTitle = g2.getFontMetrics
g2.drawString(title, (getWidth - fmTitle.stringWidth(title)) / 2, 285)
g2.setFont(new Font("Arial", Font.PLAIN, 15))
g2.setColor(new Color(255, 193, 7))
val sub = "TRAIN INFORMATION & BOOKING APP"
val fmSub = g2.getFontMetrics
g2.drawString(sub, (getWidth - fmSub.stringWidth(sub)) / 2, 312)
g2.setFont(new Font("Arial", Font.ITALIC, 13))
g2.setColor(new Color(180, 210, 240))
val load = "Starting engine..."
val fmLoad = g2.getFontMetrics
g2.drawString(load, (getWidth - fmLoad.stringWidth(load)) / 2, 345)
}
}
splash.setContentPane(logoPanel)
splash.setVisible(true)
val splashTimer = new javax.swing.Timer(1500, new ActionListener {
def actionPerformed(e: ActionEvent): Unit = {
splash.dispose()
showLogin()
}
})
splashTimer.setRepeats(false)
splashTimer.start()
}
// ----------------------------------------
// 2. DIRECT LOGIN SCREEN
// ----------------------------------------
def showLogin(): Unit = {
val login = new JFrame("Indian Railway - Login")
login.setSize(480, 360)
login.setLocationRelativeTo(null)
login.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
val panel = new JPanel(new GridLayout(0, 1, 8, 8))
panel.setBorder(BorderFactory.createEmptyBorder(20, 35, 20, 35))
panel.setBackground(new Color(235, 244, 255))
val title = new JLabel("INDIAN RAILWAY LOGIN", SwingConstants.CENTER)
title.setFont(new Font("Arial", Font.BOLD, 22))
val userLabel = new JLabel("Username:")
userLabel.setFont(new Font("Arial", Font.BOLD, 14))
val userField = new JTextField()
userField.setFont(new Font("Arial", Font.PLAIN, 16))
val passLabel = new JLabel("Password:")
passLabel.setFont(new Font("Arial", Font.BOLD, 14))
val passwordField = new JPasswordField()
passwordField.setFont(new Font("Arial", Font.PLAIN, 16))
val loginButton = new JButton("LOGIN")
loginButton.setFont(new Font("Arial", Font.BOLD, 16))
loginButton.setBackground(new Color(20, 80, 150))
loginButton.setForeground(Color.WHITE)
loginButton.setFocusPainted(false)
panel.add(title)
panel.add(userLabel)
panel.add(userField)
panel.add(passLabel)
panel.add(passwordField)
panel.add(loginButton)
login.setContentPane(panel)
def checkPassword(): Unit = {
val usernameInput = userField.getText.trim
val enteredPass = new String(passwordField.getPassword).trim
if (usernameInput.isEmpty) {
JOptionPane.showMessageDialog(login, "Please enter your Username.", "Missing Details", JOptionPane.WARNING_MESSAGE)
} else if (enteredPass.isEmpty) {
JOptionPane.showMessageDialog(login, "Please enter Password.", "Missing Details", JOptionPane.WARNING_MESSAGE)
} else {
val timeFormat = DateTimeFormatter.ofPattern("dd-MM-yyyy hh:mm:ss a")
val logTime = LocalDateTime.now().format(timeFormat)
// ??????? '7313' ??????
if (enteredPass == getPassword()) {
currentUser = usernameInput
logToCloudHistory(s"User: $currentUser | Time: $logTime | Status: SUCCESS")
login.dispose()
openMainApp()
} else {
logToCloudHistory(s"User: $usernameInput | Time: $logTime | Status: FAILED ATTEMPT")
passwordField.setText("")
JOptionPane.showMessageDialog(
login,
"Incorrect password! Please try again.",
"Login Failed",
JOptionPane.ERROR_MESSAGE
)
}
}
}
loginButton.addActionListener(new ActionListener {
def actionPerformed(e: ActionEvent): Unit = checkPassword()
})
passwordField.addActionListener(new ActionListener {
def actionPerformed(e: ActionEvent): Unit = checkPassword()
})
login.setVisible(true)
}
// ----------------------------------------
// 3. MAIN APPLICATION SCREEN
// ----------------------------------------
def openMainApp(): Unit = {
val app = new JFrame("Indian Railway Information App")
app.setSize(960, 780)
app.setLocationRelativeTo(null)
app.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
val root = new JPanel(new BorderLayout(12, 12))
root.setBorder(BorderFactory.createEmptyBorder(12, 12, 12, 12))
root.setBackground(new Color(235, 244, 255))
val topPanel = new JPanel(new GridLayout(2, 1, 4, 4))
topPanel.setBackground(new Color(235, 244, 255))
val heading = new JLabel("INDIAN RAILWAY INFORMATION", SwingConstants.CENTER)
heading.setFont(new Font("Arial", Font.BOLD, 24))
heading.setForeground(new Color(15, 65, 125))
val userTag = new JLabel(s"Logged in as: $currentUser", SwingConstants.CENTER)
userTag.setFont(new Font("Arial", Font.BOLD, 14))
userTag.setForeground(new Color(40, 110, 40))
topPanel.add(heading)
topPanel.add(userTag)
root.add(topPanel, BorderLayout.NORTH)
val output = new JTextArea()
output.setEditable(false)
output.setFont(new Font("Monospaced", Font.PLAIN, 15))
output.setLineWrap(true)
output.setWrapStyleWord(true)
output.setMargin(new Insets(10, 10, 10, 10))
val scroll = new JScrollPane(output)
scroll.setPreferredSize(new Dimension(920, 360))
root.add(scroll, BorderLayout.CENTER)
val buttons = new JPanel(new GridLayout(5, 2, 8, 8))
buttons.setPreferredSize(new Dimension(920, 240))
buttons.setBackground(new Color(235, 244, 255))
def showText(s: String): Unit = {
output.setText(s)
output.setCaretPosition(0)
}
def addButton(label: String, bgColor: Color = new Color(25, 90, 165))(action: => Unit): Unit = {
val b = new JButton(label)
b.setFont(new Font("Arial", Font.BOLD, 13))
b.setBackground(bgColor)
b.setForeground(Color.WHITE)
b.setFocusPainted(false)
b.addActionListener(new ActionListener {
def actionPerformed(e: ActionEvent): Unit = action
})
buttons.add(b)
}
def makePNR(): String = "DEMO" + (100000 + random.nextInt(900000)).toString
// 1. TRAIN SEARCH
addButton("1. Train Search") {
val query = JOptionPane.showInputDialog(app, "Enter Train No, Name, or Station (e.g., Pune / 12124 / Queen):", "Train Search", JOptionPane.QUESTION_MESSAGE)
if (query != null) {
val trimmed = query.trim.toLowerCase
if (trimmed.isEmpty) showText("Please enter a valid search term.")
else {
val found = trainList.filter { case (num, name, route, _) =>
num.toLowerCase.contains(trimmed) || name.toLowerCase.contains(trimmed) || route.toLowerCase.contains(trimmed)
}
if (found.nonEmpty) {
val resultText =
"====================================================\n" +
" TRAIN SEARCH RESULTS \n" +
"====================================================\n\n" +
found.map { case (num, name, route, fare) =>
s"Train Number : $num\nTrain Name : $name\nRoute : $route\nSample Fare : Rs. $fare"
}.mkString("\n\n----------------------------------------------------\n\n") +
"\n\n====================================================\n" +
s"Total trains found: ${found.size}"
showText(resultText)
} else {
showText(s"No train found matching: \"$query\"")
}
}
}
}
// 2. ALL TRAINS
addButton("2. All Trains") {
showText(
"====================================================\n" +
" SAMPLE TRAIN LIST \n" +
"====================================================\n\n" +
trainList.map { case (num, name, route, fare) =>
s"Train No: $num - $name\nRoute : $route\nFare : Rs. $fare"
}.mkString("\n\n----------------------------------------------------\n\n")
)
}
// 3. LIVE STATUS
addButton("3. Live Train Status") {
showText("Opening NTES railway website...")
openWebsite("https://enquiry.indianrail.gov.in/ntes/")
}
// 4. ROUTE AND DEMO BOOKING
addButton("4. Route & Booking") {
val from = JOptionPane.showInputDialog(app, "From station (e.g. Pune Jn):")
if (from != null && from.trim.nonEmpty) {
val to = JOptionPane.showInputDialog(app, "To station (e.g. Mumbai CSMT):")
if (to != null && to.trim.nonEmpty) {
val date = JOptionPane.showInputDialog(app, "Journey date (DD-MM-YYYY):")
if (date != null && date.trim.nonEmpty) {
val passenger = JOptionPane.showInputDialog(app, "Passenger name:")
if (passenger != null && passenger.trim.nonEmpty) {
val ageText = JOptionPane.showInputDialog(app, "Passenger age:")
val countText = JOptionPane.showInputDialog(app, "Number of tickets (1 to 6):")
try {
val age = ageText.trim.toInt
val count = countText.trim.toInt
if (age < 1 || age > 120 || count < 1 || count > 6) throw new IllegalArgumentException()
val pnr = makePNR()
val fare = count * 350
val ticket =
"====================================\n" +
" RAILWAY DEMO E-TICKET \n" +
"====================================\n\n" +
s"Booked By : $currentUser\n" +
s"Demo PNR : $pnr\n" +
s"Passenger : ${passenger.trim}\n" +
s"Age : $age\n" +
s"From : ${from.trim}\n" +
s"To : ${to.trim}\n" +
s"Date : ${date.trim}\n" +
s"Tickets : $count\n" +
s"Sample fare: Rs. $fare\n\n" +
"Status: DEMO BOOKING SUCCESSFUL\n" +
"===================================="
bookingHistory += ticket
showText(ticket)
JOptionPane.showMessageDialog(app, s"DEMO BOOKING SUCCESSFUL!\n\nDemo PNR: $pnr")
} catch {
case _: Exception => JOptionPane.showMessageDialog(app, "Please enter a valid age and ticket count.")
}
}
}
}
}
}
// 5. BOOKING HISTORY
addButton("5. Booking History") {
if (bookingHistory.isEmpty) showText("No demo bookings yet.")
else showText(bookingHistory.zipWithIndex.map { case (t, i) => s"BOOKING #${i + 1}\n$t" }.mkString("\n\n"))
}
// 6. PRINT TICKET
addButton("6. Print Current Ticket") {
if (output.getText.contains("RAILWAY DEMO E-TICKET")) {
try { output.print() } catch { case ex: PrinterException => JOptionPane.showMessageDialog(app, "Printing failed: " + ex.getMessage) }
} else JOptionPane.showMessageDialog(app, "Create a demo ticket first.")
}
// 7. OFFICIAL WEBSITE
addButton("7. Official Ticket Booking") {
showText("Opening official IRCTC booking website...")
openWebsite("https://www.irctc.co.in/nget/train-search")
}
// 8. CLEAR SCREEN
addButton("8. Home / Clear Screen") {
showText(s"WELCOME TO INDIAN RAILWAY APP, $currentUser!\n\nSelect an option below to proceed.")
}
// 9. ADMIN LOGIN HISTORY (????? '7313' ????????? ?????)
addButton("9. Admin Login History", new Color(110, 45, 140)) {
val pwdField = new JPasswordField()
val dialog = JOptionPane.showConfirmDialog(
app,
Array[Object]("Enter Secret History Password:", pwdField),
"Admin Access Required",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.WARNING_MESSAGE
)
if (dialog == JOptionPane.OK_OPTION) {
val enteredSecret = new String(pwdField.getPassword).trim
if (enteredSecret == getPassword()) {
showText("Fetching latest records...")
new Thread(new Runnable {
def run(): Unit = {
val remoteData = fetchCloudData(cloudHistoryUrl)
val allData = if (remoteData.trim.nonEmpty) remoteData else localHistory.mkString("\n")
SwingUtilities.invokeLater(new Runnable {
def run(): Unit = {
if (allData.trim.isEmpty) {
showText("No login records found yet.")
} else {
val formatted = allData.split("\n").zipWithIndex.map { case (rec, i) =>
s"[#${i + 1}] $rec"
}.mkString("\n----------------------------------------------------\n")
showText(
"====================================================\n" +
" ADMIN LOGS: USER LOGIN RECORDS \n" +
"====================================================\n\n" +
formatted +
"\n\n===================================================="
)
}
}
})
}
}).start()
} else {
JOptionPane.showMessageDialog(app, "Access Denied: Incorrect secret password!", "Unauthorized", JOptionPane.ERROR_MESSAGE)
}
}
}
// 10. LOGOUT BUTTON
addButton("10. Logout", new Color(180, 40, 40)) {
val confirm = JOptionPane.showConfirmDialog(app, s"Do you want to log out, $currentUser?", "Confirm Logout", JOptionPane.YES_NO_OPTION)
if (confirm == JOptionPane.YES_OPTION) {
app.dispose()
showLogin()
}
}
root.add(buttons, BorderLayout.SOUTH)
showText(s"Welcome, $currentUser!\n\nChoose an option below to proceed.")
app.setContentPane(root)
app.setVisible(true)
}
def start(): Unit = {
showSplash()
}
}
RailwayApp.start()