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
if (
width <= 0 ||
height <= 0
) {
return image
}
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
}
// ==========================================================
// MASTER PROMPT GENERATOR
// ==========================================================
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 developer, Scala Swing developer, Java2D developer, software architect, game developer, 3D game developer, rendering engineer, UI/UX designer, debugger, compiler-error analyst and code-review expert.
Your task is to transform the USER IDEA below into ONE complete, practical, playable and compile-safe Scala Swing application.
============================================================
USER IDEA
============================================================
$safeIdea
============================================================
PRIMARY OBJECTIVE
============================================================
Build the application from the exact USER IDEA.
The USER IDEA is the source of truth.
Do NOT replace the concept with another project.
Do NOT intentionally reduce it to a tiny demo.
Do NOT remove important requested features.
Do NOT return pseudocode.
Do NOT return an outline instead of code.
Do NOT return incomplete code.
Do NOT leave TODO sections.
Do NOT use placeholders.
Do NOT say "add the rest later".
Everything requested should be implemented as actual code whenever reasonably possible.
============================================================
APPLICATION COMPLETENESS
============================================================
Convert the idea into a complete application.
Implement the systems that logically belong to the idea.
Possible systems include:
- main menu
- start screen
- gameplay
- player state
- enemies
- obstacles
- movement
- controls
- collision detection
- score
- coins
- health
- lives
- levels
- checkpoints
- timer
- progress
- win state
- lose state
- game over
- restart
- pause
- resume
- settings
- HUD
- instructions
- keyboard controls
- mouse controls
- animations
- visual effects
- particles
- camera
- procedural environment
- sound hooks when practical
- save/load when appropriate
Only add systems that make sense for the USER IDEA.
============================================================
3D GAME REQUIREMENT
============================================================
If the USER IDEA requests:
3D
realistic 3D
3D game
3D driving
3D racing
3D car game
3D shooter
first person
third person
open world style
3D environment
3D world
then produce a genuinely interactive 3D-style implementation.
The application must NOT simply draw a few flat rectangles and call that 3D.
When no external 3D engine is guaranteed to exist, implement a self-contained software 3D / pseudo-3D renderer using Java2D and Swing.
Prefer standard Java/Scala APIs such as:
java.awt.Graphics2D
java.awt.geom
java.awt.image.BufferedImage
javax.swing.JPanel
javax.swing.Timer
============================================================
3D RENDERING SYSTEM
============================================================
For a 3D-style project, use real spatial concepts.
Implement where appropriate:
- world X coordinate
- world Y coordinate
- world Z coordinate
- camera X
- camera Y
- camera Z
- camera rotation
- perspective projection
- depth
- horizon
- near plane
- far plane
- field of view
- distance scaling
- polygons
- surfaces
- road or terrain
- perspective objects
- depth sorting
- clipping
- lighting approximation
- shading
- fog
- shadows when practical
- particles
- animated scenery
The renderer should calculate screen positions from world positions.
Do not fake the effect with unrelated static UI elements.
For objects behind the camera or invalid depth:
- skip them safely
- prevent division by zero
- prevent invalid screen coordinates
- prevent NaN or Infinity from reaching rendering calculations
Use safe numeric handling.
============================================================
3D DATA STRUCTURES
============================================================
Use clear and strongly typed data structures.
For example:
case class Vector3(
x: Double,
y: Double,
z: Double
)
case class Camera(
x: Double,
y: Double,
z: Double,
rotationX: Double,
rotationY: Double
)
or equivalent structures.
Keep mathematical calculations readable.
Separate rendering math from gameplay state.
============================================================
DRIVING GAME
============================================================
If the USER IDEA describes a car or driving game, implement as many appropriate systems as possible:
- player car
- steering
- throttle
- brake
- acceleration
- deceleration
- speed
- maximum speed
- road
- perspective road
- lane system
- road curves
- traffic
- enemy vehicles
- obstacles
- collision detection
- distance
- checkpoints
- score
- speed display
- progress
- camera follow
- roadside objects
- trees
- signs
- barriers
- sky
- horizon
- lighting
- shadows
- restart
- game over
- pause
- win state
Controls must actually work.
Do not describe controls without implementing them.
============================================================
GAME QUALITY
============================================================
When creating a game, make it feel playable.
Do not create only a static screen.
The game should have:
- continuous update loop
- continuous rendering
- player movement
- responsive controls
- game state
- collision logic when relevant
- score updates
- visual feedback
- restart support
- proper game-over behavior
Use javax.swing.Timer for the main update loop when appropriate.
Avoid unnecessary background threads.
============================================================
GAME STATE
============================================================
Use explicit states when appropriate.
For example:
START
PLAYING
PAUSED
GAME_OVER
WIN
Do not allow several incompatible states to execute simultaneously.
Restart must reset the required state.
============================================================
KEYBOARD INPUT
============================================================
When the game requires keyboard input:
Implement actual keyboard handling.
Possible controls may include:
W
A
S
D
Arrow keys
Space
Escape
R
Use a reliable Swing-compatible method.
Make sure the game component can receive focus.
Do not assume keyboard input works automatically.
============================================================
MOUSE INPUT
============================================================
If the idea requires mouse input:
Implement it using proper Swing mouse APIs.
Use:
MouseListener
MouseMotionListener
only when appropriate.
Ensure listeners are attached to real Components.
============================================================
SWING TIMER
============================================================
Use:
javax.swing.Timer
for repeated Swing animation and game updates.
Do not create multiple unnecessary game loops.
Do not accidentally start duplicate timers.
Keep timer state explicit.
When state changes:
call repaint() where visual rendering must update.
============================================================
PAINTING
============================================================
For custom rendering:
extend JPanel or JComponent.
Override:
paintComponent
and always call:
super.paintComponent(g)
before custom drawing.
Use Graphics2D where needed.
Do not incorrectly dispose the Swing-provided graphics object.
When creating child graphics with create(), dispose the child graphics safely.
============================================================
VISUAL REALISM
============================================================
For realistic-looking 3D-style games, improve the visual result using procedural graphics.
Use where appropriate:
- gradients
- perspective
- atmospheric fog
- sky
- horizon
- terrain
- road
- lane markings
- lighting
- shadows
- reflections
- particles
- dust
- speed effects
- environmental objects
- UI overlays
- animated scenery
When image assets are unavailable, draw them procedurally.
Do not assume external images exist.
============================================================
NO UNDECLARED EXTERNAL FILES
============================================================
Unless explicitly required by the USER IDEA, do not assume the presence of:
PNG
JPG
WAV
MP3
OBJ
FBX
JSON
TXT
external folders
custom libraries
The program should preferably be self-contained.
============================================================
SCALA SWING REQUIREMENTS
============================================================
Use Scala and Java Swing correctly.
Include every required import.
Create ONE complete source file.
The final source must be copy-paste ready.
Use:
WindowConstants.EXIT_ON_CLOSE
Never use:
JFrame.EXIT_ON_CLOSE
============================================================
TYPE SAFETY
============================================================
Be extremely careful with:
Int
Long
Float
Double
Do not accidentally return Double where Int is required.
Convert numeric values safely.
Do not assign to a val.
Do not write:
someVal = ...
when someVal was declared as val.
Use var only for changing game state.
Use val for stable references.
============================================================
DECLARATION ORDER
============================================================
Avoid forward references.
Declare data before methods that depend on it when needed.
Declare important components before listeners reference them.
Avoid using variables before initialization.
Use clear unique names.
Never create confusing name collisions.
For example:
CORRECT:
val refreshHistoryButton = ...
def refreshHistoryView(): Unit = ...
INCORRECT:
val refreshHistory = ...
def refreshHistory(): Unit = ...
============================================================
EVENT HANDLING SAFETY
============================================================
For ActionListener use valid syntax such as:
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
...
}
}
Do not call methods on Unit.
Do not pass Unit to JPanel.add.
Do not attach listeners to functions that return Unit.
============================================================
COLLECTION SAFETY
============================================================
When using arrays or collections:
- check indexes
- avoid invalid access
- avoid empty collection crashes
- remove safely
- update safely
Never assume an index is valid.
============================================================
COLLISION SAFETY
============================================================
Collision systems must safely handle:
- missing objects
- removed objects
- invalid coordinates
- zero sizes
- negative dimensions
- stale references
Keep collision calculations deterministic.
============================================================
NULL SAFETY
============================================================
Avoid null whenever practical.
Initialize state correctly.
Do not use image objects without checking whether image loading succeeded.
Do not call methods on possibly null values.
============================================================
FILE SAFETY
============================================================
For file operations:
- use try/catch
- close streams
- handle failures
- show useful messages
- do not crash the whole application
============================================================
UI SAFETY
============================================================
Use valid Swing layouts.
Do not add the same component multiple times.
Do not accidentally add a method call when a Component is required.
Do not use Unit as a Swing Component.
Do not create duplicate component names.
Use meaningful names.
============================================================
MENU SAFETY
============================================================
Use valid:
JMenuBar
JMenu
JMenuItem
Do not use unsupported Swing constants.
============================================================
PERFORMANCE
============================================================
The game should remain reasonably responsive.
Do not allocate huge objects every frame unnecessarily.
Do not create unlimited enemies or particles every timer tick.
Avoid unnecessary expensive file loading during rendering.
Reuse data where appropriate.
============================================================
RESTART SYSTEM
============================================================
If the application is a game, implement a real restart.
Restart should reset all important state, such as:
- player position
- player speed
- health
- lives
- score
- level
- enemies
- obstacles
- timers
- collision flags
- game-over flag
- win flag
- camera
- animation values
Do not leave old state active after restart.
============================================================
WIN AND LOSE SYSTEM
============================================================
When appropriate, implement:
- clear win condition
- clear lose condition
- visual feedback
- restart option
- score summary
Do not leave the game stuck in an invalid state.
============================================================
PAUSE SYSTEM
============================================================
When appropriate:
- pause gameplay
- pause movement
- pause timers or game logic
- show pause overlay
- allow resume
Do not allow player movement to continue invisibly while paused.
============================================================
HUD
============================================================
For games, add a useful HUD when appropriate.
Possible HUD elements:
- score
- speed
- health
- lives
- level
- timer
- distance
- checkpoint
- controls
Make it readable.
============================================================
USER EXPERIENCE
============================================================
The interface should be polished and understandable.
Buttons should actually work.
Text fields should actually work.
Menus should actually work.
The user should understand how to start and control the application.
============================================================
COMPILATION SAFETY AUDIT
============================================================
Before returning the final code, perform a COMPLETE compile-safety review of the ENTIRE source.
Check:
1. Undefined variables.
2. Undefined methods.
3. Duplicate variables.
4. Duplicate methods.
5. Duplicate component names.
6. Wrong variable types.
7. Wrong method return types.
8. Forward references.
9. Scope errors.
10. Shadowing problems.
11. Missing braces.
12. Missing parentheses.
13. Missing brackets.
14. Broken strings.
15. Broken triple-quoted strings.
16. Invalid Scala syntax.
17. Invalid Java syntax.
18. Invalid Swing syntax.
19. Incorrect listener syntax.
20. Incorrect timer syntax.
21. Incorrect keyboard event handling.
22. Incorrect mouse handling.
23. Incorrect JPanel.add usage.
24. Passing Unit where Component is required.
25. Calling methods on Unit.
26. Using components before they exist.
27. Invalid array indexing.
28. Invalid collection indexing.
29. Int/Double mismatch.
30. Long/Int mismatch.
31. Float/Double mismatch.
32. Assignment to immutable val.
33. Null-related runtime problems.
34. Divide-by-zero risks.
35. Camera depth problems.
36. Projection problems.
37. Invalid screen coordinates.
38. NaN/Infinity propagation.
39. Collision errors.
40. Restart errors.
41. Game-over errors.
42. Win-state errors.
43. Pause-state errors.
44. Timer duplication.
45. Repaint errors.
46. Focus errors.
47. Component duplication.
48. Listener duplication.
49. Name collisions.
50. Broken application startup.
============================================================
FULL SOURCE REVIEW
============================================================
Do NOT check only the first part of the program.
Review the ENTIRE source from:
first import
to:
final line.
Every variable must have a valid declaration.
Every method call must resolve.
Every listener must reference a valid object.
Every component must be created before use.
Every opening brace must have a matching closing brace.
Every opening parenthesis must have a matching closing parenthesis.
Every string must be closed correctly.
Every collection index must be safe.
============================================================
SECOND REVIEW
============================================================
After the first review, perform another independent review.
Specifically search mentally for:
- val/var mistakes
- Unit used as Component
- methods used before declaration
- forward references
- duplicate names
- Int vs Double problems
- invalid Swing constants
- invalid paintComponent code
- invalid Timer code
- invalid listeners
- missing repaint
- keyboard focus problems
- out-of-bounds indexing
- division by zero
- bad camera projection
- incorrect game reset
Fix all obvious issues before output.
============================================================
NO FAKE COMPLETENESS
============================================================
Do not claim a feature exists if it is not in the code.
Do not replace real implementation with comments.
Do not say:
"implement this yourself"
"add this later"
"continue"
"etc."
Do not use:
// TODO
// add the rest
...
Everything required must be present.
============================================================
SINGLE FILE RULE
============================================================
Return ONE complete Scala source file.
Do not split the implementation across multiple files.
Do not depend on undeclared classes.
Do not require the user to manually merge code.
============================================================
SCALA VERSION SAFETY
============================================================
Prefer straightforward Scala syntax compatible with common Scala desktop environments.
Avoid unnecessarily advanced syntax when simpler syntax is safer.
Do not depend on experimental features.
Do not assume libraries that are not explicitly available.
============================================================
REALISTIC 3D PRIORITY
============================================================
If the USER IDEA asks for 3D, prioritize:
1. playable game
2. correct controls
3. real perspective
4. smooth camera
5. depth
6. environment
7. collision
8. score
9. levels
10. polished HUD
11. visual effects
12. restart
13. win/lose
14. compile safety
Do not sacrifice compilation safety for unnecessary complexity.
============================================================
FINAL SOURCE REQUIREMENT
============================================================
Return:
ONE complete runnable Scala source file.
No patch.
No partial source.
No second version.
No placeholder.
No pseudocode.
No unfinished section.
No omitted classes.
No omitted methods.
No "continue here".
The final code should be ready to paste into a Scala-compatible environment.
============================================================
FINAL RESPONSE FORMAT
============================================================
Your final response must contain:
A very short explanation.
Then ONE complete Scala code block.
Do not provide additional alternative implementations.
============================================================
MOST IMPORTANT RULE
============================================================
Understand the USER IDEA first.
Then design the complete application.
Then implement it.
Then review the ENTIRE source for compilation safety.
Then review it AGAIN.
Then return only the complete implementation.
When the idea requests a realistic 3D game, produce the strongest realistic interactive 3D-style implementation that can reasonably be created as a self-contained Scala Swing/Java2D application.
Do not turn a requested 3D game into a static screen.
Do not remove important requested mechanics.
Preserve and expand the USER IDEA.
Return ONE complete compile-safe 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 realistic 3D car racing game with road,
traffic, enemies, perspective, score, speed,
keyboard steering, collisions and restart."
Then generate the MASTER PROMPT.
Copy that prompt into ChatGPT.
ChatGPT must use the exact idea and create a complete
Scala Swing project with strong compile-safety and
3D-style Java2D rendering when 3D is requested."""
)
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",
"3D Rendering",
"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.",
"3D Rendering\n\nJava2D can be used to create self-contained perspective and pseudo-3D effects with camera math and polygon projection.",
"Debugging\n\nStart from the first compiler error and inspect declarations, scope, braces, types and event code."
)
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 if (
question.contains(
"3d"
)
) {
"A Swing application can create strong 3D-style visuals using Java2D, perspective projection, camera math and procedural polygon rendering."
} 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.count(
_ == '('
) !=
code.count(
_ == ')'
)
) {
problems +=
"Possible ( ) mismatch."
}
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 if (
error.contains(
"reassignment to val"
)
) {
"""A val cannot be reassigned.
Use var only for state that truly changes, or calculate a new value instead."""
} else if (
error.contains(
"required: Int"
)
) {
"""A Swing method usually expects an Int, but a Double or another numeric type was provided.
Convert safely with .toInt when appropriate."""
} else {
"Check the first compiler error first.\n\n" +
"? missing braces\n" +
"? duplicate names\n" +
"? undefined variables\n" +
"? undefined methods\n" +
"? wrong Swing component types\n" +
"? forward references\n" +
"? incorrect listeners\n" +
"? numeric type mismatch\n" +
"? invalid timer or rendering code"
}
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 &&
index < taskModel.getSize
) {
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 &&
index < taskModel.getSize
) {
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
nextQuizButton.setEnabled(
quizIndex <
quizQuestions.length
)
} 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
)
}
)
recordActivity(
"Generated prompt from Prompt Lab"
)
}
}
)
copyPromptButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val generated =
promptOutputArea
.getText
.trim
if (
generated.isEmpty
) {
showWarning(
frame,
"PROMPT LAB",
"Generate the prompt first."
)
} else {
copyToClipboard(
generated
)
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(
""
)
recordActivity(
"Saved project: " +
name
)
}
}
}
)
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 &&
index < projectModel.getSize
) {
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.
3D RULES
When a 3D game is requested, the generated prompt
requires a self-contained software 3D / pseudo-3D
renderer using Scala Swing and Java2D when an external
3D engine is not guaranteed.
The generated prompt also requires complete compile
review, type safety, correct event handling, timer
safety, rendering safety, game state handling,
restart, win/lose and playable controls."""
)
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.
3D support:
The MASTER PROMPT requests a self-contained
Java2D/Swing software 3D or pseudo-3D renderer when
the user's idea requires 3D."""
)
settingsPanel.add(
makeLabel(
"SETTINGS",
24,
true
),
BorderLayout.NORTH
)
settingsPanel.add(
makeScroll(
settingsText
),
BorderLayout.CENTER
)
// ========================================================
// MASTER PROMPT
// ========================================================
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"
)
if (
tabs.getTabCount > 0
) {
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()
}
}
)
dashboardHistoryButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
tabs.setSelectedComponent(
historyPanel
)
refreshHistoryView()
}
}
)
dashboardSettingsButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
tabs.setSelectedComponent(
settingsPanel
)
}
}
)
// ========================================================
// 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.\n\n" +
"Enhanced 3D-oriented prompt generation enabled."
)
}
}
)
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
)
}