Last active
January 5, 2018 13:37
-
-
Save AChep/d2ee0e2767fcba3c2952a23366234e29 to your computer and use it in GitHub Desktop.
Copy paste code to Filename.kt and compile (Kotlin required). Supported keys: TAB to select or switch between figures, ARROWS to move them.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.awt.Color | |
import java.awt.Graphics | |
import java.awt.Graphics2D | |
import java.awt.RenderingHints | |
import java.awt.event.* | |
import javax.swing.SwingUtilities | |
import javax.swing.JFrame | |
import javax.swing.JPanel | |
fun main(args: Array<String>) { | |
SwingUtilities.invokeLater { | |
createAndShowGUI() | |
} | |
} | |
fun createAndShowGUI() { | |
JFrame().run { | |
setSize(640, 480) | |
title = "Artem Chepurnoy" | |
defaultCloseOperation = JFrame.EXIT_ON_CLOSE | |
contentPane.add(SurfaceFrame().apply { | |
isFocusable = true | |
focusTraversalKeysEnabled = false // so we can detect tab | |
requestFocusInWindow() | |
}) | |
isVisible = true | |
} | |
} | |
/** | |
* @author Artem Chepurnoy | |
*/ | |
class SurfaceFrame : JPanel(), KeyListener, MouseListener, MouseMotionListener { | |
private var i: Int = 0 | |
private val figures: MutableList<Figure> = ArrayList() | |
private var mouseX: Int = 0 | |
private var mouseY: Int = 0 | |
init { | |
(0 until 10).mapTo(figures) { | |
OvalFigure().apply { | |
h = 32 | |
w = 32 | |
x = 16 + it * (w + 8) | |
y = 16 | |
} | |
} | |
// add interactive listeners | |
addKeyListener(this) | |
addMouseListener(this) | |
addMouseMotionListener(this) | |
} | |
override fun paint(g: Graphics) { | |
super.paint(g) | |
(g as Graphics2D).setRenderingHint( | |
RenderingHints.KEY_ANTIALIASING, | |
RenderingHints.VALUE_ANTIALIAS_ON) | |
figures.forEachIndexed { index, figure -> figure.paint(g, index == i) } | |
} | |
// | |
// KEYS | |
// | |
override fun keyTyped(e: KeyEvent?) { | |
} | |
override fun keyPressed(e: KeyEvent) { | |
when (e.keyCode) { | |
KeyEvent.VK_TAB -> { | |
// Switch to next figure | |
i++ | |
if (i == figures.size) { | |
i = 0 | |
} | |
repaint() | |
} | |
else -> { | |
if (i >= 0) when (e.keyCode) { | |
KeyEvent.VK_LEFT -> translateFigureByX(figures[i], -10) | |
KeyEvent.VK_RIGHT -> translateFigureByX(figures[i], 10) | |
KeyEvent.VK_UP -> translateFigureByY(figures[i], -10) | |
KeyEvent.VK_DOWN -> translateFigureByY(figures[i], 10) | |
else -> return | |
} | |
repaint() | |
} | |
} | |
} | |
override fun keyReleased(e: KeyEvent?) { | |
} | |
// | |
// MOUSE | |
// | |
override fun mouseReleased(e: MouseEvent?) { | |
} | |
override fun mouseEntered(e: MouseEvent?) { | |
} | |
override fun mouseClicked(e: MouseEvent?) { | |
} | |
override fun mouseExited(e: MouseEvent?) { | |
} | |
override fun mousePressed(e: MouseEvent) { | |
mouseX = e.x | |
mouseY = e.y | |
figures.forEachIndexed { index, figure -> | |
if (figure.isTouched(mouseX, mouseY)) { | |
i = index | |
return | |
} | |
} | |
i = -1 | |
repaint() | |
} | |
override fun mouseMoved(e: MouseEvent?) { | |
} | |
override fun mouseDragged(e: MouseEvent) { | |
if (i >= 0) { | |
figures[i].also { | |
translateFigureByX(it, -mouseX + e.x) | |
translateFigureByY(it, -mouseY + e.y) | |
} | |
mouseX = e.x | |
mouseY = e.y | |
repaint() | |
} | |
} | |
private fun translateFigureByX(f: Figure, dx: Int) { | |
// TODO: We can prevent moving figure out of the panel here | |
f.x += dx | |
} | |
private fun translateFigureByY(f: Figure, dy: Int) { | |
// TODO: We can prevent moving figure out of the panel here | |
f.y += dy | |
} | |
} | |
/** | |
* @author Artem Chepurnoy | |
*/ | |
abstract class Figure { | |
companion object { | |
val COLOR_NORMAL = Color(180, 90, 70) | |
val COLOR_ACTIVATED = Color(90, 130, 240) | |
} | |
// X;Y pair represents top-left point | |
// of the figure. | |
var x = 0 | |
var y = 0 | |
/** width */ | |
var w = 0 | |
/** height */ | |
var h = 0 | |
open fun paint(g: Graphics, activated: Boolean) { | |
val color = if (activated) COLOR_ACTIVATED else COLOR_NORMAL | |
paint(g, color) | |
} | |
open fun isTouched(lx: Int, ly: Int): Boolean = lx in x..x + w && ly in y..y + h | |
abstract fun paint(g: Graphics, color: Color) | |
} | |
/** | |
* @author Artem Chepurnoy | |
*/ | |
class OvalFigure : Figure() { | |
override fun paint(g: Graphics, color: Color) { | |
g.color = color | |
g.fillOval(x, y, w, h) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment