Code Sketch
yo..............
Category: Programming
import java.awt.BasicStroke
import java.awt.BorderLayout
import java.awt.Color
import java.awt.Cursor
import java.awt.Dimension
import java.awt.FlowLayout
import java.awt.Font
import java.awt.Graphics
import java.awt.Graphics2D
import java.awt.RenderingHints
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import java.awt.event.MouseMotionAdapter
import java.awt.image.BufferedImage
import java.io.File
import javax.imageio.ImageIO
import javax.swing.DefaultListModel
import javax.swing.JButton
import javax.swing.JComboBox
import javax.swing.JColorChooser
import javax.swing.JFileChooser
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.JList
import javax.swing.JOptionPane
import javax.swing.JPanel
import javax.swing.JScrollPane
import javax.swing.JTextField
import javax.swing.ListSelectionModel
import javax.swing.SwingUtilities
import javax.swing.WindowConstants
// ============================================================
// CONSTANTS
// ============================================================
val W = 1000
val H = 600
val CX = 500
val CY = 300
// ============================================================
// COMPONENT REFERENCES
// IMPORTANT: DECLARED FIRST
// ============================================================
var frame: JFrame = null
var canvas: JPanel = null
var status: JLabel = null
var pencilButton: JButton = null
var eraserButton: JButton = null
var undoButton: JButton = null
var redoButton: JButton = null
var clearButton: JButton = null
var saveButton: JButton = null
var colorizeButton: JButton = null
var threeDButton: JButton = null
var gridButton: JButton = null
var zoomInButton: JButton = null
var zoomOutButton: JButton = null
var resetButton: JButton = null
var drawButton: JButton = null
var randomButton: JButton = null
var customButton: JButton = null
var toolBox: JComboBox[String] = null
var sizeBox: JComboBox[String] = null
var styleBox: JComboBox[String] = null
var writeField: JTextField = null
var thingList: JList[String] = null
// ============================================================
// APPLICATION STATE
// ============================================================
var currentColor = Color.BLACK
var brushSize = 6.0f
var currentTool = "PENCIL"
var zoom = 1.0
var drawing = false
var lastX = 0
var lastY = 0
var startX = 0
var startY = 0
var gridOn = false
var themeName = "SKY"
var styleName = "NORMAL"
var undoImage: BufferedImage = null
var redoImage: BufferedImage = null
// ============================================================
// IMAGE
// ============================================================
val image =
new BufferedImage(
W,
H,
BufferedImage.TYPE_INT_RGB
)
val imageGraphics =
image.createGraphics()
imageGraphics.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
imageGraphics.setRenderingHint(
RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY
)
imageGraphics.setColor(
Color.WHITE
)
imageGraphics.fillRect(
0,
0,
W,
H
)
// ============================================================
// BASIC HELPERS
// ============================================================
def setStatus(
text: String
): Unit = {
if (
status != null
) {
status.setText(
text
)
}
}
def refresh(): Unit = {
if (
canvas != null
) {
canvas.repaint()
}
}
def clearImage(): Unit = {
imageGraphics.setColor(
Color.WHITE
)
imageGraphics.fillRect(
0,
0,
W,
H
)
refresh()
}
def copyImage(
source: BufferedImage
): BufferedImage = {
val result =
new BufferedImage(
W,
H,
BufferedImage.TYPE_INT_RGB
)
val g =
result.createGraphics()
g.drawImage(
source,
0,
0,
null
)
g.dispose()
result
}
def rememberUndo(): Unit = {
undoImage =
copyImage(
image
)
redoImage =
null
}
def restore(
source: BufferedImage
): Unit = {
imageGraphics.setColor(
Color.WHITE
)
imageGraphics.fillRect(
0,
0,
W,
H
)
imageGraphics.drawImage(
source,
0,
0,
null
)
refresh()
}
def makeButton(
text: String
): JButton = {
val b =
new JButton(
text
)
b.setFont(
new Font(
"Arial",
Font.BOLD,
12
)
)
b.setFocusable(
false
)
b
}
// ============================================================
// SAVE FUNCTION
// IMPORTANT: BEFORE BUTTON ACTIONS
// ============================================================
def saveImage(
source: BufferedImage,
owner: JFrame
): Unit = {
val chooser =
new JFileChooser()
chooser.setDialogTitle(
"Save PNG Image"
)
val result =
chooser.showSaveDialog(
owner
)
if (
result ==
JFileChooser.APPROVE_OPTION
) {
try {
var file =
chooser.getSelectedFile
if (
!file.getName
.toLowerCase
.endsWith(".png")
) {
file =
new File(
file.getAbsolutePath +
".png"
)
}
ImageIO.write(
source,
"png",
file
)
setStatus(
"IMAGE SAVED!"
)
} catch {
case ex: Exception =>
JOptionPane.showMessageDialog(
owner,
ex.getMessage,
"SAVE ERROR",
JOptionPane.ERROR_MESSAGE
)
}
}
}
// ============================================================
// MOUSE POSITION
// ============================================================
def shownW(): Int = {
math.max(
1,
(W * zoom).toInt
)
}
def shownH(): Int = {
math.max(
1,
(H * zoom).toInt
)
}
def offsetX(): Int = {
(
canvas.getWidth -
shownW()
) / 2
}
def offsetY(): Int = {
(
canvas.getHeight -
shownH()
) / 2
}
def toImageX(
x: Int
): Int = {
val value =
(
(x - offsetX()) /
zoom
).toInt
math.max(
0,
math.min(
W - 1,
value
)
)
}
def toImageY(
y: Int
): Int = {
val value =
(
(y - offsetY()) /
zoom
).toInt
math.max(
0,
math.min(
H - 1,
value
)
)
}
def insideCanvas(
x: Int,
y: Int
): Boolean = {
x >= offsetX() &&
x < offsetX() + shownW() &&
y >= offsetY() &&
y < offsetY() + shownH()
}
// ============================================================
// DRAW TOOLS
// ============================================================
def spray(
x: Int,
y: Int
): Unit = {
imageGraphics.setColor(
currentColor
)
val r =
math.max(
8,
brushSize.toInt * 2
)
var i = 0
while (
i < 28
) {
val dx =
(
(i * 37) %
(r * 2 + 1)
) - r
val dy =
(
(i * 53) %
(r * 2 + 1)
) - r
if (
dx * dx +
dy * dy <=
r * r
) {
imageGraphics.fillOval(
x + dx,
y + dy,
3,
3
)
}
i += 1
}
}
// ============================================================
// BASIC OBJECT DRAWINGS
// ============================================================
def drawGeneric(
text: String
): Unit = {
clearImage()
val g =
imageGraphics
val hash =
math.abs(
text.hashCode
)
val c =
new Color(
50 + hash % 180,
50 + (hash / 7) % 180,
50 + (hash / 13) % 180
)
g.setColor(
c
)
val shape =
hash % 5
if (
shape == 0
) {
g.fillRoundRect(
CX - 190,
CY - 120,
380,
240,
40,
40
)
} else if (
shape == 1
) {
g.fillOval(
CX - 150,
CY - 150,
300,
300
)
} else if (
shape == 2
) {
val p =
new java.awt.Polygon()
p.addPoint(
CX,
CY - 170
)
p.addPoint(
CX + 170,
CY + 150
)
p.addPoint(
CX - 170,
CY + 150
)
g.fillPolygon(
p
)
} else if (
shape == 3
) {
g.fillRect(
CX - 160,
CY - 140,
320,
280
)
} else {
g.fillOval(
CX - 210,
CY - 100,
420,
200
)
}
g.setColor(
Color.BLACK
)
g.setFont(
new Font(
"Arial",
Font.BOLD,
24
)
)
val label =
text.take(
28
)
val tw =
g.getFontMetrics
.stringWidth(
label
)
g.drawString(
label,
CX - tw / 2,
555
)
g.dispose()
refresh()
}
def drawCar(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
val cy =
CY
g.setColor(
new Color(
220,
45,
50
)
)
g.fillRoundRect(
cx - 270,
cy - 35,
540,
120,
35,
35
)
val roof =
new java.awt.Polygon()
roof.addPoint(
cx - 180,
cy - 35
)
roof.addPoint(
cx - 95,
cy - 140
)
roof.addPoint(
cx + 105,
cy - 140
)
roof.addPoint(
cx + 185,
cy - 35
)
g.fillPolygon(
roof
)
g.setColor(
new Color(
120,
215,
245
)
)
g.fillRect(
cx - 140,
cy - 115,
120,
75
)
g.fillRect(
cx + 20,
cy - 115,
115,
75
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 210,
cy + 25,
95,
95
)
g.fillOval(
cx + 115,
cy + 25,
95,
95
)
g.setColor(
Color.LIGHT_GRAY
)
g.fillOval(
cx - 177,
cy + 57,
30,
30
)
g.fillOval(
cx + 148,
cy + 57,
30,
30
)
g.dispose()
refresh()
}
def drawHouse(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
g.setColor(
new Color(
245,
205,
125
)
)
g.fillRect(
cx - 205,
235,
410,
255
)
val roof =
new java.awt.Polygon()
roof.addPoint(
cx - 260,
235
)
roof.addPoint(
cx,
50
)
roof.addPoint(
cx + 260,
235
)
g.setColor(
new Color(
180,
55,
45
)
)
g.fillPolygon(
roof
)
g.setColor(
new Color(
120,
80,
45
)
)
g.fillRect(
cx - 50,
340,
100,
150
)
g.setColor(
new Color(
70,
190,
240
)
)
g.fillRect(
cx - 160,
275,
75,
75
)
g.fillRect(
cx + 85,
275,
75,
75
)
g.setColor(
new Color(
70,
165,
75
)
)
g.fillRect(
0,
490,
W,
110
)
g.dispose()
refresh()
}
def drawTree(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
g.setColor(
new Color(
70,
165,
75
)
)
g.fillRect(
0,
490,
W,
110
)
g.setColor(
new Color(
135,
82,
45
)
)
g.fillRoundRect(
cx - 45,
280,
90,
215,
25,
25
)
g.setColor(
new Color(
40,
170,
70
)
)
g.fillOval(
cx - 190,
115,
225,
190
)
g.fillOval(
cx - 15,
85,
230,
215
)
g.fillOval(
cx - 105,
35,
230,
215
)
g.dispose()
refresh()
}
def drawRobot(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
val cy =
CY
g.setColor(
new Color(
110,
170,
205
)
)
g.fillRoundRect(
cx - 155,
cy - 5,
310,
215,
35,
35
)
g.setColor(
new Color(
170,
200,
220
)
)
g.fillRoundRect(
cx - 175,
cy - 190,
350,
170,
40,
40
)
g.setColor(
Color.CYAN
)
g.fillOval(
cx - 105,
cy - 140,
60,
60
)
g.fillOval(
cx + 45,
cy - 140,
60,
60
)
g.setColor(
Color.DARK_GRAY
)
g.fillRoundRect(
cx - 85,
cy - 65,
170,
35,
15,
15
)
g.dispose()
refresh()
}
def drawCat(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
val cy =
CY
g.setColor(
new Color(
180,
180,
190
)
)
g.fillOval(
cx - 140,
cy - 5,
280,
220
)
g.fillOval(
cx - 130,
cy - 160,
260,
210
)
val leftEar =
new java.awt.Polygon()
leftEar.addPoint(
cx - 110,
cy - 120
)
leftEar.addPoint(
cx - 75,
cy - 220
)
leftEar.addPoint(
cx - 25,
cy - 140
)
val rightEar =
new java.awt.Polygon()
rightEar.addPoint(
cx + 110,
cy - 120
)
rightEar.addPoint(
cx + 75,
cy - 220
)
rightEar.addPoint(
cx + 25,
cy - 140
)
g.fillPolygon(
leftEar
)
g.fillPolygon(
rightEar
)
g.setColor(
new Color(
70,
190,
95
)
)
g.fillOval(
cx - 75,
cy - 85,
45,
45
)
g.fillOval(
cx + 30,
cy - 85,
45,
45
)
g.dispose()
refresh()
}
def drawDog(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
val cy =
CY
g.setColor(
new Color(
180,
120,
70
)
)
g.fillOval(
cx - 160,
cy - 20,
320,
205
)
g.fillOval(
cx - 135,
cy - 170,
270,
230
)
g.setColor(
new Color(
120,
75,
45
)
)
g.fillOval(
cx - 170,
cy - 120,
75,
150
)
g.fillOval(
cx + 95,
cy - 120,
75,
150
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 70,
cy - 85,
22,
25
)
g.fillOval(
cx + 48,
cy - 85,
22,
25
)
g.fillOval(
cx - 22,
cy - 35,
44,
32
)
g.dispose()
refresh()
}
def drawBird(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
val cy =
CY
g.setColor(
new Color(
120,
215,
255
)
)
g.fillRect(
0,
0,
W,
H
)
g.setColor(
new Color(
60,
130,
225
)
)
g.fillOval(
cx - 145,
cy - 90,
285,
180
)
g.fillOval(
cx + 60,
cy - 145,
135,
130
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx + 140,
cy - 105,
18,
18
)
g.dispose()
refresh()
}
def drawFish(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
val cy =
CY
g.setColor(
new Color(
65,
155,
230
)
)
g.fillOval(
cx - 175,
cy - 90,
350,
180
)
val tail =
new java.awt.Polygon()
tail.addPoint(
cx + 150,
cy
)
tail.addPoint(
cx + 260,
cy - 90
)
tail.addPoint(
cx + 260,
cy + 90
)
g.fillPolygon(
tail
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 100,
cy - 35,
22,
22
)
g.dispose()
refresh()
}
def drawFlower(): Unit = {
clearImage()
val g =
imageGraphics
val cx =
CX
val cy =
220
g.setColor(
new Color(
45,
155,
60
)
)
g.setStroke(
new BasicStroke(
15,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
cx,
cy + 55,
cx,
510
)
val flowerColors =
Array(
Color.RED,
Color.PINK,
Color.MAGENTA,
Color.ORANGE,
new Color(145,80,220),
new Color(255,80,120)
)
var i = 0
while (
i < 6
) {
val a =
i * math.Pi / 3.0
val x =
cx +
(math.cos(a) * 80).toInt -
50
val y =
cy +
(math.sin(a) * 80).toInt -
50
g.setColor(
flowerColors(i)
)
g.fillOval(
x,
y,
100,
100
)
i += 1
}
g.setColor(
Color.YELLOW
)
g.fillOval(
cx - 50,
cy - 50,
100,
100
)
g.dispose()
refresh()
}
def drawStar(): Unit = {
clearImage()
val g =
imageGraphics
val p =
new java.awt.Polygon()
var i = 0
while (
i < 10
) {
val a =
-math.Pi / 2 +
i * math.Pi / 5.0
val r =
if (
i % 2 == 0
) {
190.0
} else {
80.0
}
p.addPoint(
CX +
(math.cos(a) * r).toInt,
CY +
(math.sin(a) * r).toInt
)
i += 1
}
g.setColor(
new Color(
255,
210,
0
)
)
g.fillPolygon(
p
)
g.dispose()
refresh()
}
def drawHeart(): Unit = {
clearImage()
val g =
imageGraphics
val p =
new java.awt.geom.Path2D.Double()
p.moveTo(
CX,
CY + 190
)
p.curveTo(
CX - 270,
CY + 20,
CX - 170,
CY - 175,
CX,
CY - 45
)
p.curveTo(
CX + 170,
CY - 175,
CX + 270,
CY + 20,
CX,
CY + 190
)
g.setColor(
Color.RED
)
g.fill(
p
)
g.dispose()
refresh()
}
def drawFood(): Unit = {
clearImage()
val g =
imageGraphics
g.setColor(
new Color(
240,
175,
50
)
)
g.fillOval(
CX - 190,
CY - 100,
380,
200
)
g.setColor(
Color.RED
)
g.fillOval(
CX - 120,
CY - 10,
38,
38
)
g.fillOval(
CX + 45,
CY - 25,
38,
38
)
g.dispose()
refresh()
}
def drawSpace(): Unit = {
clearImage()
val g =
imageGraphics
g.setColor(
new Color(
5,
10,
35
)
)
g.fillRect(
0,
0,
W,
H
)
g.setColor(
Color.WHITE
)
var i = 0
while (
i < 100
) {
val x =
(i * 73) %
W
val y =
(i * 43) %
400
val s =
3 + (i % 3)
g.fillOval(
x,
y,
s,
s
)
i += 1
}
g.setColor(
new Color(
70,
140,
240
)
)
g.fillOval(
CX - 120,
CY - 120,
240,
240
)
g.dispose()
refresh()
}
// ============================================================
// TEXT TO DRAW
// ============================================================
def drawFromText(
input: String
): Unit = {
val t =
input
.trim
.toLowerCase
if (
t.length == 0
) {
setStatus(
"WRITE SOMETHING FIRST!"
)
return
}
rememberUndo()
if (
t.indexOf("car") >= 0 ||
t.indexOf("auto") >= 0 ||
t.indexOf("taxi") >= 0 ||
t.indexOf("bus") >= 0 ||
t.indexOf("truck") >= 0 ||
t.indexOf("bike") >= 0 ||
t.indexOf("bicycle") >= 0 ||
t.indexOf("scooter") >= 0
) {
drawCar()
} else if (
t.indexOf("house") >= 0 ||
t.indexOf("home") >= 0 ||
t.indexOf("school") >= 0 ||
t.indexOf("castle") >= 0 ||
t.indexOf("palace") >= 0
) {
drawHouse()
} else if (
t.indexOf("tree") >= 0 ||
t.indexOf("forest") >= 0 ||
t.indexOf("jungle") >= 0 ||
t.indexOf("plant") >= 0
) {
drawTree()
} else if (
t.indexOf("robot") >= 0
) {
drawRobot()
} else if (
t.indexOf("cat") >= 0 ||
t.indexOf("kitten") >= 0
) {
drawCat()
} else if (
t.indexOf("dog") >= 0 ||
t.indexOf("puppy") >= 0
) {
drawDog()
} else if (
t.indexOf("bird") >= 0 ||
t.indexOf("eagle") >= 0 ||
t.indexOf("parrot") >= 0 ||
t.indexOf("peacock") >= 0
) {
drawBird()
} else if (
t.indexOf("fish") >= 0 ||
t.indexOf("shark") >= 0 ||
t.indexOf("whale") >= 0 ||
t.indexOf("dolphin") >= 0
) {
drawFish()
} else if (
t.indexOf("flower") >= 0 ||
t.indexOf("rose") >= 0
) {
drawFlower()
} else if (
t.indexOf("star") >= 0
) {
drawStar()
} else if (
t.indexOf("heart") >= 0
) {
drawHeart()
} else if (
t.indexOf("pizza") >= 0 ||
t.indexOf("burger") >= 0 ||
t.indexOf("cake") >= 0 ||
t.indexOf("food") >= 0
) {
drawFood()
} else if (
t.indexOf("planet") >= 0 ||
t.indexOf("earth") >= 0 ||
t.indexOf("mars") >= 0 ||
t.indexOf("jupiter") >= 0 ||
t.indexOf("saturn") >= 0 ||
t.indexOf("moon") >= 0 ||
t.indexOf("space") >= 0 ||
t.indexOf("galaxy") >= 0
) {
drawSpace()
} else {
drawGeneric(
input
)
}
setStatus(
"DRAW COMPLETE: " +
input
)
refresh()
}
// ============================================================
// 1000+ THINGS
// ============================================================
val baseThings =
Array(
"car",
"bus",
"truck",
"bike",
"bicycle",
"motorcycle",
"scooter",
"taxi",
"train",
"metro",
"tram",
"airplane",
"jet",
"helicopter",
"rocket",
"spaceship",
"boat",
"ship",
"yacht",
"submarine",
"ambulance",
"fire truck",
"tractor",
"tank",
"house",
"home",
"school",
"hospital",
"hotel",
"shop",
"store",
"office",
"bank",
"library",
"museum",
"castle",
"palace",
"tower",
"lighthouse",
"stadium",
"airport",
"station",
"factory",
"restaurant",
"cafe",
"cinema",
"garage",
"barn",
"bridge",
"dam",
"tree",
"forest",
"jungle",
"plant",
"flower",
"rose",
"sun",
"moon",
"star",
"cloud",
"rain",
"rainbow",
"mountain",
"hill",
"river",
"lake",
"waterfall",
"volcano",
"island",
"beach",
"garden",
"desert",
"snowman",
"cactus",
"leaf",
"grass",
"cat",
"kitten",
"dog",
"puppy",
"lion",
"tiger",
"leopard",
"cheetah",
"elephant",
"giraffe",
"zebra",
"horse",
"pony",
"cow",
"buffalo",
"goat",
"sheep",
"pig",
"chicken",
"duck",
"eagle",
"parrot",
"peacock",
"owl",
"crow",
"pigeon",
"sparrow",
"penguin",
"fish",
"shark",
"whale",
"dolphin",
"octopus",
"turtle",
"rabbit",
"bunny",
"mouse",
"hamster",
"bear",
"panda",
"fox",
"wolf",
"deer",
"camel",
"kangaroo",
"monkey",
"gorilla",
"snake",
"crocodile",
"frog",
"butterfly",
"bee",
"spider",
"boy",
"girl",
"man",
"woman",
"person",
"baby",
"child",
"teacher",
"doctor",
"nurse",
"farmer",
"soldier",
"king",
"queen",
"prince",
"princess",
"superhero",
"pirate",
"astronaut",
"chef",
"scientist",
"engineer",
"artist",
"student",
"robot",
"apple",
"banana",
"orange",
"mango",
"watermelon",
"grapes",
"strawberry",
"pineapple",
"coconut",
"lemon",
"pizza",
"burger",
"sandwich",
"cake",
"donut",
"ice cream",
"chocolate",
"cookie",
"bread",
"rice",
"noodles",
"fries",
"egg",
"cheese",
"cupcake",
"candy",
"popcorn",
"carrot",
"potato",
"tomato",
"pumpkin",
"football",
"cricket",
"tennis",
"basketball",
"baseball",
"hockey",
"golf",
"trophy",
"medal",
"ball",
"bat",
"racket",
"skateboard",
"surfboard",
"heart",
"smiley",
"circle",
"square",
"triangle",
"diamond",
"arrow",
"planet",
"earth",
"mars",
"jupiter",
"saturn",
"galaxy",
"universe",
"computer",
"laptop",
"phone",
"tablet",
"camera",
"television",
"radio",
"speaker",
"headphones",
"watch",
"clock",
"lamp",
"chair",
"table",
"bed",
"sofa",
"door",
"window",
"book",
"pencil",
"pen",
"bag",
"backpack",
"umbrella",
"shoe",
"hat",
"shirt",
"dress",
"bottle",
"cup",
"glass",
"plate",
"spoon",
"fork",
"key",
"lock",
"gift",
"balloon"
)
val descriptors =
Array(
"cute",
"big",
"small",
"beautiful",
"colorful",
"cool",
"modern",
"classic",
"cartoon",
"realistic",
"fantasy",
"magic",
"futuristic",
"robotic",
"neon",
"golden",
"silver",
"blue",
"red",
"green",
"purple",
"pink",
"orange"
)
val things =
new scala.collection.mutable.ArrayBuffer[String]()
var a =
0
while (
a < baseThings.length
) {
things +=
baseThings(a)
var b =
0
while (
b < descriptors.length
) {
things +=
(
descriptors(b) +
" " +
baseThings(a)
)
b += 1
}
a += 1
}
val scenes =
Array(
"in a park",
"in a city",
"in a forest",
"on a beach",
"at night",
"at sunrise",
"at sunset",
"in space",
"underwater",
"in a garden",
"on a mountain",
"in a village",
"in a fantasy world",
"in a magical world",
"in a cartoon world"
)
var c =
0
while (
c < baseThings.length
) {
var d =
0
while (
d < scenes.length
) {
things +=
(
baseThings(c) +
" " +
scenes(d)
)
d += 1
}
c += 1
}
// ============================================================
// CREATE RIGHT SIDE LIST
// ============================================================
val listModel =
new DefaultListModel[String]()
var li =
0
while (
li < things.length
) {
listModel.addElement(
things(li)
)
li += 1
}
thingList =
new JList[String](
listModel
)
thingList.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION
)
thingList.setVisibleRowCount(
25
)
thingList.setFont(
new Font(
"Arial",
Font.PLAIN,
14
)
)
val scrollPane =
new JScrollPane(
thingList
)
scrollPane.setPreferredSize(
new Dimension(
300,
620
)
)
// ============================================================
// CREATE FRAME
// ============================================================
frame =
new JFrame(
"ULTRA LEGEND SMART DRAW - 1000+ THINGS"
)
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
frame.setSize(
1370,
850
)
frame.setLocationRelativeTo(
null
)
// ============================================================
// CREATE STATUS
// ============================================================
status =
new JLabel(
"READY"
)
status.setFont(
new Font(
"Arial",
Font.BOLD,
15
)
)
// ============================================================
// CREATE CANVAS
// ============================================================
canvas =
new JPanel {
override def paintComponent(
graphics: Graphics
): Unit = {
super.paintComponent(
graphics
)
val g =
graphics.asInstanceOf[
Graphics2D
]
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
g.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC
)
val dw =
shownW()
val dh =
shownH()
val ox =
(getWidth - dw) / 2
val oy =
(getHeight - dh) / 2
g.setColor(
new Color(
230,
230,
230
)
)
g.fillRect(
0,
0,
getWidth,
getHeight
)
g.drawImage(
image,
ox,
oy,
dw,
dh,
null
)
if (
gridOn
) {
g.setColor(
new Color(
0,
0,
0,
35
)
)
var x =
ox
while (
x <= ox + dw
) {
g.drawLine(
x,
oy,
x,
oy + dh
)
x += math.max(
20,
(40 * zoom).toInt
)
}
var y =
oy
while (
y <= oy + dh
) {
g.drawLine(
ox,
y,
ox + dw,
y
)
y += math.max(
20,
(40 * zoom).toInt
)
}
}
}
}
canvas.setCursor(
Cursor.getPredefinedCursor(
Cursor.CROSSHAIR_CURSOR
)
)
// ============================================================
// CREATE BUTTONS
// ============================================================
pencilButton =
makeButton(
"PENCIL"
)
eraserButton =
makeButton(
"ERASER"
)
undoButton =
makeButton(
"UNDO"
)
redoButton =
makeButton(
"REDO"
)
clearButton =
makeButton(
"CLEAR"
)
saveButton =
makeButton(
"SAVE"
)
colorizeButton =
makeButton(
"COLORIZE"
)
threeDButton =
makeButton(
"3D"
)
gridButton =
makeButton(
"GRID"
)
zoomInButton =
makeButton(
"ZOOM +"
)
zoomOutButton =
makeButton(
"ZOOM -"
)
resetButton =
makeButton(
"RESET"
)
drawButton =
makeButton(
"DRAW IT"
)
randomButton =
makeButton(
"RANDOM"
)
customButton =
makeButton(
"CUSTOM COLOR"
)
// ============================================================
// CONTROLS
// ============================================================
toolBox =
new JComboBox[String](
Array(
"PENCIL",
"ERASER",
"LINE",
"RECTANGLE",
"ELLIPSE",
"SPRAY"
)
)
sizeBox =
new JComboBox[String](
Array(
"2",
"3",
"4",
"6",
"8",
"10",
"14",
"18",
"24",
"30",
"40",
"50"
)
)
sizeBox.setSelectedItem(
"6"
)
styleBox =
new JComboBox[String](
Array(
"NORMAL",
"3D",
"GLOSSY",
"NEON",
"COMIC",
"MAGIC",
"GOLD"
)
)
writeField =
new JTextField(
"CAR",
15
)
// ============================================================
// TOOLBAR
// ============================================================
val toolbar =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
4,
4
)
)
toolbar.add(pencilButton)
toolbar.add(eraserButton)
toolbar.add(undoButton)
toolbar.add(redoButton)
toolbar.add(clearButton)
toolbar.add(saveButton)
toolbar.add(colorizeButton)
toolbar.add(threeDButton)
toolbar.add(gridButton)
toolbar.add(zoomInButton)
toolbar.add(zoomOutButton)
toolbar.add(resetButton)
toolbar.add(
new JLabel(
"TOOL:"
)
)
toolbar.add(
toolBox
)
toolbar.add(
new JLabel(
"SIZE:"
)
)
toolbar.add(
sizeBox
)
toolbar.add(
new JLabel(
"STYLE:"
)
)
toolbar.add(
styleBox
)
toolbar.add(
new JLabel(
"WRITE:"
)
)
toolbar.add(
writeField
)
toolbar.add(
drawButton
)
toolbar.add(
randomButton
)
// ============================================================
// COLORS
// ============================================================
def addColor(
c: Color
): Unit = {
val b =
new JButton(
" "
)
b.setPreferredSize(
new Dimension(
22,
22
)
)
b.setBackground(
c
)
b.setOpaque(
true
)
b.setFocusable(
false
)
b.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentColor =
c
currentTool =
"PENCIL"
toolBox.setSelectedItem(
"PENCIL"
)
setStatus(
"COLOR SELECTED"
)
}
}
)
toolbar.add(
b
)
}
addColor(Color.BLACK)
addColor(Color.RED)
addColor(Color.BLUE)
addColor(Color.GREEN)
addColor(Color.YELLOW)
addColor(Color.ORANGE)
addColor(Color.MAGENTA)
addColor(Color.CYAN)
addColor(Color.PINK)
toolbar.add(
customButton
)
customButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val c =
JColorChooser.showDialog(
frame,
"CUSTOM COLOR",
currentColor
)
if (
c != null
) {
currentColor =
c
currentTool =
"PENCIL"
toolBox.setSelectedItem(
"PENCIL"
)
setStatus(
"CUSTOM COLOR SELECTED"
)
}
}
}
)
// ============================================================
// TOOL BUTTONS
// ============================================================
pencilButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentTool =
"PENCIL"
toolBox.setSelectedItem(
"PENCIL"
)
setStatus(
"PENCIL ACTIVE"
)
}
}
)
eraserButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentTool =
"ERASER"
toolBox.setSelectedItem(
"ERASER"
)
setStatus(
"ERASER ACTIVE"
)
}
}
)
toolBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentTool =
toolBox
.getSelectedItem
.toString
setStatus(
"TOOL: " +
currentTool
)
}
}
)
sizeBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
try {
brushSize =
sizeBox
.getSelectedItem
.toString
.toFloat
} catch {
case _: Exception =>
}
}
}
)
// ============================================================
// SELECT THING
// ============================================================
thingList.addMouseListener(
new MouseAdapter {
override def mouseClicked(
e: MouseEvent
): Unit = {
val value =
thingList.getSelectedValue
if (
value != null
) {
writeField.setText(
value
)
setStatus(
"SELECTED: " +
value
)
}
}
}
)
// ============================================================
// DRAW IT
// ============================================================
drawButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
drawFromText(
writeField.getText
)
}
}
)
writeField.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
drawFromText(
writeField.getText
)
}
}
)
// ============================================================
// RANDOM
// ============================================================
val randomGenerator =
new scala.util.Random()
randomButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val index =
randomGenerator.nextInt(
things.length
)
val value =
things(index)
writeField.setText(
value
)
thingList.setSelectedValue(
value,
true
)
drawFromText(
value
)
}
}
)
// ============================================================
// UNDO
// ============================================================
undoButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
undoImage != null
) {
redoImage =
copyImage(
image
)
restore(
undoImage
)
undoImage =
null
setStatus(
"UNDO COMPLETE"
)
}
}
}
)
// ============================================================
// REDO
// ============================================================
redoButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
redoImage != null
) {
undoImage =
copyImage(
image
)
restore(
redoImage
)
redoImage =
null
setStatus(
"REDO COMPLETE"
)
}
}
}
)
// ============================================================
// CLEAR
// ============================================================
clearButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
rememberUndo()
clearImage()
setStatus(
"CANVAS CLEARED"
)
}
}
)
// ============================================================
// SAVE
// ============================================================
saveButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
saveImage(
image,
frame
)
}
}
)
// ============================================================
// GRID
// ============================================================
gridButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
gridOn =
!gridOn
refresh()
if (
gridOn
) {
setStatus(
"GRID ON"
)
} else {
setStatus(
"GRID OFF"
)
}
}
}
)
// ============================================================
// ZOOM +
// ============================================================
zoomInButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
zoom =
math.min(
2.5,
zoom + 0.10
)
refresh()
setStatus(
"ZOOM " +
math.round(
zoom * 100
) +
"%"
)
}
}
)
// ============================================================
// ZOOM -
// ============================================================
zoomOutButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
zoom =
math.max(
0.50,
zoom - 0.10
)
refresh()
setStatus(
"ZOOM " +
math.round(
zoom * 100
) +
"%"
)
}
}
)
// ============================================================
// RESET
// ============================================================
resetButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
zoom =
1.0
gridOn =
false
themeName =
"SKY"
styleName =
"NORMAL"
refresh()
setStatus(
"RESET COMPLETE"
)
}
}
)
// ============================================================
// MOUSE PRESS
// ============================================================
canvas.addMouseListener(
new MouseAdapter {
override def mousePressed(
e: MouseEvent
): Unit = {
if (
!insideCanvas(
e.getX,
e.getY
)
) {
drawing =
false
return
}
rememberUndo()
drawing =
true
startX =
toImageX(
e.getX
)
startY =
toImageY(
e.getY
)
lastX =
startX
lastY =
startY
if (
currentTool ==
"PENCIL"
) {
imageGraphics.setColor(
currentColor
)
val s =
math.max(
1,
brushSize.toInt
)
imageGraphics.fillOval(
startX - s / 2,
startY - s / 2,
s,
s
)
}
if (
currentTool ==
"ERASER"
) {
imageGraphics.setColor(
Color.WHITE
)
val s =
math.max(
1,
brushSize.toInt
)
imageGraphics.fillOval(
startX - s / 2,
startY - s / 2,
s,
s
)
}
if (
currentTool ==
"SPRAY"
) {
spray(
startX,
startY
)
}
refresh()
}
override def mouseReleased(
e: MouseEvent
): Unit = {
if (
!drawing
) {
return
}
val ex =
toImageX(
e.getX
)
val ey =
toImageY(
e.getY
)
if (
currentTool ==
"LINE"
) {
imageGraphics.setColor(
currentColor
)
imageGraphics.setStroke(
new BasicStroke(
brushSize
)
)
imageGraphics.drawLine(
startX,
startY,
ex,
ey
)
}
if (
currentTool ==
"RECTANGLE"
) {
imageGraphics.setColor(
currentColor
)
imageGraphics.setStroke(
new BasicStroke(
brushSize
)
)
val x =
math.min(
startX,
ex
)
val y =
math.min(
startY,
ey
)
val ww =
math.abs(
ex - startX
)
val hh =
math.abs(
ey - startY
)
imageGraphics.drawRect(
x,
y,
ww,
hh
)
}
if (
currentTool ==
"ELLIPSE"
) {
imageGraphics.setColor(
currentColor
)
imageGraphics.setStroke(
new BasicStroke(
brushSize
)
)
val x =
math.min(
startX,
ex
)
val y =
math.min(
startY,
ey
)
val ww =
math.abs(
ex - startX
)
val hh =
math.abs(
ey - startY
)
imageGraphics.drawOval(
x,
y,
ww,
hh
)
}
drawing =
false
refresh()
}
}
)
// ============================================================
// MOUSE DRAG
// ============================================================
canvas.addMouseMotionListener(
new MouseMotionAdapter {
override def mouseDragged(
e: MouseEvent
): Unit = {
if (
!drawing
) {
return
}
if (
!insideCanvas(
e.getX,
e.getY
)
) {
return
}
val x =
toImageX(
e.getX
)
val y =
toImageY(
e.getY
)
if (
currentTool ==
"PENCIL"
) {
imageGraphics.setColor(
currentColor
)
imageGraphics.setStroke(
new BasicStroke(
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
imageGraphics.drawLine(
lastX,
lastY,
x,
y
)
}
if (
currentTool ==
"ERASER"
) {
imageGraphics.setColor(
Color.WHITE
)
imageGraphics.setStroke(
new BasicStroke(
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
imageGraphics.drawLine(
lastX,
lastY,
x,
y
)
}
if (
currentTool ==
"SPRAY"
) {
spray(
x,
y
)
}
lastX =
x
lastY =
y
refresh()
}
}
)
// ============================================================
// COLORIZE
// ============================================================
val backgroundNames =
Array(
"SKY",
"SUNNY",
"SUNRISE",
"SUNSET",
"NIGHT",
"STAR NIGHT",
"SPACE",
"GALAXY",
"OCEAN",
"UNDERWATER",
"BEACH",
"ISLAND",
"FOREST",
"JUNGLE",
"MOUNTAIN",
"SNOW",
"ICE",
"DESERT",
"RAINBOW",
"CITY",
"CITY NIGHT",
"NEON CITY",
"FUTURE CITY",
"MAGIC",
"FANTASY",
"CANDY WORLD",
"PINK DREAM",
"BLUE DREAM",
"PURPLE DREAM",
"GOLDEN WORLD",
"ROYAL WORLD",
"FIRE WORLD",
"VOLCANO",
"SPRING",
"SUMMER",
"AUTUMN",
"WINTER",
"DREAM WORLD"
)
def backgroundColor(
theme: String
): Array[Color] = {
val t =
theme.toUpperCase
if (
t.indexOf("SUNSET") >= 0
) {
Array(
new Color(255,120,80),
new Color(100,50,160)
)
} else if (
t.indexOf("NIGHT") >= 0
) {
Array(
new Color(10,20,70),
new Color(60,45,125)
)
} else if (
t.indexOf("SPACE") >= 0 ||
t.indexOf("GALAXY") >= 0
) {
Array(
new Color(3,5,25),
new Color(70,10,110)
)
} else if (
t.indexOf("OCEAN") >= 0 ||
t.indexOf("UNDERWATER") >= 0
) {
Array(
new Color(80,215,255),
new Color(10,80,180)
)
} else if (
t.indexOf("FOREST") >= 0 ||
t.indexOf("JUNGLE") >= 0
) {
Array(
new Color(170,235,190),
new Color(45,145,70)
)
} else if (
t.indexOf("DESERT") >= 0
) {
Array(
new Color(255,220,145),
new Color(205,145,80)
)
} else if (
t.indexOf("MAGIC") >= 0 ||
t.indexOf("FANTASY") >= 0
) {
Array(
new Color(215,190,255),
new Color(100,50,165)
)
} else if (
t.indexOf("GOLD") >= 0
) {
Array(
new Color(255,235,130),
new Color(200,140,35)
)
} else if (
t.indexOf("FIRE") >= 0
) {
Array(
new Color(255,155,70),
new Color(180,35,35)
)
} else {
Array(
new Color(170,225,255),
new Color(100,190,110)
)
}
}
def makeColorized(
theme: String,
style: String
): BufferedImage = {
val colors =
backgroundColor(
theme
)
val result =
new BufferedImage(
W,
H,
BufferedImage.TYPE_INT_RGB
)
val g =
result.createGraphics()
g.setPaint(
new java.awt.GradientPaint(
0,
0,
colors(0),
0,
H,
colors(1)
)
)
g.fillRect(
0,
0,
W,
H
)
var x =
0
while (
x < W
) {
var y =
0
while (
y < H
) {
val rgb =
image.getRGB(
x,
y
)
val r =
(rgb >> 16) & 255
val gr =
(rgb >> 8) & 255
val b =
rgb & 255
if (
r < 245 ||
gr < 245 ||
b < 245
) {
result.setRGB(
x,
y,
rgb
)
}
y += 1
}
x += 1
}
if (
style ==
"NEON"
) {
g.setColor(
new Color(
0,
255,
255,
140
)
)
g.setStroke(
new BasicStroke(
10
)
)
g.drawRoundRect(
10,
10,
980,
580,
25,
25
)
}
if (
style ==
"GOLD"
) {
g.setColor(
new Color(
255,
215,
70,
140
)
)
g.setStroke(
new BasicStroke(
10
)
)
g.drawRoundRect(
10,
10,
980,
580,
25,
25
)
}
if (
style ==
"COMIC"
) {
g.setColor(
Color.BLACK
)
g.setStroke(
new BasicStroke(
8
)
)
g.drawRoundRect(
8,
8,
984,
584,
25,
25
)
}
g.dispose()
result
}
// ============================================================
// COLORIZE DIALOG
// ============================================================
colorizeButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val bg =
new JComboBox[String](
backgroundNames
)
val st =
new JComboBox[String](
Array(
"NORMAL",
"3D",
"GLOSSY",
"NEON",
"COMIC",
"MAGIC",
"GOLD"
)
)
val panel =
new JPanel(
new FlowLayout(
FlowLayout.LEFT
)
)
panel.add(
new JLabel(
"BACKGROUND:"
)
)
panel.add(
bg
)
panel.add(
new JLabel(
"STYLE:"
)
)
panel.add(
st
)
val answer =
JOptionPane.showConfirmDialog(
frame,
panel,
"COLORIZE DRAWING",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE
)
if (
answer ==
JOptionPane.OK_OPTION
) {
rememberUndo()
themeName =
bg.getSelectedItem
.toString
styleName =
st.getSelectedItem
.toString
val result =
makeColorized(
themeName,
styleName
)
restore(
result
)
setStatus(
"COLORIZE COMPLETE"
)
}
}
}
)
// ============================================================
// 3D PREVIEW
// ============================================================
threeDButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val result =
makeColorized(
themeName,
"3D"
)
val win =
new JFrame(
"3D PREVIEW"
)
win.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE
)
win.setSize(
1050,
720
)
win.setLocationRelativeTo(
frame
)
val panel =
new JPanel {
override def paintComponent(
graphics: Graphics
): Unit = {
super.paintComponent(
graphics
)
val g =
graphics.asInstanceOf[
Graphics2D
]
val aw =
getWidth - 30
val ah =
getHeight - 30
val scale =
math.min(
aw.toDouble /
result.getWidth,
ah.toDouble /
result.getHeight
)
val rw =
math.max(
1,
(result.getWidth * scale).toInt
)
val rh =
math.max(
1,
(result.getHeight * scale).toInt
)
val x =
(getWidth - rw) / 2
val y =
(getHeight - rh) / 2
g.drawImage(
result,
x,
y,
rw,
rh,
null
)
}
}
val save3D =
new JButton(
"SAVE 3D"
)
save3D.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
saveImage(
result,
win
)
}
}
)
win.setLayout(
new BorderLayout()
)
win.add(
panel,
BorderLayout.CENTER
)
win.add(
save3D,
BorderLayout.SOUTH
)
win.setVisible(
true
)
}
}
)
// ============================================================
// BOTTOM BAR
// ============================================================
val bottom =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
8,
5
)
)
bottom.add(
status
)
bottom.add(
new JLabel(
"1000+ THINGS | Select ? Write ? DRAW IT | F2 = Colorize"
)
)
// ============================================================
// RIGHT PANEL
// ============================================================
val rightPanel =
new JPanel(
new BorderLayout(
5,
5
)
)
rightPanel.add(
new JLabel(
"1000+ THINGS - SCROLL"
),
BorderLayout.NORTH
)
rightPanel.add(
scrollPane,
BorderLayout.CENTER
)
// ============================================================
// FINAL LAYOUT
// ============================================================
frame.setLayout(
new BorderLayout(
4,
4
)
)
frame.add(
toolbar,
BorderLayout.NORTH
)
frame.add(
canvas,
BorderLayout.CENTER
)
frame.add(
rightPanel,
BorderLayout.EAST
)
frame.add(
bottom,
BorderLayout.SOUTH
)
// ============================================================
// START
// ============================================================
SwingUtilities.invokeLater(
new Runnable {
override def run(): Unit = {
frame.setVisible(
true
)
setStatus(
"READY - 1000+ THINGS LOADED!"
)
canvas.requestFocusInWindow()
}
}
)