mig and other goodies
This commit is contained in:
@@ -1,24 +1,27 @@
|
||||
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
|
||||
|
||||
plugins {
|
||||
kotlin("jvm") version "2.1.10"
|
||||
kotlin("jvm") version "2.2.0"
|
||||
`maven-publish` // for publishToMavenLocal
|
||||
id("org.jetbrains.dokka-javadoc") version "2.0.0"
|
||||
}
|
||||
|
||||
group = "net.eksb"
|
||||
|
||||
dependencies {}
|
||||
dependencies {
|
||||
api("com.miglayout:miglayout-swing:11.4.2")
|
||||
}
|
||||
|
||||
java {
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
toolchain {
|
||||
languageVersion.set(JavaLanguageVersion.of(21))
|
||||
}
|
||||
|
||||
withSourcesJar()
|
||||
}
|
||||
kotlin {
|
||||
compilerOptions {
|
||||
jvmTarget.set(JvmTarget.JVM_17)
|
||||
jvmTarget.set(JvmTarget.JVM_21)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
13
src/main/kotlin/net/eksb/kswingutil/SwingUtil.kt
Normal file
13
src/main/kotlin/net/eksb/kswingutil/SwingUtil.kt
Normal file
@@ -0,0 +1,13 @@
|
||||
package net.eksb.kswingutil
|
||||
|
||||
import javax.swing.UIManager
|
||||
|
||||
fun systemLookAndFeel() {
|
||||
try {
|
||||
UIManager.setLookAndFeel(
|
||||
UIManager.getSystemLookAndFeelClassName()
|
||||
)
|
||||
} catch ( e:java.lang.Exception) {
|
||||
System.err.println( "Error setting laf: ${e.message}" )
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,10 @@ package net.eksb.kswingutil.ext
|
||||
|
||||
import net.eksb.kswingutil.property.MutableProperty
|
||||
import net.eksb.kswingutil.property.Property
|
||||
import java.awt.Color
|
||||
import java.awt.Component
|
||||
import javax.swing.JComponent
|
||||
import javax.swing.border.Border
|
||||
|
||||
/**
|
||||
* One-way bind a [java.awt.Component] to a [Property].
|
||||
@@ -82,4 +85,22 @@ fun <T> Component.bind(
|
||||
|
||||
// initialize component with the property's value
|
||||
propertyToComponent()
|
||||
}
|
||||
}
|
||||
|
||||
fun JComponent.bindTooltipText(property:Property<String>) {
|
||||
bind(property) {
|
||||
toolTipText = it
|
||||
}
|
||||
}
|
||||
|
||||
fun JComponent.bindBackground(property:Property<Color>) {
|
||||
bind(property) {
|
||||
background = it
|
||||
}
|
||||
}
|
||||
|
||||
fun JComponent.bindBorder(property:Property<Border>) {
|
||||
bind(property) {
|
||||
border = it
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,6 +5,9 @@ import net.eksb.kswingutil.property.Property
|
||||
import net.eksb.kswingutil.ext.bind
|
||||
import java.awt.Component
|
||||
import java.awt.Container
|
||||
import java.awt.Font
|
||||
import java.awt.event.MouseAdapter
|
||||
import java.awt.event.MouseEvent
|
||||
import javax.swing.BorderFactory
|
||||
import javax.swing.Box
|
||||
import javax.swing.DefaultComboBoxModel
|
||||
@@ -87,3 +90,30 @@ fun <T> JComboBox<T>.bind(property:MutableProperty<T>) {
|
||||
|
||||
fun Container.button(constraints:Any?=null, text:String?=null, block:JButton.()->Unit = {}):JButton = add(constraints,
|
||||
JButton(text),block)
|
||||
|
||||
fun JComponent.onHover(
|
||||
enter:(MouseEvent)->Unit,
|
||||
exit:(MouseEvent)->Unit
|
||||
) {
|
||||
addMouseListener(object: MouseAdapter() {
|
||||
override fun mouseEntered(e: MouseEvent) {
|
||||
enter.invoke(e)
|
||||
}
|
||||
override fun mouseExited(e: MouseEvent) {
|
||||
exit.invoke(e)
|
||||
}
|
||||
})
|
||||
|
||||
}
|
||||
fun JComponent.hoverProperty(): Property<Boolean> =
|
||||
MutableProperty(false).apply {
|
||||
onHover(
|
||||
enter = { e -> value = true },
|
||||
exit = { e -> value = false }
|
||||
)
|
||||
}
|
||||
|
||||
fun JComponent.bold() {
|
||||
font = font.deriveFont(Font.BOLD)
|
||||
repaint()
|
||||
}
|
||||
|
||||
74
src/main/kotlin/net/eksb/kswingutil/mig/Mig.kt
Normal file
74
src/main/kotlin/net/eksb/kswingutil/mig/Mig.kt
Normal file
@@ -0,0 +1,74 @@
|
||||
package net.eksb.kswingutil.mig
|
||||
|
||||
// Utility and extension functions for using MigLayout. See http://miglayout.com/
|
||||
|
||||
import java.awt.Container
|
||||
import java.util.UUID
|
||||
|
||||
import net.miginfocom.swing.*
|
||||
|
||||
// Let users import net.eksb.kswingutil.mig.* and not have to also import net.miginfocom.layout.*
|
||||
typealias LC = net.miginfocom.layout.LC
|
||||
typealias AC = net.miginfocom.layout.AC
|
||||
typealias CC = net.miginfocom.layout.CC
|
||||
|
||||
fun Container.migLayout(
|
||||
layoutConstraints:LC?=null,
|
||||
colConstraints:AC?=null,
|
||||
rowConstraints:AC?=null
|
||||
) {
|
||||
layout = MigLayout(
|
||||
( layoutConstraints ?: LC() ).debugIfEnv(),
|
||||
colConstraints ?: AC(),
|
||||
rowConstraints ?: AC() )
|
||||
}
|
||||
|
||||
fun CC.heightMin():CC = height("min")
|
||||
|
||||
/**
|
||||
* Set a cell to take up the full height of the row
|
||||
* without impacting the height of the row.
|
||||
* Or, in other words, to take the full height of the tallest cell
|
||||
* besides this one.
|
||||
*/
|
||||
fun CC.heightGrowMin():CC = growY().heightMin()
|
||||
|
||||
fun AC.grow(w:Int) = grow(w.toFloat())
|
||||
fun AC.grow(w:Double) = grow(w.toFloat())
|
||||
|
||||
/**
|
||||
* Set all columns to be the same width.
|
||||
*
|
||||
* This works by setting [AC.sizeGroup] to the same thing
|
||||
* for all columns.
|
||||
*
|
||||
* After this method returns, the end, [AC.curIx] is the last index.
|
||||
*/
|
||||
fun AC.allColsSameWidth():AC = apply {
|
||||
val group = UUID.randomUUID().toString()
|
||||
(0 until count).forEach { index ->
|
||||
index(index).sizeGroup(group)
|
||||
}
|
||||
}
|
||||
|
||||
fun AC.alignRight() = align("right")
|
||||
fun CC.alignRight() = alignX("right")
|
||||
fun AC.alignLeft() = align("left")
|
||||
fun CC.alignLeft() = alignX("left")
|
||||
fun AC.alignCenter() = align("center")
|
||||
fun CC.alignCenter() = alignX("center")
|
||||
|
||||
private val debug:Boolean = System.getenv("SWINGUTIL_MIG_DEBUG")?.toBoolean() == true
|
||||
/**
|
||||
* Show debug decorations if $SWINGUTIL_MIG_DEBUG is set to "true"
|
||||
* @param repaintMillis The new debug repaint interval.
|
||||
*/
|
||||
fun LC.debugIfEnv(repaintMillis:Int=300):LC = apply {
|
||||
if ( debug ) {
|
||||
debug(repaintMillis)
|
||||
}
|
||||
}
|
||||
|
||||
fun LC.noInsets() = insetsAll("0")
|
||||
|
||||
fun LC.noGridGap() = gridGap("0","0")
|
||||
@@ -14,4 +14,26 @@ fun <T,R> Property<T>.map(transform:(T)->R):Property<R> =
|
||||
/**
|
||||
* Get a [Property] that is true when this property is not null.
|
||||
*/
|
||||
fun <T> Property<T>.mapNotNull():Property<Boolean> = map { it != null }
|
||||
fun <T> Property<T>.mapNotNull():Property<Boolean> = map { it != null }
|
||||
|
||||
/**
|
||||
* Create a Property<T> that is updated to the value generated by [op]
|
||||
* when any of the supplied [props] change.
|
||||
*
|
||||
* @param props Update this property when any of these properties change.
|
||||
* @param op Calculates the value of this property
|
||||
*/
|
||||
fun <T> propertyFrom(vararg props:Property<*>, op:()->T): Property<T> =
|
||||
MutableProperty(op())
|
||||
.apply {
|
||||
props.forEach { prop ->
|
||||
prop.addListener { _, _ ->
|
||||
value = op()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a `Property<Boolean>` that is `!this.value`.
|
||||
*/
|
||||
operator fun Property<Boolean>.not():Property<Boolean> = map { ! it }
|
||||
|
||||
Reference in New Issue
Block a user