Code Sketch
yoooo.... tati
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.GradientPaint
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.KeyAdapter
import java.awt.event.KeyEvent
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.BorderFactory
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 CANVAS_WIDTH = 1000
val CANVAS_HEIGHT = 600
val CENTER_X = 500
val CENTER_Y = 300
// ============================================================
// COMPONENT REFERENCES
// ============================================================
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 zoomInButton: JButton = null
var zoomOutButton: JButton = null
var gridButton: JButton = null
var resetButton: JButton = null
var drawButton: JButton = null
var randomButton: JButton = null
var customColorButton: JButton = null
var searchButton: JButton = null
var toolBox: JComboBox[String] = null
var sizeBox: JComboBox[String] = null
var styleBox: JComboBox[String] = null
var writeField: JTextField = null
var searchField: JTextField = null
var thingsList: JList[String] = null
// ============================================================
// APP STATE
// ============================================================
var currentColor = Color.BLACK
var brushSize = 6.0f
var currentTool = "PENCIL"
var zoomLevel = 1.0
var isDrawing = false
var lastX = 0
var lastY = 0
var startX = 0
var startY = 0
var gridEnabled = false
var currentTheme = "SKY"
var currentStyle = "NORMAL"
var undoImage: BufferedImage = null
var redoImage: BufferedImage = null
// ============================================================
// MAIN IMAGE
// ============================================================
val drawingImage =
new BufferedImage(
CANVAS_WIDTH,
CANVAS_HEIGHT,
BufferedImage.TYPE_INT_RGB
)
val drawingGraphics =
drawingImage.createGraphics()
drawingGraphics.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
drawingGraphics.setRenderingHint(
RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY
)
drawingGraphics.setRenderingHint(
RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE
)
drawingGraphics.setColor(
Color.WHITE
)
drawingGraphics.fillRect(
0,
0,
CANVAS_WIDTH,
CANVAS_HEIGHT
)
// ============================================================
// HELPERS
// ============================================================
def setStatus(
text: String
): Unit = {
if (status != null) {
status.setText(text)
}
}
def refreshCanvas(): Unit = {
if (canvas != null) {
canvas.repaint()
}
}
def clearImage(): Unit = {
drawingGraphics.setComposite(
java.awt.AlphaComposite.Src
)
drawingGraphics.setColor(
Color.WHITE
)
drawingGraphics.fillRect(
0,
0,
CANVAS_WIDTH,
CANVAS_HEIGHT
)
refreshCanvas()
}
def copyImage(
source: BufferedImage
): BufferedImage = {
val result =
new BufferedImage(
CANVAS_WIDTH,
CANVAS_HEIGHT,
BufferedImage.TYPE_INT_RGB
)
val g =
result.createGraphics()
g.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC
)
g.drawImage(
source,
0,
0,
null
)
g.dispose()
result
}
def rememberUndo(): Unit = {
undoImage =
copyImage(
drawingImage
)
redoImage =
null
}
def restoreImage(
source: BufferedImage
): Unit = {
drawingGraphics.setColor(
Color.WHITE
)
drawingGraphics.fillRect(
0,
0,
CANVAS_WIDTH,
CANVAS_HEIGHT
)
drawingGraphics.drawImage(
source,
0,
0,
null
)
refreshCanvas()
}
def makeButton(
text: String
): JButton = {
val b =
new JButton(
text
)
b.setFont(
new Font(
"Arial",
Font.BOLD,
12
)
)
b.setFocusable(
false
)
b
}
// ============================================================
// SAVE
// ============================================================
def saveImageToFile(
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
)
}
}
}
// ============================================================
// CANVAS POSITION
// ============================================================
def shownWidth(): Int = {
math.max(
1,
(
CANVAS_WIDTH *
zoomLevel
).toInt
)
}
def shownHeight(): Int = {
math.max(
1,
(
CANVAS_HEIGHT *
zoomLevel
).toInt
)
}
def offsetX(): Int = {
(
canvas.getWidth -
shownWidth()
) / 2
}
def offsetY(): Int = {
(
canvas.getHeight -
shownHeight()
) / 2
}
def mouseToImageX(
screenX: Int
): Int = {
val result =
(
(screenX - offsetX()) /
zoomLevel
).toInt
math.max(
0,
math.min(
CANVAS_WIDTH - 1,
result
)
)
}
def mouseToImageY(
screenY: Int
): Int = {
val result =
(
(screenY - offsetY()) /
zoomLevel
).toInt
math.max(
0,
math.min(
CANVAS_HEIGHT - 1,
result
)
)
}
def insideCanvas(
x: Int,
y: Int
): Boolean = {
x >= offsetX() &&
x < offsetX() + shownWidth() &&
y >= offsetY() &&
y < offsetY() + shownHeight()
}
// ============================================================
// SPRAY
// ============================================================
def drawSpray(
x: Int,
y: Int
): Unit = {
drawingGraphics.setColor(
currentColor
)
val radius =
math.max(
8,
brushSize.toInt * 2
)
var i = 0
while (
i < 30
) {
val dx =
(
(i * 37) %
(radius * 2 + 1)
) -
radius
val dy =
(
(i * 53) %
(radius * 2 + 1)
) -
radius
if (
dx * dx +
dy * dy <=
radius * radius
) {
drawingGraphics.fillOval(
x + dx,
y + dy,
3,
3
)
}
i += 1
}
}
// ============================================================
// GENERIC DRAWING
// ============================================================
def drawGeneric(
text: String
): Unit = {
clearImage()
val g =
drawingGraphics
val hash =
math.abs(
text.hashCode
)
val objectColor =
new Color(
40 + hash % 190,
40 + (hash / 7) % 190,
40 + (hash / 13) % 190
)
g.setColor(
objectColor
)
val typeId =
hash % 7
if (
typeId == 0
) {
g.fillRoundRect(
CENTER_X - 190,
CENTER_Y - 120,
380,
240,
40,
40
)
} else if (
typeId == 1
) {
g.fillOval(
CENTER_X - 150,
CENTER_Y - 150,
300,
300
)
} else if (
typeId == 2
) {
val p =
new java.awt.Polygon()
p.addPoint(
CENTER_X,
CENTER_Y - 180
)
p.addPoint(
CENTER_X + 175,
CENTER_Y + 145
)
p.addPoint(
CENTER_X - 175,
CENTER_Y + 145
)
g.fillPolygon(
p
)
} else if (
typeId == 3
) {
g.fillRect(
CENTER_X - 160,
CENTER_Y - 140,
320,
280
)
} else if (
typeId == 4
) {
g.fillOval(
CENTER_X - 210,
CENTER_Y - 105,
420,
210
)
} else if (
typeId == 5
) {
val p =
new java.awt.Polygon()
var i = 0
while (
i < 6
) {
val a =
i * math.Pi / 3.0
p.addPoint(
CENTER_X +
(math.cos(a) * 175).toInt,
CENTER_Y +
(math.sin(a) * 175).toInt
)
i += 1
}
g.fillPolygon(
p
)
} else {
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
) {
185.0
} else {
80.0
}
p.addPoint(
CENTER_X +
(math.cos(a) * r).toInt,
CENTER_Y +
(math.sin(a) * r).toInt
)
i += 1
}
g.fillPolygon(
p
)
}
g.setColor(
Color.BLACK
)
g.setFont(
new Font(
"Arial",
Font.BOLD,
23
)
)
val label =
text.take(30)
val tw =
g.getFontMetrics
.stringWidth(
label
)
g.drawString(
label,
CENTER_X - tw / 2,
555
)
g.dispose()
refreshCanvas()
}
// ============================================================
// CAR
// ============================================================
def drawCar(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
val cy =
CENTER_Y
g.setColor(
new Color(
220,
45,
50
)
)
g.fillRoundRect(
cx - 270,
cy - 30,
540,
120,
35,
35
)
val roof =
new java.awt.Polygon()
roof.addPoint(
cx - 180,
cy - 30
)
roof.addPoint(
cx - 95,
cy - 145
)
roof.addPoint(
cx + 105,
cy - 145
)
roof.addPoint(
cx + 185,
cy - 30
)
g.fillPolygon(
roof
)
g.setColor(
new Color(
125,
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 - 178,
cy + 57,
30,
30
)
g.fillOval(
cx + 147,
cy + 57,
30,
30
)
g.setColor(
Color.YELLOW
)
g.fillOval(
cx - 260,
cy - 7,
28,
24
)
g.fillOval(
cx + 232,
cy - 7,
28,
24
)
g.dispose()
refreshCanvas()
}
// ============================================================
// HOUSE
// ============================================================
def drawHouse(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
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,
78,
45
)
)
g.fillRect(
cx - 50,
340,
100,
150
)
g.setColor(
new Color(
80,
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,
CANVAS_WIDTH,
110
)
g.dispose()
refreshCanvas()
}
// ============================================================
// TREE
// ============================================================
def drawTree(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
g.setColor(
new Color(
70,
165,
75
)
)
g.fillRect(
0,
490,
CANVAS_WIDTH,
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()
refreshCanvas()
}
// ============================================================
// ROBOT
// ============================================================
def drawRobot(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
val cy =
CENTER_Y
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.setColor(
Color.RED
)
g.fillOval(
cx - 20,
cy - 275,
40,
40
)
g.setColor(
Color.DARK_GRAY
)
g.setStroke(
new BasicStroke(
8,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
cx - 155,
cy + 55,
cx - 240,
cy + 120
)
g.drawLine(
cx + 155,
cy + 55,
cx + 240,
cy + 120
)
g.dispose()
refreshCanvas()
}
// ============================================================
// CAT
// ============================================================
def drawCat(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
val cy =
CENTER_Y
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(
75,
185,
95
)
)
g.fillOval(
cx - 75,
cy - 85,
45,
45
)
g.fillOval(
cx + 30,
cy - 85,
45,
45
)
g.setColor(
Color.PINK
)
g.fillOval(
cx - 12,
cy - 25,
24,
18
)
g.setColor(
Color.DARK_GRAY
)
g.setStroke(
new BasicStroke(
4,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
cx - 25,
cy - 10,
cx - 105,
cy - 30
)
g.drawLine(
cx + 25,
cy - 10,
cx + 105,
cy - 30
)
g.dispose()
refreshCanvas()
}
// ============================================================
// DOG
// ============================================================
def drawDog(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
val cy =
CENTER_Y
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()
refreshCanvas()
}
// ============================================================
// BIRD
// ============================================================
def drawBird(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
val cy =
CENTER_Y
g.setPaint(
new GradientPaint(
0,
0,
new Color(
120,
215,
255
),
0,
CANVAS_HEIGHT,
Color.WHITE
)
)
g.fillRect(
0,
0,
CANVAS_WIDTH,
CANVAS_HEIGHT
)
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.setColor(
Color.ORANGE
)
val beak =
new java.awt.Polygon()
beak.addPoint(
cx + 195,
cy - 80
)
beak.addPoint(
cx + 260,
cy - 55
)
beak.addPoint(
cx + 195,
cy - 35
)
g.fillPolygon(
beak
)
g.dispose()
refreshCanvas()
}
// ============================================================
// FISH
// ============================================================
def drawFish(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
val cy =
CENTER_Y
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()
refreshCanvas()
}
// ============================================================
// FLOWER
// ============================================================
def drawFlower(): Unit = {
clearImage()
val g =
drawingGraphics
val cx =
CENTER_X
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 colors =
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 angle =
i * math.Pi / 3.0
val px =
cx +
(math.cos(angle) * 80).toInt -
50
val py =
cy +
(math.sin(angle) * 80).toInt -
50
g.setColor(
colors(i)
)
g.fillOval(
px,
py,
100,
100
)
i += 1
}
g.setColor(
Color.YELLOW
)
g.fillOval(
cx - 50,
cy - 50,
100,
100
)
g.dispose()
refreshCanvas()
}
// ============================================================
// STAR
// ============================================================
def drawStar(): Unit = {
clearImage()
val g =
drawingGraphics
val star =
new java.awt.Polygon()
var i =
0
while (
i < 10
) {
val angle =
-math.Pi / 2 +
i * math.Pi / 5.0
val radius =
if (
i % 2 == 0
) {
190.0
} else {
80.0
}
star.addPoint(
CENTER_X +
(math.cos(angle) * radius).toInt,
CENTER_Y +
(math.sin(angle) * radius).toInt
)
i += 1
}
g.setColor(
new Color(
255,
210,
0
)
)
g.fillPolygon(
star
)
g.dispose()
refreshCanvas()
}
// ============================================================
// HEART
// ============================================================
def drawHeart(): Unit = {
clearImage()
val g =
drawingGraphics
val heart =
new java.awt.geom.Path2D.Double()
heart.moveTo(
CENTER_X,
CENTER_Y + 190
)
heart.curveTo(
CENTER_X - 270,
CENTER_Y + 20,
CENTER_X - 170,
CENTER_Y - 175,
CENTER_X,
CENTER_Y - 45
)
heart.curveTo(
CENTER_X + 170,
CENTER_Y - 175,
CENTER_X + 270,
CENTER_Y + 20,
CENTER_X,
CENTER_Y + 190
)
g.setColor(
Color.RED
)
g.fill(
heart
)
g.dispose()
refreshCanvas()
}
// ============================================================
// FOOD
// ============================================================
def drawFood(): Unit = {
clearImage()
val g =
drawingGraphics
g.setColor(
new Color(
240,
175,
50
)
)
g.fillOval(
CENTER_X - 190,
CENTER_Y - 100,
380,
200
)
g.setColor(
Color.RED
)
g.fillOval(
CENTER_X - 120,
CENTER_Y - 10,
38,
38
)
g.fillOval(
CENTER_X + 45,
CENTER_Y - 25,
38,
38
)
g.dispose()
refreshCanvas()
}
// ============================================================
// SPACE
// ============================================================
def drawSpace(): Unit = {
clearImage()
val g =
drawingGraphics
g.setColor(
new Color(
5,
10,
35
)
)
g.fillRect(
0,
0,
CANVAS_WIDTH,
CANVAS_HEIGHT
)
g.setColor(
Color.WHITE
)
var i =
0
while (
i < 120
) {
val x =
(i * 73) %
CANVAS_WIDTH
val y =
(i * 43) %
430
val size =
2 + (i % 4)
g.fillOval(
x,
y,
size,
size
)
i += 1
}
g.setColor(
new Color(
75,
145,
240
)
)
g.fillOval(
CENTER_X - 120,
CENTER_Y - 120,
240,
240
)
g.dispose()
refreshCanvas()
}
// ============================================================
// TEXT DRAW ENGINE
// ============================================================
def drawFromText(
input: String
): Unit = {
val text =
input
.trim
.toLowerCase
if (
text.length == 0
) {
setStatus(
"WRITE SOMETHING FIRST!"
)
return
}
rememberUndo()
if (
text.indexOf("car") >= 0 ||
text.indexOf("auto") >= 0 ||
text.indexOf("taxi") >= 0 ||
text.indexOf("bus") >= 0 ||
text.indexOf("truck") >= 0 ||
text.indexOf("bike") >= 0 ||
text.indexOf("bicycle") >= 0 ||
text.indexOf("motorcycle") >= 0 ||
text.indexOf("scooter") >= 0
) {
drawCar()
} else if (
text.indexOf("house") >= 0 ||
text.indexOf("home") >= 0 ||
text.indexOf("school") >= 0 ||
text.indexOf("building") >= 0 ||
text.indexOf("castle") >= 0 ||
text.indexOf("palace") >= 0
) {
drawHouse()
} else if (
text.indexOf("tree") >= 0 ||
text.indexOf("forest") >= 0 ||
text.indexOf("jungle") >= 0 ||
text.indexOf("plant") >= 0
) {
drawTree()
} else if (
text.indexOf("robot") >= 0
) {
drawRobot()
} else if (
text.indexOf("cat") >= 0 ||
text.indexOf("kitten") >= 0
) {
drawCat()
} else if (
text.indexOf("dog") >= 0 ||
text.indexOf("puppy") >= 0
) {
drawDog()
} else if (
text.indexOf("bird") >= 0 ||
text.indexOf("eagle") >= 0 ||
text.indexOf("parrot") >= 0 ||
text.indexOf("peacock") >= 0
) {
drawBird()
} else if (
text.indexOf("fish") >= 0 ||
text.indexOf("shark") >= 0 ||
text.indexOf("whale") >= 0 ||
text.indexOf("dolphin") >= 0
) {
drawFish()
} else if (
text.indexOf("flower") >= 0 ||
text.indexOf("rose") >= 0
) {
drawFlower()
} else if (
text.indexOf("star") >= 0
) {
drawStar()
} else if (
text.indexOf("heart") >= 0
) {
drawHeart()
} else if (
text.indexOf("pizza") >= 0 ||
text.indexOf("burger") >= 0 ||
text.indexOf("cake") >= 0 ||
text.indexOf("food") >= 0
) {
drawFood()
} else if (
text.indexOf("planet") >= 0 ||
text.indexOf("earth") >= 0 ||
text.indexOf("mars") >= 0 ||
text.indexOf("jupiter") >= 0 ||
text.indexOf("saturn") >= 0 ||
text.indexOf("moon") >= 0 ||
text.indexOf("space") >= 0 ||
text.indexOf("galaxy") >= 0 ||
text.indexOf("universe") >= 0 ||
text.indexOf("rocket") >= 0
) {
drawSpace()
} else {
drawGeneric(
input
)
}
setStatus(
"DRAW COMPLETE: " +
input
)
refreshCanvas()
}
// ============================================================
// 1000+ THINGS
// ============================================================
val baseThings =
Array(
"car",
"bus",
"truck",
"bike",
"bicycle",
"motorcycle",
"scooter",
"taxi",
"train",
"metro",
"tram",
"plane",
"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",
"hen",
"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",
"guitar",
"piano",
"drum",
"violin",
"flute",
"microphone",
"keyboard",
"printer",
"map",
"flag",
"crown",
"shield",
"magic wand",
"treasure chest",
"campfire",
"tent",
"road",
"traffic light",
"street lamp",
"fountain",
"playground",
"slide",
"swing",
"bench",
"flower pot",
"watering can",
"farm",
"windmill",
"silo"
)
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 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",
"in a futuristic city"
)
val allThings =
new scala.collection.mutable.ArrayBuffer[String]()
var baseIndex =
0
while (
baseIndex <
baseThings.length
) {
allThings +=
baseThings(baseIndex)
var descriptorIndex =
0
while (
descriptorIndex <
descriptors.length
) {
allThings +=
(
descriptors(descriptorIndex) +
" " +
baseThings(baseIndex)
)
descriptorIndex += 1
}
var sceneIndex =
0
while (
sceneIndex <
scenes.length
) {
allThings +=
(
baseThings(baseIndex) +
" " +
scenes(sceneIndex)
)
sceneIndex += 1
}
baseIndex += 1
}
// ============================================================
// LIST MODEL
// ============================================================
val listModel =
new DefaultListModel[String]()
var itemIndex =
0
while (
itemIndex <
allThings.length
) {
listModel.addElement(
allThings(itemIndex)
)
itemIndex += 1
}
// ============================================================
// SEARCH PANEL
// ============================================================
searchField =
new JTextField(
12
)
searchButton =
makeButton(
"SEARCH"
)
def performSearch(): Unit = {
val query =
searchField
.getText
.trim
.toLowerCase
listModel.clear()
if (
query.length == 0
) {
var i =
0
while (
i < allThings.length
) {
listModel.addElement(
allThings(i)
)
i += 1
}
setStatus(
"SHOWING ALL " +
allThings.length +
" THINGS"
)
} else {
var i =
0
var found =
0
while (
i < allThings.length
) {
val value =
allThings(i)
if (
value
.toLowerCase
.indexOf(query) >= 0
) {
listModel.addElement(
value
)
found += 1
}
i += 1
}
setStatus(
"FOUND " +
found +
" THINGS"
)
}
}
searchButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
performSearch()
}
}
)
searchField.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
performSearch()
}
}
)
// ============================================================
// MAIN FRAME
// ============================================================
frame =
new JFrame(
"ULTRA LEGEND SMART DRAW - 1000+ THINGS"
)
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
frame.setSize(
1400,
850
)
frame.setLocationRelativeTo(
null
)
// ============================================================
// STATUS
// ============================================================
status =
new JLabel(
"READY"
)
status.setFont(
new Font(
"Arial",
Font.BOLD,
15
)
)
// ============================================================
// 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 =
shownWidth()
val dh =
shownHeight()
val ox =
(getWidth - dw) / 2
val oy =
(getHeight - dh) / 2
g.setColor(
new Color(
235,
235,
235
)
)
g.fillRect(
0,
0,
getWidth,
getHeight
)
g.drawImage(
drawingImage,
ox,
oy,
dw,
dh,
null
)
if (
gridEnabled
) {
g.setColor(
new Color(
0,
0,
0,
35
)
)
var gx =
ox
while (
gx <= ox + dw
) {
g.drawLine(
gx,
oy,
gx,
oy + dh
)
gx += math.max(
20,
(40 * zoomLevel).toInt
)
}
var gy =
oy
while (
gy <= oy + dh
) {
g.drawLine(
ox,
gy,
ox + dw,
gy
)
gy += math.max(
20,
(40 * zoomLevel).toInt
)
}
}
}
}
canvas.setBackground(
Color.WHITE
)
canvas.setCursor(
Cursor.getPredefinedCursor(
Cursor.CROSSHAIR_CURSOR
)
)
// ============================================================
// RIGHT SIDE THINGS LIST
// ============================================================
thingsList =
new JList[String](
listModel
)
thingsList.setSelectionMode(
ListSelectionModel.SINGLE_SELECTION
)
thingsList.setFont(
new Font(
"Arial",
Font.PLAIN,
14
)
)
thingsList.setVisibleRowCount(
25
)
val scrollPane =
new JScrollPane(
thingsList
)
scrollPane.setPreferredSize(
new Dimension(
310,
620
)
)
// ============================================================
// RIGHT PANEL
// ============================================================
val rightTitle =
new JLabel(
"1000+ THINGS"
)
rightTitle.setFont(
new Font(
"Arial",
Font.BOLD,
18
)
)
val rightHelp =
new JLabel(
"CLICK ANY ITEM = INSTANT DRAW"
)
rightHelp.setFont(
new Font(
"Arial",
Font.BOLD,
11
)
)
val searchTop =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
3,
3
)
)
searchTop.add(
searchField
)
searchTop.add(
searchButton
)
val rightTop =
new JPanel(
new BorderLayout()
)
rightTop.add(
rightTitle,
BorderLayout.NORTH
)
rightTop.add(
rightHelp,
BorderLayout.CENTER
)
rightTop.add(
searchTop,
BorderLayout.SOUTH
)
val rightPanel =
new JPanel(
new BorderLayout(
5,
5
)
)
rightPanel.setBorder(
BorderFactory.createEmptyBorder(
6,
6,
6,
6
)
)
rightPanel.add(
rightTop,
BorderLayout.NORTH
)
rightPanel.add(
scrollPane,
BorderLayout.CENTER
)
// ============================================================
// TOOL 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"
)
zoomInButton =
makeButton(
"ZOOM +"
)
zoomOutButton =
makeButton(
"ZOOM -"
)
gridButton =
makeButton(
"GRID"
)
resetButton =
makeButton(
"RESET"
)
drawButton =
makeButton(
"DRAW IT"
)
randomButton =
makeButton(
"RANDOM"
)
customColorButton =
makeButton(
"CUSTOM"
)
// ============================================================
// 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 addColorButton(
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
)
}
addColorButton(Color.BLACK)
addColorButton(Color.RED)
addColorButton(Color.BLUE)
addColorButton(Color.GREEN)
addColorButton(Color.YELLOW)
addColorButton(Color.ORANGE)
addColorButton(Color.MAGENTA)
addColorButton(Color.CYAN)
addColorButton(Color.PINK)
addColorButton(new Color(128,64,0))
addColorButton(new Color(110,70,180))
toolbar.add(
customColorButton
)
customColorButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val chosen =
JColorChooser.showDialog(
frame,
"CUSTOM COLOR",
currentColor
)
if (
chosen != null
) {
currentColor =
chosen
currentTool =
"PENCIL"
toolBox.setSelectedItem(
"PENCIL"
)
setStatus(
"CUSTOM COLOR SELECTED"
)
}
}
}
)
// ============================================================
// PENCIL BUTTON
// ============================================================
pencilButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentTool =
"PENCIL"
toolBox.setSelectedItem(
"PENCIL"
)
setStatus(
"PENCIL ACTIVE"
)
}
}
)
// ============================================================
// ERASER BUTTON
// ============================================================
eraserButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentTool =
"ERASER"
toolBox.setSelectedItem(
"ERASER"
)
setStatus(
"ERASER ACTIVE"
)
}
}
)
// ============================================================
// TOOL BOX
// ============================================================
toolBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val selected =
toolBox.getSelectedItem
if (
selected != null
) {
currentTool =
selected.toString
setStatus(
"TOOL: " +
currentTool
)
}
}
}
)
// ============================================================
// SIZE BOX
// ============================================================
sizeBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
try {
brushSize =
sizeBox
.getSelectedItem
.toString
.toFloat
} catch {
case _: Exception =>
}
}
}
)
// ============================================================
// STYLE BOX
// ============================================================
styleBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentStyle =
styleBox
.getSelectedItem
.toString
}
}
)
// ============================================================
// MOST IMPORTANT PART:
// ANY LIST ITEM = INSTANT DRAW
// ============================================================
thingsList.addListSelectionListener(
new javax.swing.event.ListSelectionListener {
override def valueChanged(
e: javax.swing.event.ListSelectionEvent
): Unit = {
if (
!e.getValueIsAdjusting
) {
val selected =
thingsList.getSelectedValue
if (
selected != null &&
selected.trim.length > 0
) {
writeField.setText(
selected
)
drawFromText(
selected
)
setStatus(
"INSTANT DRAW: " +
selected
)
refreshCanvas()
}
}
}
}
)
// ============================================================
// DRAW IT
// ============================================================
drawButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val text =
writeField
.getText
.trim
if (
text.length > 0
) {
drawFromText(
text
)
} else {
val selected =
thingsList.getSelectedValue
if (
selected != null
) {
writeField.setText(
selected
)
drawFromText(
selected
)
} else {
setStatus(
"WRITE OR SELECT A THING"
)
}
}
}
}
)
// ============================================================
// ENTER
// ============================================================
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(
allThings.length
)
val value =
allThings(index)
writeField.setText(
value
)
drawFromText(
value
)
setStatus(
"RANDOM: " +
value
)
}
}
)
// ============================================================
// UNDO
// ============================================================
undoButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
undoImage != null
) {
redoImage =
copyImage(
drawingImage
)
restoreImage(
undoImage
)
undoImage =
null
setStatus(
"UNDO COMPLETE"
)
} else {
setStatus(
"NOTHING TO UNDO"
)
}
}
}
)
// ============================================================
// REDO
// ============================================================
redoButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
redoImage != null
) {
undoImage =
copyImage(
drawingImage
)
restoreImage(
redoImage
)
redoImage =
null
setStatus(
"REDO COMPLETE"
)
} else {
setStatus(
"NOTHING TO REDO"
)
}
}
}
)
// ============================================================
// 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 = {
saveImageToFile(
drawingImage,
frame
)
}
}
)
// ============================================================
// GRID
// ============================================================
gridButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
gridEnabled =
!gridEnabled
refreshCanvas()
if (
gridEnabled
) {
setStatus(
"GRID ON"
)
} else {
setStatus(
"GRID OFF"
)
}
}
}
)
// ============================================================
// ZOOM IN
// ============================================================
zoomInButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
zoomLevel =
math.min(
2.5,
zoomLevel + 0.10
)
refreshCanvas()
setStatus(
"ZOOM " +
math.round(
zoomLevel * 100
) +
"%"
)
}
}
)
// ============================================================
// ZOOM OUT
// ============================================================
zoomOutButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
zoomLevel =
math.max(
0.50,
zoomLevel - 0.10
)
refreshCanvas()
setStatus(
"ZOOM " +
math.round(
zoomLevel * 100
) +
"%"
)
}
}
)
// ============================================================
// RESET
// ============================================================
resetButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
zoomLevel =
1.0
gridEnabled =
false
currentTheme =
"SKY"
currentStyle =
"NORMAL"
refreshCanvas()
setStatus(
"RESET COMPLETE"
)
}
}
)
// ============================================================
// MOUSE PRESS
// ============================================================
canvas.addMouseListener(
new MouseAdapter {
override def mousePressed(
e: MouseEvent
): Unit = {
if (
!insideCanvas(
e.getX,
e.getY
)
) {
isDrawing =
false
return
}
rememberUndo()
isDrawing =
true
startX =
mouseToImageX(
e.getX
)
startY =
mouseToImageY(
e.getY
)
lastX =
startX
lastY =
startY
if (
currentTool ==
"PENCIL"
) {
drawingGraphics.setColor(
currentColor
)
val s =
math.max(
1,
brushSize.toInt
)
drawingGraphics.fillOval(
startX - s / 2,
startY - s / 2,
s,
s
)
}
if (
currentTool ==
"ERASER"
) {
drawingGraphics.setColor(
Color.WHITE
)
val s =
math.max(
1,
brushSize.toInt
)
drawingGraphics.fillOval(
startX - s / 2,
startY - s / 2,
s,
s
)
}
if (
currentTool ==
"SPRAY"
) {
drawSpray(
startX,
startY
)
}
refreshCanvas()
}
override def mouseReleased(
e: MouseEvent
): Unit = {
if (
!isDrawing
) {
return
}
val endX =
mouseToImageX(
e.getX
)
val endY =
mouseToImageY(
e.getY
)
if (
currentTool ==
"LINE"
) {
drawingGraphics.setColor(
currentColor
)
drawingGraphics.setStroke(
new BasicStroke(
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
drawingGraphics.drawLine(
startX,
startY,
endX,
endY
)
}
if (
currentTool ==
"RECTANGLE"
) {
drawingGraphics.setColor(
currentColor
)
drawingGraphics.setStroke(
new BasicStroke(
brushSize
)
)
val x =
math.min(
startX,
endX
)
val y =
math.min(
startY,
endY
)
val width =
math.abs(
endX -
startX
)
val height =
math.abs(
endY -
startY
)
drawingGraphics.drawRect(
x,
y,
width,
height
)
}
if (
currentTool ==
"ELLIPSE"
) {
drawingGraphics.setColor(
currentColor
)
drawingGraphics.setStroke(
new BasicStroke(
brushSize
)
)
val x =
math.min(
startX,
endX
)
val y =
math.min(
startY,
endY
)
val width =
math.abs(
endX -
startX
)
val height =
math.abs(
endY -
startY
)
drawingGraphics.drawOval(
x,
y,
width,
height
)
}
isDrawing =
false
refreshCanvas()
}
}
)
// ============================================================
// MOUSE DRAG
// ============================================================
canvas.addMouseMotionListener(
new MouseMotionAdapter {
override def mouseDragged(
e: MouseEvent
): Unit = {
if (
!isDrawing
) {
return
}
if (
!insideCanvas(
e.getX,
e.getY
)
) {
return
}
val x =
mouseToImageX(
e.getX
)
val y =
mouseToImageY(
e.getY
)
if (
currentTool ==
"PENCIL"
) {
drawingGraphics.setColor(
currentColor
)
drawingGraphics.setStroke(
new BasicStroke(
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
drawingGraphics.drawLine(
lastX,
lastY,
x,
y
)
}
if (
currentTool ==
"ERASER"
) {
drawingGraphics.setColor(
Color.WHITE
)
drawingGraphics.setStroke(
new BasicStroke(
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
drawingGraphics.drawLine(
lastX,
lastY,
x,
y
)
}
if (
currentTool ==
"SPRAY"
) {
drawSpray(
x,
y
)
}
lastX =
x
lastY =
y
refreshCanvas()
}
}
)
// ============================================================
// BACKGROUND LIST
// ============================================================
val backgroundNames =
Array(
"SKY",
"SUNNY",
"SUNRISE",
"SUNSET",
"GOLDEN SUNSET",
"NIGHT",
"STAR NIGHT",
"SPACE",
"GALAXY",
"COSMIC",
"OCEAN",
"DEEP OCEAN",
"UNDERWATER",
"BEACH",
"TROPICAL BEACH",
"ISLAND",
"PARADISE",
"FOREST",
"DEEP FOREST",
"JUNGLE",
"MOUNTAIN",
"SNOW",
"ICE",
"DESERT",
"RAINBOW",
"CITY",
"CITY NIGHT",
"NEON CITY",
"FUTURE CITY",
"MAGIC",
"FANTASY",
"FAIRY WORLD",
"CANDY WORLD",
"PINK DREAM",
"BLUE DREAM",
"PURPLE DREAM",
"GOLDEN WORLD",
"ROYAL WORLD",
"FIRE WORLD",
"VOLCANO",
"SPRING",
"SUMMER",
"AUTUMN",
"WINTER",
"DREAM WORLD"
)
def getBackgroundColors(
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("SUNRISE") >= 0
) {
Array(
new Color(255,180,100),
new Color(255,235,170)
)
} else if (
t.indexOf("NIGHT") >= 0
) {
Array(
new Color(10,20,70),
new Color(65,45,125)
)
} else if (
t.indexOf("SPACE") >= 0 ||
t.indexOf("GALAXY") >= 0 ||
t.indexOf("COSMIC") >= 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(90,220,255),
new Color(10,80,190)
)
} 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("CANDY") >= 0 ||
t.indexOf("PINK") >= 0
) {
Array(
new Color(255,200,225),
new Color(245,100,175)
)
} else if (
t.indexOf("GOLD") >= 0 ||
t.indexOf("ROYAL") >= 0
) {
Array(
new Color(255,235,130),
new Color(200,140,35)
)
} else if (
t.indexOf("FIRE") >= 0 ||
t.indexOf("VOLCANO") >= 0
) {
Array(
new Color(255,155,70),
new Color(180,35,35)
)
} else if (
t.indexOf("PURPLE") >= 0
) {
Array(
new Color(220,190,255),
new Color(105,45,170)
)
} else {
Array(
new Color(170,225,255),
new Color(100,190,110)
)
}
}
def makeColorizedImage(
theme: String,
style: String
): BufferedImage = {
val colors =
getBackgroundColors(
theme
)
val result =
new BufferedImage(
CANVAS_WIDTH,
CANVAS_HEIGHT,
BufferedImage.TYPE_INT_RGB
)
val g =
result.createGraphics()
g.setPaint(
new GradientPaint(
0,
0,
colors(0),
0,
CANVAS_HEIGHT,
colors(1)
)
)
g.fillRect(
0,
0,
CANVAS_WIDTH,
CANVAS_HEIGHT
)
var x =
0
while (
x < CANVAS_WIDTH
) {
var y =
0
while (
y < CANVAS_HEIGHT
) {
val rgb =
drawingImage.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 ==
"3D"
) {
g.setColor(
new Color(
0,
0,
0,
75
)
)
g.setStroke(
new BasicStroke(
12
)
)
g.drawRoundRect(
12,
12,
976,
576,
30,
30
)
}
if (
style ==
"GLOSSY"
) {
g.setColor(
new Color(
255,
255,
255,
65
)
)
g.fillRoundRect(
20,
20,
960,
125,
35,
35
)
}
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 ==
"COMIC"
) {
g.setColor(
Color.BLACK
)
g.setStroke(
new BasicStroke(
8
)
)
g.drawRoundRect(
8,
8,
984,
584,
25,
25
)
}
if (
style ==
"MAGIC"
) {
g.setColor(
Color.WHITE
)
var i =
0
while (
i < 70
) {
g.fillOval(
(i * 83) %
CANVAS_WIDTH,
(i * 47) %
CANVAS_HEIGHT,
5,
5
)
i += 1
}
}
if (
style ==
"GOLD"
) {
g.setColor(
new Color(
255,
215,
70,
140
)
)
g.setStroke(
new BasicStroke(
10
)
)
g.drawRoundRect(
12,
12,
976,
576,
30,
30
)
}
g.dispose()
result
}
// ============================================================
// COLORIZE BUTTON
// ============================================================
colorizeButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val bg =
new JComboBox[String](
backgroundNames
)
val style =
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(
style
)
val answer =
JOptionPane.showConfirmDialog(
frame,
panel,
"COLORIZE DRAWING",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE
)
if (
answer ==
JOptionPane.OK_OPTION
) {
rememberUndo()
currentTheme =
bg.getSelectedItem
.toString
currentStyle =
style.getSelectedItem
.toString
styleBox.setSelectedItem(
currentStyle
)
val result =
makeColorizedImage(
currentTheme,
currentStyle
)
restoreImage(
result
)
setStatus(
"COLORIZE COMPLETE"
)
}
}
}
)
// ============================================================
// 3D PREVIEW
// ============================================================
threeDButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val result =
makeColorizedImage(
currentTheme,
"3D"
)
val preview =
new JFrame(
"3D PREVIEW"
)
preview.setDefaultCloseOperation(
WindowConstants.DISPOSE_ON_CLOSE
)
preview.setSize(
1080,
760
)
preview.setLocationRelativeTo(
frame
)
val previewPanel =
new JPanel {
override def paintComponent(
graphics: Graphics
): Unit = {
super.paintComponent(
graphics
)
val g =
graphics.asInstanceOf[
Graphics2D
]
g.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC
)
val maxW =
getWidth - 30
val maxH =
getHeight - 30
val scale =
math.min(
maxW.toDouble /
result.getWidth,
maxH.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.setFocusable(
false
)
save3D.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
saveImageToFile(
result,
preview
)
}
}
)
preview.setLayout(
new BorderLayout()
)
preview.add(
previewPanel,
BorderLayout.CENTER
)
preview.add(
save3D,
BorderLayout.SOUTH
)
preview.setVisible(
true
)
}
}
)
// ============================================================
// KEYBOARD
// ============================================================
canvas.setFocusable(
true
)
canvas.addKeyListener(
new KeyAdapter {
override def keyPressed(
e: KeyEvent
): Unit = {
if (
e.isControlDown &&
e.getKeyCode ==
KeyEvent.VK_Z
) {
if (
undoImage != null
) {
redoImage =
copyImage(
drawingImage
)
restoreImage(
undoImage
)
undoImage =
null
setStatus(
"UNDO COMPLETE"
)
}
}
if (
e.isControlDown &&
e.getKeyCode ==
KeyEvent.VK_Y
) {
if (
redoImage != null
) {
undoImage =
copyImage(
drawingImage
)
restoreImage(
redoImage
)
redoImage =
null
setStatus(
"REDO COMPLETE"
)
}
}
if (
e.getKeyCode ==
KeyEvent.VK_F2
) {
colorizeButton.doClick()
}
if (
e.getKeyCode ==
KeyEvent.VK_F3
) {
threeDButton.doClick()
}
}
}
)
// ============================================================
// BOTTOM BAR
// ============================================================
val bottomBar =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
8,
5
)
)
bottomBar.add(
status
)
bottomBar.add(
new JLabel(
"CLICK ANY RIGHT-SIDE THING = DRAW | WRITE + DRAW IT | F2 Colorize | F3 3D"
)
)
// ============================================================
// FINAL UI
// ============================================================
frame.setLayout(
new BorderLayout(
4,
4
)
)
frame.add(
toolbar,
BorderLayout.NORTH
)
frame.add(
canvas,
BorderLayout.CENTER
)
frame.add(
rightPanel,
BorderLayout.EAST
)
frame.add(
bottomBar,
BorderLayout.SOUTH
)
// ============================================================
// START
// ============================================================
SwingUtilities.invokeLater(
new Runnable {
override def run(): Unit = {
frame.setVisible(
true
)
canvas.requestFocusInWindow()
setStatus(
"READY - " +
allThings.length +
" THINGS LOADED!"
)
}
}
)