or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

data-binding.mdextensions.mdgui-building.mdindex.mdlayout-management.mdlook-and-feel.mdmodels.md

look-and-feel.mddocs/

0

# Look and Feel Management

1

2

Simplified Look and Feel management with support for system LAFs and third-party themes, providing easy access to platform-specific appearance and custom styling.

3

4

## Capabilities

5

6

### LookAndFeelHelper

7

8

The central helper class for managing Look and Feel configuration with built-in support for popular LAFs.

9

10

```groovy { .api }

11

/**

12

* Singleton helper for Look and Feel management

13

*/

14

class LookAndFeelHelper {

15

/** Get singleton instance */

16

static LookAndFeelHelper getInstance()

17

18

/** Configure Look and Feel with attributes and initialization code */

19

LookAndFeel lookAndFeel(Object value, Map attributes = [:], Closure initClosure = null)

20

21

/** Register alias for Look and Feel class name */

22

String addLookAndFeelAlias(String alias, String className)

23

24

/** Add custom attribute handler for specific LAF */

25

String addLookAndFeelAttributeHandler(String className, String attr, Closure handler)

26

27

/** Check if this is a leaf node in builder pattern */

28

boolean isLeaf()

29

}

30

```

31

32

### Built-in Look and Feel Aliases

33

34

Pre-configured aliases for common Look and Feel implementations.

35

36

```groovy { .api }

37

// System Look and Feels

38

'system' // UIManager.getSystemLookAndFeelClassName()

39

'crossPlatform' // UIManager.getCrossPlatformLookAndFeelClassName()

40

41

// Platform-specific LAFs

42

'metal' // javax.swing.plaf.metal.MetalLookAndFeel

43

'nimbus' // com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel (if available)

44

'windows' // com.sun.java.swing.plaf.windows.WindowsLookAndFeel

45

'win2k' // com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel

46

'mac' // com.apple.laf.AquaLookAndFeel (if available)

47

'motif' // com.sun.java.swing.plaf.motif.MotifLookAndFeel

48

'gtk' // com.sun.java.swing.plaf.gtk.GTKLookAndFeel

49

'synth' // javax.swing.plaf.synth.SynthLookAndFeel

50

51

// Third-party LAFs (requires external libraries)

52

'plastic' // com.jgoodies.looks.plastic.PlasticLookAndFeel

53

'plastic3D' // com.jgoodies.looks.plastic.Plastic3DLookAndFeel

54

'plasticXP' // com.jgoodies.looks.plastic.PlasticXPLookAndFeel

55

'substance' // org.pushingpixels.substance.api.SubstanceLookAndFeel

56

'napkin' // net.sourceforge.napkinlaf.NapkinLookAndFeel

57

```

58

59

**Usage Examples:**

60

61

```groovy

62

import groovy.swing.SwingBuilder

63

64

// Set system Look and Feel

65

SwingBuilder.lookAndFeel('system')

66

67

// Try multiple LAFs in fallback order

68

SwingBuilder.lookAndFeel('nimbus', 'system', 'metal')

69

70

// Set LAF with configuration

71

SwingBuilder.lookAndFeel('metal', [

72

theme: 'ocean',

73

boldFonts: false

74

])

75

76

// Use LAF with initialization closure

77

SwingBuilder.lookAndFeel('nimbus') { laf ->

78

// Custom initialization code

79

UIManager.put('control', new Color(240, 240, 240))

80

}

81

```

82

83

### SwingBuilder LAF Integration

84

85

Look and Feel methods integrated into SwingBuilder for convenient usage.

86

87

```groovy { .api }

88

/**

89

* SwingBuilder static methods for LAF management

90

*/

91

class SwingBuilder {

92

/** Configure LAF with single parameter */

93

static LookAndFeel lookAndFeel(Object laf)

94

95

/** Configure LAF with initialization closure */

96

static LookAndFeel lookAndFeel(Object laf, Closure initCode)

97

98

/** Configure LAF with attributes and optional closure */

99

static LookAndFeel lookAndFeel(Map attributes = [:], Object laf = null, Closure initCode = null)

100

101

/** Try multiple LAFs in order until one succeeds */

102

static LookAndFeel lookAndFeel(Object... lafs)

103

}

104

```

105

106

**Usage Examples:**

107

108

