Code Sketch
yoooo...............
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.MouseAdapter
import java.awt.event.MouseEvent
import java.awt.event.MouseMotionAdapter
import java.awt.image.BufferedImage
import java.io.File
import java.util.Locale
import javax.imageio.ImageIO
import javax.swing.JButton
import javax.swing.JComboBox
import javax.swing.JFileChooser
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.JOptionPane
import javax.swing.JPanel
import javax.swing.JTextField
import javax.swing.SwingUtilities
import javax.swing.WindowConstants
// ============================================================
// SMART DRAW STUDIO PRO
// ============================================================
val W = 1000
val H = 600
var currentColor = Color.BLACK
var brushSize = 6.0f
var eraserMode = false
var drawing = false
var lastX = 0
var lastY = 0
var undoImage: BufferedImage = null
var redoImage: BufferedImage = null
// ============================================================
// CANVAS IMAGE
// ============================================================
val drawingImage =
new BufferedImage(
W,
H,
BufferedImage.TYPE_INT_RGB
)
val pen =
drawingImage.createGraphics()
pen.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
pen.setColor(
Color.WHITE
)
pen.fillRect(
0,
0,
W,
H
)
// ============================================================
// IMAGE HELPERS
// ============================================================
def copyImage(
src: BufferedImage
): BufferedImage = {
val dst =
new BufferedImage(
src.getWidth,
src.getHeight,
BufferedImage.TYPE_INT_RGB
)
val g =
dst.createGraphics()
g.drawImage(
src,
0,
0,
null
)
g.dispose()
dst
}
def rememberUndo(): Unit = {
undoImage =
copyImage(
drawingImage
)
redoImage =
null
}
def restoreImage(
src: BufferedImage
): Unit = {
pen.setColor(
Color.WHITE
)
pen.fillRect(
0,
0,
W,
H
)
pen.drawImage(
src,
0,
0,
null
)
}
def clearImage(): Unit = {
pen.setColor(
Color.WHITE
)
pen.fillRect(
0,
0,
W,
H
)
}
// ============================================================
// MAIN WINDOW
// ============================================================
val frame =
new JFrame(
"SMART DRAW STUDIO PRO"
)
frame.setDefaultCloseOperation(
WindowConstants.EXIT_ON_CLOSE
)
frame.setSize(
1160,
790
)
frame.setLocationRelativeTo(
null
)
// ============================================================
// STATUS
// ============================================================
val status =
new JLabel(
"Ready - Write an idea or draw with the pencil!"
)
status.setFont(
new Font(
"Arial",
Font.BOLD,
15
)
)
// ============================================================
// CANVAS
// ============================================================
val canvas =
new JPanel {
override def paintComponent(
g: Graphics
): Unit = {
super.paintComponent(
g
)
val g2 =
g.asInstanceOf[Graphics2D]
g2.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
g2.drawImage(
drawingImage,
0,
0,
null
)
}
}
canvas.setBackground(
Color.WHITE
)
canvas.setPreferredSize(
new Dimension(
W,
H
)
)
canvas.setCursor(
Cursor.getPredefinedCursor(
Cursor.CROSSHAIR_CURSOR
)
)
// ============================================================
// TOOLBAR
// ============================================================
val toolbar =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
5,
5
)
)
def makeButton(
text: String
): JButton = {
val b =
new JButton(
text
)
b.setFont(
new Font(
"Arial",
Font.BOLD,
12
)
)
b.setFocusable(
false
)
b
}
val pencilButton =
makeButton(
"PENCIL"
)
val eraserButton =
makeButton(
"ERASER"
)
val undoButton =
makeButton(
"UNDO"
)
val redoButton =
makeButton(
"REDO"
)
val clearButton =
makeButton(
"CLEAR"
)
val saveButton =
makeButton(
"SAVE"
)
toolbar.add(
pencilButton
)
toolbar.add(
eraserButton
)
toolbar.add(
undoButton
)
toolbar.add(
redoButton
)
toolbar.add(
clearButton
)
toolbar.add(
saveButton
)
// ============================================================
// BRUSH SIZE
// ============================================================
toolbar.add(
new JLabel(
"SIZE:"
)
)
val sizeBox =
new JComboBox[String](
Array(
"2",
"4",
"6",
"10",
"16",
"24",
"35",
"50"
)
)
sizeBox.setSelectedItem(
"6"
)
toolbar.add(
sizeBox
)
// ============================================================
// COLOR PALETTE
// ============================================================
toolbar.add(
new JLabel(
"COLORS:"
)
)
def addColor(
c: Color
): Unit = {
val b =
new JButton(
" "
)
b.setPreferredSize(
new Dimension(
25,
25
)
)
b.setBackground(
c
)
b.setOpaque(
true
)
b.setFocusable(
false
)
b.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
currentColor =
c
eraserMode =
false
status.setText(
"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)
addColor(
new Color(
128,
64,
0
)
)
// ============================================================
// WRITE AREA
// ============================================================
toolbar.add(
new JLabel(
"WRITE:"
)
)
val writeField =
new JTextField(
"CAR",
14
)
toolbar.add(
writeField
)
val drawItButton =
makeButton(
"DRAW IT"
)
toolbar.add(
drawItButton
)
// ============================================================
// COLORIZE BUTTON
// ============================================================
val colorizeButton =
makeButton(
"COLORIZE DRAWING"
)
colorizeButton.setFont(
new Font(
"Arial",
Font.BOLD,
13
)
)
toolbar.add(
colorizeButton
)
// ============================================================
// MOUSE PRESS
// ============================================================
canvas.addMouseListener(
new MouseAdapter {
override def mousePressed(
e: MouseEvent
): Unit = {
rememberUndo()
drawing =
true
lastX =
math.max(
0,
math.min(
W - 1,
e.getX
)
)
lastY =
math.max(
0,
math.min(
H - 1,
e.getY
)
)
if (
eraserMode
) {
pen.setColor(
Color.WHITE
)
} else {
pen.setColor(
currentColor
)
}
val s =
math.max(
1,
brushSize.toInt
)
pen.fillOval(
lastX - s / 2,
lastY - s / 2,
s,
s
)
canvas.repaint()
}
override def mouseReleased(
e: MouseEvent
): Unit = {
drawing =
false
}
}
)
// ============================================================
// MOUSE DRAG
// ============================================================
canvas.addMouseMotionListener(
new MouseMotionAdapter {
override def mouseDragged(
e: MouseEvent
): Unit = {
if (
drawing
) {
val x =
math.max(
0,
math.min(
W - 1,
e.getX
)
)
val y =
math.max(
0,
math.min(
H - 1,
e.getY
)
)
if (
eraserMode
) {
pen.setColor(
Color.WHITE
)
} else {
pen.setColor(
currentColor
)
}
pen.setStroke(
new BasicStroke(
brushSize,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
pen.drawLine(
lastX,
lastY,
x,
y
)
lastX =
x
lastY =
y
canvas.repaint()
}
}
}
)
// ============================================================
// TOOL ACTIONS
// ============================================================
pencilButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
eraserMode =
false
status.setText(
"Pencil active"
)
}
}
)
eraserButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
eraserMode =
true
status.setText(
"Eraser active"
)
}
}
)
sizeBox.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
try {
brushSize =
sizeBox
.getSelectedItem
.toString
.toFloat
} catch {
case _: Exception =>
}
}
}
)
// ============================================================
// UNDO
// ============================================================
undoButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
undoImage != null
) {
redoImage =
copyImage(
drawingImage
)
restoreImage(
undoImage
)
undoImage =
null
canvas.repaint()
status.setText(
"Undo complete"
)
}
}
}
)
// ============================================================
// REDO
// ============================================================
redoButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
if (
redoImage != null
) {
undoImage =
copyImage(
drawingImage
)
restoreImage(
redoImage
)
redoImage =
null
canvas.repaint()
status.setText(
"Redo complete"
)
}
}
}
)
// ============================================================
// CLEAR
// ============================================================
clearButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
rememberUndo()
clearImage()
canvas.repaint()
status.setText(
"Canvas cleared"
)
}
}
)
// ============================================================
// SAVE
// ============================================================
saveButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
val chooser =
new JFileChooser()
chooser.setDialogTitle(
"Save Drawing"
)
if (
chooser.showSaveDialog(
frame
) ==
JFileChooser.APPROVE_OPTION
) {
try {
var file =
chooser.getSelectedFile
if (
!file.getName
.toLowerCase
.endsWith(
".png"
)
) {
file =
new File(
file.getAbsolutePath +
".png"
)
}
ImageIO.write(
drawingImage,
"png",
file
)
status.setText(
"Drawing saved!"
)
} catch {
case ex: Exception =>
JOptionPane.showMessageDialog(
frame,
ex.getMessage,
"Save Error",
JOptionPane.ERROR_MESSAGE
)
}
}
}
}
)
// ============================================================
// BASIC SHAPE HELPERS
// ============================================================
def setupWhite(
g: Graphics2D
): Unit = {
g.setColor(
Color.WHITE
)
g.fillRect(
0,
0,
W,
H
)
}
def setupAA(
g: Graphics2D
): Unit = {
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
)
}
def centerX: Int =
W / 2
def centerY: Int =
H / 2
// ============================================================
// DRAW CAR
// ============================================================
def drawCar(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
g.setColor(
new Color(
210,
35,
45
)
)
g.fillRoundRect(
cx - 260,
cy - 40,
520,
120,
35,
35
)
val roof =
new java.awt.Polygon()
roof.addPoint(
cx - 175,
cy - 40
)
roof.addPoint(
cx - 95,
cy - 145
)
roof.addPoint(
cx + 105,
cy - 145
)
roof.addPoint(
cx + 180,
cy - 40
)
g.fillPolygon(
roof
)
g.setColor(
new Color(
120,
205,
240
)
)
g.fillPolygon(
new java.awt.Polygon(
Array(
cx - 140,
cx - 85,
cx - 10,
cx - 10
),
Array(
cy - 43,
cy - 122,
cy - 122,
cy - 43
),
4
)
)
g.fillPolygon(
new java.awt.Polygon(
Array(
cx + 10,
cx + 10,
cx + 110,
cx + 150
),
Array(
cy - 43,
cy - 122,
cy - 122,
cy - 43
),
4
)
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 195,
cy + 35,
90,
90
)
g.fillOval(
cx + 105,
cy + 35,
90,
90
)
g.setColor(
Color.LIGHT_GRAY
)
g.fillOval(
cx - 166,
cy + 65,
32,
32
)
g.fillOval(
cx + 134,
cy + 65,
32,
32
)
g.setColor(
Color.YELLOW
)
g.fillOval(
cx + 220,
cy - 15,
32,
28
)
g.fillOval(
cx - 252,
cy - 15,
32,
28
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW HOUSE
// ============================================================
def drawHouse(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
g.setColor(
new Color(
245,
205,
125
)
)
g.fillRect(
cx - 200,
cy - 70,
400,
250
)
val roof =
new java.awt.Polygon()
roof.addPoint(
cx - 245,
cy - 70
)
roof.addPoint(
cx,
cy - 245
)
roof.addPoint(
cx + 245,
cy - 70
)
g.setColor(
new Color(
175,
60,
45
)
)
g.fillPolygon(
roof
)
g.setColor(
new Color(
125,
75,
45
)
)
g.fillRect(
cx - 48,
cy + 35,
96,
145
)
g.setColor(
new Color(
85,
190,
240
)
)
g.fillRect(
cx - 160,
cy - 15,
75,
75
)
g.fillRect(
cx + 85,
cy - 15,
75,
75
)
g.setColor(
new Color(
80,
170,
80
)
)
g.fillRect(
0,
H - 110,
W,
110
)
g.setColor(
Color.YELLOW
)
g.fillOval(
70,
55,
100,
100
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW TREE
// ============================================================
def drawTree(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
g.setColor(
new Color(
75,
170,
75
)
)
g.fillRect(
0,
H - 110,
W,
110
)
g.setColor(
new Color(
135,
85,
45
)
)
g.fillRoundRect(
cx - 42,
270,
84,
230,
25,
25
)
g.setColor(
new Color(
40,
170,
65
)
)
g.fillOval(
cx - 180,
100,
220,
190
)
g.fillOval(
cx - 20,
75,
220,
210
)
g.fillOval(
cx - 95,
30,
220,
205
)
g.setColor(
Color.YELLOW
)
g.fillOval(
W - 165,
50,
95,
95
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW SUN
// ============================================================
def drawSun(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
g.setPaint(
new GradientPaint(
0,
0,
new Color(
100,
190,
255
),
0,
H,
new Color(
255,
215,
125
)
)
)
g.fillRect(
0,
0,
W,
H
)
g.setColor(
new Color(
255,
195,
35
)
)
g.fillOval(
centerX - 110,
centerY - 130,
220,
220
)
g.setColor(
new Color(
75,
165,
80
)
)
g.fillRect(
0,
H - 140,
W,
140
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW FLOWER
// ============================================================
def drawFlower(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
240
g.setColor(
new Color(
45,
160,
60
)
)
g.setStroke(
new BasicStroke(
16.0f,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
cx,
cy + 50,
cx,
H - 90
)
val colors =
Array(
Color.RED,
Color.PINK,
Color.MAGENTA,
Color.ORANGE,
new Color(140, 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) * 78).toInt -
50
val py =
cy +
(math.sin(angle) * 78).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.setColor(
new Color(
70,
165,
70
)
)
g.fillRect(
0,
H - 85,
W,
85
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW ROBOT
// ============================================================
def drawRobot(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
g.setColor(
new Color(
115,
160,
195
)
)
g.fillRoundRect(
cx - 150,
cy - 10,
300,
215,
35,
35
)
g.setColor(
new Color(
155,
190,
210
)
)
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.DARK_GRAY
)
g.setStroke(
new BasicStroke(
10
)
)
g.drawLine(
cx,
cy - 190,
cx,
cy - 255
)
g.setColor(
Color.RED
)
g.fillOval(
cx - 20,
cy - 275,
40,
40
)
g.setColor(
new Color(
120,
155,
180
)
)
g.fillRoundRect(
cx - 240,
cy + 10,
80,
195,
35,
35
)
g.fillRoundRect(
cx + 160,
cy + 10,
80,
195,
35,
35
)
g.fillRoundRect(
cx - 105,
cy + 195,
75,
145,
30,
30
)
g.fillRoundRect(
cx + 30,
cy + 195,
75,
145,
30,
30
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW PERSON
// ============================================================
def drawPerson(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val headY =
110
g.setColor(
new Color(
245,
190,
145
)
)
g.fillOval(
cx - 70,
headY,
140,
150
)
g.setColor(
new Color(
55,
35,
25
)
)
g.fillArc(
cx - 73,
headY - 18,
146,
90,
0,
180
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 38,
headY + 55,
13,
13
)
g.fillOval(
cx + 25,
headY + 55,
13,
13
)
g.setColor(
new Color(
55,
120,
215
)
)
g.fillRoundRect(
cx - 100,
headY + 145,
200,
180,
30,
30
)
g.setColor(
new Color(
245,
190,
145
)
)
g.setStroke(
new BasicStroke(
27,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
cx - 85,
headY + 185,
cx - 175,
headY + 300
)
g.drawLine(
cx + 85,
headY + 185,
cx + 175,
headY + 300
)
g.setColor(
new Color(
45,
45,
55
)
)
g.setStroke(
new BasicStroke(
40,
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND
)
)
g.drawLine(
cx - 45,
headY + 310,
cx - 60,
headY + 455
)
g.drawLine(
cx + 45,
headY + 310,
cx + 60,
headY + 455
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW CAT
// ============================================================
def drawCat(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
g.setColor(
new Color(
180,
180,
190
)
)
g.fillOval(
cx - 140,
cy - 10,
280,
220
)
g.fillOval(
cx - 130,
cy - 160,
260,
210
)
val ear1 =
new java.awt.Polygon()
ear1.addPoint(
cx - 110,
cy - 120
)
ear1.addPoint(
cx - 75,
cy - 220
)
ear1.addPoint(
cx - 25,
cy - 140
)
val ear2 =
new java.awt.Polygon()
ear2.addPoint(
cx + 110,
cy - 120
)
ear2.addPoint(
cx + 75,
cy - 220
)
ear2.addPoint(
cx + 25,
cy - 140
)
g.fillPolygon(
ear1
)
g.fillPolygon(
ear2
)
g.setColor(
new Color(
80,
190,
100
)
)
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.dispose()
canvas.repaint()
}
// ============================================================
// DRAW DOG
// ============================================================
def drawDog(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
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(
125,
80,
50
)
)
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()
canvas.repaint()
}
// ============================================================
// DRAW BIRD
// ============================================================
def drawBird(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
g.setPaint(
new GradientPaint(
0,
0,
new Color(
130,
215,
255
),
0,
H,
Color.WHITE
)
)
g.fillRect(
0,
0,
W,
H
)
val cx =
centerX
val cy =
centerY
g.setColor(
new Color(
70,
130,
220
)
)
g.fillOval(
cx - 140,
cy - 90,
280,
180
)
g.fillOval(
cx + 65,
cy - 145,
135,
130
)
g.setColor(
new Color(
45,
95,
180
)
)
g.fillOval(
cx - 120,
cy - 55,
135,
110
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx + 140,
cy - 110,
18,
18
)
g.setColor(
Color.ORANGE
)
val beak =
new java.awt.Polygon()
beak.addPoint(
cx + 190,
cy - 85
)
beak.addPoint(
cx + 260,
cy - 58
)
beak.addPoint(
cx + 190,
cy - 38
)
g.fillPolygon(
beak
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW STAR
// ============================================================
def drawStar(): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val polygon =
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
}
polygon.addPoint(
centerX +
(math.cos(angle) * radius).toInt,
centerY +
(math.sin(angle) * radius).toInt
)
i += 1
}
g.setColor(
new Color(
255,
205,
0
)
)
g.fillPolygon(
polygon
)
g.setColor(
new Color(
220,
140,
0
)
)
g.setStroke(
new BasicStroke(
5
)
)
g.drawPolygon(
polygon
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW GENERIC VEHICLE
// ============================================================
def drawVehicle(
kind: String
): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val baseY =
centerY
val lower =
kind.toLowerCase(
Locale.ENGLISH
)
var bodyColor =
new Color(
60,
120,
220
)
if (
lower.indexOf(
"fire"
) >= 0
) {
bodyColor =
new Color(
230,
45,
40
)
}
if (
lower.indexOf(
"police"
) >= 0
) {
bodyColor =
new Color(
45,
55,
85
)
}
if (
lower.indexOf(
"school"
) >= 0
) {
bodyColor =
new Color(
245,
185,
40
)
}
g.setColor(
bodyColor
)
if (
lower.indexOf(
"bike"
) >= 0 ||
lower.indexOf(
"cycle"
) >= 0 ||
lower.indexOf(
"bicycle"
) >= 0
) {
g.setStroke(
new BasicStroke(
7
)
)
g.drawOval(
cx - 180,
baseY + 10,
110,
110
)
g.drawOval(
cx + 70,
baseY + 10,
110,
110
)
g.drawLine(
cx - 125,
baseY + 65,
cx - 20,
baseY - 35
)
g.drawLine(
cx - 20,
baseY - 35,
cx + 125,
baseY + 65
)
g.drawLine(
cx - 125,
baseY + 65,
cx + 125,
baseY + 65
)
g.drawLine(
cx + 125,
baseY + 65,
cx + 70,
baseY - 30
)
} else {
g.fillRoundRect(
cx - 260,
baseY - 50,
520,
120,
30,
30
)
g.setColor(
new Color(
150,
215,
240
)
)
g.fillRoundRect(
cx - 155,
baseY - 120,
300,
80,
25,
25
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 185,
baseY + 35,
85,
85
)
g.fillOval(
cx + 100,
baseY + 35,
85,
85
)
}
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW GENERIC ANIMAL
// ============================================================
def drawAnimal(
kind: String
): Unit = {
val lower =
kind.toLowerCase(
Locale.ENGLISH
)
if (
lower.indexOf(
"bird"
) >= 0
) {
drawBird()
return
}
if (
lower.indexOf(
"cat"
) >= 0
) {
drawCat()
return
}
if (
lower.indexOf(
"dog"
) >= 0
) {
drawDog()
return
}
if (
lower.indexOf(
"fish"
) >= 0
) {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
g.setColor(
new Color(
70,
150,
230
)
)
g.fillOval(
cx - 170,
cy - 95,
340,
190
)
val tail =
new java.awt.Polygon()
tail.addPoint(
cx + 150,
cy
)
tail.addPoint(
cx + 255,
cy - 90
)
tail.addPoint(
cx + 255,
cy + 90
)
g.fillPolygon(
tail
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 85,
cy - 45,
22,
22
)
g.dispose()
canvas.repaint()
return
}
// Default animal = simple friendly animal
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
g.setColor(
new Color(
190,
145,
95
)
)
g.fillOval(
cx - 155,
cy - 15,
310,
205
)
g.fillOval(
cx - 120,
cy - 160,
240,
200
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 65,
cy - 90,
18,
20
)
g.fillOval(
cx + 45,
cy - 90,
18,
20
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW FOOD
// ============================================================
def drawFood(
kind: String
): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
val lower =
kind.toLowerCase(
Locale.ENGLISH
)
if (
lower.indexOf(
"apple"
) >= 0
) {
g.setColor(
new Color(
220,
40,
45
)
)
g.fillOval(
cx - 115,
cy - 100,
115,
170
)
g.fillOval(
cx,
cy - 100,
115,
170
)
g.setColor(
new Color(
80,
140,
60
)
)
g.fillOval(
cx + 35,
cy - 140,
70,
32
)
} else if (
lower.indexOf(
"pizza"
) >= 0
) {
val pizza =
new java.awt.Polygon()
pizza.addPoint(
cx,
cy - 190
)
pizza.addPoint(
cx - 230,
cy + 155
)
pizza.addPoint(
cx + 230,
cy + 155
)
g.setColor(
new Color(
240,
175,
45
)
)
g.fillPolygon(
pizza
)
g.setColor(
new Color(
205,
45,
45
)
)
g.fillOval(
cx - 100,
cy + 5,
38,
38
)
g.fillOval(
cx + 40,
cy - 15,
38,
38
)
} else {
g.setColor(
new Color(
240,
170,
60
)
)
g.fillOval(
cx - 190,
cy - 100,
380,
210
)
}
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW BUILDING
// ============================================================
def drawBuilding(
kind: String
): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val lower =
kind.toLowerCase(
Locale.ENGLISH
)
var buildingColor =
new Color(
220,
190,
130
)
if (
lower.indexOf(
"hospital"
) >= 0
) {
buildingColor =
Color.WHITE
}
if (
lower.indexOf(
"school"
) >= 0
) {
buildingColor =
new Color(
245,
205,
120
)
}
if (
lower.indexOf(
"castle"
) >= 0
) {
buildingColor =
new Color(
180,
170,
210
)
}
g.setColor(
buildingColor
)
g.fillRect(
cx - 200,
80,
400,
380
)
g.setColor(
new Color(
80,
150,
220
)
)
var row =
0
while (
row < 3
) {
var col =
0
while (
col < 4
) {
g.fillRect(
cx - 160 +
col * 95,
115 +
row * 105,
55,
65
)
col += 1
}
row += 1
}
g.setColor(
new Color(
125,
80,
50
)
)
g.fillRect(
cx - 48,
360,
96,
100
)
if (
lower.indexOf(
"hospital"
) >= 0
) {
g.setColor(
Color.RED
)
g.fillRect(
cx - 15,
145,
30,
100
)
g.fillRect(
cx - 50,
180,
100,
30
)
}
if (
lower.indexOf(
"castle"
) >= 0
) {
g.setColor(
new Color(
110,
80,
150
)
)
var i =
-1
while (
i <= 1
) {
g.fillRect(
cx + i * 175 - 30,
25,
60,
80
)
i += 1
}
}
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW NATURE
// ============================================================
def drawNature(
kind: String
): Unit = {
val lower =
kind.toLowerCase(
Locale.ENGLISH
)
if (
lower.indexOf(
"tree"
) >= 0 ||
lower.indexOf(
"forest"
) >= 0
) {
drawTree()
return
}
if (
lower.indexOf(
"flower"
) >= 0 ||
lower.indexOf(
"rose"
) >= 0
) {
drawFlower()
return
}
drawSun()
}
// ============================================================
// DRAW IDEA FALLBACK
// ============================================================
def drawUnknown(
text: String
): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
g.setColor(
new Color(
70,
90,
125
)
)
g.setStroke(
new BasicStroke(
4
)
)
g.drawRoundRect(
80,
80,
W - 160,
H - 160,
25,
25
)
g.setColor(
new Color(
40,
55,
85
)
)
g.setFont(
new Font(
"Arial",
Font.BOLD,
72
)
)
val word =
text.toUpperCase(
Locale.ENGLISH
)
val width =
g.getFontMetrics
.stringWidth(
word
)
val x =
math.max(
25,
(W - width) / 2
)
g.drawString(
word,
x,
H / 2
)
g.setFont(
new Font(
"Arial",
Font.PLAIN,
20
)
)
g.drawString(
"Add a known object name to create its built-in drawing.",
230,
H / 2 + 65
)
g.dispose()
canvas.repaint()
}
// ============================================================
// WORD SEARCH HELPER
// ============================================================
def hasAny(
text: String,
words: Array[String]
): Boolean = {
var i =
0
while (
i < words.length
) {
if (
text.indexOf(
words(i)
) >= 0
) {
return true
}
i += 1
}
false
}
// ============================================================
// 100+ OBJECT CATEGORIES
// ============================================================
// VEHICLES
val vehicleWords =
Array(
"car",
"auto",
"automobile",
"taxi",
"bus",
"truck",
"lorry",
"van",
"jeep",
"suv",
"bike",
"bicycle",
"cycle",
"motorcycle",
"scooter",
"motorbike",
"rickshaw",
"train",
"railway",
"metro",
"tram",
"subway",
"airplane",
"plane",
"aeroplane",
"jet",
"helicopter",
"rocket",
"ship",
"boat",
"yacht",
"submarine",
"ambulance",
"firetruck",
"fire truck",
"police car",
"school bus"
)
// ANIMALS
val animalWords =
Array(
"cat",
"kitten",
"dog",
"puppy",
"bird",
"fish",
"shark",
"whale",
"dolphin",
"octopus",
"turtle",
"tortoise",
"rabbit",
"bunny",
"mouse",
"rat",
"hamster",
"horse",
"pony",
"cow",
"buffalo",
"goat",
"sheep",
"pig",
"chicken",
"hen",
"rooster",
"duck",
"eagle",
"parrot",
"peacock",
"owl",
"crow",
"pigeon",
"sparrow",
"penguin",
"lion",
"tiger",
"leopard",
"cheetah",
"elephant",
"giraffe",
"zebra",
"monkey",
"gorilla",
"bear",
"panda",
"fox",
"wolf",
"deer",
"camel",
"kangaroo",
"snake",
"crocodile",
"frog",
"butterfly",
"bee",
"ant"
)
// FOOD
val foodWords =
Array(
"apple",
"banana",
"orange",
"mango",
"watermelon",
"grapes",
"strawberry",
"pineapple",
"coconut",
"lemon",
"pizza",
"burger",
"sandwich",
"cake",
"donut",
"ice cream",
"icecream",
"chocolate",
"cookie",
"bread",
"rice",
"noodles",
"fries",
"egg",
"cheese",
"cupcake",
"lollipop",
"candy",
"hotdog",
"popcorn"
)
// BUILDINGS
val buildingWords =
Array(
"house",
"home",
"building",
"school",
"hospital",
"hotel",
"shop",
"store",
"office",
"bank",
"library",
"museum",
"church",
"temple",
"mosque",
"castle",
"palace",
"tower",
"lighthouse",
"stadium",
"airport",
"station",
"factory",
"restaurant"
)
// PEOPLE / CHARACTERS
val personWords =
Array(
"boy",
"girl",
"man",
"woman",
"person",
"human",
"child",
"baby",
"kid",
"teacher",
"doctor",
"nurse",
"police",
"fireman",
"farmer",
"soldier",
"king",
"queen",
"prince",
"princess",
"superhero",
"robot"
)
// NATURE
val natureWords =
Array(
"tree",
"forest",
"plant",
"flower",
"rose",
"sun",
"moon",
"star",
"cloud",
"rain",
"rainbow",
"mountain",
"hill",
"river",
"lake",
"waterfall",
"volcano",
"island",
"beach",
"garden",
"desert",
"snow",
"snowman"
)
// SPORTS / OBJECTS
val sportsWords =
Array(
"football",
"soccer",
"cricket",
"bat",
"ball",
"tennis",
"basketball",
"baseball",
"hockey",
"golf",
"medal",
"trophy",
"football goal",
"goal",
"net"
)
// SCHOOL / DAILY OBJECTS
val objectWords =
Array(
"book",
"notebook",
"pen",
"pencil",
"eraser",
"ruler",
"bag",
"schoolbag",
"computer",
"laptop",
"phone",
"mobile",
"television",
"tv",
"camera",
"clock",
"watch",
"lamp",
"chair",
"table",
"bed",
"sofa",
"door",
"window",
"key",
"umbrella",
"bottle",
"cup",
"glass",
"plate"
)
// ============================================================
// DRAW FROM TEXT
// ============================================================
def drawFromText(
originalText: String
): Unit = {
val text =
originalText
.trim
.toLowerCase(
Locale.ENGLISH
)
if (
text.length == 0
) {
JOptionPane.showMessageDialog(
frame,
"WRITE ????? ??????? ????.",
"DRAW IT",
JOptionPane.INFORMATION_MESSAGE
)
return
}
rememberUndo()
// ----------------------------------------------------------
// ROBOT
// ----------------------------------------------------------
if (
hasAny(
text,
Array(
"robot",
"android"
)
)
) {
drawRobot()
status.setText(
"Robot drawing created!"
)
return
}
// ----------------------------------------------------------
// PEOPLE
// ----------------------------------------------------------
if (
hasAny(
text,
personWords
)
) {
drawPerson()
status.setText(
"Person drawing created!"
)
return
}
// ----------------------------------------------------------
// ANIMALS
// ----------------------------------------------------------
if (
hasAny(
text,
animalWords
)
) {
drawAnimal(
text
)
status.setText(
"Animal drawing created!"
)
return
}
// ----------------------------------------------------------
// FOOD
// ----------------------------------------------------------
if (
hasAny(
text,
foodWords
)
) {
drawFood(
text
)
status.setText(
"Food drawing created!"
)
return
}
// ----------------------------------------------------------
// BUILDINGS
// ----------------------------------------------------------
if (
hasAny(
text,
buildingWords
)
) {
if (
text.indexOf("house") >= 0 ||
text.indexOf("home") >= 0
) {
drawHouse()
} else {
drawBuilding(
text
)
}
status.setText(
"Building drawing created!"
)
return
}
// ----------------------------------------------------------
// VEHICLES
// ----------------------------------------------------------
if (
hasAny(
text,
vehicleWords
)
) {
if (
text.indexOf("car") >= 0 ||
text.indexOf("auto") >= 0 ||
text.indexOf("taxi") >= 0 ||
text.indexOf("jeep") >= 0 ||
text.indexOf("suv") >= 0 ||
text.indexOf("van") >= 0
) {
drawCar()
} else {
drawVehicle(
text
)
}
status.setText(
"Vehicle drawing created!"
)
return
}
// ----------------------------------------------------------
// NATURE
// ----------------------------------------------------------
if (
hasAny(
text,
natureWords
)
) {
if (
text.indexOf("tree") >= 0 ||
text.indexOf("forest") >= 0
) {
drawTree()
} else if (
text.indexOf("flower") >= 0 ||
text.indexOf("rose") >= 0
) {
drawFlower()
} else if (
text.indexOf("sun") >= 0
) {
drawSun()
} else {
drawNature(
text
)
}
status.setText(
"Nature drawing created!"
)
return
}
// ----------------------------------------------------------
// SPORTS
// ----------------------------------------------------------
if (
hasAny(
text,
sportsWords
)
) {
drawBall(
text
)
status.setText(
"Sports drawing created!"
)
return
}
// ----------------------------------------------------------
// GENERAL OBJECTS
// ----------------------------------------------------------
if (
hasAny(
text,
objectWords
)
) {
drawSimpleObject(
text
)
status.setText(
"Object drawing created!"
)
return
}
// ----------------------------------------------------------
// STAR
// ----------------------------------------------------------
if (
text.indexOf("star") >= 0
) {
drawStar()
status.setText(
"Star drawing created!"
)
return
}
// ----------------------------------------------------------
// UNKNOWN
// ----------------------------------------------------------
drawUnknown(
text
)
status.setText(
"Drawing created from the written idea."
)
}
// ============================================================
// DRAW SPORTS BALL
// ============================================================
def drawBall(
kind: String
): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val cx =
centerX
val cy =
centerY
var ballColor =
Color.WHITE
if (
kind.indexOf("football") >= 0 ||
kind.indexOf("soccer") >= 0
) {
ballColor =
Color.WHITE
}
if (
kind.indexOf("basket") >= 0
) {
ballColor =
new Color(
235,
135,
45
)
}
if (
kind.indexOf("tennis") >= 0
) {
ballColor =
new Color(
210,
240,
70
)
}
if (
kind.indexOf("cricket") >= 0
) {
ballColor =
new Color(
190,
35,
45
)
}
g.setColor(
ballColor
)
g.fillOval(
cx - 135,
cy - 135,
270,
270
)
g.setColor(
Color.BLACK
)
g.setStroke(
new BasicStroke(
5
)
)
g.drawOval(
cx - 135,
cy - 135,
270,
270
)
// Decorative lines
g.drawArc(
cx - 80,
cy - 115,
180,
230,
20,
210
)
g.drawArc(
cx - 115,
cy - 65,
230,
150,
150,
180
)
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW SIMPLE OBJECT
// ============================================================
def drawSimpleObject(
kind: String
): Unit = {
val g =
drawingImage.createGraphics()
setupAA(g)
setupWhite(g)
val lower =
kind.toLowerCase(
Locale.ENGLISH
)
val cx =
centerX
val cy =
centerY
if (
lower.indexOf("book") >= 0 ||
lower.indexOf("notebook") >= 0
) {
g.setColor(
new Color(
55,
100,
200
)
)
g.fillRoundRect(
cx - 180,
cy - 120,
360,
245,
12,
12
)
g.setColor(
Color.WHITE
)
g.fillRect(
cx - 145,
cy - 80,
290,
160
)
} else if (
lower.indexOf("phone") >= 0 ||
lower.indexOf("mobile") >= 0
) {
g.setColor(
Color.DARK_GRAY
)
g.fillRoundRect(
cx - 100,
cy - 190,
200,
380,
30,
30
)
g.setColor(
new Color(
100,
180,
240
)
)
g.fillRoundRect(
cx - 78,
cy - 145,
156,
285,
12,
12
)
g.setColor(
Color.BLACK
)
g.fillOval(
cx - 15,
cy + 150,
30,
30
)
} else if (
lower.indexOf("clock") >= 0 ||
lower.indexOf("watch") >= 0
) {
g.setColor(
Color.WHITE
)
g.fillOval(
cx - 145,
cy - 145,
290,
290
)
g.setColor(
Color.DARK_GRAY
)
g.setStroke(
new BasicStroke(
8
)
)
g.drawOval(
cx - 145,
cy - 145,
290,
290
)
g.drawLine(
cx,
cy,
cx,
cy - 85
)
g.drawLine(
cx,
cy,
cx + 65,
cy
)
} else if (
lower.indexOf("lamp") >= 0
) {
g.setColor(
new Color(
240,
190,
60
)
)
val shade =
new java.awt.Polygon()
shade.addPoint(
cx - 110,
cy - 150
)
shade.addPoint(
cx + 110,
cy - 150
)
shade.addPoint(
cx + 70,
cy - 20
)
shade.addPoint(
cx - 70,
cy - 20
)
g.fillPolygon(
shade
)
g.setColor(
Color.DARK_GRAY
)
g.setStroke(
new BasicStroke(
14
)
)
g.drawLine(
cx,
cy - 20,
cx,
cy + 160
)
g.drawLine(
cx - 65,
cy + 160,
cx + 65,
cy + 160
)
} else {
// Generic colorful object
g.setColor(
new Color(
80,
135,
225
)
)
g.fillRoundRect(
cx - 160,
cy - 120,
320,
240,
30,
30
)
g.setColor(
Color.YELLOW
)
g.fillOval(
cx - 65,
cy - 65,
130,
130
)
}
g.dispose()
canvas.repaint()
}
// ============================================================
// DRAW IDEA BUTTON
// ============================================================
drawItButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
drawFromText(
writeField.getText
)
}
}
)
// ============================================================
// ENTER KEY SUPPORT
// ============================================================
writeField.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
drawFromText(
writeField.getText
)
}
}
)
// ============================================================
// COLORIZE THEMES
// ============================================================
val themes =
Array(
"COLORFUL GARDEN",
"SUNNY DAY",
"BEAUTIFUL SUNSET",
"NIGHT SKY",
"SPACE",
"DEEP OCEAN",
"BEACH",
"FOREST",
"MOUNTAIN",
"RAINBOW",
"CARTOON WORLD",
"MAGICAL WORLD",
"CITY",
"NEON CITY",
"SNOW WORLD",
"DESERT",
"PINK DREAM",
"BLUE DREAM",
"GREEN NATURE",
"GOLDEN WORLD"
)
// ============================================================
// BACKGROUND THEME
// ============================================================
def makeThemeBackground(
g: Graphics2D,
theme: String
): Unit = {
val upper =
theme.toUpperCase(
Locale.ENGLISH
)
var top =
new Color(
155,
215,
255
)
var bottom =
new Color(
90,
180,
100
)
if (
upper.indexOf(
"SUNNY"
) >= 0
) {
top =
new Color(
100,
195,
255
)
bottom =
new Color(
255,
225,
120
)
}
if (
upper.indexOf(
"SUNSET"
) >= 0
) {
top =
new Color(
255,
110,
90
)
bottom =
new Color(
115,
65,
155
)
}
if (
upper.indexOf(
"NIGHT"
) >= 0
) {
top =
new Color(
20,
28,
80
)
bottom =
new Color(
65,
50,
105
)
}
if (
upper.indexOf(
"SPACE"
) >= 0
) {
top =
new Color(
5,
5,
30
)
bottom =
new Color(
35,
10,
70
)
}
if (
upper.indexOf(
"OCEAN"
) >= 0
) {
top =
new Color(
100,
220,
255
)
bottom =
new Color(
20,
80,
190
)
}
if (
upper.indexOf(
"BEACH"
) >= 0
) {
top =
new Color(
105,
215,
255
)
bottom =
new Color(
245,
210,
135
)
}
if (
upper.indexOf(
"FOREST"
) >= 0 ||
upper.indexOf(
"NATURE"
) >= 0
) {
top =
new Color(
175,
235,
205
)
bottom =
new Color(
55,
145,
65
)
}
if (
upper.indexOf(
"MOUNTAIN"
) >= 0
) {
top =
new Color(
175,
220,
255
)
bottom =
new Color(
110,
130,
155
)
}
if (
upper.indexOf(
"RAINBOW"
) >= 0
) {
top =
new Color(
255,
170,
210
)
bottom =
new Color(
130,
210,
255
)
}
if (
upper.indexOf(
"CARTOON"
) >= 0
) {
top =
new Color(
255,
230,
100
)
bottom =
new Color(
120,
220,
130
)
}
if (
upper.indexOf(
"MAGICAL"
) >= 0
) {
top =
new Color(
195,
125,
255
)
bottom =
new Color(
90,
55,
165
)
}
if (
upper.indexOf(
"CITY"
) >= 0
) {
top =
new Color(
125,
150,
200
)
bottom =
new Color(
60,
65,
80
)
}
if (
upper.indexOf(
"NEON"
) >= 0
) {
top =
new Color(
10,
15,
60
)
bottom =
new Color(
70,
0,
100
)
}
if (
upper.indexOf(
"SNOW"
) >= 0
) {
top =
Color.WHITE
bottom =
new Color(
175,
220,
250
)
}
if (
upper.indexOf(
"DESERT"
) >= 0
) {
top =
new Color(
255,
215,
145
)
bottom =
new Color(
205,
145,
85
)
}
if (
upper.indexOf(
"PINK"
) >= 0
) {
top =
new Color(
255,
190,
225
)
bottom =
new Color(
245,
110,
180
)
}
if (
upper.indexOf(
"BLUE"
) >= 0
) {
top =
new Color(
180,
225,
255
)
bottom =
new Color(
70,
120,
220
)
}
if (
upper.indexOf(
"GREEN"
) >= 0
) {
top =
new Color(
190,
240,
200
)
bottom =
new Color(
55,
160,
75
)
}
if (
upper.indexOf(
"GOLDEN"
) >= 0
) {
top =
new Color(
255,
230,
130
)
bottom =
new Color(
210,
145,
45
)
}
if (
upper.indexOf(
"DREAM"
) >= 0
) {
top =
new Color(
215,
190,
255
)
bottom =
new Color(
120,
190,
255
)
}
g.setPaint(
new GradientPaint(
0,
0,
top,
0,
H,
bottom
)
)
g.fillRect(
0,
0,
W,
H
)
}
// ============================================================
// DECORATIONS
// ============================================================
def addThemeDecorations(
g: Graphics2D,
theme: String
): Unit = {
val upper =
theme.toUpperCase(
Locale.ENGLISH
)
// Clouds
if (
upper.indexOf("NIGHT") < 0 &&
upper.indexOf("SPACE") < 0
) {
g.setColor(
new Color(
255,
255,
255,
125
)
)
g.fillOval(
60,
65,
140,
45
)
g.fillOval(
100,
40,
100,
70
)
g.fillOval(
160,
65,
145,
45
)
}
// Sun
if (
upper.indexOf("SUN") >= 0 ||
upper.indexOf("SUNNY") >= 0 ||
upper.indexOf("BEACH") >= 0 ||
upper.indexOf("SUNSET") >= 0 ||
upper.indexOf("GARDEN") >= 0
) {
g.setColor(
new Color(
255,
210,
45
)
)
g.fillOval(
W - 155,
45,
100,
100
)
}
// Stars
if (
upper.indexOf("NIGHT") >= 0 ||
upper.indexOf("SPACE") >= 0 ||
upper.indexOf("MAGICAL") >= 0
) {
g.setColor(
Color.WHITE
)
var i =
0
while (
i < 55
) {
val x =
(i * 83) % W
val y =
(i * 47) % 300
g.fillOval(
x,
y,
4,
4
)
i += 1
}
}
// Rainbow
if (
upper.indexOf(
"RAINBOW"
) >= 0
) {
val rainbowColors =
Array(
Color.RED,
Color.ORANGE,
Color.YELLOW,
Color.GREEN,
Color.CYAN,
Color.BLUE,
Color.MAGENTA
)
var i =
0
while (
i < rainbowColors.length
) {
g.setColor(
rainbowColors(i)
)
g.setStroke(
new BasicStroke(
10.0f
)
)
g.drawArc(
250,
140 + i * 10,
500 - i * 20,
330 - i * 20,
0,
180
)
i += 1
}
}
// Ground
if (
upper.indexOf("OCEAN") >= 0 ||
upper.indexOf("BEACH") >= 0
) {
g.setColor(
new Color(
30,
125,
190,
180
)
)
g.fillRect(
0,
H - 100,
W,
100
)
} else if (
upper.indexOf("SPACE") < 0 &&
upper.indexOf("NIGHT") < 0
) {
g.setColor(
new Color(
75,
165,
80,
175
)
)
g.fillRect(
0,
H - 100,
W,
100
)
}
}
// ============================================================
// COLORIZE IMAGE
// ============================================================
def colorizeDrawing(
theme: String
): BufferedImage = {
val result =
new BufferedImage(
W,
H,
BufferedImage.TYPE_INT_RGB
)
val g =
result.createGraphics()
setupAA(g)
// Background first
makeThemeBackground(
g,
theme
)
addThemeDecorations(
g,
theme
)
// ----------------------------------------------------------
// Draw original image over background
// ----------------------------------------------------------
g.drawImage(
drawingImage,
0,
0,
null
)
// ----------------------------------------------------------
// Soft glow
// ----------------------------------------------------------
g.setColor(
new Color(
255,
255,
255,
45
)
)
g.fillOval(
centerX - 230,
centerY - 230,
460,
460
)
// ----------------------------------------------------------
// Highlight dots
// ----------------------------------------------------------
g.setColor(
Color.WHITE
)
var i =
0
while (
i < 28
) {
val x =
(i * 71) % W
val y =
(i * 43) % H
g.fillOval(
x,
y,
4,
4
)
i += 1
}
// ----------------------------------------------------------
// Frame
// ----------------------------------------------------------
g.setColor(
new Color(
30,
50,
90,
190
)
)
g.setStroke(
new BasicStroke(
5
)
)
g.drawRoundRect(
8,
8,
W - 16,
H - 16,
25,
25
)
// ----------------------------------------------------------
// Theme title
// ----------------------------------------------------------
g.setColor(
new Color(
20,
30,
50,
185
)
)
g.fillRoundRect(
20,
20,
230,
40,
15,
15
)
g.setColor(
Color.WHITE
)
g.setFont(
new Font(
"Arial",
Font.BOLD,
14
)
)
g.drawString(
theme,
35,
45
)
g.dispose()
result
}
// ============================================================
// COLORIZE OPTION DIALOG
// ============================================================
def chooseColorTheme(): Unit = {
val combo =
new JComboBox[String](
themes
)
combo.setSelectedIndex(
0
)
val panel =
new JPanel(
new BorderLayout(
10,
10
)
)
panel.add(
new JLabel(
"???????? drawing ??? ???????"
),
BorderLayout.NORTH
)
panel.add(
combo,
BorderLayout.CENTER
)
val answer =
JOptionPane.showConfirmDialog(
frame,
panel,
"COLORIZE DRAWING",
JOptionPane.OK_CANCEL_OPTION,
JOptionPane.PLAIN_MESSAGE
)
if (
answer ==
JOptionPane.OK_OPTION
) {
val selected =
combo
.getSelectedItem
.toString
rememberUndo()
status.setText(
"Colorizing: " +
selected
)
val result =
colorizeDrawing(
selected
)
restoreImage(
result
)
canvas.repaint()
status.setText(
"Colorize complete: " +
selected
)
}
}
// ============================================================
// COLORIZE BUTTON
// ============================================================
colorizeButton.addActionListener(
new ActionListener {
override def actionPerformed(
e: ActionEvent
): Unit = {
chooseColorTheme()
}
}
)
// ============================================================
// KEYBOARD SHORTCUTS
// ============================================================
frame.addKeyListener(
new java.awt.event.KeyAdapter {
override def keyPressed(
e: java.awt.event.KeyEvent
): Unit = {
if (
e.isControlDown &&
e.getKeyCode ==
java.awt.event.KeyEvent.VK_Z
) {
undoButton.doClick()
}
if (
e.isControlDown &&
e.getKeyCode ==
java.awt.event.KeyEvent.VK_Y
) {
redoButton.doClick()
}
}
}
)
frame.setFocusable(
true
)
// ============================================================
// FINAL LAYOUT
// ============================================================
frame.setLayout(
new BorderLayout()
)
frame.add(
toolbar,
BorderLayout.NORTH
)
frame.add(
canvas,
BorderLayout.CENTER
)
val bottom =
new JPanel(
new FlowLayout(
FlowLayout.LEFT,
8,
5
)
)
bottom.add(
status
)
frame.add(
bottom,
BorderLayout.SOUTH
)
// ============================================================
// START
// ============================================================
SwingUtilities.invokeLater(
new Runnable {
override def run(): Unit = {
frame.setVisible(
true
)
canvas.requestFocusInWindow()
}
}
)