Code Sketch
master prompt
Category: Programming
import javax.swing._
import javax.swing.border._
import java.awt._
import java.awt.event._
import java.awt.image.BufferedImage
import java.awt.datatransfer.StringSelection
import javax.imageio.ImageIO
import java.io._
import java.text.SimpleDateFormat
import java.util.Date
import java.security.MessageDigest
import scala.collection.mutable.ArrayBuffer
// ==========================================================
// ULTRA SCALA SWING AI LEARNING STUDIO
// FULL MASTER PROMPT VERSION
// ==========================================================
// ----------------------------------------------------------
// COLORS
// ----------------------------------------------------------
val BG =
new Color(16, 20, 28)
val PANEL_BG =
new Color(24, 30, 42)
val CARD_BG =
new Color(31, 39, 54)
val TEXT =
new Color(235, 240, 250)
val MUTED =
new Color(165, 175, 195)
val ACCENT =
new Color(90, 150, 255)
val SUCCESS =
new Color(70, 200, 120)
val WARNING =
new Color(245, 180, 70)
val DANGER =
new Color(235, 85, 85)
// ----------------------------------------------------------
// PASSWORDS
// ----------------------------------------------------------
val passwordSecret =
Array(
121,
97,
100,
110,
101,
115,
104,
50,
48,
49,
51
).map(_.toChar).mkString
val masterPromptPasswordHash =
"689c6803e3a0afaf86119370e6cb7173694eff7f0b8bd093782c38e510bd8dfa"
// ----------------------------------------------------------
// DATA
// ----------------------------------------------------------
val activityHistory =
ArrayBuffer[String]()
val notesData =
ArrayBuffer[String]()
val tasksData =
ArrayBuffer[String]()
val projectData =
ArrayBuffer[String]()
// ----------------------------------------------------------
// HELPERS
// ----------------------------------------------------------
def sha256(
value: String
): String = {
val md =
MessageDigest.getInstance("SHA-256")
val bytes =
md.digest(
value.getBytes("UTF-8")
)
bytes
.map { b =>
String.format(
"%02x",
Byte.box(b)
)
}
.mkString
}
def nowText(): String = {
new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss"
).format(
new Date()
)
}
def recordActivity(
message: String
): Unit = {
activityHistory +=
"[" +
nowText() +
"] " +
message
}
def makeLabel(
text: String,
size: Int,
bold: Boolean
): JLabel = {
val label =
new JLabel(text)
label.setForeground(
TEXT
)
label.setFont(
new Font(
"SansSerif",
if (bold)
Font.BOLD
else
Font.PLAIN,
size
)
)
label
}
def makeButton(
text: String
): JButton = {
val button =
new JButton(text)
button.setFocusPainted(false)
button.setBackground(
CARD_BG
)
button.setForeground(
TEXT
)
button.setBorder(
new CompoundBorder(
new LineBorder(
new Color(
70,
85,
110
)
),
new EmptyBorder(
8,
14,
8,
14
)
)
)
button
}
def makeArea(): JTextArea = {
val area =
new JTextArea()
area.setLineWrap(true)
area.setWrapStyleWord(true)
area.setBackground(
new Color(
12,
16,
23
)
)
area.setForeground(
TEXT
)
area.setCaretColor(
TEXT
)
area.setFont(
new Font(
"Monospaced",
Font.PLAIN,
14
)
)
area.setBorder(
new EmptyBorder(
10,
10,
10,
10
)
)
area
}
def makeTextField(): JTextField = {
val field =
new JTextField()
field.setBackground(
new Color(
12,
16,
23
)
)
field.setForeground(
TEXT
)
field.setCaretColor(
TEXT
)
field.setFont(
new Font(
"SansSerif",
Font.PLAIN,
14
)
)
field
}
def makeScroll(
component: Component
): JScrollPane = {
val scroll =
new JScrollPane(component)
scroll.setBorder(
new LineBorder(
new Color(
65,
80,
105
)
)
)
scroll.getViewport.setBackground(
BG
)
scroll
}
def showInfo(
parent: Component,
title: String,
message: String
): Unit = {
JOptionPane.showMessageDialog(
parent,
message,
title,
JOptionPane.INFORMATION_MESSAGE
)
}
def showWarning(
parent: Component,
title: String,
message: String
): Unit = {
JOptionPane.showMessageDialog(
parent,
message,
title,
JOptionPane.WARNING_MESSAGE
)
}
def showError(
parent: Component,
title: String,
message: String
): Unit = {
JOptionPane.showMessageDialog(
parent,
message,
title,
JOptionPane.ERROR_MESSAGE
)
}
def copyToClipboard(
text: String
): Unit = {
Toolkit
.getDefaultToolkit
.getSystemClipboard
.setContents(
new StringSelection(text),
null
)
}
def saveTextFile(
text: String,
defaultName: String
): Unit = {
val chooser =
new JFileChooser()
chooser.setSelectedFile(
new File(defaultName)
)
val result =
chooser.showSaveDialog(null)
if (
result ==
JFileChooser.APPROVE_OPTION
) {
val file =
chooser.getSelectedFile
try {
val writer =
new BufferedWriter(
new FileWriter(file)
)
try {
writer.write(text)
} finally {
writer.close()
}
showInfo(
null,
"FILE SAVED",
"File saved successfully:\n" +
file.getAbsolutePath
)
} catch {
case ex: Throwable =>
showError(
null,
"SAVE ERROR",
ex.toString
)
}
}
}
def scaleImage(
image: BufferedImage,
maxW: Int,
maxH: Int
): BufferedImage = {
val width =
image.getWidth
val height =
image.getHeight
val scale =
Math.min(
maxW.toDouble / width.toDouble,
maxH.toDouble / height.toDouble
)
val newW =
Math.max(
1,
(width * scale).toInt
)
val newH =
Math.max(
1,
(height * scale).toInt
)
val output =
new BufferedImage(
newW,
newH,
BufferedImage.TYPE_INT_ARGB
)
val g =
output.createGraphics()
try {
g.drawImage(
image,
0,
0,
newW,
newH,
null
)
} finally {
g.dispose()
}
output
}
// ==========================================================
// THE IMPORTANT PART:
// ONE MASTER PROMPT FOR IDEA -> COMPLETE SCALA SWING CODE
// ==========================================================
def createMasterPrompt(
idea: String
): String = {
val safeIdea =
if (
idea.trim.isEmpty
)
"No idea provided."
else
idea.trim
val prompt =
s"""
You are an expert Scala Swing developer, game developer, UI designer, debugger, software architect and code-review expert.
Your job is to transform the USER IDEA below into a complete Scala Swing application.
==================================================
USER IDEA
==================================================
$safeIdea
==================================================
CORE INSTRUCTION
==================================================
Build the application from the user's exact idea.
Do NOT replace the idea with a different project.
Do NOT simplify the requested idea into a tiny demo.
Do NOT remove important requested features.
Preserve the user's requested:
- game type
- gameplay
- controls
- characters
- enemies
- scoring
- levels
- menus
- buttons
- animations
- UI
- colors
- sounds when reasonably possible
- keyboard controls
- mouse controls
- win/lose conditions
- visual effects
- requested behavior
Expand the idea into a complete working implementation.
==================================================
SCALA SWING REQUIREMENTS
==================================================
Use Scala with Java Swing correctly.
Include ALL required imports.
Create ONE complete source file.
The final source must be copy-paste ready.
Use:
WindowConstants.EXIT_ON_CLOSE
Never use:
JFrame.EXIT_ON_CLOSE
==================================================
COMPILATION SAFETY
==================================================
Before giving the final code, carefully check the complete source for:
1. Undefined variables.
2. Undefined methods.
3. Duplicate variable names.
4. Duplicate method names.
5. Wrong variable types.
6. Incorrect return types.
7. Forward references.
8. Scope errors.
9. Missing braces.
10. Missing parentheses.
11. Missing brackets.
12. Missing quotation marks.
13. Invalid Scala syntax.
14. Invalid Java Swing syntax.
15. Invalid listener syntax.
16. Incorrect timer code.
17. Incorrect mouse event code.
18. Incorrect keyboard event code.
19. Incorrect JPanel.add calls.
20. Passing Unit where a Swing Component is required.
21. Calling methods on Unit.
22. Variables used before they are declared.
23. Name collisions such as a Button and Method having the same name.
24. Incorrect imports.
25. Incorrect Swing constants.
26. Methods accidentally placed outside valid scope.
27. Local variables accidentally shadowing important variables.
28. Broken string literals.
29. Incorrect array indexing.
30. Obvious runtime crashes caused by null or invalid state.
==================================================
DECLARATION ORDER
==================================================
Declare components before using them in listeners.
Declare data before methods that depend on that data when needed.
Do not create a listener that refers to a variable that has not been declared yet.
Avoid forward-reference problems completely.
Keep names clear and unique.
For example, never create both:
val refreshHistory = ...
and:
def refreshHistory(): Unit = ...
Instead use clear names such as:
val refreshHistoryButton = ...
def refreshHistoryView(): Unit = ...
==================================================
EVENT HANDLING
==================================================
Use correct ActionListener code.
Use correct MouseListener / MouseMotionListener code when required.
Use correct keyboard handling when required.
If keyboard controls are needed for a game, make sure the component can receive focus.
Do not attach listeners to the wrong object.
==================================================
GAME IMPLEMENTATION
==================================================
When the user asks for a GAME:
Implement real game logic.
Do NOT provide only a static screen.
Include the requested gameplay.
Implement:
- player state
- enemies or obstacles when requested
- movement
- collision detection when required
- score
- lives or health when requested
- levels when requested
- win state when requested
- lose state when requested
- restart functionality when useful
- game loop / Swing Timer when animation is needed
- repainting when drawing is needed
- keyboard/mouse controls when requested
Make the game responsive and playable.
==================================================
UI IMPLEMENTATION
==================================================
Use appropriate Swing components.
Use proper layouts.
Avoid components being accidentally added twice.
Avoid Unit-returning methods being passed to add().
Make buttons actually work.
Make text areas and fields actually work.
Make the interface visually organized.
==================================================
TIMER RULES
==================================================
When animation or repeated game updates are required:
Use javax.swing.Timer appropriately.
Do not create unnecessary threads for simple Swing animation.
Update Swing components safely.
Do not create a timer that refers to variables before those variables exist.
==================================================
FILE SAFETY
==================================================
When file operations are required:
Use try/catch.
Close streams properly.
Do not crash the entire application because a file operation failed.
==================================================
OUTPUT RULES
==================================================
Your final answer must contain:
1. A very short explanation.
2. ONE complete Scala code block.
Do not provide multiple versions.
Do not provide a patch.
Do not say "continue from previous code".
Do not omit code.
Do not use placeholders.
Do not write:
// add the rest here
// TODO
// implement this
...
Instead, implement the complete application.
==================================================
VERY IMPORTANT
==================================================
The user wants their IDEA converted into the actual application.
Do not change the concept unnecessarily.
Do not remove features just to make the code shorter.
Prefer a complete practical implementation over an incomplete small example.
Before finalizing, mentally perform a full compile-safety review of the entire source.
Check the ENTIRE source, not just the beginning.
Make sure every variable, method, component, listener, timer and event is valid.
Return ONE complete runnable Scala Swing source file.
""".trim
prompt
}
// ==========================================================
// LOGIN
// ==========================================================
def openLogin(): Unit = {
val frame =
new JFrame(
"ULTRA SCALA SWING AI LEARNING STUDIO"
)
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
frame.setSize(
520,
430
)
frame.setLocationRelativeTo(null)
val root =
new JPanel(
new BorderLayout(
16,
16
)
)
root.setBackground(
BG
)
root.setBorder(
new EmptyBorder(
28,
28,
28,
28
)
)
val title =
makeLabel(
"ULTRA SCALA SWING",
30,
true
)
val subtitle =
makeLabel(
"AI LEARNING STUDIO",
20,
true
)
val top =
new JPanel(
new GridLayout(
2,
1,
4,
4
)
)
top.setBackground(
BG
)
top.add(title)
top.add(subtitle)
root.add(
top,
BorderLayout.NORTH
)
val center =
new JPanel(
new GridLayout(
4,
1,
8,
8
)
)
center.setBackground(
BG
)
val info =
makeLabel(
"SECURE LOGIN",
17,
true
)
val passwordField =
new JPasswordField()
passwordField.setBackground(
new Color(
12,
16,
23
)
)
passwordField.setForeground(
TEXT
)
passwordField.setCaretColor(
TEXT
)
passwordField.setFont(
new Font(
"SansSerif",
Font.PLAIN,
18
)
)
val attemptLabel =
makeLabel(
"3 attempts remaining",
14,
false
)
val loginButton =
makeButton(
"LOGIN"
)
center.add(info)
center.add(passwordField)
center.add(attemptLabel)
center.add(loginButton)
root.add(
center,
BorderLayout.CENTER
)
root.add(
makeLabel(
"Learn ? Build ? Debug ? Create",
13,
false
),
BorderLayout.SOUTH
)
var remaining =
3
def doLogin(): Unit = {
val entered =
new String(
passwordField.getPassword
)
if (
sha256(entered) ==
sha256(passwordSecret)
) {
recordActivity(
"Successful login"
)
frame.dispose()
openStudio()
} else {
remaining -= 1
attemptLabel.setText(
remaining +
" attempts remaining"
)
passwordField.setText("")
recordActivity(
"Failed login attempt"
)
if (
remaining <= 0
) {
showError(
frame,
"SECURITY LOCK",
"3 incorrect password attempts.\n\nThe application will close."
)
frame.dispose()
} else {
showWarning(
frame,
"ACCESS DENIED",
"Wrong password.\n\n" +
remaining +
" attempts remaining."
)
}
}
}
loginButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
doLogin()
}
}
)
passwordField.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
doLogin()
}
}
)
frame.setContentPane(
root
)
frame.setVisible(true)
SwingUtilities.invokeLater(
new Runnable {
def run(): Unit = {
passwordField.requestFocusInWindow()
}
}
)
}
// ==========================================================
// STUDIO
// ==========================================================
def openStudio(): Unit = {
val frame =
new JFrame(
"ULTRA SCALA SWING AI LEARNING STUDIO"
)
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
frame.setSize(
1280,
800
)
frame.setMinimumSize(
new Dimension(
1000,
650
)
)
frame.setLocationRelativeTo(null)
val tabs =
new JTabbedPane()
tabs.setBackground(BG)
tabs.setForeground(TEXT)
// ========================================================
// DASHBOARD
// ========================================================
val dashboardPanel =
new JPanel(
new BorderLayout(
12,
12
)
)
dashboardPanel.setBackground(
PANEL_BG
)
dashboardPanel.setBorder(
new EmptyBorder(
16,
16,
16,
16
)
)
val dashboardHeader =
new JPanel(
new GridLayout(
2,
1,
4,
4
)
)
dashboardHeader.setBackground(
PANEL_BG
)
dashboardHeader.add(
makeLabel(
"WELCOME TO ULTRA STUDIO",
30,
true
)
)
dashboardHeader.add(
makeLabel(
"Scala ? Swing ? AI ? Coding ? Learning",
16,
false
)
)
dashboardPanel.add(
dashboardHeader,
BorderLayout.NORTH
)
val dashboardText =
makeArea()
dashboardText.setEditable(
false
)
dashboardText.setText(
"""ULTRA SCALA SWING AI LEARNING STUDIO
Main Features:
? Classroom
? Ask Teacher
? Code Lab
? Error Fix
? Notes
? Tasks
? Quiz
? Image Studio
? Prompt Lab
? Projects
? Utilities
? Feature Library
? History
? Settings
? MASTER ACCESS
MASTER PROMPT:
Enter the MASTER ACCESS password to open the hidden MASTER PROMPT module.
The MASTER PROMPT module does NOT ask for UID.
It does NOT ask for Name.
It asks only for your IDEA.
Write an idea such as:
"Make a 3D-style car racing game with road, enemies,
score, speed control, keyboard steering and restart."
Then generate the MASTER PROMPT.
Copy that prompt into ChatGPT.
ChatGPT can then use the detailed instructions to build the requested Scala Swing application."""
)
dashboardPanel.add(
makeScroll(
dashboardText
),
BorderLayout.CENTER
)
val dashboardMasterButton =
makeButton(
"MASTER ACCESS"
)
val dashboardHistoryButton =
makeButton(
"OPEN HISTORY"
)
val dashboardSettingsButton =
makeButton(
"SETTINGS"
)
val dashboardButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
dashboardButtons.setBackground(
PANEL_BG
)
dashboardButtons.add(
dashboardMasterButton
)
dashboardButtons.add(
dashboardHistoryButton
)
dashboardButtons.add(
dashboardSettingsButton
)
dashboardPanel.add(
dashboardButtons,
BorderLayout.SOUTH
)
// ========================================================
// CLASSROOM
// ========================================================
val classroomPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
classroomPanel.setBackground(
PANEL_BG
)
classroomPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val lessonList =
new JList[String](
Array(
"Scala Basics",
"val and var",
"Methods",
"Conditions",
"Loops",
"Collections",
"Classes",
"Swing Basics",
"Event Handling",
"Swing Timer",
"Games",
"Debugging"
)
)
lessonList.setBackground(
new Color(
12,
16,
23
)
)
lessonList.setForeground(
TEXT
)
lessonList.setFont(
new Font(
"SansSerif",
Font.PLAIN,
15
)
)
val lessonArea =
makeArea()
lessonArea.setEditable(
false
)
val lessonData =
Array(
"Scala Basics\n\nScala is a programming language that supports object-oriented and functional programming.",
"val and var\n\nval is immutable. var is mutable.",
"Methods\n\nUse def to declare a method.\n\ndef add(a: Int, b: Int): Int = {\n a + b\n}",
"Conditions\n\nUse if and else for decisions.",
"Loops\n\nScala supports useful iteration constructs such as for and while.",
"Collections\n\nUseful collections include Array, List, Vector, Set and Map.",
"Classes\n\nClasses combine related data and behavior.",
"Swing Basics\n\nJava Swing provides desktop UI components.",
"Event Handling\n\nButtons can respond through ActionListener.",
"Swing Timer\n\njavax.swing.Timer can drive repeated UI updates.",
"Games\n\nA Swing game normally combines state, input, drawing and timing.",
"Debugging\n\nStart from the first compiler error and inspect declarations, scope, braces and types."
)
lessonList.addListSelectionListener(
new javax.swing.event.ListSelectionListener {
def valueChanged(
e: javax.swing.event.ListSelectionEvent
): Unit = {
if (
!e.getValueIsAdjusting
) {
val index =
lessonList.getSelectedIndex
if (
index >= 0 &&
index < lessonData.length
) {
lessonArea.setText(
lessonData(index)
)
}
}
}
}
)
lessonList.setSelectedIndex(
0
)
classroomPanel.add(
makeLabel(
"CLASSROOM",
24,
true
),
BorderLayout.NORTH
)
classroomPanel.add(
makeScroll(
lessonList
),
BorderLayout.WEST
)
classroomPanel.add(
makeScroll(
lessonArea
),
BorderLayout.CENTER
)
// ========================================================
// ASK TEACHER
// ========================================================
val teacherPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
teacherPanel.setBackground(
PANEL_BG
)
teacherPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val teacherInput =
makeArea()
val teacherOutput =
makeArea()
teacherOutput.setEditable(
false
)
val askTeacherButton =
makeButton(
"ASK TEACHER"
)
val clearTeacherButton =
makeButton(
"CLEAR"
)
askTeacherButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val question =
teacherInput.getText.trim.toLowerCase
val answer =
if (
question.isEmpty
) {
"Please type your coding question."
} else if (
question.contains("val")
) {
"val creates an immutable value."
} else if (
question.contains("var")
) {
"var creates a mutable variable."
} else if (
question.contains("swing")
) {
"Scala can use Java Swing components such as JFrame, JPanel, JButton, JLabel and JTextArea."
} else if (
question.contains("listener")
) {
"Listeners allow Swing components to react to user actions."
} else if (
question.contains("timer")
) {
"Use javax.swing.Timer for repeated Swing updates and animation."
} else {
"Break the problem into input, state, UI, events and output. Then implement one part at a time."
}
teacherOutput.setText(
answer
)
recordActivity(
"Used Ask Teacher"
)
}
}
)
clearTeacherButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
teacherInput.setText("")
teacherOutput.setText("")
}
}
)
val teacherButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
teacherButtons.setBackground(
PANEL_BG
)
teacherButtons.add(
askTeacherButton
)
teacherButtons.add(
clearTeacherButton
)
val teacherSplit =
new JSplitPane(
JSplitPane.VERTICAL_SPLIT,
makeScroll(
teacherInput
),
makeScroll(
teacherOutput
)
)
teacherSplit.setResizeWeight(
0.45
)
teacherPanel.add(
makeLabel(
"ASK TEACHER",
24,
true
),
BorderLayout.NORTH
)
teacherPanel.add(
teacherSplit,
BorderLayout.CENTER
)
teacherPanel.add(
teacherButtons,
BorderLayout.SOUTH
)
// ========================================================
// CODE LAB
// ========================================================
val codeLabPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
codeLabPanel.setBackground(
PANEL_BG
)
codeLabPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val codeArea =
makeArea()
codeArea.setText(
"""import javax.swing._
import java.awt._
val frame = new JFrame("Scala Swing")
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
frame.setSize(
500,
300
)
val label =
new JLabel("Hello Scala Swing!")
frame.add(label)
frame.setLocationRelativeTo(null)
frame.setVisible(true)
"""
)
val codeOutput =
makeArea()
codeOutput.setEditable(
false
)
val analyzeCodeButton =
makeButton(
"ANALYZE CODE"
)
val copyCodeButton =
makeButton(
"COPY"
)
val saveCodeButton =
makeButton(
"SAVE"
)
val clearCodeButton =
makeButton(
"CLEAR"
)
analyzeCodeButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val code =
codeArea.getText
val problems =
ArrayBuffer[String]()
if (
code.trim.isEmpty
) {
problems +=
"Code area is empty."
}
if (
code.contains(
"JFrame.EXIT_ON_CLOSE"
)
) {
problems +=
"Use WindowConstants.EXIT_ON_CLOSE."
}
if (
code.count(
_ == '{'
) !=
code.count(
_ == '}'
)
) {
problems +=
"Possible { } mismatch."
}
if (
code.contains(
"def refreshHistory"
) &&
code.contains(
"val refreshHistory"
)
) {
problems +=
"Possible duplicate refreshHistory name. Use refreshHistoryButton and refreshHistoryView."
}
if (
problems.isEmpty
) {
codeOutput.setText(
"No obvious common issue detected.\n\n" +
"This quick analyzer is not a replacement for the Scala compiler."
)
} else {
codeOutput.setText(
problems.mkString(
"Possible issues:\n\n",
"\n\n",
""
)
)
}
recordActivity(
"Analyzed Code Lab code"
)
}
}
)
copyCodeButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
copyToClipboard(
codeArea.getText
)
showInfo(
frame,
"COPIED",
"Code copied."
)
}
}
)
saveCodeButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
saveTextFile(
codeArea.getText,
"ScalaCode.scala"
)
}
}
)
clearCodeButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
codeArea.setText("")
codeOutput.setText("")
}
}
)
val codeButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
codeButtons.setBackground(
PANEL_BG
)
codeButtons.add(
analyzeCodeButton
)
codeButtons.add(
copyCodeButton
)
codeButtons.add(
saveCodeButton
)
codeButtons.add(
clearCodeButton
)
val codeSplit =
new JSplitPane(
JSplitPane.VERTICAL_SPLIT,
makeScroll(
codeArea
),
makeScroll(
codeOutput
)
)
codeSplit.setResizeWeight(
0.65
)
codeLabPanel.add(
makeLabel(
"CODE LAB",
24,
true
),
BorderLayout.NORTH
)
codeLabPanel.add(
codeSplit,
BorderLayout.CENTER
)
codeLabPanel.add(
codeButtons,
BorderLayout.SOUTH
)
// ========================================================
// ERROR FIX
// ========================================================
val errorPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
errorPanel.setBackground(
PANEL_BG
)
errorPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val errorInput =
makeArea()
val errorOutput =
makeArea()
errorOutput.setEditable(
false
)
val fixErrorButton =
makeButton(
"FIX ERROR"
)
val clearErrorButton =
makeButton(
"CLEAR"
)
fixErrorButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val error =
errorInput
.getText
.trim
val answer =
if (
error.contains(
"EXIT_ON_CLOSE"
)
) {
"""Use:
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
Do not use JFrame.EXIT_ON_CLOSE."""
} else if (
error.contains(
"already defined as value"
)
) {
"""The same name is being used twice.
For example:
val refreshHistory = ...
def refreshHistory(): Unit = ...
Use unique names:
val refreshHistoryButton = ...
def refreshHistoryView(): Unit = ..."""
} else if (
error.contains(
"cannot be applied to (Unit)"
)
) {
"""A method returning Unit is being passed where a Component is required.
Wrong:
historyButtons.add(
refreshHistory()
)
Correct:
historyButtons.add(
refreshHistoryButton
)"""
} else if (
error.contains(
"addActionListener is not a member of Unit"
)
) {
"""The variable before addActionListener is resolving to Unit.
Make sure it is actually a JButton or another valid Swing component."""
} else {
"Check the first compiler error first.\n\nLook for:\n\n" +
"? missing braces\n" +
"? duplicate names\n" +
"? undefined variables\n" +
"? undefined methods\n" +
"? wrong Swing component types\n" +
"? forward references\n" +
"? incorrect listeners"
}
errorOutput.setText(
if (error.isEmpty)
"Paste a compiler error first."
else
answer
)
recordActivity(
"Used Error Fix"
)
}
}
)
clearErrorButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
errorInput.setText("")
errorOutput.setText("")
}
}
)
val errorButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
errorButtons.setBackground(
PANEL_BG
)
errorButtons.add(
fixErrorButton
)
errorButtons.add(
clearErrorButton
)
val errorSplit =
new JSplitPane(
JSplitPane.VERTICAL_SPLIT,
makeScroll(
errorInput
),
makeScroll(
errorOutput
)
)
errorSplit.setResizeWeight(
0.45
)
errorPanel.add(
makeLabel(
"ERROR FIX",
24,
true
),
BorderLayout.NORTH
)
errorPanel.add(
errorSplit,
BorderLayout.CENTER
)
errorPanel.add(
errorButtons,
BorderLayout.SOUTH
)
// ========================================================
// NOTES
// ========================================================
val notesPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
notesPanel.setBackground(
PANEL_BG
)
notesPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val notesTitleField =
makeTextField()
val notesArea =
makeArea()
val notesModel =
new DefaultListModel[String]()
val notesList =
new JList[String](
notesModel
)
notesList.setBackground(
new Color(
12,
16,
23
)
)
notesList.setForeground(
TEXT
)
val saveNoteButton =
makeButton(
"SAVE NOTE"
)
val loadNoteButton =
makeButton(
"LOAD"
)
val deleteNoteButton =
makeButton(
"DELETE"
)
saveNoteButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val title =
notesTitleField.getText.trim
val body =
notesArea.getText
if (
title.isEmpty
) {
showWarning(
frame,
"NOTES",
"Enter a note title."
)
} else {
notesData +=
title +
"||" +
body
notesModel.addElement(
title
)
notesTitleField.setText("")
notesArea.setText("")
recordActivity(
"Saved note: " +
title
)
}
}
}
)
loadNoteButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val index =
notesList.getSelectedIndex
if (
index >= 0 &&
index < notesData.length
) {
val parts =
notesData(index).split(
"\\|\\|",
2
)
if (
parts.length == 2
) {
notesTitleField.setText(
parts(0)
)
notesArea.setText(
parts(1)
)
}
}
}
}
)
deleteNoteButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val index =
notesList.getSelectedIndex
if (
index >= 0 &&
index < notesData.length
) {
notesData.remove(index)
notesModel.remove(index)
notesTitleField.setText("")
notesArea.setText("")
}
}
}
)
val notesButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
notesButtons.setBackground(
PANEL_BG
)
notesButtons.add(
saveNoteButton
)
notesButtons.add(
loadNoteButton
)
notesButtons.add(
deleteNoteButton
)
val notesEditor =
new JPanel(
new BorderLayout(
8,
8
)
)
notesEditor.setBackground(
PANEL_BG
)
notesEditor.add(
notesTitleField,
BorderLayout.NORTH
)
notesEditor.add(
makeScroll(
notesArea
),
BorderLayout.CENTER
)
notesEditor.add(
notesButtons,
BorderLayout.SOUTH
)
notesPanel.add(
makeLabel(
"NOTES",
24,
true
),
BorderLayout.NORTH
)
notesPanel.add(
makeScroll(
notesList
),
BorderLayout.WEST
)
notesPanel.add(
notesEditor,
BorderLayout.CENTER
)
// ========================================================
// TASKS
// ========================================================
val tasksPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
tasksPanel.setBackground(
PANEL_BG
)
tasksPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val taskField =
makeTextField()
val taskModel =
new DefaultListModel[String]()
val taskList =
new JList[String](
taskModel
)
taskList.setBackground(
new Color(
12,
16,
23
)
)
taskList.setForeground(
TEXT
)
val addTaskButton =
makeButton(
"ADD TASK"
)
val completeTaskButton =
makeButton(
"COMPLETE"
)
val deleteTaskButton =
makeButton(
"DELETE"
)
addTaskButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val task =
taskField.getText.trim
if (
task.nonEmpty
) {
tasksData +=
task
taskModel.addElement(
task
)
taskField.setText("")
recordActivity(
"Added task: " +
task
)
}
}
}
)
completeTaskButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val index =
taskList.getSelectedIndex
if (
index >= 0
) {
val text =
taskModel.getElementAt(
index
)
if (
!text.startsWith("[DONE]")
) {
taskModel.setElementAt(
"[DONE] " + text,
index
)
}
}
}
}
)
deleteTaskButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val index =
taskList.getSelectedIndex
if (
index >= 0
) {
taskModel.remove(index)
if (
index < tasksData.length
) {
tasksData.remove(index)
}
}
}
}
)
val taskTop =
new JPanel(
new BorderLayout(
6,
6
)
)
taskTop.setBackground(
PANEL_BG
)
taskTop.add(
taskField,
BorderLayout.CENTER
)
taskTop.add(
addTaskButton,
BorderLayout.EAST
)
val taskBottom =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
taskBottom.setBackground(
PANEL_BG
)
taskBottom.add(
completeTaskButton
)
taskBottom.add(
deleteTaskButton
)
val taskCenter =
new JPanel(
new BorderLayout(
8,
8
)
)
taskCenter.setBackground(
PANEL_BG
)
taskCenter.add(
taskTop,
BorderLayout.NORTH
)
taskCenter.add(
makeScroll(
taskList
),
BorderLayout.CENTER
)
taskCenter.add(
taskBottom,
BorderLayout.SOUTH
)
tasksPanel.add(
makeLabel(
"TASKS",
24,
true
),
BorderLayout.NORTH
)
tasksPanel.add(
taskCenter,
BorderLayout.CENTER
)
// ========================================================
// QUIZ
// ========================================================
val quizPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
quizPanel.setBackground(
PANEL_BG
)
quizPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val quizQuestion =
makeLabel(
"QUIZ READY",
20,
true
)
val quizButtonsPanel =
new JPanel(
new GridLayout(
4,
1,
8,
8
)
)
quizButtonsPanel.setBackground(
PANEL_BG
)
val quizOptions =
Array(
makeButton(""),
makeButton(""),
makeButton(""),
makeButton("")
)
quizOptions.foreach(
quizButtonsPanel.add
)
val quizQuestions =
Array(
(
"Which keyword declares an immutable value?",
Array("var", "val", "let", "const"),
1
),
(
"Which component accepts multi-line text?",
Array(
"JLabel",
"JTextArea",
"JButton",
"JFrame"
),
2
),
(
"Which constant is correct for JFrame closing?",
Array(
"JFrame.EXIT_ON_CLOSE",
"WindowConstants.EXIT_ON_CLOSE",
"Frame.EXIT",
"JWindow.EXIT"
),
2
)
)
var quizIndex =
0
var quizScore =
0
var quizAnswered =
false
val quizScoreLabel =
makeLabel(
"Score: 0",
15,
true
)
val nextQuizButton =
makeButton(
"NEXT"
)
def loadQuiz(): Unit = {
if (
quizIndex <
quizQuestions.length
) {
val q =
quizQuestions(
quizIndex
)
quizQuestion.setText(
(
quizIndex + 1
) +
". " +
q._1
)
var i =
0
while (
i < 4
) {
quizOptions(i).setText(
q._2(i)
)
quizOptions(i).setEnabled(
true
)
i += 1
}
quizAnswered =
false
} else {
quizQuestion.setText(
"QUIZ COMPLETE!"
)
var i =
0
while (
i < 4
) {
quizOptions(i).setText("")
quizOptions(i).setEnabled(false)
i += 1
}
nextQuizButton.setEnabled(
false
)
}
quizScoreLabel.setText(
"Score: " +
quizScore +
" / " +
quizQuestions.length
)
}
var quizButtonIndex =
0
while (
quizButtonIndex <
quizOptions.length
) {
val selectedIndex =
quizButtonIndex
quizOptions(
quizButtonIndex
).addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
!quizAnswered &&
quizIndex <
quizQuestions.length
) {
quizAnswered =
true
val correctIndex =
quizQuestions(
quizIndex
)._3 - 1
if (
selectedIndex ==
correctIndex
) {
quizScore += 1
quizQuestion.setText(
quizQuestion.getText +
" ? Correct"
)
} else {
quizQuestion.setText(
quizQuestion.getText +
" ? Wrong"
)
}
var i =
0
while (
i <
quizOptions.length
) {
quizOptions(i).setEnabled(false)
i += 1
}
quizScoreLabel.setText(
"Score: " +
quizScore +
" / " +
quizQuestions.length
)
}
}
}
)
quizButtonIndex += 1
}
nextQuizButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
quizIndex <
quizQuestions.length
) {
quizIndex += 1
loadQuiz()
}
}
}
)
val quizBottom =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
quizBottom.setBackground(
PANEL_BG
)
quizBottom.add(
quizScoreLabel
)
quizBottom.add(
nextQuizButton
)
quizPanel.add(
makeLabel(
"QUIZ",
24,
true
),
BorderLayout.NORTH
)
val quizCenter =
new JPanel(
new BorderLayout(
10,
10
)
)
quizCenter.setBackground(
PANEL_BG
)
quizCenter.add(
quizQuestion,
BorderLayout.NORTH
)
quizCenter.add(
quizButtonsPanel,
BorderLayout.CENTER
)
quizCenter.add(
quizBottom,
BorderLayout.SOUTH
)
quizPanel.add(
quizCenter,
BorderLayout.CENTER
)
loadQuiz()
// ========================================================
// IMAGE STUDIO
// ========================================================
val imagePanel =
new JPanel(
new BorderLayout(
10,
10
)
)
imagePanel.setBackground(
PANEL_BG
)
imagePanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val imagePreview =
new JLabel(
"No image selected",
SwingConstants.CENTER
)
imagePreview.setForeground(
MUTED
)
val openImageButton =
makeButton(
"OPEN IMAGE"
)
val clearImageButton =
makeButton(
"CLEAR"
)
openImageButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val chooser =
new JFileChooser()
if (
chooser.showOpenDialog(frame) ==
JFileChooser.APPROVE_OPTION
) {
val file =
chooser.getSelectedFile
try {
val image =
ImageIO.read(file)
if (
image == null
) {
showError(
frame,
"IMAGE",
"Unsupported image."
)
} else {
imagePreview.setIcon(
new ImageIcon(
scaleImage(
image,
800,
550
)
)
)
imagePreview.setText("")
recordActivity(
"Opened image: " +
file.getName
)
}
} catch {
case ex: Throwable =>
showError(
frame,
"IMAGE",
ex.toString
)
}
}
}
}
)
clearImageButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
imagePreview.setIcon(null)
imagePreview.setText(
"No image selected"
)
}
}
)
val imageButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
imageButtons.setBackground(
PANEL_BG
)
imageButtons.add(
openImageButton
)
imageButtons.add(
clearImageButton
)
imagePanel.add(
makeLabel(
"IMAGE STUDIO",
24,
true
),
BorderLayout.NORTH
)
imagePanel.add(
imagePreview,
BorderLayout.CENTER
)
imagePanel.add(
imageButtons,
BorderLayout.SOUTH
)
// ========================================================
// PROMPT LAB
// ========================================================
val promptLabPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
promptLabPanel.setBackground(
PANEL_BG
)
promptLabPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val promptIdeaArea =
makeArea()
val promptOutputArea =
makeArea()
promptOutputArea.setEditable(
false
)
val generatePromptButton =
makeButton(
"GENERATE PROMPT"
)
val copyPromptButton =
makeButton(
"COPY"
)
generatePromptButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val idea =
promptIdeaArea.getText.trim
promptOutputArea.setText(
if (
idea.isEmpty
) {
"Write your idea first."
} else {
createMasterPrompt(
idea
)
}
)
}
}
)
copyPromptButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
copyToClipboard(
promptOutputArea.getText
)
showInfo(
frame,
"COPIED",
"Prompt copied."
)
}
}
)
val promptButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
promptButtons.setBackground(
PANEL_BG
)
promptButtons.add(
generatePromptButton
)
promptButtons.add(
copyPromptButton
)
val promptSplit =
new JSplitPane(
JSplitPane.VERTICAL_SPLIT,
makeScroll(
promptIdeaArea
),
makeScroll(
promptOutputArea
)
)
promptSplit.setResizeWeight(
0.4
)
promptLabPanel.add(
makeLabel(
"PROMPT LAB",
24,
true
),
BorderLayout.NORTH
)
promptLabPanel.add(
promptSplit,
BorderLayout.CENTER
)
promptLabPanel.add(
promptButtons,
BorderLayout.SOUTH
)
// ========================================================
// PROJECTS
// ========================================================
val projectsPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
projectsPanel.setBackground(
PANEL_BG
)
projectsPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val projectNameField =
makeTextField()
val projectDescriptionArea =
makeArea()
val projectModel =
new DefaultListModel[String]()
val projectList =
new JList[String](
projectModel
)
projectList.setBackground(
new Color(
12,
16,
23
)
)
projectList.setForeground(
TEXT
)
val saveProjectButton =
makeButton(
"SAVE"
)
val loadProjectButton =
makeButton(
"LOAD"
)
val deleteProjectButton =
makeButton(
"DELETE"
)
saveProjectButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val name =
projectNameField.getText.trim
if (
name.isEmpty
) {
showWarning(
frame,
"PROJECTS",
"Enter a project name."
)
} else {
projectData +=
name +
"||" +
projectDescriptionArea.getText
projectModel.addElement(
name
)
projectNameField.setText("")
projectDescriptionArea.setText("")
}
}
}
)
loadProjectButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val index =
projectList.getSelectedIndex
if (
index >= 0 &&
index < projectData.length
) {
val parts =
projectData(index).split(
"\\|\\|",
2
)
if (
parts.length == 2
) {
projectNameField.setText(
parts(0)
)
projectDescriptionArea.setText(
parts(1)
)
}
}
}
}
)
deleteProjectButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val index =
projectList.getSelectedIndex
if (
index >= 0
) {
projectModel.remove(index)
if (
index < projectData.length
) {
projectData.remove(index)
}
}
}
}
)
val projectEditor =
new JPanel(
new BorderLayout(
8,
8
)
)
projectEditor.setBackground(
PANEL_BG
)
projectEditor.add(
projectNameField,
BorderLayout.NORTH
)
projectEditor.add(
makeScroll(
projectDescriptionArea
),
BorderLayout.CENTER
)
val projectButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
projectButtons.setBackground(
PANEL_BG
)
projectButtons.add(
saveProjectButton
)
projectButtons.add(
loadProjectButton
)
projectButtons.add(
deleteProjectButton
)
projectEditor.add(
projectButtons,
BorderLayout.SOUTH
)
projectsPanel.add(
makeLabel(
"PROJECTS",
24,
true
),
BorderLayout.NORTH
)
projectsPanel.add(
makeScroll(
projectList
),
BorderLayout.WEST
)
projectsPanel.add(
projectEditor,
BorderLayout.CENTER
)
// ========================================================
// UTILITIES
// ========================================================
val utilitiesPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
utilitiesPanel.setBackground(
PANEL_BG
)
utilitiesPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val stopwatchLabel =
makeLabel(
"00:00:00",
42,
true
)
stopwatchLabel.setHorizontalAlignment(
SwingConstants.CENTER
)
var stopwatchSeconds =
0L
var stopwatchRunning =
false
val stopwatchTimer =
new javax.swing.Timer(
1000,
null
)
stopwatchTimer.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
stopwatchRunning
) {
stopwatchSeconds += 1
val h =
stopwatchSeconds / 3600
val m =
(
stopwatchSeconds % 3600
) / 60
val s =
stopwatchSeconds % 60
stopwatchLabel.setText(
"%02d:%02d:%02d".format(
h,
m,
s
)
)
}
}
}
)
val startStopwatchButton =
makeButton(
"START"
)
val stopStopwatchButton =
makeButton(
"STOP"
)
val resetStopwatchButton =
makeButton(
"RESET"
)
startStopwatchButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
stopwatchRunning =
true
stopwatchTimer.start()
}
}
)
stopStopwatchButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
stopwatchRunning =
false
}
}
)
resetStopwatchButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
stopwatchRunning =
false
stopwatchSeconds =
0L
stopwatchLabel.setText(
"00:00:00"
)
}
}
)
val utilityButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
utilityButtons.setBackground(
PANEL_BG
)
utilityButtons.add(
startStopwatchButton
)
utilityButtons.add(
stopStopwatchButton
)
utilityButtons.add(
resetStopwatchButton
)
utilitiesPanel.add(
makeLabel(
"UTILITIES",
24,
true
),
BorderLayout.NORTH
)
utilitiesPanel.add(
stopwatchLabel,
BorderLayout.CENTER
)
utilitiesPanel.add(
utilityButtons,
BorderLayout.SOUTH
)
// ========================================================
// FEATURE LIBRARY
// ========================================================
val libraryPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
libraryPanel.setBackground(
PANEL_BG
)
libraryPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val libraryArea =
makeArea()
libraryArea.setEditable(
false
)
libraryArea.setText(
"""FEATURE LIBRARY
SECURE LOGIN
3-attempt password protection.
CLASSROOM
Scala and Swing learning lessons.
ASK TEACHER
Simple coding guidance.
CODE LAB
Write and analyze code.
ERROR FIX
Common Scala Swing error guidance.
NOTES
Save notes during the session.
TASKS
Manage coding tasks.
QUIZ
Practice Scala and Swing knowledge.
IMAGE STUDIO
Open and preview images.
PROMPT LAB
Generate reusable coding prompts.
PROJECTS
Store project ideas.
UTILITIES
Stopwatch.
HISTORY
Track activity.
SETTINGS
Application settings.
MASTER ACCESS
Protected MASTER PROMPT area.
MASTER PROMPT
No UID.
No NAME.
Only IDEA.
The generated prompt is designed to make ChatGPT produce a complete Scala Swing project while preserving the user's exact idea and checking common compilation issues."""
)
libraryPanel.add(
makeLabel(
"FEATURE LIBRARY",
24,
true
),
BorderLayout.NORTH
)
libraryPanel.add(
makeScroll(
libraryArea
),
BorderLayout.CENTER
)
// ========================================================
// HISTORY
// ========================================================
val historyPanel =
new JPanel(
new BorderLayout(
8,
8
)
)
historyPanel.setBackground(
PANEL_BG
)
historyPanel.setBorder(
new EmptyBorder(
12,
12,
12,
12
)
)
val historyArea =
makeArea()
historyArea.setEditable(
false
)
val refreshHistoryButton =
makeButton(
"REFRESH"
)
val exportHistoryButton =
makeButton(
"EXPORT"
)
val clearHistoryButton =
makeButton(
"CLEAR"
)
val historyButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
historyButtons.setBackground(
PANEL_BG
)
historyButtons.add(
refreshHistoryButton
)
historyButtons.add(
exportHistoryButton
)
historyButtons.add(
clearHistoryButton
)
def refreshHistoryView(): Unit = {
if (
activityHistory.isEmpty
) {
historyArea.setText(
"No activity yet."
)
} else {
historyArea.setText(
activityHistory
.reverse
.mkString("\n")
)
}
historyArea.setCaretPosition(
0
)
}
refreshHistoryButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
refreshHistoryView()
}
}
)
exportHistoryButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
activityHistory.isEmpty
) {
showInfo(
frame,
"HISTORY",
"Nothing to export."
)
} else {
saveTextFile(
activityHistory
.reverse
.mkString("\n"),
"ActivityHistory.txt"
)
}
}
}
)
clearHistoryButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
activityHistory.clear()
refreshHistoryView()
}
}
)
historyPanel.add(
makeLabel(
"ACTIVITY HISTORY",
24,
true
),
BorderLayout.NORTH
)
historyPanel.add(
makeScroll(
historyArea
),
BorderLayout.CENTER
)
historyPanel.add(
historyButtons,
BorderLayout.SOUTH
)
// ========================================================
// SETTINGS
// ========================================================
val settingsPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
settingsPanel.setBackground(
PANEL_BG
)
settingsPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val settingsText =
makeArea()
settingsText.setEditable(
false
)
settingsText.setText(
"""ULTRA SCALA SWING AI LEARNING STUDIO
STATUS: READY
MASTER PROMPT:
Password protected.
No UID field.
No NAME field.
Only the IDEA is required."""
)
settingsPanel.add(
makeLabel(
"SETTINGS",
24,
true
),
BorderLayout.NORTH
)
settingsPanel.add(
makeScroll(
settingsText
),
BorderLayout.CENTER
)
// ========================================================
// MASTER PROMPT
// HIDDEN UNTIL CORRECT PASSWORD
// ========================================================
var masterUnlocked =
false
var masterTabAdded =
false
val masterPromptPanel =
new JPanel(
new BorderLayout(
10,
10
)
)
masterPromptPanel.setBackground(
PANEL_BG
)
masterPromptPanel.setBorder(
new EmptyBorder(
14,
14,
14,
14
)
)
val masterTitle =
makeLabel(
"MASTER PROMPT",
26,
true
)
val masterStatus =
makeLabel(
"ACCESS GRANTED",
16,
true
)
masterStatus.setForeground(
SUCCESS
)
val masterIntro =
makeLabel(
"Enter your IDEA only. No UID. No Name.",
15,
false
)
val masterIdeaArea =
makeArea()
masterIdeaArea.setToolTipText(
"Write only your game/app/software idea here."
)
val masterOutputArea =
makeArea()
masterOutputArea.setEditable(
false
)
val generateMasterPromptButton =
makeButton(
"GENERATE MASTER PROMPT"
)
val copyMasterPromptButton =
makeButton(
"COPY MASTER PROMPT"
)
val clearMasterPromptButton =
makeButton(
"CLEAR"
)
val lockMasterPromptButton =
makeButton(
"LOCK MASTER PROMPT"
)
val masterButtons =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
masterButtons.setBackground(
PANEL_BG
)
masterButtons.add(
generateMasterPromptButton
)
masterButtons.add(
copyMasterPromptButton
)
masterButtons.add(
clearMasterPromptButton
)
masterButtons.add(
lockMasterPromptButton
)
val masterIdeaPanel =
new JPanel(
new BorderLayout(
6,
6
)
)
masterIdeaPanel.setBackground(
PANEL_BG
)
masterIdeaPanel.add(
masterIntro,
BorderLayout.NORTH
)
masterIdeaPanel.add(
makeScroll(
masterIdeaArea
),
BorderLayout.CENTER
)
val masterOutputPanel =
new JPanel(
new BorderLayout(
6,
6
)
)
masterOutputPanel.setBackground(
PANEL_BG
)
masterOutputPanel.add(
makeLabel(
"GENERATED MASTER PROMPT",
17,
true
),
BorderLayout.NORTH
)
masterOutputPanel.add(
makeScroll(
masterOutputArea
),
BorderLayout.CENTER
)
val masterSplit =
new JSplitPane(
JSplitPane.VERTICAL_SPLIT,
masterIdeaPanel,
masterOutputPanel
)
masterSplit.setResizeWeight(
0.38
)
val masterHeader =
new JPanel(
new BorderLayout(
10,
4
)
)
masterHeader.setBackground(
PANEL_BG
)
val masterHeading =
new JPanel(
new GridLayout(
2,
1,
2,
2
)
)
masterHeading.setBackground(
PANEL_BG
)
masterHeading.add(
masterTitle
)
masterHeading.add(
masterStatus
)
masterHeader.add(
masterHeading,
BorderLayout.WEST
)
masterPromptPanel.add(
masterHeader,
BorderLayout.NORTH
)
masterPromptPanel.add(
masterSplit,
BorderLayout.CENTER
)
masterPromptPanel.add(
masterButtons,
BorderLayout.SOUTH
)
// --------------------------------------------------------
// GENERATE MASTER PROMPT
// --------------------------------------------------------
generateMasterPromptButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
!masterUnlocked
) {
showWarning(
frame,
"MASTER PROMPT",
"MASTER PROMPT is locked."
)
} else {
val idea =
masterIdeaArea
.getText
.trim
if (
idea.isEmpty
) {
showWarning(
frame,
"MASTER PROMPT",
"Write your IDEA first."
)
} else {
masterOutputArea.setText(
createMasterPrompt(
idea
)
)
masterOutputArea.setCaretPosition(
0
)
recordActivity(
"Generated MASTER PROMPT"
)
}
}
}
}
)
// --------------------------------------------------------
// COPY MASTER PROMPT
// --------------------------------------------------------
copyMasterPromptButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val generated =
masterOutputArea
.getText
.trim
if (
generated.isEmpty
) {
showWarning(
frame,
"MASTER PROMPT",
"Generate the prompt first."
)
} else {
copyToClipboard(
generated
)
showInfo(
frame,
"MASTER PROMPT",
"MASTER PROMPT copied to clipboard."
)
recordActivity(
"Copied MASTER PROMPT"
)
}
}
}
)
// --------------------------------------------------------
// CLEAR MASTER PROMPT
// --------------------------------------------------------
clearMasterPromptButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
masterIdeaArea.setText("")
masterOutputArea.setText("")
}
}
)
// --------------------------------------------------------
// LOCK MASTER PROMPT
// --------------------------------------------------------
def lockMasterPrompt(): Unit = {
if (
masterTabAdded
) {
tabs.remove(
masterPromptPanel
)
masterTabAdded =
false
}
masterUnlocked =
false
masterIdeaArea.setText("")
masterOutputArea.setText("")
masterStatus.setText(
"LOCKED"
)
masterStatus.setForeground(
WARNING
)
recordActivity(
"Locked MASTER PROMPT"
)
tabs.setSelectedIndex(
0
)
}
lockMasterPromptButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
lockMasterPrompt()
}
}
)
// --------------------------------------------------------
// UNLOCK MASTER PROMPT
// --------------------------------------------------------
def unlockMasterPrompt(): Unit = {
val passwordField =
new JPasswordField()
passwordField.setPreferredSize(
new Dimension(
320,
35
)
)
val wrapper =
new JPanel(
new BorderLayout(
8,
8
)
)
wrapper.add(
new JLabel(
"Enter MASTER ACCESS password:"
),
BorderLayout.NORTH
)
wrapper.add(
passwordField,
BorderLayout.CENTER
)
val result =
JOptionPane.showConfirmDialog(
frame,
wrapper,
"MASTER PROMPT ACCESS",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE
)
if (
result ==
JOptionPane.OK_OPTION
) {
val entered =
new String(
passwordField.getPassword
)
val enteredHash =
sha256(
entered
)
if (
enteredHash ==
masterPromptPasswordHash
) {
masterUnlocked =
true
masterStatus.setText(
"ACCESS GRANTED"
)
masterStatus.setForeground(
SUCCESS
)
if (
!masterTabAdded
) {
tabs.addTab(
"MASTER PROMPT",
masterPromptPanel
)
masterTabAdded =
true
}
tabs.setSelectedComponent(
masterPromptPanel
)
recordActivity(
"MASTER PROMPT unlocked"
)
} else {
masterUnlocked =
false
showWarning(
frame,
"ACCESS DENIED",
"Wrong MASTER ACCESS password.\n\nMASTER PROMPT remains hidden."
)
recordActivity(
"Failed MASTER PROMPT access"
)
}
}
}
dashboardMasterButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
unlockMasterPrompt()
}
}
)
// ========================================================
// NORMAL TABS
// ========================================================
tabs.addTab(
"DASHBOARD",
dashboardPanel
)
tabs.addTab(
"CLASSROOM",
classroomPanel
)
tabs.addTab(
"ASK TEACHER",
teacherPanel
)
tabs.addTab(
"CODE LAB",
codeLabPanel
)
tabs.addTab(
"ERROR FIX",
errorPanel
)
tabs.addTab(
"NOTES",
notesPanel
)
tabs.addTab(
"TASKS",
tasksPanel
)
tabs.addTab(
"QUIZ",
quizPanel
)
tabs.addTab(
"IMAGE STUDIO",
imagePanel
)
tabs.addTab(
"PROMPT LAB",
promptLabPanel
)
tabs.addTab(
"PROJECTS",
projectsPanel
)
tabs.addTab(
"UTILITIES",
utilitiesPanel
)
tabs.addTab(
"FEATURE LIBRARY",
libraryPanel
)
tabs.addTab(
"HISTORY",
historyPanel
)
tabs.addTab(
"SETTINGS",
settingsPanel
)
// ========================================================
// MENU
// ========================================================
val menuBar =
new JMenuBar()
val fileMenu =
new JMenu("File")
val historyMenuItem =
new JMenuItem(
"Open History"
)
val masterMenuItem =
new JMenuItem(
"MASTER ACCESS"
)
val exitMenuItem =
new JMenuItem(
"Exit"
)
historyMenuItem.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
tabs.setSelectedComponent(
historyPanel
)
refreshHistoryView()
}
}
)
masterMenuItem.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
unlockMasterPrompt()
}
}
)
exitMenuItem.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
frame.dispose()
}
}
)
fileMenu.add(
historyMenuItem
)
fileMenu.addSeparator()
fileMenu.add(
masterMenuItem
)
fileMenu.addSeparator()
fileMenu.add(
exitMenuItem
)
val helpMenu =
new JMenu("Help")
val aboutItem =
new JMenuItem(
"About"
)
aboutItem.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
showInfo(
frame,
"ABOUT",
"ULTRA SCALA SWING AI LEARNING STUDIO\n\n" +
"MASTER PROMPT enabled.\n" +
"No UID field.\n" +
"No NAME field.\n" +
"Only IDEA is required."
)
}
}
)
helpMenu.add(
aboutItem
)
menuBar.add(
fileMenu
)
menuBar.add(
helpMenu
)
frame.setJMenuBar(
menuBar
)
// ========================================================
// KEYBOARD SHORTCUT
// ========================================================
val rootPane =
frame.getRootPane
val inputMap =
rootPane.getInputMap(
JComponent.WHEN_IN_FOCUSED_WINDOW
)
val actionMap =
rootPane.getActionMap
inputMap.put(
KeyStroke.getKeyStroke(
KeyEvent.VK_H,
InputEvent.CTRL_DOWN_MASK
),
"openHistory"
)
actionMap.put(
"openHistory",
new AbstractAction {
override def actionPerformed(
e: ActionEvent
): Unit = {
tabs.setSelectedComponent(
historyPanel
)
refreshHistoryView()
}
}
)
inputMap.put(
KeyStroke.getKeyStroke(
KeyEvent.VK_F1,
0
),
"showAbout"
)
actionMap.put(
"showAbout",
new AbstractAction {
override def actionPerformed(
e: ActionEvent
): Unit = {
showInfo(
frame,
"HELP",
"Ctrl+H = History\nF1 = Help\n\nMASTER ACCESS = Protected MASTER PROMPT"
)
}
}
)
// ========================================================
// START
// ========================================================
recordActivity(
"Studio opened"
)
refreshHistoryView()
frame.setContentPane(
tabs
)
frame.setVisible(
true
)
}
// ==========================================================
// SAFE STARTUP
// ==========================================================
try {
SwingUtilities.invokeLater(
new Runnable {
def run(): Unit = {
try {
openLogin()
} catch {
case ex: Throwable =>
JOptionPane.showMessageDialog(
null,
ex.toString,
"Startup Error",
JOptionPane.ERROR_MESSAGE
)
}
}
}
)
} catch {
case ex: Throwable =>
JOptionPane.showMessageDialog(
null,
ex.toString,
"Startup Error",
JOptionPane.ERROR_MESSAGE
)
}