Skip to content

Instantly share code, notes, and snippets.

@AChep
Last active January 5, 2018 13:37
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AChep/d2ee0e2767fcba3c2952a23366234e29 to your computer and use it in GitHub Desktop.
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.
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