```groovy

109

// Simple LAF setting

110

SwingBuilder.lookAndFeel('nimbus')

111

112

// LAF with initialization

113

SwingBuilder.lookAndFeel('metal') { laf ->

114

MetalLookAndFeel.setCurrentTheme(new OceanTheme())

115

}

116

117

// LAF with attributes

118

SwingBuilder.lookAndFeel([theme: 'steel'], 'metal')

119

120

// Fallback LAF selection

121

SwingBuilder.lookAndFeel('substance', 'nimbus', 'system')

122

```

123

124

### Metal Look and Feel Customization

125

126

Special support for Metal LAF themes and configuration.

127

128

```groovy { .api }

129

// Metal LAF extended attributes

130

[

131

theme: 'ocean' | 'steel' | MetalTheme, // Predefined or custom theme

132

boldFonts: boolean, // Enable/disable bold fonts

133

noxp: boolean // Disable XP styling

134

]

135

```

136

137

**Usage Examples:**

138

139

```groovy

140

// Ocean theme with bold fonts disabled

141

SwingBuilder.lookAndFeel('metal', [

142

theme: 'ocean',

143

boldFonts: false

144

])

145

146

// Steel theme (classic Metal)

147

SwingBuilder.lookAndFeel('metal', [theme: 'steel'])

148

149

// Custom Metal theme

150

import javax.swing.plaf.metal.*

151

152

class CustomMetalTheme extends DefaultMetalTheme {

153

String getName() { 'Custom Theme' }

154

ColorUIResource getPrimary1() { new ColorUIResource(66, 33, 66) }

155

}

156

157

SwingBuilder.lookAndFeel('metal', [theme: new CustomMetalTheme()])

158

```

159

160

### Substance Look and Feel Integration

161

162

Support for Substance LAF skins and themes (requires external library).

163

164

```groovy { .api }

165

// Substance LAF extended attributes

166

[

167

theme: Object, // Substance theme object

168

skin: Object, // Substance skin object

169

watermark: Object // Substance watermark object

170

]

171

```

172

173

**Usage Examples:**

174

175

```groovy

176

// Substance with skin (requires Substance library)

177

try {

178

SwingBuilder.lookAndFeel('substance', [

179

skin: 'org.pushingpixels.substance.api.skin.BusinessSkin'

180

])

181

} catch (Exception e) {

182

// Fallback to system LAF

183

SwingBuilder.lookAndFeel('system')

184

}

185

```

186

187

### Custom Look and Feel Registration

188

189

Methods for registering custom LAF aliases and attribute handlers.

190

191

```groovy { .api }

192

/**

193

* Register custom LAF alias

194

*/

195

String addLookAndFeelAlias(String alias, String className)

196

197

/**

198

* Add custom attribute handler for specific LAF

199

*/

200

String addLookAndFeelAttributeHandler(String className, String attr, Closure handler)

201

```

202

203

**Usage Examples:**

204

205

```groovy

206

def helper = LookAndFeelHelper.getInstance()

207

208

// Register custom LAF alias

209

helper.addLookAndFeelAlias('myLaf', 'com.example.MyLookAndFeel')

210

211

// Add custom attribute handler

212

helper.addLookAndFeelAttributeHandler(

213

'com.example.MyLookAndFeel',

214

'customProperty'

215

) { laf, value ->

216

laf.setCustomProperty(value)

217

}

218

219

// Use custom LAF

220

SwingBuilder.lookAndFeel('myLaf', [customProperty: 'value'])

221

```

222

223

### LAF Utilities and Helpers

224

225

Utility methods for LAF detection and management.

226

227

```groovy { .api }

228

/**

229

* Static utility methods for LAF detection

230

*/

231

class LookAndFeelHelper {

232

/** Get Nimbus LAF class name if available */

233

static String getNimbusLAFName()

234

235

/** Get Aqua LAF class name if available (Mac) */

236

static String getAquaLAFName()

237

238

/** Get Substance LAF class name if available */

239

static String getSubstanceLAFName()

240

}

241

242

// UIManager utilities

243

UIManager.getSystemLookAndFeelClassName()

244

UIManager.getCrossPlatformLookAndFeelClassName()

245

UIManager.getInstalledLookAndFeels()

246

UIManager.getLookAndFeel()

247

```

248

249

**Usage Examples:**

250

251

