|
Groovy example source code file (SwingBuilderBindingsTest.groovy)
The Groovy SwingBuilderBindingsTest.groovy source code/* * $Id: SwingBuilderBindingsTest.groovy 20649 2010-08-23 15:11:45Z aalmiray $ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package groovy.swing import java.awt.event.ActionEvent import java.beans.PropertyChangeEvent import java.beans.PropertyVetoException import javax.swing.DefaultBoundedRangeModel import javax.swing.DefaultButtonModel import javax.swing.text.PlainDocument import java.text.SimpleDateFormat import groovy.beans.Bindable import groovy.beans.Vetoable import javax.swing.SpinnerNumberModel import javax.swing.ListSelectionModel import javax.swing.DefaultListModel public class SwingBuilderBindingsTest extends GroovySwingTestCase { public void testSliderValueBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { slider(id:'sl') textField(id:'txt', text:bind(source:sl, sourceProperty:'value', id:'binding')) slider(id:'slReverse', value:bind(source:sl, sourceProperty:'value', id:'bindingReverse')) // need to use a second slider for reverse test, because string->int autobox, not so happy } swing.sl.value = 10 assert swing.txt.text == '10' swing.sl.value = 95 assert swing.txt.text == '95' swing.binding.rebind() swing.sl.value = 42 assert swing.txt.text == '42' swing.binding.unbind() swing.sl.value = 13 assert swing.txt.text == '42' swing.binding.bind() assert swing.txt.text == '42' swing.binding.update() assert swing.txt.text == '13' swing.sl.model = new DefaultBoundedRangeModel(30, 1, 20, 40) assert swing.txt.text == '30' // first make sure we've been fireing assert swing.slReverse.value == 30 swing.slReverse.value = 21 swing.bindingReverse.reverseUpdate() assert swing.sl.value == 21 } } public void testSpinnerValueBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { spinner(id:'sp', model:spinnerNumberModel(minimum:0, maximum:100, stepSize:5)) textField(id:'txt', text:bind(source:sp, sourceProperty:'value', id:'binding')) spinner(id:'spReverse', value:bind(source:sp, sourceProperty:'value', id:'bindingReverse')) // need to use a second spinner for reverse test, because string->int autobox, not so happy } swing.sp.value = 10 assert swing.txt.text == '10' swing.sp.value = 95 assert swing.txt.text == '95' swing.binding.rebind() swing.sp.value = 42 assert swing.txt.text == '42' swing.binding.unbind() swing.sp.value = 13 assert swing.txt.text == '42' swing.binding.bind() assert swing.txt.text == '42' swing.binding.update() assert swing.txt.text == '13' swing.sp.model = new SpinnerNumberModel(30, 20, 40, 1) assert swing.txt.text == '30' // first make sure we've been fireing assert swing.spReverse.value == 30 swing.spReverse.value = 21 swing.bindingReverse.reverseUpdate() assert swing.sp.value == 21 } } public void testScrollBarValueBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { scrollBar(id:'sb') textField(id:'txt', text:bind(source:sb, sourceProperty:'value', id:'binding')) scrollBar(id:'sbReverse', value:bind(source:sb, sourceProperty:'value', id:'bindingReverse')) // need to use a second scrollBar for reverse test, because string->int autobox, not so happy } swing.sb.value = 10 assert swing.txt.text == '10' swing.sb.value = 85 assert swing.txt.text == '85' swing.binding.rebind() swing.sb.value = 42 assert swing.txt.text == '42' swing.binding.unbind() swing.sb.value = 13 assert swing.txt.text == '42' swing.binding.bind() assert swing.txt.text == '42' swing.binding.update() assert swing.txt.text == '13' swing.sb.model = new DefaultBoundedRangeModel(30, 1, 20, 40) assert swing.txt.text == '30' // first make sure we've been fireing assert swing.sbReverse.value == 30 swing.sbReverse.value = 21 swing.bindingReverse.reverseUpdate() assert swing.sb.value == 21 } } public void testTextFieldTextBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { textField('Bind', id:'txts') textField(id:'txt', text:bind(source:txts, sourceProperty:'text', id:'binding')) } assert swing.txt.text == 'Bind' swing.txts.text = 'Text' assert swing.txt.text == 'Text' swing.txts.text = 'Easily' assert swing.txt.text == 'Easily' swing.binding.rebind() swing.txts.text = 'With' assert swing.txt.text == 'With' swing.binding.unbind() swing.txts.text = 'bind()' assert swing.txt.text == 'With' swing.binding.bind() assert swing.txt.text == 'With' swing.binding.update() assert swing.txt.text == 'bind()' swing.txt.text = 'reversal' swing.binding.reverseUpdate() assert swing.txts.text == 'reversal' PlainDocument doc = new PlainDocument() doc.insertString(0, '{}', null) swing.txts.document = doc assert swing.txt.text == '{}' } } public void testCheckboxSelectedBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { checkBox(id:'cb') textField(id:'txt', enabled:bind(source:cb, sourceProperty:'selected', id:'binding')) } assert swing.txt.enabled == swing.cb.selected swing.cb.selected = !swing.cb.selected assert swing.txt.enabled == swing.cb.selected swing.cb.selected = !swing.cb.selected assert swing.txt.enabled == swing.cb.selected swing.binding.rebind() swing.cb.selected = !swing.cb.selected assert swing.txt.enabled == swing.cb.selected swing.binding.unbind() swing.cb.selected = !swing.cb.selected assert swing.txt.enabled != swing.cb.selected swing.binding.bind() assert swing.txt.enabled != swing.cb.selected swing.binding.update() assert swing.txt.enabled == swing.cb.selected DefaultButtonModel md = new DefaultButtonModel() md.enabled = !swing.txt.enabled swing.cb.model = md assert swing.txt.enabled == swing.cb.selected swing.txt.enabled = !swing.txt.enabled swing.binding.reverseUpdate() assert swing.txt.enabled == swing.cb.selected } } public void testComboBoxBindSyntheticProperties() { testInEDT { SwingBuilder swing = new SwingBuilder() def comboData = ['Alpha', 'Bravo', 'Charlie', 'Delta'] def vectorData = ['Adams', 'Boston', 'Chicago', 'Denver'] swing.frame() { comboBox(id: 'combo01', items:comboData) comboBox(id: 'combo02', model: new javax.swing.DefaultComboBoxModel(new Vector(vectorData))) t1e = label(text:bind {combo01.elements}) t1sx = label(text:bind {combo01.selectedIndex}) t1se = label(text:bind {combo01.selectedElement}) t1si = label(text:bind {combo01.selectedItem}) t2e = label(text:bind {combo02.elements}) t2sx = label(text:bind {combo02.selectedIndex}) t2se = label(text:bind {combo02.selectedElement}) t2si = label(text:bind {combo02.selectedItem}) } assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '0' assert swing.t1se.text == 'Alpha' assert swing.t1si.text == 'Alpha' assert swing.t2e.text == '[Adams, Boston, Chicago, Denver]' assert swing.t2sx.text == '0' assert swing.t2se.text == 'Adams' assert swing.t2si.text == 'Adams' swing.combo01.selectedIndex = 1 assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '1' assert swing.t1se.text == 'Bravo' assert swing.t1si.text == 'Bravo' swing.combo02.selectedIndex = 1 assert swing.t2e.text == '[Adams, Boston, Chicago, Denver]' assert swing.t2sx.text == '1' assert swing.t2se.text == 'Boston' assert swing.t2si.text == 'Boston' swing.combo01.selectedIndex = -1 assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '-1' assert swing.t1se.text == null assert swing.t1si.text == null swing.combo02.selectedIndex = -1 assert swing.t2e.text == '[Adams, Boston, Chicago, Denver]' assert swing.t2sx.text == '-1' assert swing.t2se.text == null assert swing.t2si.text == null swing.combo01.selectedItem = 'Charlie' assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '2' assert swing.t1se.text == 'Charlie' assert swing.t1si.text == 'Charlie' swing.combo02.selectedItem = 'Chicago' assert swing.t2e.text == '[Adams, Boston, Chicago, Denver]' assert swing.t2sx.text == '2' assert swing.t2se.text == 'Chicago' assert swing.t2si.text == 'Chicago' swing.combo01.selectedItem = 'Fox Trot' assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '2' assert swing.t1se.text == 'Charlie' assert swing.t1si.text == 'Charlie' swing.combo02.selectedItem = 'Frank' assert swing.t2e.text == '[Adams, Boston, Chicago, Denver]' assert swing.t2sx.text == '2' assert swing.t2se.text == 'Chicago' assert swing.t2si.text == 'Chicago' swing.combo01.selectedElement = 'Delta' assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '3' assert swing.t1se.text == 'Delta' assert swing.t1si.text == 'Delta' swing.combo02.selectedElement = 'Denver' assert swing.t2e.text == '[Adams, Boston, Chicago, Denver]' assert swing.t2sx.text == '3' assert swing.t2se.text == 'Denver' assert swing.t2si.text == 'Denver' swing.combo01.selectedElement = 'Golf' assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '3' assert swing.t1se.text == 'Delta' assert swing.t1si.text == 'Delta' swing.combo02.selectedElement = 'George' assert swing.t2e.text == '[Adams, Boston, Chicago, Denver]' assert swing.t2sx.text == '3' assert swing.t2se.text == 'Denver' assert swing.t2si.text == 'Denver' swing.combo01.model.addElement('Echo') assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta, Echo]' swing.combo02.model.addElement('Easy') assert swing.t2e.text == '[Adams, Boston, Chicago, Denver, Easy]' swing.combo01.model.removeElement('Bravo') assert swing.t1e.text == '[Alpha, Charlie, Delta, Echo]' swing.combo02.model.removeElement('Adams') assert swing.t2e.text == '[Boston, Chicago, Denver, Easy]' } } public void testListBindSyntheticProperties() { testInEDT { SwingBuilder swing = new SwingBuilder() def listModel = new DefaultListModel() ['Alpha', 'Bravo', 'Charlie', 'Delta'].each {listModel << it} def map = [sis:null, ses: null, svs: null] as ObservableMap swing.frame() { list(id: 'list01', model: listModel, selectionMode: ListSelectionModel.SINGLE_SELECTION) t1e = label(text:bind {list01.elements}) t1sx = label(text:bind {list01.selectedIndex}) t1se = label(text:bind {list01.selectedElement}) t1si = label(text:bind {list01.selectedValue}) bean(map, sis:bind {list01.selectedIndices}, ses:bind {list01.selectedElements}, svs:bind {list01.selectedValues}) } assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' swing.list01.selectedIndex = -1 assert swing.t1sx.text == '-1' assert swing.t1se.text == null assert swing.t1si.text == null assert map.sis == [] assert map.ses == [] assert map.svs == [] swing.list01.selectedIndex = 0 assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '0' assert swing.t1se.text == 'Alpha' assert swing.t1si.text == 'Alpha' assert map.sis == [0] assert map.ses == ['Alpha'] assert map.svs == ['Alpha'] swing.list01.selectedIndex = 1 assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '1' assert swing.t1se.text == 'Bravo' assert swing.t1si.text == 'Bravo' assert map.sis == [1] assert map.ses == ['Bravo'] assert map.svs == ['Bravo'] swing.list01.selectedValue = 'Charlie' assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '2' assert swing.t1se.text == 'Charlie' assert swing.t1si.text == 'Charlie' assert map.sis == [2] assert map.ses == ['Charlie'] assert map.svs == ['Charlie'] swing.list01.selectedValue = 'Fox Trot' assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '2' assert swing.t1se.text == 'Charlie' assert swing.t1si.text == 'Charlie' assert map.sis == [2] assert map.ses == ['Charlie'] assert map.svs == ['Charlie'] swing.list01.selectedElement = 'Delta' assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '3' assert swing.t1se.text == 'Delta' assert swing.t1si.text == 'Delta' assert map.sis == [3] assert map.ses == ['Delta'] assert map.svs == ['Delta'] swing.list01.selectedElement = 'Golf' assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta]' assert swing.t1sx.text == '3' assert swing.t1se.text == 'Delta' assert swing.t1si.text == 'Delta' assert map.sis == [3] assert map.ses == ['Delta'] assert map.svs == ['Delta'] swing.list01.selectionMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION swing.list01.selectedIndices = ([1i, 3i] as int[]) assert swing.t1sx.text == '1' assert swing.t1se.text == 'Bravo' assert swing.t1si.text == 'Bravo' assert map.sis == [1, 3] assert map.ses == ['Bravo', 'Delta'] assert map.svs == ['Bravo', 'Delta'] swing.list01.model.addElement('Echo') assert swing.t1e.text == '[Alpha, Bravo, Charlie, Delta, Echo]' swing.list01.model.removeElement('Bravo') assert swing.t1e.text == '[Alpha, Charlie, Delta, Echo]' } } public void testEventBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() def capture swing.actions() { button('Button!', id:'b') textField(id:'txt', text:bind(source:b, sourceEvent:'actionPerformed', sourceValue:{b.text})) textField(id:'txt2', text:bind(source:b, sourceEvent:'actionPerformed', sourceValue:{evt->capture=evt; 'Captured!'})) } assert swing.txt.text == 'Button!' swing.b.text = 'Pressed!' // not pressed yet... assert swing.txt.text == 'Button!' swing.b.doClick() //ok, now it's pressed assert swing.txt.text == 'Pressed!' //check that we get evet as closure arg assert swing.txt2.text == 'Captured!' assert capture instanceof ActionEvent } } public void testPropertyBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { checkBox('Button!', id:'cb') textField(id:'txt', enabled:bind(source:cb, sourceProperty:'enabled', id:'binding')) } assert swing.txt.enabled == swing.cb.enabled swing.cb.enabled = !swing.cb.enabled assert swing.txt.enabled == swing.cb.enabled swing.cb.enabled = !swing.cb.enabled assert swing.txt.enabled == swing.cb.enabled swing.binding.rebind() swing.cb.enabled = !swing.cb.enabled assert swing.txt.enabled == swing.cb.enabled swing.binding.unbind() swing.cb.enabled = !swing.cb.enabled assert swing.txt.enabled != swing.cb.enabled swing.binding.bind() assert swing.txt.enabled != swing.cb.enabled swing.binding.update() assert swing.txt.enabled == swing.cb.enabled swing.txt.enabled = !swing.txt.enabled swing.binding.reverseUpdate() assert swing.txt.enabled == swing.cb.enabled DefaultButtonModel md = new DefaultButtonModel() md.enabled = !swing.txt.enabled swing.cb.model = md assert swing.txt.enabled == swing.cb.enabled } } public void testBindGroup() { testInEDT { SwingBuilder swing = new SwingBuilder() int enabledChangeCount = 1 swing.actions() { bindGroup(id:'testGroup') checkBox('Button!', id:'cb') textField(id:'txt1', text:bind(source:cb, sourceProperty:'text', group:testGroup)) textField(id:'txt2', text:bind(source:cb, sourceProperty:'text', sourceValue: {enabledChangeCount++}, group:testGroup)) textField(id:'txt3', text:bind(source:cb, sourceProperty:'text', group:testGroup)) } assert swing.txt1.text == 'Button!' assert swing.txt2.text == '1' assert swing.txt3.text == 'Button!' swing.testGroup.unbind() swing.cb.text = 'CheckBox!' swing.cb.selected = true assert swing.txt1.text == 'Button!' assert swing.txt2.text == '1' assert swing.txt3.text == 'Button!' swing.testGroup.update() assert swing.txt1.text == 'CheckBox!' assert swing.txt2.text == '2' assert swing.txt3.text == 'CheckBox!' swing.testGroup.bind() swing.cb.text = 'ComboBox!' swing.cb.selected = true assert swing.txt1.text == 'ComboBox!' assert swing.txt2.text == '3' assert swing.txt3.text == 'ComboBox!' // test auto-bind // test explicit true swing.actions() { bindGroup(id:'testGroup', bind:true) checkBox('Button!', id:'cb') textField(id:'txt1', text:bind(source:cb, sourceProperty:'text', group:testGroup)) } assert swing.txt1.text == 'Button!' swing.cb.text = 'CheckBox!' assert swing.txt1.text == 'CheckBox!' // test explicit false swing.actions() { bindGroup(id:'testGroup', bind:false) checkBox('Button!', id:'cb') textField(id:'txt1', text:bind(source:cb, sourceProperty:'text', group:testGroup)) } assert swing.txt1.text == 'Button!' swing.cb.text = 'CheckBox!' assert swing.txt1.text == 'Button!' // test implied = true swing.actions() { bindGroup(id:'testGroup') checkBox('Button!', id:'cb') textField(id:'txt1', text:bind(source:cb, sourceProperty:'text', group:testGroup)) } assert swing.txt1.text == 'Button!' swing.cb.text = 'CheckBox!' assert swing.txt1.text == 'CheckBox!' } } public void testPropertyEventBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() int enabledChangeCount = 1 swing.actions() { checkBox('Button!', id:'cb') textField(id:'txtp', text:bind(source:cb, sourceProperty:'text',)) textField(id:'txtpv', text:bind(source:cb, sourceProperty:'text', sourceValue: {enabledChangeCount++})) textField(id:'txtep', text:bind(source:cb, sourceEvent:'stateChanged', sourceProperty:'text')) } shouldFail { swing.actions() { // all three are pointless textField(id:'txtepv', enabled:bind(source:cb, sourceEvent:'stateChanged', sourceProperty:'text', sourceValue: {enabledChangeCount++})) } } shouldFail { swing.actions() { // just value isn't enough info textField(id:'txtv', enabled:bind(source:cb, sourceValue: {enabledChangeCount++})) } } shouldFail { swing.actions() { // just event isn't enough textField(id:'txtepv', enabled:bind(source:cb, sourceEvent:'stateChanged')) } } assert swing.txtp.text == 'Button!' assert swing.txtpv.text == '1' assert swing.txtep.text == 'Button!' swing.cb.text = 'CheckBox!' assert swing.txtp.text == 'CheckBox!' assert swing.txtpv.text == '2' assert swing.txtep.text == 'Button!' swing.cb.selected = true assert swing.txtp.text == 'CheckBox!' assert swing.txtpv.text == '2' assert swing.txtep.text == 'CheckBox!' } } public void testReversePropertyBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { textField(id:'txt') checkBox('Button!', id:'cb', enabled:bind(target:txt, targetProperty:'enabled', id:'binding')) } assert swing.txt.enabled == swing.cb.enabled swing.cb.enabled = !swing.cb.enabled assert swing.txt.enabled == swing.cb.enabled swing.cb.enabled = !swing.cb.enabled assert swing.txt.enabled == swing.cb.enabled swing.binding.rebind() swing.cb.enabled = !swing.cb.enabled assert swing.txt.enabled == swing.cb.enabled swing.binding.unbind() swing.cb.enabled = !swing.cb.enabled assert swing.txt.enabled != swing.cb.enabled swing.binding.bind() assert swing.txt.enabled != swing.cb.enabled swing.binding.update() assert swing.txt.enabled == swing.cb.enabled swing.txt.enabled = !swing.txt.enabled swing.binding.reverseUpdate() assert swing.txt.enabled == swing.cb.enabled DefaultButtonModel md = new DefaultButtonModel() md.enabled = !swing.txt.enabled swing.cb.model = md assert swing.txt.enabled == swing.cb.enabled } } public void testValueNodeBinding() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { checkBox(id:'cb1') checkBox('Button!', id:'cb2', selected:bind(source:cb1, 'selected', id:'binding1')) checkBox(id:'cb3') checkBox('Button!', id:'cb4', selected:bind(target:cb3, 'selected', id:'binding2')) } assert !swing.cb1.selected assert !swing.cb2.selected swing.cb1.selected=true assert swing.cb1.selected assert swing.cb2.selected swing.cb2.selected=false assert swing.cb1.selected assert !swing.cb2.selected swing.cb1.selected=false swing.cb1.selected=true assert swing.cb1.selected assert swing.cb2.selected assert !swing.cb3.selected assert !swing.cb4.selected swing.cb3.selected=true assert swing.cb3.selected assert !swing.cb4.selected swing.cb4.selected=true assert swing.cb3.selected assert swing.cb4.selected swing.cb4.selected=false assert !swing.cb3.selected assert !swing.cb4.selected } } public void testReversePropertyPropertites() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { textField(id:'txt') checkBox('Button!', id:'cb1', enabled:bind(target:txt, targetProperty:'enabled', converter: {it}, id:'binding1')) checkBox('Button!', id:'cb2', enabled:bind(target:txt, targetProperty:'enabled', id:'binding2')) } assert swing.binding1.converter != null assert swing.binding2.converter == null } } public void testConverters() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { checkBox(id:'doner') checkBox(id:'cb1', enabled:bind(source:doner, sourceProperty:'enabled', converter: {it}, id:'binding1')) checkBox(id:'cb2', enabled:bind(source:doner, sourceProperty:'enabled', id:'binding2') {it}) checkBox(id:'cb3', enabled:bind(source:doner, sourceProperty:'enabled', id:'binding3')) } assert swing.binding1.converter != null assert swing.binding2.converter != null assert swing.binding3.converter == null // check double duty shouldFail(RuntimeException) { swing.actions() { checkBox(id:'doner') checkBox(id:'cb1', enabled:bind(source:doner, sourceProperty:'enabled', converter: {it}, id:'binding1') {it}) } } // check reversed bindings swing.actions() { checkBox(id:'doner') checkBox(id:'cb1', enabled:bind(target:doner, targetProperty:'enabled', converter: {it}, id:'binding1')) checkBox(id:'cb2', enabled:bind(target:doner, targetProperty:'enabled', id:'binding2') {it}) checkBox(id:'cb3', enabled:bind(target:doner, targetProperty:'enabled', id:'binding3')) } assert swing.binding1.converter != null assert swing.binding2.converter != null assert swing.binding3.converter == null // check double duty shouldFail(RuntimeException) { swing.actions() { checkBox(id:'doner') checkBox(id:'cb1', enabled:bind(target:doner, targetProperty:'enabled', converter: {it}, id:'binding1') {it}) } } } } public void testDateConverters() { testInEDT { BindableBean model = new BindableBean() model.date = new Date() def dateConverter = { dateString -> new SimpleDateFormat("dd.MM.yyyy").parse(dateString) } def dateValidator = { dateString -> try { def parser = new SimpleDateFormat("dd.MM.yyyy") parser.lenient = false parser.parse(dateString) } catch (Exception e) { return false } return true } SwingBuilder swing = new SwingBuilder() swing.actions() { tf1 = textField('01.01.1970', id:'birthdayText', columns:20, text:bind ( validator: dateValidator, converter: dateConverter, target:model, targetProperty:'birthday' )) tf2 = textField('01.01.1970', id:'birthdayText', columns:20) binding = bind ( source: tf2, sourceProperty: 'text', validator: dateValidator, converter: dateConverter, target:model, targetProperty:'birthday' ) } } } public void testPropertyValuePassthrough() { testInEDT { SwingBuilder swing = new SwingBuilder() swing.actions() { spinner(id:'spin1', value:4) spinner(id:'spin2', value:8) slider(id:'s1', value:bind(target:spin1, targetProperty:'value', id:'binding1', value:15)) slider(id:'s2', value:bind(source:spin2, sourceProperty:'value', id:'binding2', value:16)) } // s1 is the source, so it's value should be reflected assert swing.s1.value == 15 // s2 is target, not source, so it's value setting should have no effect assert swing.s2.value == 8 swing.actions() { slider(id:'s3', value:4) slider(id:'s4', value:8) textArea(id:'t1', text:bind(target:s3, targetProperty:'value', id:'binding3', value:'15', converter: {Integer.parseInt(it)})) textArea(id:'t2', text:bind(source:s4, sourceProperty:'value', id:'binding4', value:'16', converter: {Integer.parseInt(it)})) } // s1 is the source, so it's value should be reflected assert swing.s3.value == 15 // s2 is target, not source, so it's value setting should have no effect assert swing.s4.value == 8 } } public void testModel() { testInEDT { SwingBuilder swing = new SwingBuilder() def bean = new org.codehaus.groovy.runtime.DummyBean() swing.bindProxy(bean, id:'dummyBean') // test initial binding swing.textField(id:'textField', text:swing.dummyBean.name) assert swing.textField.text == bean.name // test no live update by default bean.name = 'Jochen' assert swing.textField.text != bean.name // test for no update on bean change bean = new org.codehaus.groovy.runtime.DummyBean() bean.name = 'Alex' swing.dummyBean.setModel(bean) assert swing.textField.text != bean.name //test for auto-update swing.bindProxy(bean, id:'boundDummyBean', bind:true) swing.textField(id:'boundTextField', text:swing.boundDummyBean.name) assert swing.boundTextField.text == bean.name bean.name = 'Danno' assert swing.boundTextField.text == bean.name // old model binding could be listening... assert swing.textField.text != bean.name } } public void testModelUpdate() { testInEDT { SwingBuilder swing = new SwingBuilder() def bean = new org.codehaus.groovy.runtime.DummyBean() swing.bindProxy(bean, id:'dummyBean', bind:true) // test initial binding bean.name = 'Jochen' swing.textField(id:'textField', text:swing.dummyBean.name) assert swing.textField.text == bean.name // test for update on bean change bean = new org.codehaus.groovy.runtime.DummyBean() bean.name = 'Alex' swing.dummyBean.setModel(bean) assert swing.textField.text == bean.name // now simply one more live update: test fails here because // setModel() has called rebind() instead of bind()! bean.name = 'Danno' assert swing.textField.text == bean.name // test unbound, nothing should update no matter what we do swing.dummyBean.unbind() bean.name = 'Guillaume' assert swing.textField.text != bean.name bean = new org.codehaus.groovy.runtime.DummyBean() bean.name = 'Andres' swing.dummyBean.setModel(bean) assert swing.textField.text != bean.name bean.name = 'James' assert swing.textField.text != bean.name // but a manual update should work swing.dummyBean.update() assert swing.textField.text == bean.name } } def mutualPropertyShortWorkout = { source, sourceProperty, sourceMutators, target, targetProperty, targetMutators, binding -> sourceMutators[0]() targetMutators[0]() // test forward binding assert source[sourceProperty] == target[targetProperty] sourceMutators[1]() assert source[sourceProperty] == target[targetProperty] sourceMutators[0]() assert source[sourceProperty] == target[targetProperty] // test reverse binding targetMutators[1]() assert source[sourceProperty] == target[targetProperty] targetMutators[0]() assert source[sourceProperty] == target[targetProperty] } def mutualPropertyWorkout = { source, sourceProperty, sourceMutators, target, targetProperty, targetMutators, binding -> mutualPropertyShortWorkout(source, sourceProperty, sourceMutators, target, targetProperty, targetMutators, binding) // test rebound binding.rebind() targetMutators[1]() assert source[sourceProperty] == target[targetProperty] sourceMutators[0]() assert source[sourceProperty] == target[targetProperty] // test unbound not updating binding.unbind() sourceMutators[1]() assert source[sourceProperty] != target[targetProperty] targetMutators[1]() assert source[sourceProperty] == target[targetProperty] sourceMutators[0]() assert source[sourceProperty] != target[targetProperty] // test manual forward update sourceMutators[0]() assert source[sourceProperty] != target[targetProperty] binding.update() assert source[sourceProperty] == target[targetProperty] // test manual reverse update sourceMutators[1]() assert source[sourceProperty] != target[targetProperty] binding.reverseUpdate() assert source[sourceProperty] == target[targetProperty] } public void testMutualPropertyBinding() { testInEDT { ['full', 'source', 'target'].each { mode -> // contextual bind mode ['prop', 'synth'].each { target -> // target binding ['prop', 'synth'].each { source -> // source binding println "Trying $mode binding on $source source and $target target" SwingBuilder swing = new SwingBuilder() def sProp, tProp swing.actions() { switch (source) { case 'prop': sProp = 'enabled' st = new BindableBean(text:'Baz') break case 'synth': sProp = 'selected' st = textField(text:'Baz') break default: fail() } switch (target) { case 'prop': tProp = 'enabled' tt = new BindableBean(text:'Baz') break case 'synth': tProp = 'selected' tt = textField(text:'Baz') break default: fail() } switch (mode) { case 'full': checkBox(id:'cb1') checkBox(id:'cb2') bind(source: cb1, sourceProperty: sProp, target: cb2, targetProperty: tProp, id:'binding', mutual:'true') bind('text', source: st, target: tt, id:'textBinding', mutual:'true') break case 'source': checkBox(id:'cb2') checkBox(id:'cb1', "$sProp": bind( target: cb2, targetProperty:tProp, id:'binding', mutual:'true')) bean(st, text:bind( target: tt, 'text', id:'textBinding', mutual:'true')) break case 'target': checkBox(id:'cb1') checkBox(id:'cb2', "$tProp": bind( source: cb1, sourceProperty:sProp, id:'binding', mutual:'true')) bean(tt, text:bind( source: st, 'text', id:'textBinding', mutual:'true')) break default: fail() } } mutualPropertyWorkout(swing.cb1, sProp, [{swing.cb1[sProp] = true}, {swing.cb1[sProp] = false}], swing.cb2, tProp, [{swing.cb2[tProp] = true}, {swing.cb2[tProp] = false}], swing.binding) mutualPropertyWorkout(swing.st, 'text', [{swing.st.text = "Foo"}, {swing.st.text = "Bar"}], swing.tt, 'text', [{swing.tt.text = "Foo"}, {swing.tt.text = "Bar"}], swing.textBinding) } if (mode != 'source') { println "Trying $mode binding on event source and $target target" SwingBuilder swing = new SwingBuilder() def tProp swing.actions() { st = button(actionCommand:'Baz') switch (target) { case 'prop': tProp = 'enabled' tt = new BindableBean(text:'Baz') break case 'synth': tProp = 'selected' tt = textField(text:'Baz') break default: fail() } switch (mode) { case 'full': checkBox(id:'cb1') checkBox(id:'cb2') bind(source: cb1, sourceEvent: 'actionPerformed', sourceProperty: 'borderPaintedFlat', target: cb2, targetProperty: tProp, id:'binding', mutual:'true') bind('text', source: st, sourceEvent: 'actionPerformed', sourceProperty:'actionCommand', target: tt, id:'textBinding', mutual:'true') break case 'target': checkBox(id:'cb1') checkBox(id:'cb2', "$tProp": bind( source: cb1, sourceEvent: 'actionPerformed', sourceProperty: 'borderPaintedFlat', id:'binding', mutual:'true')) bean(tt, text:bind( source: st, 'actionCommand', sourceEvent: 'actionPerformed', id:'textBinding', mutual:'true')) break default: fail() } mutualPropertyShortWorkout(swing.cb1, 'borderPaintedFlat', [{swing.cb1.borderPaintedFlat = true; swing.cb1.doClick()}, {swing.cb1.borderPaintedFlat = false; swing.cb1.doClick()}], swing.cb2, tProp, [{swing.cb2[tProp] = true}, {swing.cb2[tProp] = false}], swing.binding) mutualPropertyShortWorkout(swing.st, 'actionCommand', [{swing.st.actionCommand = "Foo"; swing.st.doClick()}, {swing.st.actionCommand = "Bar"; swing.st.doClick()}], swing.tt, 'text', [{swing.tt.text = "Foo"}, {swing.tt.text = "Bar"}], swing.textBinding) } } } } println "finished all permutations successfully" } } public void testConverter() { testInEDT { SwingBuilder swing = new SwingBuilder() def model = new BindableBean() def toNumber = { v -> if( v == null || v == "" ) return null try { return new Integer(v) } catch( x ) { return null } } swing.actions { frame( title: "Binding test", size: [100,60]) { textField( id: "t1", text: bind(target:model, targetProperty: "value", converter: {toNumber(it)}) ) textField( id: "t2", text: bind(target:model, 'floatValue', value:'1234', converter: { Float.parseFloat(it) * 2 })) } } assert model.floatValue == 2468 swing.t1.text = '1234' assert model.value == 1234 } } public void testValidator() { testInEDT { SwingBuilder swing = new SwingBuilder() def model = new BindableBean() def isInteger = { v -> try { Float.parseFloat(v) return true } catch (NumberFormatException ignore) { return false } } swing.actions { frame( title: "Binding test", size: [100,60]) { textField( id: "t1", text: bind(target:model, value:'123', targetProperty: "value", validator: isInteger, converter: Integer.&parseInt) ) } } assert model.value == 123 swing.t1.text = '1234' assert model.value == 1234 swing.t1.text = 'Bogus' assert model.value == 1234 swing.t1.text = '12345' assert model.value == 12345 } } public void testBindableVetoable() { testInEDT { def bbean = new BindableBean() bbean.vetoableChange = { PropertyChangeEvent pce -> if( pce.newValue ==~ /.*[ ]+.*/ ) { throw new PropertyVetoException( "No spaces allowed", pce ) } } def abean = null SwingBuilder.build { abean = bean(new BindableBean(), text:'text', id:'tf') bean(bbean, vetoField:bind { tf.text } ) } abean.text = "test1" assert abean.text == bbean.vetoField abean.text = "this should fail" assert abean.text != bbean.vetoField } } } @Bindable class BindableBean { boolean enabled Integer value float floatValue int pvalue String text Date date @Vetoable String vetoField } Other Groovy examples (source code examples)Here is a short list of links related to this Groovy SwingBuilderBindingsTest.groovy source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.