A declarative Swing GUI builder for Groovy applications that provides a concise and maintainable way to create complex Swing user interfaces
npx @tessl/cli install tessl/maven-org-codehaus-groovy--groovy-swing@3.0.0Groovy Swing Builder is a declarative GUI builder for Groovy applications that provides a concise and maintainable way to create complex Swing user interfaces. It leverages Groovy's builder pattern and metaprogramming capabilities to dramatically reduce the boilerplate code typically associated with Swing development while maintaining full access to the complete Swing component ecosystem.
Maven:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-swing</artifactId>
<version>3.0.25</version>
</dependency>Gradle:
implementation 'org.codehaus.groovy:groovy-swing:3.0.25'import groovy.swing.SwingBuilder
import groovy.swing.LookAndFeelHelperFor specific factory classes:
import groovy.swing.factory.*
import groovy.swing.binding.*
import groovy.model.*import groovy.swing.SwingBuilder
import javax.swing.*
// Create a simple GUI using SwingBuilder
def swing = new SwingBuilder()
def frame = swing.frame(title: 'Hello Groovy Swing', defaultCloseOperation: JFrame.EXIT_ON_CLOSE) {
panel {
label(text: 'Hello, World!')
button(text: 'Click Me') {
actionPerformed { e ->
JOptionPane.showMessageDialog(null, 'Button clicked!')
}
}
}
}
frame.pack()
frame.visible = true
// Using EDT builder for thread safety
SwingBuilder.edtBuilder {
frame(title: 'EDT Example', defaultCloseOperation: JFrame.EXIT_ON_CLOSE) {
textField(text: 'Type here...', columns: 20)
}.show()
}Groovy Swing Builder is built around several key components:
The primary SwingBuilder class and factory system for declarative GUI construction with the builder pattern.
class SwingBuilder extends FactoryBuilderSupport {
static final String DELEGATE_PROPERTY_OBJECT_ID = "_delegateProperty:id"
static final String DEFAULT_DELEGATE_PROPERTY_OBJECT_ID = "id"
SwingBuilder(boolean init = true)
SwingBuilder edt(Closure c)
SwingBuilder doLater(Closure c)
SwingBuilder doOutside(Closure c)
Object build(Closure c)
KeyStroke shortcut(key, modifier = 0)
KeyStroke shortcut(String key, modifier = 0)
void createKeyStrokeAction(Map attributes, JComponent component = null)
static SwingBuilder edtBuilder(Closure c)
static LookAndFeel lookAndFeel(Object... lafs)
static LookAndFeel lookAndFeel(Object laf, Closure initCode)
static LookAndFeel lookAndFeel(Map attributes, Object laf, Closure initCode)
}Sophisticated binding system for connecting GUI components to data models with validation, conversion, and automatic synchronization.
interface FullBinding extends BindingUpdatable {
SourceBinding getSourceBinding()
TargetBinding getTargetBinding()
void setSourceBinding(SourceBinding source)
void setTargetBinding(TargetBinding target)
void setValidator(Closure validator)
void setConverter(Closure converter)
void setReverseConverter(Closure reverseConverter)
}
interface ValueModel {
Object getValue()
void setValue(Object value)
Class getType()
boolean isEditable()
}Comprehensive layout system including all standard Swing layouts plus custom table-based layout manager.
// Standard layouts via LayoutFactory
borderLayout(hgap: 5, vgap: 5)
gridLayout(rows: 2, cols: 3, hgap: 5, vgap: 5)
flowLayout(alignment: FlowLayout.CENTER)
// Enhanced GridBag with constraint handling
gridBagLayout()
gridBagConstraints(gridx: 0, gridy: 0, weightx: 1.0)
// Custom table layout
tableLayout {
tr {
td { button(text: 'Button 1') }
td { button(text: 'Button 2') }
}
}Simplified Look and Feel management with support for system LAFs and third-party themes.
class LookAndFeelHelper {
static LookAndFeelHelper getInstance()
LookAndFeel lookAndFeel(Object value, Map attributes, Closure initClosure)
String addLookAndFeelAlias(String alias, String className)
String addLookAndFeelAttributeHandler(String className, String attr, Closure handler)
}Groovy-specific enhancements to standard Swing components providing collection-like operators and convenient methods.
// Collection-like operations for containers
panel << button // Add component using left-shift
button = panel[0] // Access by index
panel.size() // Get component count
panel.each { ... } // Iterate over components
// Enhanced operations for various components
listModel << 'item' // Add to list model
comboBox << 'option' // Add to combo box
buttonGroup << radioButton // Add to button groupObservable data containers and specialized models supporting property change notifications and data binding integration.
interface ValueModel {
Object getValue()
void setValue(Object value)
Class getType()
boolean isEditable()
}
class ValueHolder implements ValueModel {
ValueHolder(Object value = null)
}
class PropertyModel implements ValueModel {
PropertyModel(Object bean, String property)
}
class FormModel implements ValueModel {
FormModel(Map initialData = [:])
boolean isDirty()
Map<String, List<String>> validate()
}abstract class FactoryBuilderSupport {
protected Map<String, Factory> factories
protected Object current
protected LinkedList<Object> contexts
void registerFactory(String name, Factory factory)
Object build(Closure c)
Object getCurrent()
}
interface Factory {
Object newInstance(FactoryBuilderSupport builder, Object name, Object value, Map attributes)
boolean isLeaf()
boolean onHandleNodeAttributes(FactoryBuilderSupport builder, Object node, Map attributes)
void onNodeCompleted(FactoryBuilderSupport builder, Object parent, Object node)
}interface BindingUpdatable {
void bind()
void unbind()
void rebind()
void update()
void reverseUpdate()
}
interface SourceBinding extends BindingUpdatable {
Object getSourceValue()
void setSourceBinding(PropertyChangeListener listener)
}
interface TargetBinding extends BindingUpdatable {
void setTargetValue(Object value)
}
interface TriggerBinding {
FullBinding getFullBinding()
void setFullBinding(FullBinding fullBinding)
void bind()
void unbind()
}// Text component bindings
interface JTextComponentProperties {
Object getText(JTextComponent self)
void setText(JTextComponent self, Object value)
}
// Button state bindings
interface AbstractButtonProperties {
Object getSelected(AbstractButton self)
void setSelected(AbstractButton self, Object value)
}
// Selection model bindings
interface JListProperties {
Object getSelectedElement(JList self)
Object getSelectedElements(JList self)
Object getSelectedIndex(JList self)
Object getSelectedIndices(JList self)
Object getSelectedValue(JList self)
Object getSelectedValues(JList self)
}