```groovy

252

// Check available LAFs

253

def installedLafs = UIManager.getInstalledLookAndFeels()

254

println "Available LAFs:"

255

installedLafs.each { lafInfo ->

256

println " ${lafInfo.name}: ${lafInfo.className}"

257

}

258

259

// Conditional LAF selection based on platform

260

def platformLaf = System.getProperty('os.name').toLowerCase().contains('mac') ? 'mac' : 'system'

261

SwingBuilder.lookAndFeel(platformLaf)

262

263

// Get current LAF information

264

def currentLaf = UIManager.getLookAndFeel()

265

println "Current LAF: ${currentLaf.name} (${currentLaf.class.name})"

266

```

267

268

### Application Integration

269

270

Best practices for integrating LAF management into applications.

271

272

```groovy { .api }

273

// Application startup LAF configuration

274

class Application {

275

static void initializeLookAndFeel() {

276

// Set LAF before creating any Swing components

277

SwingBuilder.lookAndFeel('nimbus', 'system')

278

279

// Configure global UI properties

280

UIManager.put('OptionPane.messageFont', new Font('Dialog', Font.PLAIN, 12))

281

UIManager.put('OptionPane.buttonFont', new Font('Dialog', Font.PLAIN, 12))

282

}

283

284

static void main(String[] args) {

285

SwingUtilities.invokeLater {

286

initializeLookAndFeel()

287

createAndShowGUI()

288

}

289

}

290

}

291

```

292

293

**Usage Examples:**

294

295

```groovy

296

// Complete application LAF setup

297

import groovy.swing.SwingBuilder

298

import javax.swing.*

299

300

class MyApplication {

301

static void main(String[] args) {

302

// Initialize LAF early

303

SwingUtilities.invokeLater {

304

// Try preferred LAFs with fallback

305

SwingBuilder.lookAndFeel('nimbus', 'system', 'metal')

306

307

// Create main GUI

308

def swing = new SwingBuilder()

309

def frame = swing.frame(

310

title: 'My Application',

311

defaultCloseOperation: JFrame.EXIT_ON_CLOSE,

312

size: [800, 600]

313

) {

314

menuBar {

315

menu(text: 'View') {

316

menu(text: 'Look and Feel') {

317

UIManager.installedLookAndFeels.each { lafInfo ->

318

menuItem(text: lafInfo.name) {

319

actionPerformed { e ->

320

try {

321

UIManager.setLookAndFeel(lafInfo.className)

322

SwingUtilities.updateComponentTreeUI(frame)

323

} catch (Exception ex) {

324

JOptionPane.showMessageDialog(frame,

325

"Failed to set LAF: ${ex.message}")

326

}

327

}

328

}

329

}

330

}

331

}

332

}

333

panel {

334

// main content

335

}

336

}

337

frame.visible = true

338

}

339

}

340

}

341

```

342

343

### Error Handling

344

345

Proper error handling for LAF operations.

346

347

```groovy { .api }

348

// LAF setting with error handling

349

try {

350

SwingBuilder.lookAndFeel('preferredLaf')

351

} catch (UnsupportedLookAndFeelException e) {

352

println "LAF not supported: ${e.message}"

353

SwingBuilder.lookAndFeel('system') // fallback

354

} catch (ClassNotFoundException e) {

355

println "LAF class not found: ${e.message}"

356

SwingBuilder.lookAndFeel('metal') // fallback

357

} catch (Exception e) {

358

println "LAF error: ${e.message}"

359

// Keep current LAF

360

}

361

```

362

363

**Usage Examples:**

364

365

```groovy

366

// Robust LAF selection with logging

367

def selectLookAndFeel() {

368

def candidates = ['nimbus', 'system', 'metal']

369

370

for (laf in candidates) {

371

try {

372

SwingBuilder.lookAndFeel(laf)

373

println "Successfully set LAF: $laf"

374

return

375

} catch (Exception e) {

376

println "Failed to set LAF $laf: ${e.message}"

377

}

378

}

379

380

println "Warning: Using default LAF"

381

}

382

383

// Dynamic LAF switching in running application

384

def switchLookAndFeel(String lafName, Component rootComponent) {

385

try {

386

def oldLaf = UIManager.getLookAndFeel()

387

SwingBuilder.lookAndFeel(lafName)

388

SwingUtilities.updateComponentTreeUI(rootComponent)

389

println "Switched from ${oldLaf.name} to ${UIManager.getLookAndFeel().name}"

390

} catch (Exception e) {

391

JOptionPane.showMessageDialog(rootComponent,

392

"Could not switch to $lafName: ${e.message}",

393

'Look and Feel Error',

394

JOptionPane.ERROR_MESSAGE)

395

}

396

}

397

```