mirror of
https://github.com/TermoraDev/termora.git
synced 2026-01-15 18:02:58 +08:00
203 lines
5.7 KiB
Kotlin
203 lines
5.7 KiB
Kotlin
package app.termora
|
|
|
|
import com.formdev.flatlaf.FlatClientProperties
|
|
import com.formdev.flatlaf.extras.components.*
|
|
import com.formdev.flatlaf.ui.FlatTextBorder
|
|
import org.apache.commons.lang3.StringUtils
|
|
import java.awt.Component
|
|
import java.awt.event.*
|
|
import java.text.ParseException
|
|
import javax.swing.DefaultListCellRenderer
|
|
import javax.swing.JComboBox
|
|
import javax.swing.JList
|
|
import javax.swing.SpinnerNumberModel
|
|
import javax.swing.text.AttributeSet
|
|
import javax.swing.text.DefaultFormatterFactory
|
|
import javax.swing.text.PlainDocument
|
|
|
|
|
|
open class OutlineTextField(var maxLength: Int = Int.MAX_VALUE) : FlatTextField() {
|
|
init {
|
|
this.addKeyListener(object : KeyAdapter() {
|
|
override fun keyPressed(e: KeyEvent) {
|
|
outline = null
|
|
}
|
|
})
|
|
|
|
|
|
document = object : PlainDocument() {
|
|
override fun insertString(offs: Int, str: String?, a: AttributeSet?) {
|
|
if (str != null && str.length + length <= maxLength) {
|
|
super.insertString(offs, str, a)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class OutlineTextArea : FlatTextArea() {
|
|
init {
|
|
border = FlatTextBorder()
|
|
|
|
addFocusListener(object : FocusAdapter() {
|
|
override fun focusLost(e: FocusEvent) {
|
|
border = FlatTextBorder()
|
|
}
|
|
|
|
override fun focusGained(e: FocusEvent) {
|
|
border = FlatTextBorder()
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
class OutlineComboBox<T> : FlatComboBox<T>() {
|
|
init {
|
|
addItemListener {
|
|
if (it.stateChange == ItemEvent.SELECTED) {
|
|
putClientProperty(FlatClientProperties.OUTLINE, null)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class FixedLengthTextArea(var maxLength: Int = Int.MAX_VALUE) : FlatTextArea() {
|
|
init {
|
|
document = object : PlainDocument() {
|
|
override fun insertString(offs: Int, str: String?, a: AttributeSet?) {
|
|
if (str != null && str.length + length <= maxLength) {
|
|
super.insertString(offs, str, a)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
class OutlinePasswordField(
|
|
var maxLength: Int = Int.MAX_VALUE,
|
|
var allowSpace: Boolean = false
|
|
) : FlatPasswordField() {
|
|
init {
|
|
addKeyListener(object : KeyAdapter() {
|
|
override fun keyPressed(e: KeyEvent) {
|
|
outline = null
|
|
}
|
|
})
|
|
|
|
document = object : PlainDocument() {
|
|
override fun insertString(offs: Int, str: String?, a: AttributeSet?) {
|
|
if (str != null && str.length + length <= maxLength) {
|
|
val text = if (allowSpace) str else str.replace(StringUtils.SPACE, StringUtils.EMPTY)
|
|
if (text.isNotEmpty()) {
|
|
super.insertString(offs, text, a)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
styleMap = mapOf(
|
|
"showRevealButton" to true
|
|
)
|
|
|
|
putClientProperty("JPasswordField.cutCopyAllowed", true)
|
|
}
|
|
}
|
|
|
|
open class OutlineFormattedTextField : FlatFormattedTextField() {
|
|
init {
|
|
this.addKeyListener(object : KeyAdapter() {
|
|
override fun keyPressed(e: KeyEvent) {
|
|
outline = null
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
open class EmailFormattedTextField(var maxLength: Int = Int.MAX_VALUE) : OutlineFormattedTextField() {
|
|
init {
|
|
formatterFactory = DefaultFormatterFactory(object : AbstractFormatter() {
|
|
private val regex = Regex(
|
|
("^(?=.{1,64}@)[A-Za-z0-9\\+_-]+(\\.[A-Za-z0-9\\+_-]+)*@"
|
|
+ "[^-][A-Za-z0-9\\+-]+(\\.[A-Za-z0-9\\+-]+)*(\\.[A-Za-z]{2,})$")
|
|
)
|
|
|
|
override fun stringToValue(text: String?): Any {
|
|
if (text.isNullOrBlank()) return String()
|
|
if (!regex.matches(text)) throw ParseException("Not an email", 0)
|
|
return text
|
|
}
|
|
|
|
override fun valueToString(value: Any?): String {
|
|
return value?.toString() ?: String()
|
|
}
|
|
|
|
})
|
|
|
|
|
|
document = object : PlainDocument() {
|
|
override fun insertString(offs: Int, str: String?, a: AttributeSet?) {
|
|
if (str != null && str.length + length <= maxLength) {
|
|
super.insertString(offs, str, a)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
abstract class NumberSpinner(
|
|
value: Int,
|
|
minimum: Int,
|
|
maximum: Int,
|
|
) : FlatSpinner() {
|
|
init {
|
|
val snm = SpinnerNumberModel()
|
|
snm.minimum = minimum
|
|
snm.maximum = maximum
|
|
snm.value = value
|
|
model = snm
|
|
}
|
|
|
|
override fun getModel(): SpinnerNumberModel {
|
|
return super.getModel() as SpinnerNumberModel
|
|
}
|
|
}
|
|
|
|
class PortSpinner(value: Int = 22) : NumberSpinner(value, 0, UShort.MAX_VALUE.toInt()) {
|
|
init {
|
|
setEditor(NumberEditor(this, "#"))
|
|
}
|
|
}
|
|
|
|
class IntSpinner(value: Int, minimum: Int = Int.MIN_VALUE, maximum: Int = Int.MAX_VALUE) :
|
|
NumberSpinner(value, minimum, maximum) {
|
|
init {
|
|
setEditor(NumberEditor(this, "#"))
|
|
}
|
|
}
|
|
|
|
class YesOrNoComboBox : JComboBox<Boolean>() {
|
|
init {
|
|
renderer = object : DefaultListCellRenderer() {
|
|
override fun getListCellRendererComponent(
|
|
list: JList<*>?,
|
|
value: Any?,
|
|
index: Int,
|
|
isSelected: Boolean,
|
|
cellHasFocus: Boolean
|
|
): Component {
|
|
return super.getListCellRendererComponent(
|
|
list,
|
|
if (value == true) I18n.getString("termora.yes") else I18n.getString("termora.no"),
|
|
index,
|
|
isSelected,
|
|
cellHasFocus
|
|
)
|
|
}
|
|
}
|
|
|
|
addItem(true)
|
|
addItem(false)
|
|
}
|
|
} |