CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-org-codehaus-groovy--groovy-swing

A declarative Swing GUI builder for Groovy applications that provides a concise and maintainable way to create complex Swing user interfaces

Pending
Overview
Eval results
Files

models.mddocs/

Value Models and Data Models

Observable data containers and specialized models that support property change notifications and data binding integration.

Capabilities

Core Value Model Interface

The foundation interface for all observable data containers.

/**
 * Interface for observable values with change notification support
 */
interface ValueModel {
    /** Get the current value */
    Object getValue()
    
    /** Set the value and notify listeners */
    void setValue(Object value)
    
    /** Get the expected type of values */
    Class getType()
    
    /** Check if the model allows value changes */
    boolean isEditable()
    
    /** Add property change listener */
    void addPropertyChangeListener(PropertyChangeListener listener)
    
    /** Remove property change listener */
    void removePropertyChangeListener(PropertyChangeListener listener)
}

Basic Value Models

Simple value containers for common use cases.

/**
 * Basic value container with property change support
 */
class ValueHolder implements ValueModel {
    /** Create with initial value */
    ValueHolder(Object value = null)
    
    /** Create with initial value and type constraint */
    ValueHolder(Object value, Class type)
    
    /** Create with initial value, type, and editability */
    ValueHolder(Object value, Class type, boolean editable)
}

/**
 * Property-based value model for bean properties
 */
class PropertyModel implements ValueModel {
    /** Create model for bean property */
    PropertyModel(Object bean, String property)
    
    /** Get the source bean */
    Object getBean()
    
    /** Get the property name */
    String getProperty()
}

/**
 * Nested property model for deep property access
 */
class NestedValueModel implements ValueModel {
    /** Create model for nested property path */
    NestedValueModel(Object bean, String propertyPath)
    
    /** Get the source bean */
    Object getBean()
    
    /** Get the property path (e.g., "address.street") */
    String getPropertyPath()
}

/**
 * Closure-based computed value model
 */
class ClosureModel implements ValueModel {
    /** Create read-only computed model */
    ClosureModel(Closure readClosure)
    
    /** Create read-write computed model */
    ClosureModel(Closure readClosure, Closure writeClosure)
    
    /** Create with type constraint */
    ClosureModel(Closure readClosure, Class type)
    
    /** Create full-featured computed model */
    ClosureModel(Closure readClosure, Closure writeClosure, Class type)
}

Form Models

Specialized models for form data management.

/**
 * Model for managing form data with validation and buffering
 */
class FormModel implements ValueModel {
    /** Create form model with initial data */
    FormModel(Map initialData = [:])
    
    /** Get value for specific field */
    Object getFieldValue(String fieldName)
    
    /** Set value for specific field */
    void setFieldValue(String fieldName, Object value)
    
    /** Check if form has changes from initial state */
    boolean isDirty()
    
    /** Check if specific field has changes */
    boolean isFieldDirty(String fieldName)
    
    /** Reset form to initial state */
    void reset()
    
    /** Commit current values as new initial state */
    void commit()
    
    /** Get all field names */
    Set<String> getFieldNames()
    
    /** Add field validator */
    void addFieldValidator(String fieldName, Closure validator)
    
    /** Remove field validator */
    void removeFieldValidator(String fieldName, Closure validator)
    
    /** Validate all fields */
    Map<String, List<String>> validate()
    
    /** Validate specific field */
    List<String> validateField(String fieldName)
}

Table Models

Enhanced table models with Groovy-specific features.

/**
 * Extended DefaultTableModel with enhanced Groovy support
 */
class DefaultTableModel extends javax.swing.table.DefaultTableModel {
    /** Create with column names */
    DefaultTableModel(List columnNames)
    
    /** Create with data and column names */
    DefaultTableModel(List<List> data, List columnNames)
    
    /** Create with data map and column names */
    DefaultTableModel(List<Map> data, List columnNames)
    
    /** Add row using Map */
    void addRow(Map rowData)
    
    /** Insert row using Map */
    void insertRow(int index, Map rowData)
    
    /** Get row as Map */
    Map getRowAsMap(int rowIndex)
    
    /** Set row from Map */
    void setRowFromMap(int rowIndex, Map rowData)
    
    /** Find rows matching criteria */
    List<Integer> findRows(Closure criteria)
    
    /** Filter rows by criteria */
    List<Map> filterRows(Closure criteria)
}

/**
 * Extended table column with enhanced features
 */
class DefaultTableColumn extends TableColumn {
    /** Create with identifier and display name */
    DefaultTableColumn(Object identifier, String displayName)
    
    /** Set column renderer from closure */
    void setRendererFromClosure(Closure rendererClosure)
    
