Code Sketch
yyyyyy
Category: Programming
import java.awt._
import java.awt.datatransfer.StringSelection
import java.awt.event._
import java.io._
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.security.MessageDigest
import javax.imageio.ImageIO
import javax.swing._
import javax.swing.border._
import javax.swing.event._
import javax.swing.filechooser.FileNameExtensionFilter
// ============================================================
// IMAGE PROFILE
// ============================================================
case class ImageProfile(
fileName: String,
absolutePath: String,
width: Int,
height: Int,
ratio: Double,
averageR: Int,
averageG: Int,
averageB: Int,
brightness: Int,
dominantHex: String
)
// ============================================================
// SECURITY
// ============================================================
object PlatformSecurity {
private val PASSWORD_HASH =
"951f97336a749358c189391a108e9bff26e4ff756cfeb365af5809a2b1c33ef8"
def sha256(text: String): String = {
val digest =
MessageDigest.getInstance("SHA-256")
val bytes =
digest.digest(
text.getBytes(StandardCharsets.UTF_8)
)
val builder =
new StringBuilder
var i = 0
while (i < bytes.length) {
val value = bytes(i) & 0xff
val hex = Integer.toHexString(value)
if (hex.length == 1) {
builder.append("0")
}
builder.append(hex)
i += 1
}
builder.toString
}
def verify(candidate: String): Boolean = {
val candidateHash =
sha256(candidate)
MessageDigest.isEqual(
candidateHash.getBytes(StandardCharsets.UTF_8),
PASSWORD_HASH.getBytes(StandardCharsets.UTF_8)
)
}
}
// ============================================================
// IMAGE ANALYZER
// ============================================================
object ImageAnalyzer {
def analyze(file: File): Option[ImageProfile] = {
try {
val image =
ImageIO.read(file)
if (image == null) {
None
} else {
val width =
image.getWidth
val height =
image.getHeight
var totalR = 0L
var totalG = 0L
var totalB = 0L
var totalBrightness = 0L
var count = 0L
val stepX =
math.max(1, width / 48)
val stepY =
math.max(1, height / 48)
var y = 0
while (y < height) {
var x = 0
while (x < width) {
val rgb =
image.getRGB(x, y)
val r =
(rgb >> 16) & 0xff
val g =
(rgb >> 8) & 0xff
val b =
rgb & 0xff
totalR += r
totalG += g
totalB += b
totalBrightness +=
((r * 299) +
(g * 587) +
(b * 114)) / 1000
count += 1L
x += stepX
}
y += stepY
}
val safeCount =
math.max(1L, count)
val averageR =
(totalR / safeCount).toInt
val averageG =
(totalG / safeCount).toInt
val averageB =
(totalB / safeCount).toInt
val brightness =
(totalBrightness / safeCount).toInt
val dominantHex =
"#%02X%02X%02X".format(
averageR,
averageG,
averageB
)
Some(
ImageProfile(
file.getName,
file.getAbsolutePath,
width,
height,
if (height == 0)
1.0
else
width.toDouble / height.toDouble,
averageR,
averageG,
averageB,
brightness,
dominantHex
)
)
}
} catch {
case _: Throwable =>
None
}
}
def makePreviewIcon(
file: File,
maxWidth: Int,
maxHeight: Int
): Option[ImageIcon] = {
try {
val image =
ImageIO.read(file)
if (image == null) {
None
} else {
val sourceWidth =
math.max(1, image.getWidth)
val sourceHeight =
math.max(1, image.getHeight)
val scale =
math.min(
maxWidth.toDouble / sourceWidth,
maxHeight.toDouble / sourceHeight
)
val finalScale =
math.min(1.0, scale)
val newWidth =
math.max(
1,
(image.getWidth * finalScale).toInt
)
val newHeight =
math.max(
1,
(image.getHeight * finalScale).toInt
)
val scaled =
image.getScaledInstance(
newWidth,
newHeight,
Image.SCALE_SMOOTH
)
Some(
new ImageIcon(scaled)
)
}
} catch {
case _: Throwable =>
None
}
}
}
// ============================================================
// HTML TOOLS
// ============================================================
object HtmlTools {
def escapeHtml(text: String): String = {
if (text == null) {
""
} else {
text
.replace("&", "&")
.replace("<", "<")
.replace(">", ">")
.replace("\"", """)
.replace("'", "'")
}
}
def escapeAttribute(text: String): String = {
escapeHtml(text)
.replace("\n", " ")
.replace("\r", " ")
}
def slug(text: String): String = {
val cleaned =
Option(text)
.getOrElse("")
.toLowerCase
.replaceAll("[^a-z0-9]+", "-")
val trimmed =
cleaned
.replaceAll("^-+", "")
.replaceAll("-+$", "")
if (trimmed.isEmpty) {
"creator-project"
} else {
trimmed.take(56)
}
}
}
// ============================================================
// PROJECT GENERATOR
// IMPORTANT: No line-ending "+" concatenation is used.
// ============================================================
object ProjectGenerator {
private val commonCss =
"""
|<style>
|*{box-sizing:border-box}
|html,body{
|margin:0;
|padding:0;
|min-height:100%;
|font-family:Inter,Segoe UI,Arial,sans-serif
|}
|body{
|background:#0b1020;
|color:#edf2ff
|}
|.page{
|max-width:1120px;
|margin:0 auto;
|padding:36px
|}
|.card{
|background:rgba(20,28,52,.92);
|border:1px solid rgba(255,255,255,.10);
|border-radius:24px;
|padding:28px;
|box-shadow:0 18px 55px rgba(0,0,0,.22)
|}
|.hero{
|padding:56px 36px;
|text-align:center;
|border-radius:28px;
|background:linear-gradient(135deg,#131d3c,#17264f)
|}
|.eyebrow{
|display:inline-block;
|padding:8px 12px;
|border-radius:999px;
|background:rgba(255,255,255,.08);
|font-size:12px;
|letter-spacing:1.4px;
|text-transform:uppercase
|}
|h1{
|font-size:52px;
|line-height:1.02;
|margin:18px 0 14px
|}
|h2{
|font-size:28px;
|margin:0 0 12px
|}
|h3{
|font-size:18px;
|margin:0 0 8px
|}
|p{
|color:#b7c2dc;
|line-height:1.7
|}
|.muted{
|color:#8f9ab6
|}
|.grid{
|display:grid;
|grid-template-columns:repeat(3,1fr);
|gap:18px;
|margin-top:22px
|}
|.grid2{
|display:grid;
|grid-template-columns:repeat(2,1fr);
|gap:18px;
|margin-top:22px
|}
|.pill{
|display:inline-block;
|padding:8px 12px;
|margin:5px;
|border-radius:999px;
|background:#202b4d;
|color:#cfdaff;
|font-size:13px
|}
|.btn{
|display:inline-block;
|padding:13px 18px;
|border-radius:13px;
|background:#6d7dff;
|color:#fff;
|text-decoration:none;
|font-weight:700;
|margin:6px 4px;
|border:0;
|cursor:pointer
|}
|.btn.secondary{
|background:#253251
|}
|input,textarea,select{
|width:100%;
|padding:13px 15px;
|border-radius:12px;
|border:1px solid #364363;
|background:#0f1730;
|color:#fff
|}
|label{
|display:block;
|font-weight:700;
|margin:0 0 7px
|}
|.field{
|margin-bottom:16px
|}
|.metric{
|font-size:34px;
|font-weight:800;
|margin-top:4px
|}
|.bar{
|height:9px;
|border-radius:999px;
|background:#253251;
|overflow:hidden
|}
|.fill{
|height:100%;
|border-radius:999px;
|background:#6d7dff
|}
|.footer{
|margin-top:24px;
|color:#7f8aa5;
|text-align:center;
|font-size:12px
|}
|.avatar{
|width:92px;
|height:92px;
|border-radius:50%;
|background:#273b7a;
|margin:0 auto 18px;
|display:flex;
|align-items:center;
|justify-content:center;
|font-size:34px;
|font-weight:800
|}
|.tag{
|padding:6px 10px;
|border-radius:8px;
|background:#1b2745;
|color:#bdc9ea;
|display:inline-block;
|margin:4px;
|font-size:12px
|}
|.row{
|display:flex;
|gap:14px;
|align-items:center;
|justify-content:space-between;
|flex-wrap:wrap
|}
|.progress{
|margin-top:10px
|}
|.code-chip{
|font-family:Consolas,Monaco,monospace;
|background:#09101f;
|border:1px solid #263353;
|padding:12px;
|border-radius:12px;
|overflow:auto
|}
|.notice{
|padding:14px 16px;
|border-radius:14px;
|background:rgba(109,125,255,.10);
|border:1px solid rgba(109,125,255,.24);
|color:#ced7ff
|}
|</style>
|""".stripMargin
private def join(parts: String*): String = {
parts.mkString
}
private def baseHtml(
title: String,
category: String,
body: String,
image: Option[ImageProfile],
generation: Int
): String = {
val safeTitle =
HtmlTools.escapeHtml(title)
val imageSection =
image match {
case Some(profile) =>
val imageUri =
HtmlTools.escapeAttribute(
new File(
profile.absolutePath
).toURI.toString
)
join(
"<div class='card' style='margin-top:20px'>",
"<div class='row'>",
"<div>",
"<h3>Reference Visual</h3>",
"<p class='muted'>",
"Imported design reference analyzed locally.",
"</p>",
"</div>",
"<span class='pill'>",
profile.width.toString,
" � ",
profile.height.toString,
"</span>",
"</div>",
"<img src='",
imageUri,
"' style='display:block;max-width:100%;",
"max-height:420px;border-radius:18px;",
"margin-top:16px;margin-left:auto;",
"margin-right:auto'/>",
"</div>"
)
case None =>
""
}
join(
"<!DOCTYPE html>",
"<html>",
"<head>",
"<meta charset='UTF-8'>",
"<meta name='viewport' ",
"content='width=device-width,initial-scale=1'>",
"<title>",
safeTitle,
"</title>",
commonCss,
"</head>",
"<body>",
"<main class='page'>",
body,
imageSection,
"<div class='footer'>",
"Generated by Developer Creator Platform � ",
HtmlTools.escapeHtml(category),
" � Generation ",
generation.toString,
"</div>",
"</main>",
"</body>",
"</html>"
)
}
private def inferTitle(
prompt: String,
category: String
): String = {
val clean =
Option(prompt)
.getOrElse("")
.trim
if (clean.isEmpty) {
category + " Project"
} else {
val first =
clean
.split("[.!?\\n]")
.headOption
.getOrElse(clean)
.trim
.take(58)
if (first.isEmpty) {
category + " Project"
} else {
first
}
}
}
def generate(
category: String,
prompt: String,
image: Option[ImageProfile],
generation: Int
): String = {
val cleanPrompt =
Option(prompt)
.getOrElse("")
.trim
val safePrompt =
HtmlTools.escapeHtml(
cleanPrompt
)
val title =
inferTitle(
prompt,
category
)
val visualColor =
image
.map(_.dominantHex)
.getOrElse("#6D7DFF")
val imageInsight =
image match {
case Some(p) =>
join(
"<div class='notice'>",
"Reference analysis: ",
p.width.toString,
"�",
p.height.toString,
" � aspect ",
"%.2f".format(p.ratio),
" � sampled dominant tone ",
p.dominantHex,
" � brightness ",
p.brightness.toString,
"/255.",
"</div>"
)
case None =>
join(
"<div class='notice'>",
"No reference image uploaded. ",
"The generator is using prompt-driven layout decisions.",
"</div>"
)
}
val body =
category match {
// ------------------------------------------------------
// WEBSITES
// ------------------------------------------------------
case "Websites" =>
join(
"<section class='hero' ",
"style='border-top:5px solid ",
visualColor,
"'>",
"<span class='eyebrow'>Website Studio</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"A flexible multi-section website generated from your brief."
else
safePrompt,
"</p>",
"<a class='btn' href='#explore'>Explore Project</a>",
"<a class='btn secondary' href='#contact'>Contact</a>",
"</section>",
"<section id='explore' class='grid'>",
"<div class='card'>",
"<h3>Hero</h3>",
"<p>",
"Clear value proposition, responsive hierarchy, ",
"and strong call to action.",
"</p>",
"</div>",
"<div class='card'>",
"<h3>Features</h3>",
"<p>",
"Reusable cards, sections, metrics, and content modules ",
"are ready to customize.",
"</p>",
"</div>",
"<div class='card'>",
"<h3>Contact</h3>",
"<p>",
"Built with semantic structure and form-ready controls.",
"</p>",
"</div>",
"</section>",
imageInsight,
"<section id='contact' class='card' ",
"style='margin-top:20px'>",
"<h2>Contact</h2>",
"<div class='grid2'>",
"<div class='field'>",
"<label>Name</label>",
"<input placeholder='Your name'>",
"</div>",
"<div class='field'>",
"<label>Email</label>",
"<input placeholder='you@example.com'>",
"</div>",
"</div>",
"<button class='btn'>Send Message</button>",
"</section>"
)
// ------------------------------------------------------
// LINKS
// ------------------------------------------------------
case "Links" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Link Hub</span>",
"<div class='avatar'>L</div>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
"Your links, resources, socials, and important ",
"destinations in one clean page.",
"</p>",
"<a class='btn' href='#links'>",
"Open Link Collection",
"</a>",
"</section>",
"<section id='links' class='card' ",
"style='margin-top:20px'>",
"<h2>Quick Links</h2>",
"<p class='muted'>",
if (safePrompt.isEmpty)
"Add your links and short descriptions."
else
safePrompt,
"</p>",
"<a class='btn' href='#'>Main Website</a>",
"<a class='btn' href='#'>Portfolio</a>",
"<a class='btn secondary' href='#'>Social Profile</a>",
"<a class='btn secondary' href='#'>Contact</a>",
"</section>"
)
// ------------------------------------------------------
// BIO PAGES
// ------------------------------------------------------
case "Bio Pages" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Bio Creator</span>",
"<div class='avatar'>B</div>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"Creator � Developer � Builder � Dreamer"
else
safePrompt,
"</p>",
"<span class='pill'>Developer</span>",
"<span class='pill'>Designer</span>",
"<span class='pill'>Creator</span>",
"</section>",
"<section class='grid2'>",
"<div class='card'>",
"<h2>About</h2>",
"<p>",
"Use this area for your story, skills, goals, ",
"and professional summary.",
"</p>",
"</div>",
"<div class='card'>",
"<h2>Focus</h2>",
"<p>",
"Projects, collaborations, experiments, and future ",
"ideas can be highlighted here.",
"</p>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// APPS
// ------------------------------------------------------
case "Apps" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>App Generator</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"A polished application interface with cards, navigation, " +
"actions, and status areas."
else
safePrompt,
"</p>",
"<button class='btn'>Launch App</button>",
"</section>",
"<section class='grid'>",
"<div class='card'>",
"<h3>Home</h3>",
"<p>Primary application workspace.</p>",
"</div>",
"<div class='card'>",
"<h3>Activity</h3>",
"<p>Recent actions and updates.</p>",
"</div>",
"<div class='card'>",
"<h3>Settings</h3>",
"<p>Preferences and configuration.</p>",
"</div>",
"</section>",
"<section class='card' style='margin-top:20px'>",
"<h2>App State</h2>",
"<div class='row'>",
"<span class='muted'>Status</span>",
"<span class='tag'>READY</span>",
"</div>",
"<div class='row'>",
"<span class='muted'>Mode</span>",
"<span class='tag'>LOCAL</span>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// GAMES
// ------------------------------------------------------
case "Games" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Game Creator</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"A game shell with HUD, player state, objectives, " +
"and action controls."
else
safePrompt,
"</p>",
"<button class='btn'>Start Game</button>",
"<button class='btn secondary'>How To Play</button>",
"</section>",
"<section class='grid'>",
"<div class='card'>",
"<h3>PLAYER</h3>",
"<div class='metric'>100 HP</div>",
"<div class='progress'>",
"<div class='bar'>",
"<div class='fill' style='width:80%'></div>",
"</div>",
"</div>",
"</div>",
"<div class='card'>",
"<h3>SCORE</h3>",
"<div class='metric'>000250</div>",
"<p class='muted'>",
"Best score tracked in your project state.",
"</p>",
"</div>",
"<div class='card'>",
"<h3>LEVEL</h3>",
"<div class='metric'>01</div>",
"<p class='muted'>Progression-ready structure.</p>",
"</div>",
"</section>",
"<section class='card' style='margin-top:20px'>",
"<h2>Controls</h2>",
"<span class='tag'>W A S D</span>",
"<span class='tag'>ARROWS</span>",
"<span class='tag'>SPACE</span>",
"<span class='tag'>MOUSE</span>",
"</section>"
)
// ------------------------------------------------------
// LANDING PAGES
// ------------------------------------------------------
case "Landing Pages" =>
join(
"<section class='hero' ",
"style='background:linear-gradient(135deg,",
visualColor,
",#10162c)'>",
"<span class='eyebrow'>Launch Ready</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"A conversion-focused landing page with clear " +
"hierarchy and compact messaging."
else
safePrompt,
"</p>",
"<a class='btn' href='#cta'>Get Started</a>",
"</section>",
"<section class='grid'>",
"<div class='card'>",
"<h3>Fast Setup</h3>",
"<p>Simple sections that can be customized quickly.</p>",
"</div>",
"<div class='card'>",
"<h3>Strong Message</h3>",
"<p>Hero-first layout with clear benefits and trust signals.</p>",
"</div>",
"<div class='card'>",
"<h3>Action Focused</h3>",
"<p>Buttons and forms are positioned around the main goal.</p>",
"</div>",
"</section>",
"<section id='cta' class='card' ",
"style='margin-top:20px;text-align:center'>",
"<h2>Ready to build?</h2>",
"<p>Turn your idea into a presentable project.</p>",
"<button class='btn'>Create Now</button>",
"</section>"
)
// ------------------------------------------------------
// UI DESIGNS
// ------------------------------------------------------
case "UI Designs" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>UI Design Lab</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"Component-first interface exploration with cards, " +
"spacing, typography, and controls."
else
safePrompt,
"</p>",
"</section>",
"<section class='grid2'>",
"<div class='card'>",
"<h2>Components</h2>",
"<button class='btn'>Primary</button>",
"<button class='btn secondary'>Secondary</button>",
"<span class='pill'>Badge</span>",
"<span class='pill'>New</span>",
"</div>",
"<div class='card'>",
"<h2>Form Preview</h2>",
"<div class='field'>",
"<label>Project name</label>",
"<input placeholder='Type here'>",
"</div>",
"<div class='field'>",
"<label>Message</label>",
"<textarea rows='4' ",
"placeholder='Describe your design'></textarea>",
"</div>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// TOOLS
// ------------------------------------------------------
case "Tools" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Tool Builder</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"An interactive utility layout ready for your custom logic."
else
safePrompt,
"</p>",
"</section>",
"<section class='card' style='margin-top:20px'>",
"<div class='field'>",
"<label>Input</label>",
"<textarea rows='6' ",
"placeholder='Enter data...'></textarea>",
"</div>",
"<button class='btn'>Run Tool</button>",
"<button class='btn secondary'>Clear</button>",
"<div class='card' ",
"style='margin-top:18px;background:#0b1328'>",
"<h3>Output</h3>",
"<div class='code-chip'>",
"Output will appear here.",
"</div>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// PORTFOLIOS
// ------------------------------------------------------
case "Portfolios" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Portfolio Studio</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"A project portfolio with featured work, capabilities, " +
"and contact information."
else
safePrompt,
"</p>",
"</section>",
"<section class='grid'>",
"<div class='card'>",
"<span class='tag'>01</span>",
"<h3>Featured Project</h3>",
"<p>",
"Show the strongest project with a focused story and results.",
"</p>",
"<button class='btn'>View</button>",
"</div>",
"<div class='card'>",
"<span class='tag'>02</span>",
"<h3>Experiment</h3>",
"<p>",
"Highlight creative tests, prototypes, and technical exploration.",
"</p>",
"<button class='btn secondary'>Open</button>",
"</div>",
"<div class='card'>",
"<span class='tag'>03</span>",
"<h3>Case Study</h3>",
"<p>",
"Present the problem, process, solution, and impact.",
"</p>",
"<button class='btn secondary'>Read</button>",
"</div>",
"</section>",
"<section class='card' style='margin-top:20px'>",
"<h2>Skills</h2>",
"<span class='pill'>Development</span>",
"<span class='pill'>UI/UX</span>",
"<span class='pill'>Creative Coding</span>",
"<span class='pill'>Problem Solving</span>",
"</section>"
)
// ------------------------------------------------------
// FORMS
// ------------------------------------------------------
case "Forms" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Form Builder</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"A clean, accessible form structure generated from your requirements."
else
safePrompt,
"</p>",
"</section>",
"<section class='card' style='margin-top:20px'>",
"<div class='field'>",
"<label>Full Name</label>",
"<input placeholder='Enter your name'>",
"</div>",
"<div class='field'>",
"<label>Email</label>",
"<input type='email' placeholder='you@example.com'>",
"</div>",
"<div class='field'>",
"<label>Category</label>",
"<select>",
"<option>Choose one</option>",
"<option>General</option>",
"<option>Support</option>",
"<option>Project</option>",
"</select>",
"</div>",
"<div class='field'>",
"<label>Message</label>",
"<textarea rows='6' ",
"placeholder='Tell us more...'></textarea>",
"</div>",
"<button class='btn'>Submit Form</button>",
"</section>"
)
// ------------------------------------------------------
// DASHBOARDS
// ------------------------------------------------------
case "Dashboards" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Dashboard Generator</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"An analytics-style dashboard with metrics, progress, " +
"and action cards."
else
safePrompt,
"</p>",
"</section>",
"<section class='grid'>",
"<div class='card'>",
"<p class='muted'>USERS</p>",
"<div class='metric'>12,540</div>",
"<span class='tag'>+12%</span>",
"</div>",
"<div class='card'>",
"<p class='muted'>PROJECTS</p>",
"<div class='metric'>348</div>",
"<span class='tag'>+8%</span>",
"</div>",
"<div class='card'>",
"<p class='muted'>TASKS</p>",
"<div class='metric'>1,284</div>",
"<span class='tag'>73%</span>",
"</div>",
"</section>",
"<section class='grid2'>",
"<div class='card'>",
"<h2>Progress</h2>",
"<p class='muted'>Primary goal completion</p>",
"<div class='bar'>",
"<div class='fill' style='width:72%'></div>",
"</div>",
"</div>",
"<div class='card'>",
"<h2>Activity</h2>",
"<p class='muted'>Latest system events</p>",
"<div class='row'>",
"<span>New project</span>",
"<span class='tag'>2m</span>",
"</div>",
"<div class='row'>",
"<span>Upload complete</span>",
"<span class='tag'>9m</span>",
"</div>",
"<div class='row'>",
"<span>Profile updated</span>",
"<span class='tag'>18m</span>",
"</div>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// API JSON
// ------------------------------------------------------
case "API / JSON" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Data & API</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"A clean developer-facing API response and endpoint documentation layout."
else
safePrompt,
"</p>",
"</section>",
"<section class='grid2'>",
"<div class='card'>",
"<h2>Endpoint</h2>",
"<span class='tag'>GET</span>",
"<div class='code-chip'>",
"/api/v1/projects",
"</div>",
"<p class='muted'>",
"Returns project metadata in JSON format.",
"</p>",
"</div>",
"<div class='card'>",
"<h2>Example</h2>",
"<div class='code-chip'>",
"{"status":"ok","items":3}",
"</div>",
"<p class='muted'>",
"Use this section for schemas and response samples.",
"</p>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// COMPONENTS
// ------------------------------------------------------
case "Components" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Component Studio</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"Build reusable buttons, cards, alerts, navigation, " +
"inputs, and layout primitives."
else
safePrompt,
"</p>",
"</section>",
"<section class='grid'>",
"<div class='card'>",
"<h3>Button System</h3>",
"<button class='btn'>Action</button>",
"<button class='btn secondary'>More</button>",
"</div>",
"<div class='card'>",
"<h3>Status</h3>",
"<span class='tag'>ACTIVE</span>",
"<span class='tag'>DRAFT</span>",
"<span class='tag'>READY</span>",
"</div>",
"<div class='card'>",
"<h3>Notice</h3>",
"<div class='notice'>",
"Reusable information component.",
"</div>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// ICONS
// ------------------------------------------------------
case "Icons" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Icon & Visual Lab</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"A scalable visual board for icons, symbols, badges, " +
"and small interface graphics."
else
safePrompt,
"</p>",
"</section>",
"<section class='grid'>",
"<div class='card' ",
"style='text-align:center;font-size:42px'>",
"?",
"<p class='muted'>Star</p>",
"</div>",
"<div class='card' ",
"style='text-align:center;font-size:42px'>",
"?",
"<p class='muted'>Settings</p>",
"</div>",
"<div class='card' ",
"style='text-align:center;font-size:42px'>",
"?",
"<p class='muted'>Success</p>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// CREATIVE PROJECTS
// ------------------------------------------------------
case "Creative Projects" =>
join(
"<section class='hero' ",
"style='background:radial-gradient(circle at top left,",
visualColor,
",#10162d 58%)'>",
"<span class='eyebrow'>Creative Lab</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"An open canvas for experiments, prototypes, interactive stories, " +
"visual projects, and unusual ideas."
else
safePrompt,
"</p>",
"<a class='btn' href='#canvas'>Open Canvas</a>",
"</section>",
"<section id='canvas' class='card' ",
"style='margin-top:20px;min-height:250px;text-align:center'>",
"<h2>Creative Canvas</h2>",
"<p class='muted'>",
"Use this area as the starting point for your custom creation.",
"</p>",
"<div style='margin:25px auto;width:85%;height:110px;",
"border-radius:18px;background:linear-gradient(100deg,",
visualColor,
",#17264f,#0e1428)'>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// BLANK
// ------------------------------------------------------
case "Blank Project" =>
join(
"<section class='hero'>",
"<span class='eyebrow'>Blank Project</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"Start from a clean, extensible base and shape it into anything you need."
else
safePrompt,
"</p>",
"<button class='btn'>Begin</button>",
"</section>",
"<section class='grid2'>",
"<div class='card'>",
"<h2>Structure</h2>",
"<p>",
"Header, main content, utility modules, and footer are ready to adapt.",
"</p>",
"</div>",
"<div class='card'>",
"<h2>Next Step</h2>",
"<p>",
"Keep iterating in the code editor and regenerate whenever the idea changes.",
"</p>",
"</div>",
"</section>"
)
// ------------------------------------------------------
// FALLBACK
// ------------------------------------------------------
case _ =>
join(
"<section class='hero'>",
"<span class='eyebrow'>",
HtmlTools.escapeHtml(category),
"</span>",
"<h1>",
HtmlTools.escapeHtml(title),
"</h1>",
"<p>",
if (safePrompt.isEmpty)
"Describe what you want to build and generate a new project."
else
safePrompt,
"</p>",
"<button class='btn'>Create</button>",
"</section>"
)
}
baseHtml(
title,
category,
body,
image,
generation
)
}
}
// ============================================================
// LOGIN PANEL
// ============================================================
class LoginPanel(
onSuccess: () => Unit
) extends JPanel(new GridBagLayout()) {
private val loginBackground =
new Color(
7,
11,
22
)
private val cardBackground =
new Color(
17,
24,
43
)
private val accent =
new Color(
109,
125,
255
)
private val soft =
new Color(
168,
180,
214
)
setBackground(
loginBackground
)
private val card =
new JPanel(
new GridBagLayout()
)
card.setBackground(
cardBackground
)
card.setBorder(
new CompoundBorder(
new LineBorder(
new Color(
51,
65,
102
),
1,
true
),
new EmptyBorder(
34,
40,
34,
40
)
)
)
private val constraints =
new GridBagConstraints()
constraints.gridx = 0
constraints.weightx = 1.0
constraints.fill =
GridBagConstraints.HORIZONTAL
private val brand =
new JLabel(
"DEVELOPER CREATOR"
)
brand.setHorizontalAlignment(
SwingConstants.CENTER
)
brand.setForeground(
new Color(
146,
159,
255
)
)
brand.setFont(
new Font(
"SansSerif",
Font.BOLD,
14
)
)
private val title =
new JLabel(
"Secure Developer Platform"
)
title.setHorizontalAlignment(
SwingConstants.CENTER
)
title.setForeground(
Color.WHITE
)
title.setFont(
new Font(
"SansSerif",
Font.BOLD,
28
)
)
private val subtitle =
new JLabel(
"Enter the private platform password to continue"
)
subtitle.setHorizontalAlignment(
SwingConstants.CENTER
)
subtitle.setForeground(
soft
)
subtitle.setFont(
new Font(
"SansSerif",
Font.PLAIN,
13
)
)
private val passwordField =
new JPasswordField()
passwordField.setPreferredSize(
new Dimension(
320,
44
)
)
passwordField.setFont(
new Font(
"SansSerif",
Font.PLAIN,
17
)
)
passwordField.setBackground(
new Color(
10,
16,
32
)
)
passwordField.setForeground(
Color.WHITE
)
passwordField.setCaretColor(
Color.WHITE
)
passwordField.setBorder(
new CompoundBorder(
new LineBorder(
new Color(
56,
71,
111
),
1,
true
),
new EmptyBorder(
6,
10,
6,
10
)
)
)
private val status =
new JLabel(" ")
status.setHorizontalAlignment(
SwingConstants.CENTER
)
status.setForeground(
new Color(
244,
110,
110
)
)
status.setFont(
new Font(
"SansSerif",
Font.BOLD,
12
)
)
private val loginButton =
new JButton(
"UNLOCK PLATFORM"
)
loginButton.setPreferredSize(
new Dimension(
320,
44
)
)
loginButton.setBackground(
accent
)
loginButton.setForeground(
Color.WHITE
)
loginButton.setFocusPainted(
false
)
loginButton.setBorder(
new EmptyBorder(
8,
16,
8,
16
)
)
loginButton.setFont(
new Font(
"SansSerif",
Font.BOLD,
13
)
)
private val showButton =
new JButton(
"Show"
)
showButton.setFocusPainted(
false
)
showButton.setBackground(
new Color(
30,
41,
70
)
)
showButton.setForeground(
new Color(
202,
211,
238
)
)
showButton.setBorder(
new EmptyBorder(
8,
12,
8,
12
)
)
private val passwordRow =
new JPanel(
new BorderLayout(
8,
0
)
)
passwordRow.setOpaque(
false
)
passwordRow.add(
passwordField,
BorderLayout.CENTER
)
passwordRow.add(
showButton,
BorderLayout.EAST
)
private val info =
new JLabel(
"<html>" +
"<div style='text-align:center'>" +
"Local SHA-256 verification<br>" +
"No plaintext password is stored in this source." +
"</div>" +
"</html>"
)
info.setHorizontalAlignment(
SwingConstants.CENTER
)
info.setForeground(
new Color(
126,
139,
174
)
)
info.setFont(
new Font(
"SansSerif",
Font.PLAIN,
11
)
)
private def addRow(
component: Component,
top: Int,
bottom: Int
): Unit = {
constraints.gridy += 1
constraints.insets =
new Insets(
top,
0,
bottom,
0
)
card.add(
component,
constraints
)
}
constraints.gridy = -1
addRow(
brand,
0,
10
)
addRow(
title,
0,
8
)
addRow(
subtitle,
0,
24
)
addRow(
passwordRow,
0,
12
)
addRow(
loginButton,
0,
8
)
addRow(
status,
0,
14
)
addRow(
info,
0,
0
)
add(card)
private var attempts =
0
private var locked =
false
private var passwordVisible =
false
showButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
passwordVisible =
!passwordVisible
passwordField.setEchoChar(
if (passwordVisible)
0.toChar
else
'?'
)
showButton.setText(
if (passwordVisible)
"Hide"
else
"Show"
)
}
}
)
private def performLogin(): Unit = {
if (locked) {
return
}
val candidate =
new String(
passwordField.getPassword
)
if (candidate.isEmpty) {
status.setText(
"Enter the password."
)
return
}
if (
PlatformSecurity.verify(
candidate
)
) {
status.setForeground(
new Color(
105,
225,
158
)
)
status.setText(
"Access granted."
)
loginButton.setEnabled(false)
passwordField.setEnabled(false)
showButton.setEnabled(false)
val transitionTimer =
new Timer(
180,
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val timer =
e.getSource
.asInstanceOf[Timer]
timer.stop()
onSuccess()
}
}
)
transitionTimer.setRepeats(
false
)
transitionTimer.start()
} else {
attempts += 1
passwordField.setText(
""
)
val remaining =
math.max(
0,
5 - attempts
)
status.setForeground(
new Color(
244,
110,
110
)
)
status.setText(
"Incorrect password. Attempts remaining: " +
remaining
)
if (attempts >= 5) {
locked = true
loginButton.setEnabled(false)
passwordField.setEnabled(false)
showButton.setEnabled(false)
status.setText(
"Too many attempts. Locked for 10 seconds."
)
val unlockTimer =
new Timer(
10000,
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val timer =
e.getSource
.asInstanceOf[Timer]
timer.stop()
attempts = 0
locked = false
loginButton.setEnabled(
true
)
passwordField.setEnabled(
true
)
showButton.setEnabled(
true
)
status.setText(
"You may try again."
)
}
}
)
unlockTimer.setRepeats(
false
)
unlockTimer.start()
}
}
}
loginButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
performLogin()
}
}
)
passwordField.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
performLogin()
}
}
)
}
// ============================================================
// MAIN DEVELOPER PLATFORM
// ============================================================
class DeveloperPlatformPanel(
frame: JFrame
) extends JPanel(new BorderLayout()) {
// NOTE:
// This is intentionally NOT named "background".
private val appBackground =
new Color(
8,
13,
25
)
private val panelBg =
new Color(
13,
20,
37
)
private val borderColor =
new Color(
44,
59,
92
)
private val textColor =
new Color(
235,
240,
255
)
private val mutedColor =
new Color(
145,
158,
190
)
private val accent =
new Color(
109,
125,
255
)
private val success =
new Color(
98,
218,
154
)
private val categories =
Array(
"Websites",
"Links",
"Bio Pages",
"Apps",
"Games",
"Landing Pages",
"UI Designs",
"Tools",
"Portfolios",
"Forms",
"Dashboards",
"API / JSON",
"Components",
"Icons",
"Creative Projects",
"Blank Project"
)
private var selectedCategory =
"Websites"
private var currentImage:
Option[ImageProfile] =
None
private var generationCount =
0
private var projectCode =
ProjectGenerator.generate(
selectedCategory,
"Create a modern professional project.",
currentImage,
generationCount
)
// ==========================================================
// COMPONENTS
// ==========================================================
private val categoryModel =
new DefaultListModel[String]()
private val categoryList =
new JList[String](
categoryModel
)
private val searchField =
new JTextField()
private val promptArea =
new JTextArea()
private val codeArea =
new JTextArea()
private val previewPane =
new JEditorPane()
private val outputCards =
new JPanel(
new CardLayout()
)
private val statusLabel =
new JLabel(
"Ready"
)
private val imageNameLabel =
new JLabel(
"No reference image"
)
private val imagePreviewLabel =
new JLabel()
private val generateButton =
new JButton(
"Generate"
)
private val regenerateButton =
new JButton(
"Regenerate"
)
private val previewButton =
new JButton(
"Preview"
)
private val editButton =
new JButton(
"Edit Code"
)
private val copyButton =
new JButton(
"Copy Code"
)
private val downloadButton =
new JButton(
"Download Code"
)
private val saveProjectButton =
new JButton(
"Save Project"
)
private val openProjectButton =
new JButton(
"Open Project"
)
private val newProjectButton =
new JButton(
"New Project"
)
private val uploadImageButton =
new JButton(
"Upload Image"
)
private val removeImageButton =
new JButton(
"Remove Image"
)
private val previewCard =
new JPanel(
new BorderLayout()
)
private val codeCard =
new JPanel(
new BorderLayout()
)
setBackground(
appBackground
)
// ==========================================================
// HELPERS
// ==========================================================
private def configureButton(
button: JButton,
primary: Boolean
): Unit = {
button.setFocusPainted(
false
)
button.setFont(
new Font(
"SansSerif",
Font.BOLD,
12
)
)
button.setBorder(
new EmptyBorder(
9,
13,
9,
13
)
)
if (primary) {
button.setBackground(
accent
)
button.setForeground(
Color.WHITE
)
} else {
button.setBackground(
new Color(
29,
42,
71
)
)
button.setForeground(
new Color(
219,
227,
248
)
)
}
}
private def configureTitleLabel(
label: JLabel,
size: Int
): Unit = {
label.setForeground(
textColor
)
label.setFont(
new Font(
"SansSerif",
Font.BOLD,
size
)
)
}
private def configureMutedLabel(
label: JLabel
): Unit = {
label.setForeground(
mutedColor
)
label.setFont(
new Font(
"SansSerif",
Font.PLAIN,
11
)
)
}
// ==========================================================
// TOP BAR
// ==========================================================
private val topBar =
new JPanel(
new BorderLayout(
12,
0
)
)
topBar.setBackground(
panelBg
)
topBar.setBorder(
new CompoundBorder(
new MatteBorder(
0,
0,
1,
0,
borderColor
),
new EmptyBorder(
12,
14,
12,
14
)
)
)
private val brandPanel =
new JPanel()
brandPanel.setOpaque(
false
)
brandPanel.setLayout(
new BoxLayout(
brandPanel,
BoxLayout.Y_AXIS
)
)
private val brandLabel =
new JLabel(
"DEVELOPER CREATOR PLATFORM"
)
configureTitleLabel(
brandLabel,
17
)
private val brandSub =
new JLabel(
"A to Z creation workspace � local generation studio"
)
configureMutedLabel(
brandSub
)
brandPanel.add(
brandLabel
)
brandPanel.add(
Box.createVerticalStrut(3)
)
brandPanel.add(
brandSub
)
private val topActions =
new JPanel(
new FlowLayout(
FlowLayout.RIGHT,
7,
0
)
)
topActions.setOpaque(
false
)
configureButton(
newProjectButton,
false
)
configureButton(
saveProjectButton,
false
)
configureButton(
openProjectButton,
false
)
configureButton(
downloadButton,
false
)
topActions.add(
newProjectButton
)
topActions.add(
saveProjectButton
)
topActions.add(
openProjectButton
)
topActions.add(
downloadButton
)
topBar.add(
brandPanel,
BorderLayout.WEST
)
topBar.add(
topActions,
BorderLayout.EAST
)
add(
topBar,
BorderLayout.NORTH
)
// ==========================================================
// LEFT PANEL
// ==========================================================
private val leftPanel =
new JPanel(
new BorderLayout(
0,
10
)
)
leftPanel.setBackground(
panelBg
)
leftPanel.setBorder(
new EmptyBorder(
14,
12,
14,
10
)
)
leftPanel.setPreferredSize(
new Dimension(
205,
0
)
)
private val categoryTitle =
new JLabel(
"CREATE"
)
configureTitleLabel(
categoryTitle,
12
)
private val categorySubtitle =
new JLabel(
"Choose what you want to build"
)
configureMutedLabel(
categorySubtitle
)
private val categoryHeader =
new JPanel()
categoryHeader.setOpaque(
false
)
categoryHeader.setLayout(
new BoxLayout(
categoryHeader,
BoxLayout.Y_AXIS
)
)
categoryHeader.add(
categoryTitle
)
categoryHeader.add(
Box.createVerticalStrut(3)
)
categoryHeader.add(
categorySubtitle
)
searchField.setBackground(
new Color(
9,
15,
29
)
)
searchField.setForeground(
textColor
)
searchField.setCaretColor(
Color.WHITE
)
searchField.setBorder(
new CompoundBorder(
new LineBorder(
borderColor,
1,
true
),
new EmptyBorder(
4,
7,
4,
7
)
)
)
searchField.setPreferredSize(
new Dimension(
170,
36
)
)
private val leftNorth =
new JPanel(
new BorderLayout(
0,
9
)
)
leftNorth.setOpaque(
false
)
leftNorth.add(
categoryHeader,
BorderLayout.NORTH
)
leftNorth.add(
searchField,
BorderLayout.SOUTH
)
private val categoryScroll =
new JScrollPane(
categoryList
)
categoryScroll.setBorder(
new LineBorder(
borderColor,
1,
true
)
)
categoryScroll.getViewport.setBackground(
new Color(
10,
16,
31
)
)
categoryList.setBackground(
new Color(
10,
16,
31
)
)
categoryList.setForeground(
new Color(
205,
215,
240
)
)
categoryList.setFont(
new Font(
"SansSerif",
Font.PLAIN,
13
)
)
categoryList.setFixedCellHeight(
38
)
categoryList.setSelectionBackground(
new Color(
61,
76,
139
)
)
categoryList.setSelectionForeground(
Color.WHITE
)
private val leftFooter =
new JLabel(
"<html>" +
"<div style='color:#71809e;width:165px'>" +
"Prompt + image + category ? generate ? edit ? preview ? export" +
"</div>" +
"</html>"
)
leftPanel.add(
leftNorth,
BorderLayout.NORTH
)
leftPanel.add(
categoryScroll,
BorderLayout.CENTER
)
leftPanel.add(
leftFooter,
BorderLayout.SOUTH
)
var categoryIndex =
0
while (
categoryIndex <
categories.length
) {
categoryModel.addElement(
categories(categoryIndex)
)
categoryIndex += 1
}
categoryList.setSelectedIndex(
0
)
// ==========================================================
// CENTER PANEL
// ==========================================================
private val centerPanel =
new JPanel(
new BorderLayout(
0,
10
)
)
centerPanel.setBackground(
appBackground
)
centerPanel.setBorder(
new EmptyBorder(
14,
10,
14,
10
)
)
private val editorHeader =
new JPanel(
new BorderLayout()
)
editorHeader.setOpaque(
false
)
private val editorTitlePanel =
new JPanel()
editorTitlePanel.setOpaque(
false
)
editorTitlePanel.setLayout(
new BoxLayout(
editorTitlePanel,
BoxLayout.Y_AXIS
)
)
private val editorTitle =
new JLabel(
"Prompt & Generator"
)
configureTitleLabel(
editorTitle,
18
)
private val editorHint =
new JLabel(
"Describe your idea in natural language. The generator turns it into editable code."
)
configureMutedLabel(
editorHint
)
editorTitlePanel.add(
editorTitle
)
editorTitlePanel.add(
Box.createVerticalStrut(4)
)
editorTitlePanel.add(
editorHint
)
private val editorActions =
new JPanel(
new FlowLayout(
FlowLayout.RIGHT,
7,
0
)
)
editorActions.setOpaque(
false
)
configureButton(
generateButton,
true
)
configureButton(
regenerateButton,
false
)
configureButton(
previewButton,
false
)
configureButton(
editButton,
false
)
editorActions.add(
generateButton
)
editorActions.add(
regenerateButton
)
editorActions.add(
previewButton
)
editorActions.add(
editButton
)
editorHeader.add(
editorTitlePanel,
BorderLayout.WEST
)
editorHeader.add(
editorActions,
BorderLayout.EAST
)
promptArea.setLineWrap(
true
)
promptArea.setWrapStyleWord(
true
)
promptArea.setBackground(
new Color(
11,
18,
34
)
)
promptArea.setForeground(
textColor
)
promptArea.setCaretColor(
Color.WHITE
)
promptArea.setFont(
new Font(
"SansSerif",
Font.PLAIN,
15
)
)
promptArea.setBorder(
new EmptyBorder(
16,
16,
16,
16
)
)
promptArea.setText(
"Create a modern professional website for a gaming creator. " +
"Use a bold hero section, project cards, social links, contact form, " +
"responsive layout, dark theme, clean typography, and strong call-to-action."
)
private val promptScroll =
new JScrollPane(
promptArea
)
promptScroll.setBorder(
new LineBorder(
borderColor,
1,
true
)
)
// ==========================================================
// QUICK IDEA
// ==========================================================
private val quickIdeasPanel =
new JPanel(
new BorderLayout()
)
quickIdeasPanel.setBackground(
panelBg
)
quickIdeasPanel.setBorder(
new CompoundBorder(
new LineBorder(
borderColor,
1,
true
),
new EmptyBorder(
10,
12,
10,
12
)
)
)
private val quickLabel =
new JLabel(
"QUICK IDEA"
)
configureTitleLabel(
quickLabel,
11
)
private val quickText =
new JLabel(
"<html>" +
"<div style='color:#9da9c5'>" +
"Try: "Build a futuristic dashboard with analytics, " +
"user cards, a side menu and activity feed."" +
"</div>" +
"</html>"
)
private val quickButton =
new JButton(
"Use Example"
)
configureButton(
quickButton,
false
)
private val quickLeft =
new JPanel()
quickLeft.setOpaque(
false
)
quickLeft.setLayout(
new BoxLayout(
quickLeft,
BoxLayout.Y_AXIS
)
)
quickLeft.add(
quickLabel
)
quickLeft.add(
Box.createVerticalStrut(5)
)
quickLeft.add(
quickText
)
quickIdeasPanel.add(
quickLeft,
BorderLayout.CENTER
)
quickIdeasPanel.add(
quickButton,
BorderLayout.EAST
)
// ==========================================================
// IMAGE PANEL
// ==========================================================
private val uploadPanel =
new JPanel(
new BorderLayout(
10,
0
)
)
uploadPanel.setBackground(
panelBg
)
uploadPanel.setBorder(
new CompoundBorder(
new LineBorder(
borderColor,
1,
true
),
new EmptyBorder(
12,
12,
12,
12
)
)
)
private val uploadTextPanel =
new JPanel()
uploadTextPanel.setOpaque(
false
)
uploadTextPanel.setLayout(
new BoxLayout(
uploadTextPanel,
BoxLayout.Y_AXIS
)
)
private val referenceTitle =
new JLabel(
"REFERENCE IMAGE"
)
configureTitleLabel(
referenceTitle,
11
)
imageNameLabel.setForeground(
mutedColor
)
imageNameLabel.setFont(
new Font(
"SansSerif",
Font.PLAIN,
11
)
)
uploadTextPanel.add(
referenceTitle
)
uploadTextPanel.add(
Box.createVerticalStrut(5)
)
uploadTextPanel.add(
imageNameLabel
)
private val imageButtonsPanel =
new JPanel(
new FlowLayout(
FlowLayout.RIGHT,
6,
0
)
)
imageButtonsPanel.setOpaque(
false
)
configureButton(
uploadImageButton,
false
)
configureButton(
removeImageButton,
false
)
imageButtonsPanel.add(
uploadImageButton
)
imageButtonsPanel.add(
removeImageButton
)
uploadPanel.add(
uploadTextPanel,
BorderLayout.CENTER
)
uploadPanel.add(
imageButtonsPanel,
BorderLayout.EAST
)
centerPanel.add(
editorHeader,
BorderLayout.NORTH
)
private val centerBody =
new JPanel(
new BorderLayout(
0,
10
)
)
centerBody.setOpaque(
false
)
centerBody.add(
promptScroll,
BorderLayout.CENTER
)
private val centerBottom =
new JPanel()
centerBottom.setOpaque(
false
)
centerBottom.setLayout(
new BoxLayout(
centerBottom,
BoxLayout.Y_AXIS
)
)
centerBottom.add(
quickIdeasPanel
)
centerBottom.add(
Box.createVerticalStrut(8)
)
centerBottom.add(
uploadPanel
)
centerBody.add(
centerBottom,
BorderLayout.SOUTH
)
centerPanel.add(
centerBody,
BorderLayout.CENTER
)
// ==========================================================
// RIGHT PANEL
// ==========================================================
private val rightPanel =
new JPanel(
new BorderLayout(
0,
10
)
)
rightPanel.setBackground(
panelBg
)
rightPanel.setBorder(
new EmptyBorder(
14,
10,
14,
12
)
)
rightPanel.setPreferredSize(
new Dimension(
575,
0
)
)
private val rightHeader =
new JPanel(
new BorderLayout()
)
rightHeader.setOpaque(
false
)
private val outputTitlePanel =
new JPanel()
outputTitlePanel.setOpaque(
false
)
outputTitlePanel.setLayout(
new BoxLayout(
outputTitlePanel,
BoxLayout.Y_AXIS
)
)
private val outputTitle =
new JLabel(
"Preview & Output"
)
configureTitleLabel(
outputTitle,
18
)
private val outputSub =
new JLabel(
"Your generated artifact appears here."
)
configureMutedLabel(
outputSub
)
outputTitlePanel.add(
outputTitle
)
outputTitlePanel.add(
Box.createVerticalStrut(4)
)
outputTitlePanel.add(
outputSub
)
private val statusPanel =
new JPanel(
new FlowLayout(
FlowLayout.RIGHT,
5,
0
)
)
statusPanel.setOpaque(
false
)
statusLabel.setForeground(
success
)
statusLabel.setFont(
new Font(
"SansSerif",
Font.BOLD,
11
)
)
statusPanel.add(
statusLabel
)
rightHeader.add(
outputTitlePanel,
BorderLayout.WEST
)
rightHeader.add(
statusPanel,
BorderLayout.EAST
)
// ==========================================================
// PREVIEW
// ==========================================================
previewCard.setBackground(
new Color(
10,
16,
31
)
)
previewCard.setBorder(
new LineBorder(
borderColor,
1,
true
)
)
private val browserBar =
new JPanel(
new BorderLayout()
)
browserBar.setBackground(
new Color(
18,
26,
46
)
)
browserBar.setBorder(
new EmptyBorder(
8,
10,
8,
10
)
)
private val browserDots =
new JLabel(
"? ? ?"
)
browserDots.setForeground(
new Color(
120,
135,
169
)
)
browserDots.setFont(
new Font(
"SansSerif",
Font.BOLD,
12
)
)
private val browserAddress =
new JLabel(
" local://developer-preview"
)
browserAddress.setForeground(
new Color(
146,
160,
192
)
)
browserAddress.setFont(
new Font(
"Monospaced",
Font.PLAIN,
11
)
)
browserBar.add(
browserDots,
BorderLayout.WEST
)
browserBar.add(
browserAddress,
BorderLayout.CENTER
)
previewPane.setContentType(
"text/html"
)
previewPane.setEditable(
false
)
previewPane.putClientProperty(
JEditorPane.HONOR_DISPLAY_PROPERTIES,
java.lang.Boolean.TRUE
)
previewPane.setBorder(
new EmptyBorder(
12,
12,
12,
12
)
)
private val previewScroll =
new JScrollPane(
previewPane
)
previewScroll.setBorder(
null
)
previewCard.add(
browserBar,
BorderLayout.NORTH
)
previewCard.add(
previewScroll,
BorderLayout.CENTER
)
// ==========================================================
// CODE CARD
// ==========================================================
codeArea.setBackground(
new Color(
8,
13,
25
)
)
codeArea.setForeground(
new Color(
211,
220,
243
)
)
codeArea.setCaretColor(
Color.WHITE
)
codeArea.setFont(
new Font(
"Monospaced",
Font.PLAIN,
12
)
)
codeArea.setTabSize(
2
)
codeArea.setLineWrap(
false
)
codeArea.setText(
projectCode
)
private val codeScroll =
new JScrollPane(
codeArea
)
codeScroll.setBorder(
null
)
private val codeToolbar =
new JPanel(
new BorderLayout()
)
codeToolbar.setBackground(
new Color(
18,
26,
46
)
)
codeToolbar.setBorder(
new EmptyBorder(
8,
10,
8,
10
)
)
private val codeLabel =
new JLabel(
"Generated HTML / CSS / UI CODE"
)
codeLabel.setForeground(
new Color(
168,
181,
213
)
)
codeLabel.setFont(
new Font(
"SansSerif",
Font.BOLD,
11
)
)
codeToolbar.add(
codeLabel,
BorderLayout.WEST
)
codeCard.setBackground(
new Color(
8,
13,
25
)
)
codeCard.setBorder(
new LineBorder(
borderColor,
1,
true
)
)
codeCard.add(
codeToolbar,
BorderLayout.NORTH
)
codeCard.add(
codeScroll,
BorderLayout.CENTER
)
outputCards.setOpaque(
false
)
outputCards.add(
previewCard,
"PREVIEW"
)
outputCards.add(
codeCard,
"CODE"
)
private val outputButtonBar =
new JPanel(
new FlowLayout(
FlowLayout.RIGHT,
7,
0
)
)
outputButtonBar.setOpaque(
false
)
configureButton(
copyButton,
false
)
outputButtonBar.add(
copyButton
)
private val outputOuter =
new JPanel(
new BorderLayout(
0,
8
)
)
outputOuter.setOpaque(
false
)
outputOuter.add(
outputCards,
BorderLayout.CENTER
)
outputOuter.add(
outputButtonBar,
BorderLayout.SOUTH
)
rightPanel.add(
rightHeader,
BorderLayout.NORTH
)
rightPanel.add(
outputOuter,
BorderLayout.CENTER
)
// ==========================================================
// SPLITS
// ==========================================================
private val horizontalSplit =
new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
leftPanel,
centerPanel
)
horizontalSplit.setDividerLocation(
205
)
horizontalSplit.setDividerSize(
5
)
horizontalSplit.setBorder(
null
)
horizontalSplit.setBackground(
appBackground
)
private val mainSplit =
new JSplitPane(
JSplitPane.HORIZONTAL_SPLIT,
horizontalSplit,
rightPanel
)
mainSplit.setDividerLocation(
700
)
mainSplit.setDividerSize(
5
)
mainSplit.setBorder(
null
)
mainSplit.setBackground(
appBackground
)
add(
mainSplit,
BorderLayout.CENTER
)
// ==========================================================
// FILTER CATEGORIES
// ==========================================================
private def filterCategories(
filterText: String
): Unit = {
categoryModel.clear()
val lower =
Option(filterText)
.getOrElse("")
.trim
.toLowerCase
var i =
0
while (
i < categories.length
) {
if (
lower.isEmpty ||
categories(i)
.toLowerCase
.contains(lower)
) {
categoryModel.addElement(
categories(i)
)
}
i += 1
}
if (
categoryModel.size() > 0
) {
categoryList.setSelectedIndex(
0
)
}
}
// ==========================================================
// SELECT CATEGORY
// ==========================================================
private def selectCategoryByName(
name: String
): Unit = {
var i =
0
while (
i < categoryModel.size()
) {
if (
categoryModel.getElementAt(i) ==
name
) {
categoryList.setSelectedIndex(
i
)
return
}
i += 1
}
}
// ==========================================================
// CARD LAYOUT
// ==========================================================
private def currentCardLayout:
CardLayout = {
outputCards
.getLayout
.asInstanceOf[CardLayout]
}
// ==========================================================
// PREVIEW
// ==========================================================
private def showPreview(): Unit = {
projectCode =
codeArea.getText
try {
previewPane.setText(
projectCode
)
previewPane.setCaretPosition(
0
)
currentCardLayout.show(
outputCards,
"PREVIEW"
)
statusLabel.setForeground(
success
)
statusLabel.setText(
"Preview updated"
)
} catch {
case ex: Throwable =>
statusLabel.setForeground(
new Color(
244,
160,
110
)
)
statusLabel.setText(
"Preview error: " +
Option(
ex.getMessage
).getOrElse(
"unknown"
)
)
}
}
// ==========================================================
// CODE
// ==========================================================
private def showCode(): Unit = {
projectCode =
codeArea.getText
currentCardLayout.show(
outputCards,
"CODE"
)
codeArea.requestFocusInWindow()
statusLabel.setForeground(
new Color(
174,
194,
248
)
)
statusLabel.setText(
"Editing generated code"
)
}
// ==========================================================
// GENERATE
// ==========================================================
private def generateProject(
forceRegenerate: Boolean
): Unit = {
if (forceRegenerate) {
generationCount += 1
} else if (
generationCount == 0
) {
generationCount = 1
}
val selectedValue =
categoryList.getSelectedValue
if (
selectedValue != null
) {
selectedCategory =
selectedValue
}
val prompt =
promptArea.getText.trim
projectCode =
ProjectGenerator.generate(
selectedCategory,
prompt,
currentImage,
generationCount
)
codeArea.setText(
projectCode
)
codeArea.setCaretPosition(
0
)
previewPane.setText(
projectCode
)
previewPane.setCaretPosition(
0
)
currentCardLayout.show(
outputCards,
"PREVIEW"
)
statusLabel.setForeground(
success
)
statusLabel.setText(
if (forceRegenerate)
"Regenerated � revision " +
generationCount
else
"Generated � revision " +
generationCount
)
}
// ==========================================================
// COPY CODE
// ==========================================================
private def copyCodeToClipboard(): Unit = {
try {
val clipboard =
Toolkit
.getDefaultToolkit
.getSystemClipboard
clipboard.setContents(
new StringSelection(
codeArea.getText
),
null
)
statusLabel.setForeground(
success
)
statusLabel.setText(
"Code copied to clipboard"
)
} catch {
case _: Throwable =>
statusLabel.setForeground(
new Color(
244,
160,
110
)
)
statusLabel.setText(
"Clipboard unavailable"
)
}
}
// ==========================================================
// DOWNLOAD
// ==========================================================
private def chooseDownloadPath:
Option[File] = {
val chooser =
new JFileChooser()
chooser.setDialogTitle(
"Download Generated Code"
)
chooser.setSelectedFile(
new File(
HtmlTools.slug(
selectedCategory
) +
"-" +
HtmlTools.slug(
Option(
promptArea.getText
).getOrElse(
"project"
)
) +
".html"
)
)
val result =
chooser.showSaveDialog(
this
)
if (
result ==
JFileChooser.APPROVE_OPTION
) {
Some(
chooser.getSelectedFile
)
} else {
None
}
}
private def downloadCode(): Unit = {
chooseDownloadPath match {
case Some(file) =>
try {
val parent =
file.getParentFile
if (
parent != null &&
!parent.exists()
) {
parent.mkdirs()
}
Files.write(
file.toPath,
codeArea
.getText
.getBytes(
StandardCharsets.UTF_8
)
)
statusLabel.setForeground(
success
)
statusLabel.setText(
"Downloaded: " +
file.getName
)
} catch {
case ex: Throwable =>
statusLabel.setForeground(
new Color(
244,
160,
110
)
)
statusLabel.setText(
"Download failed: " +
Option(
ex.getMessage
).getOrElse(
"unknown"
)
)
}
case None =>
}
}
// ==========================================================
// SAVE PROJECT
// ==========================================================
private def saveProject(): Unit = {
val chooser =
new JFileChooser()
chooser.setDialogTitle(
"Save Developer Creator Project"
)
chooser.setSelectedFile(
new File(
HtmlTools.slug(
Option(
promptArea.getText
).getOrElse(
"project"
)
) +
".dcp"
)
)
if (
chooser.showSaveDialog(
this
) ==
JFileChooser.APPROVE_OPTION
) {
val file =
chooser.getSelectedFile
try {
val properties =
new java.util.Properties()
properties.setProperty(
"version",
"1"
)
properties.setProperty(
"category",
selectedCategory
)
properties.setProperty(
"generation",
generationCount.toString
)
properties.setProperty(
"prompt",
java.util.Base64
.getEncoder
.encodeToString(
promptArea
.getText
.getBytes(
StandardCharsets.UTF_8
)
)
)
properties.setProperty(
"code",
java.util.Base64
.getEncoder
.encodeToString(
codeArea
.getText
.getBytes(
StandardCharsets.UTF_8
)
)
)
val output =
new FileOutputStream(
file
)
try {
properties.store(
output,
"Developer Creator Project"
)
} finally {
output.close()
}
statusLabel.setForeground(
success
)
statusLabel.setText(
"Project saved: " +
file.getName
)
} catch {
case ex: Throwable =>
statusLabel.setForeground(
new Color(
244,
160,
110
)
)
statusLabel.setText(
"Save failed: " +
Option(
ex.getMessage
).getOrElse(
"unknown"
)
)
}
}
}
// ==========================================================
// OPEN PROJECT
// ==========================================================
private def openProject(): Unit = {
val chooser =
new JFileChooser()
chooser.setDialogTitle(
"Open Developer Creator Project"
)
if (
chooser.showOpenDialog(
this
) ==
JFileChooser.APPROVE_OPTION
) {
val file =
chooser.getSelectedFile
try {
val properties =
new java.util.Properties()
val input =
new FileInputStream(
file
)
try {
properties.load(
input
)
} finally {
input.close()
}
val loadedCategory =
properties.getProperty(
"category",
"Websites"
)
val promptEncoded =
properties.getProperty(
"prompt",
""
)
val codeEncoded =
properties.getProperty(
"code",
""
)
val loadedPrompt =
if (
promptEncoded.isEmpty
) {
""
} else {
new String(
java.util.Base64
.getDecoder
.decode(
promptEncoded
),
StandardCharsets.UTF_8
)
}
val loadedCode =
if (
codeEncoded.isEmpty
) {
""
} else {
new String(
java.util.Base64
.getDecoder
.decode(
codeEncoded
),
StandardCharsets.UTF_8
)
}
val parsedGeneration =
try {
properties
.getProperty(
"generation",
"1"
)
.toInt
} catch {
case _: Throwable =>
1
}
generationCount =
math.max(
1,
parsedGeneration
)
selectCategoryByName(
loadedCategory
)
selectedCategory =
loadedCategory
promptArea.setText(
loadedPrompt
)
projectCode =
if (
loadedCode.nonEmpty
) {
loadedCode
} else {
ProjectGenerator.generate(
selectedCategory,
loadedPrompt,
currentImage,
generationCount
)
}
codeArea.setText(
projectCode
)
previewPane.setText(
projectCode
)
previewPane.setCaretPosition(
0
)
currentCardLayout.show(
outputCards,
"PREVIEW"
)
statusLabel.setForeground(
success
)
statusLabel.setText(
"Project loaded: " +
file.getName
)
} catch {
case ex: Throwable =>
statusLabel.setForeground(
new Color(
244,
160,
110
)
)
statusLabel.setText(
"Open failed: " +
Option(
ex.getMessage
).getOrElse(
"unknown"
)
)
}
}
}
// ==========================================================
// NEW PROJECT
// ==========================================================
private def newProject(): Unit = {
generationCount =
0
currentImage =
None
selectedCategory =
"Websites"
selectCategoryByName(
selectedCategory
)
promptArea.setText(
"Create a modern project for a creative developer. " +
"Include a strong hero section, useful content cards, " +
"responsive structure, a clear navigation area, " +
"and a professional visual style."
)
codeArea.setText(
ProjectGenerator.generate(
selectedCategory,
promptArea.getText,
currentImage,
generationCount
)
)
projectCode =
codeArea.getText
previewPane.setText(
projectCode
)
previewPane.setCaretPosition(
0
)
imageNameLabel.setText(
"No reference image"
)
imagePreviewLabel.setIcon(
null
)
statusLabel.setForeground(
new Color(
174,
194,
248
)
)
statusLabel.setText(
"New project ready"
)
currentCardLayout.show(
outputCards,
"PREVIEW"
)
}
// ==========================================================
// UPLOAD IMAGE
// ==========================================================
private def uploadReferenceImage():
Unit = {
val chooser =
new JFileChooser()
chooser.setDialogTitle(
"Choose Reference Image"
)
val filters =
Array(
"jpg",
"jpeg",
"png",
"gif",
"bmp"
)
chooser.setFileFilter(
new FileNameExtensionFilter(
"Image files",
filters: _*
)
)
if (
chooser.showOpenDialog(
this
) ==
JFileChooser.APPROVE_OPTION
) {
val file =
chooser.getSelectedFile
ImageAnalyzer.analyze(
file
) match {
case Some(profile) =>
currentImage =
Some(profile)
imageNameLabel.setText(
profile.fileName +
" � " +
profile.width +
"�" +
profile.height +
" � " +
profile.dominantHex
)
ImageAnalyzer
.makePreviewIcon(
file,
72,
54
) match {
case Some(icon) =>
imagePreviewLabel.setIcon(
icon
)
case None =>
imagePreviewLabel.setIcon(
null
)
}
statusLabel.setForeground(
success
)
statusLabel.setText(
"Image analyzed � layout + color hints prepared"
)
generateProject(
true
)
case None =>
statusLabel.setForeground(
new Color(
244,
160,
110
)
)
statusLabel.setText(
"Could not read that image"
)
}
}
}
// ==========================================================
// REMOVE IMAGE
// ==========================================================
private def removeReferenceImage():
Unit = {
currentImage =
None
imageNameLabel.setText(
"No reference image"
)
imagePreviewLabel.setIcon(
null
)
statusLabel.setForeground(
new Color(
174,
194,
248
)
)
statusLabel.setText(
"Reference image removed"
)
}
// ==========================================================
// CATEGORY LISTENER
// ==========================================================
categoryList.addListSelectionListener(
new ListSelectionListener {
override def valueChanged(
e: ListSelectionEvent
): Unit = {
if (
!e.getValueIsAdjusting
) {
val value =
categoryList.getSelectedValue
if (
value != null
) {
selectedCategory =
value
editorTitle.setText(
"Prompt & Generator � " +
selectedCategory
)
statusLabel.setForeground(
new Color(
174,
194,
248
)
)
statusLabel.setText(
"Selected: " +
selectedCategory
)
}
}
}
}
)
// ==========================================================
// SEARCH LISTENER
// ==========================================================
searchField
.getDocument
.addDocumentListener(
new DocumentListener {
override def insertUpdate(
e: DocumentEvent
): Unit = {
filterCategories(
searchField.getText
)
}
override def removeUpdate(
e: DocumentEvent
): Unit = {
filterCategories(
searchField.getText
)
}
override def changedUpdate(
e: DocumentEvent
): Unit = {
filterCategories(
searchField.getText
)
}
}
)
// ==========================================================
// QUICK BUTTON
// ==========================================================
quickButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
promptArea.setText(
"Build a futuristic developer dashboard with a left navigation menu, " +
"analytics cards, active projects, recent activity, notifications, " +
"a search bar, responsive layout, dark theme, and polished glass-like panels."
)
selectedCategory =
"Dashboards"
selectCategoryByName(
selectedCategory
)
statusLabel.setForeground(
new Color(
174,
194,
248
)
)
statusLabel.setText(
"Example prompt inserted"
)
promptArea.requestFocusInWindow()
}
}
)
// ==========================================================
// BUTTON EVENTS
// ==========================================================
generateButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
generateProject(
false
)
}
}
)
regenerateButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
generateProject(
true
)
}
}
)
previewButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
showPreview()
}
}
)
editButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
showCode()
}
}
)
copyButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
copyCodeToClipboard()
}
}
)
downloadButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
downloadCode()
}
}
)
saveProjectButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
saveProject()
}
}
)
openProjectButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
openProject()
}
}
)
newProjectButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
newProject()
}
}
)
uploadImageButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
uploadReferenceImage()
}
}
)
removeImageButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
removeReferenceImage()
}
}
)
// ==========================================================
// CODE DOCUMENT LISTENER
// ==========================================================
codeArea
.getDocument
.addDocumentListener(
new DocumentListener {
override def insertUpdate(
e: DocumentEvent
): Unit = {
projectCode =
codeArea.getText
}
override def removeUpdate(
e: DocumentEvent
): Unit = {
projectCode =
codeArea.getText
}
override def changedUpdate(
e: DocumentEvent
): Unit = {
projectCode =
codeArea.getText
}
}
)
// ==========================================================
// KEYBOARD SHORTCUTS
// ==========================================================
private val keyboardActions =
new KeyAdapter {
override def keyPressed(
e: KeyEvent
): Unit = {
if (
e.isControlDown &&
e.getKeyCode ==
KeyEvent.VK_S
) {
saveProject()
} else if (
e.isControlDown &&
e.getKeyCode ==
KeyEvent.VK_O
) {
openProject()
} else if (
e.isControlDown &&
e.getKeyCode ==
KeyEvent.VK_ENTER
) {
generateProject(
false
)
} else if (
e.isControlDown &&
e.isShiftDown &&
e.getKeyCode ==
KeyEvent.VK_C
) {
copyCodeToClipboard()
}
}
}
promptArea.addKeyListener(
keyboardActions
)
codeArea.addKeyListener(
keyboardActions
)
categoryList.addKeyListener(
keyboardActions
)
searchField.addKeyListener(
keyboardActions
)
// ==========================================================
// SPLIT CONFIGURATION
// ==========================================================
private def configureSplitBehavior():
Unit = {
SwingUtilities.invokeLater(
new Runnable {
override def run():
Unit = {
try {
horizontalSplit.setDividerLocation(
205
)
val target =
math.max(
670,
getWidth - 590
)
mainSplit.setDividerLocation(
target
)
} catch {
case _: Throwable =>
}
}
}
)
}
// ==========================================================
// INITIAL PREVIEW
// ==========================================================
previewPane.setText(
projectCode
)
previewPane.setCaretPosition(
0
)
configureSplitBehavior()
setFocusable(
true
)
requestFocusInWindow()
}
// ============================================================
// APPLICATION
// ============================================================
val appFrame =
new JFrame(
"Developer Creator Platform"
)
appFrame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
appFrame.setMinimumSize(
new Dimension(
1120,
720
)
)
// ============================================================
// LOGIN SUCCESS
// ============================================================
val loginPanel =
new LoginPanel(
() => {
val platform =
new DeveloperPlatformPanel(
appFrame
)
appFrame.setContentPane(
platform
)
appFrame.setTitle(
"Developer Creator Platform � A to Z Studio"
)
appFrame.setSize(
1440,
880
)
appFrame.setLocationRelativeTo(
null
)
appFrame.setVisible(
true
)
platform.requestFocusInWindow()
platform.revalidate()
platform.repaint()
}
)
// ============================================================
// SHOW LOGIN
// ============================================================
appFrame.setContentPane(
loginPanel
)
appFrame.setSize(
560,
610
)
appFrame.setLocationRelativeTo(
null
)
appFrame.setVisible(
true
)
loginPanel.requestFocusInWindow()