Working table editor

This commit is contained in:
downthecrop 2025-09-19 22:07:17 -07:00
parent 5e4ee2a5da
commit b61f4da214
2 changed files with 97 additions and 13 deletions

View file

@ -38,10 +38,6 @@ class plugin : Plugin() {
@Exposed(description = "Username to account type mappings (0=Normal, 1=IM, 2=HCIM, 3=UIM)") @Exposed(description = "Username to account type mappings (0=Normal, 1=IM, 2=HCIM, 3=UIM)")
private var usernameMatches = HashMap<String, Int>() private var usernameMatches = HashMap<String, Int>()
// Not used anymore - keeping for reference
// @Exposed(description = "Manual username entries (format: username:accountType, e.g., 'example:1')")
// private var manualEntries = listOf<String>()
private var ACCOUNT_TYPE = 0 private var ACCOUNT_TYPE = 0
private var component: Component? = null private var component: Component? = null

View file

@ -212,11 +212,39 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
editorPanel.border = BorderFactory.createEmptyBorder(5, 0, 5, 0) editorPanel.border = BorderFactory.createEmptyBorder(5, 0, 5, 0)
editorPanel.maximumSize = Dimension(Int.MAX_VALUE, 250) editorPanel.maximumSize = Dimension(Int.MAX_VALUE, 250)
// Get the "Exposed" annotation specifically and retrieve its description, if available
val exposedAnnotation = field.annotations.firstOrNull { annotation ->
annotation.annotationClass.simpleName == "Exposed"
}
val description = exposedAnnotation?.let { annotation ->
try {
val descriptionField = annotation.annotationClass.java.getMethod("description")
descriptionField.invoke(annotation) as String
} catch (e: NoSuchMethodException) {
"" // No description method, return empty string
}
} ?: ""
// Create title label // Create title label
val titleLabel = JLabel("${field.name} (Key-Value Pairs)").apply { val titleLabel = JLabel("${field.name} (Key-Value Pairs)").apply {
foreground = secondaryColor foreground = secondaryColor
font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16) font = Font("RuneScape Small", Font.TRUETYPE_FONT, 16)
alignmentX = Component.LEFT_ALIGNMENT alignmentX = Component.LEFT_ALIGNMENT
// Add mouse listener to the label only if a description is available
if (description.isNotBlank()) {
cursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)
addMouseListener(object : MouseAdapter() {
override fun mouseEntered(e: MouseEvent) {
showCustomToolTip(description, this@apply)
}
override fun mouseExited(e: MouseEvent) {
SettingsPanel.customToolTipWindow?.isVisible = false
}
})
}
} }
// Get the current HashMap value // Get the current HashMap value
@ -309,24 +337,84 @@ class SettingsPanel(private val plugin: Plugin) : JPanel() {
// Apply button // Apply button
val applyButton = JButton("Apply Changes").apply { val applyButton = JButton("Apply Changes").apply {
maximumSize = Dimension(220, 30) maximumSize = Dimension(120, 30)
addActionListener { addActionListener {
try { try {
// Create a new HashMap from the table data // Create a new HashMap from the table data
// We need to determine the key and value types from the field's generic type // We need to determine the key and value types from the field's generic type
val newHashMap = HashMap<String, Any>() val newHashMap = HashMap<Any, Any>()
for (i in 0 until tableModel.rowCount) { for (i in 0 until tableModel.rowCount) {
val key = tableModel.getValueAt(i, 0).toString() val key = tableModel.getValueAt(i, 0).toString()
val value = tableModel.getValueAt(i, 1).toString() val value = tableModel.getValueAt(i, 1).toString()
// Only add non-empty keys // Only add non-empty keys
if (key.isNotBlank()) { if (key.isNotBlank()) {
// Try to convert the value to the appropriate type // Skip empty values
val convertedValue = try { if (value.isBlank()) {
// For now, we'll keep everything as strings Helpers.showToast(
// In the future, we could parse based on the generic type information this@SettingsPanel,
value "Skipping entry with empty value for key '$key'",
JOptionPane.WARNING_MESSAGE
)
continue
}
// Try to convert the value to the appropriate type based on the field's generic type
val convertedValue = try {
// For HashMap<String, Int> which is what FooTextPlugin uses
if (field.genericType.toString().contains("java.util.HashMap<java.lang.String, java.lang.Integer>") ||
field.genericType.toString().contains("HashMap<String, Int>") ||
field.genericType.toString().contains("HashMap<String, Integer>")) {
try {
val intValue = value.toInt()
// For FooTextPlugin, account types should be 0-3
if (field.declaringClass.simpleName == "plugin" &&
field.declaringClass.`package`.name.contains("FooTextPlugin")) {
if (intValue < 0 || intValue > 3) {
Helpers.showToast(
this@SettingsPanel,
"Account type for '$key' should be 0-3. Using 0 as default.",
JOptionPane.WARNING_MESSAGE
)
0
} else {
intValue
}
} else {
intValue
}
} catch (e: NumberFormatException) {
Helpers.showToast(
this@SettingsPanel,
"Invalid number format for key '$key': '$value'. Using 0 as default.",
JOptionPane.WARNING_MESSAGE
)
0
}
}
// For other numeric types
else if (field.genericType.toString().contains("java.lang.Integer") ||
field.genericType.toString().contains("int")) {
value.toInt()
}
else if (field.genericType.toString().contains("java.lang.Double") ||
field.genericType.toString().contains("double")) {
value.toDouble()
}
else if (field.genericType.toString().contains("java.lang.Float") ||
field.genericType.toString().contains("float")) {
value.toFloat()
}
else if (field.genericType.toString().contains("java.lang.Boolean") ||
field.genericType.toString().contains("boolean")) {
value.toBoolean()
}
// Default to string for other types
else {
value
}
} catch (e: Exception) { } catch (e: Exception) {
value // fallback to string // If conversion fails, keep as string
value
} }
newHashMap[key] = convertedValue newHashMap[key] = convertedValue
} }