    /** Set column editor from closure */
    void setEditorFromClosure(Closure editorClosure)
    
    /** Set column validator */
    void setValidator(Closure validator)
    
    /** Get column validator */
    Closure getValidator()
}

Model Utilities

Utility classes for working with models.

/**
 * Utility for wrapping lists as ListModel
 */
class ListWrapperListModel implements ListModel {
    /** Create wrapper for existing list */
    ListWrapperListModel(List wrappedList)
    
    /** Get the wrapped list */
    List getList()
    
    /** Refresh model after list changes */
    void refresh()
}

/**
 * Base class for sortable table models
 */
class TableSorter extends AbstractTableModel implements TableModelListener {
    /** Create sorter for existing table model */
    TableSorter(TableModel model)
    
    /** Sort by column */
    void sortByColumn(int column)
    
    /** Sort by column with custom comparator */
    void sortByColumn(int column, Comparator comparator)
    
    /** Check if column is sortable */
    boolean isSortable(int column)
    
    /** Set column sortable state */
    void setSortable(int column, boolean sortable)
}

Usage Examples

Basic Value Models

import groovy.model.*

// Simple value holder
def nameModel = new ValueHolder('John Doe')
nameModel.addPropertyChangeListener { evt ->
    println "Name changed from '${evt.oldValue}' to '${evt.newValue}'"
}
nameModel.value = 'Jane Smith'  // Triggers listener

// Property model
class Person {
    String name
    int age
}
def person = new Person(name: 'Alice', age: 30)
def nameProperty = new PropertyModel(person, 'name')
def ageProperty = new PropertyModel(person, 'age')

// Changes to person will notify model listeners
person.name = 'Bob'

Nested Property Models

class Address {
    String street
    String city
}

class Customer {
    String name
    Address address
}

def customer = new Customer(
    name: 'John',
    address: new Address(street: '123 Main St', city: 'Anytown')
)

// Access nested properties
def streetModel = new NestedValueModel(customer, 'address.street')
def cityModel = new NestedValueModel(customer, 'address.city')

println streetModel.value  // "123 Main St"
streetModel.value = '456 Oak Ave'
println customer.address.street  // "456 Oak Ave"

Computed Models

def firstNameModel = new ValueHolder('John')
def lastNameModel = new ValueHolder('Doe')

// Read-only computed model
def fullNameModel = new ClosureModel { 
    "${firstNameModel.value} ${lastNameModel.value}"
}

println fullNameModel.value  // "John Doe"

// Read-write computed model
def temperatureF = new ValueHolder(32.0)
def temperatureC = new ClosureModel(
    { (temperatureF.value - 32) * 5 / 9 },  // Read closure
    { temperatureF.value = it * 9 / 5 + 32 } // Write closure
)

temperatureC.value = 0.0
println temperatureF.value  // 32.0

Form Models

def formModel = new FormModel([
    firstName: 'John',
    lastName: 'Doe',
    email: 'john@example.com',
    age: 30
])

// Add validators
formModel.addFieldValidator('email') { value ->
    if (!value?.contains('@')) {
        return 'Invalid email format'
    }
    return null
}

formModel.addFieldValidator('age') { value ->
    if (value < 18) {
        return 'Must be 18 or older'
    }
    return null
}

// Make changes
formModel.setFieldValue('email', 'invalid-email')
formModel.setFieldValue('age', 16)

// Validate
def errors = formModel.validate()
errors.each { field, messages ->
    println "$field: ${messages.join(', ')}"
}

// Check dirty state
println "Form is dirty: ${formModel.dirty}"
println "Email field is dirty: ${formModel.isFieldDirty('email')}"

Enhanced Table Models

def columns = ['Name', 'Age', 'Email']
def tableModel = new DefaultTableModel(columns)

// Add rows using Maps
tableModel.addRow([name: 'Alice', age: 25, email: 'alice@example.com'])
tableModel.addRow([name: 'Bob', age: 30, email: 'bob@example.com'])
tableModel.addRow([name: 'Charlie', age: 35, email: 'charlie@example.com'])

// Find rows by criteria
def youngUsers = tableModel.findRows { row ->
    tableModel.getRowAsMap(row).age < 30
}

// Filter data
def filteredData = tableModel.filterRows { rowMap ->
    rowMap.name.startsWith('A')
}

println "Young users: $youngUsers"
println "Names starting with A: $filteredData"

Install with Tessl CLI

npx tessl i tessl/maven-org-codehaus-groovy--groovy-swing

docs

data-binding.md

extensions.md

gui-building.md

index.md

layout-management.md

look-and-feel.md

models.md

tile.json