Differences
This shows you the differences between two versions of the page.
|
association_editor [2012/03/30 17:46] srdjan.lukovic |
association_editor [2012/07/09 10:50] (current) srdjan.lukovic [GUI Code] |
||
|---|---|---|---|
| Line 1: | Line 1: | ||
| - | ====== Association Editor ====== | + | ====== Selection List ====== |
| - | This sample demonstrates distinctive feature, dynamically linking objects. | + | |
| + | **Selection List** is a [[SOLoist Sample Applications|SOLoist sample application]] that shows how persistent selections of a subset of objects linked over an association can be implemented by means of another (subsetting) association and the appropriate configuration of the //Element Component//. | ||
| + | |||
| + | The intention is to enable selection of a subset of //Bank Advisers// that are linked to a particular object of //Person// by checkboxes. | ||
| + | |||
| + | The particular object of //Person// whose //Bank Advisers// are shown in the list is fetched via a Service Access Point component. It provides the fetched object to its output pin that is wired to the input pin of the list box. | ||
| + | |||
| + | The list box is configured to render all objects linked to the slot //myBankAdvisers//, but to edit the (subsetting) slot //successfulAdvisers//. | ||
| + | |||
| + | This way, instead of using Boolean attributes as flags, a subsetting association is used to store the selection. The selection is inherently persistent. | ||
| ==== Live example ==== | ==== Live example ==== | ||
| Line 6: | Line 15: | ||
| [[http://soloistdemo.org/SampleApplications/associationeditor.html]]\\ | [[http://soloistdemo.org/SampleApplications/associationeditor.html]]\\ | ||
| [[http://soloistdemo.org/SampleApplications/oql?q=SELECT+p%2C+p.name%2C+p.gender%2C+p.age%2C+p.dateOfBirth%2C+p.height%2C+p.isMarried%2C+p.photo%2C+p.rootFolder%0D%0AFROM+Person+p&f=html | OQL Query: Persons]] | [[http://soloistdemo.org/SampleApplications/oql?q=SELECT+p%2C+p.name%2C+p.gender%2C+p.age%2C+p.dateOfBirth%2C+p.height%2C+p.isMarried%2C+p.photo%2C+p.rootFolder%0D%0AFROM+Person+p&f=html | OQL Query: Persons]] | ||
| + | |{{screen:associationeditor.png?250}}| | ||
| ===== UML Model ===== | ===== UML Model ===== | ||
| Line 15: | Line 25: | ||
| ===== GUI Code ===== | ===== GUI Code ===== | ||
| <code java> | <code java> | ||
| - | package rs.sol.sampleapps; | ||
| - | |||
| - | import rs.sol.sampleapps.commands.CreatePerson; | ||
| - | import rs.sol.soloist.helpers.init.DefaultContextInit; | ||
| - | import rs.sol.soloist.helpers.init.Initializer; | ||
| - | import rs.sol.soloist.helpers.init.InitializerFailedException; | ||
| - | import rs.sol.soloist.modelreader.Repository; | ||
| - | import rs.sol.soloist.server.builtindomains.builtindatatypes.Boolean; | ||
| - | import rs.sol.soloist.server.builtindomains.builtindatatypes.Date; | ||
| - | import rs.sol.soloist.server.builtindomains.builtindatatypes.Integer; | ||
| - | import rs.sol.soloist.server.builtindomains.builtindatatypes.Real; | ||
| - | import rs.sol.soloist.server.builtindomains.builtindatatypes.Text; | ||
| - | import rs.sol.soloist.server.builtindomains.common.ElementDescriptor; | ||
| - | import rs.sol.soloist.server.guiconfiguration.components.GUIApplicationComponent; | ||
| - | import rs.sol.soloist.server.guiconfiguration.components.GUIButtonComponent; | ||
| - | import rs.sol.soloist.server.guiconfiguration.components.GUILabelComponent; | ||
| - | import rs.sol.soloist.server.guiconfiguration.components.GUIPanelComponent; | ||
| - | import rs.sol.soloist.server.guiconfiguration.construction.GUIComponentBinding; | ||
| - | import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIElementComponent; | ||
| - | import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIInputKind; | ||
| - | import rs.sol.soloist.server.guiconfiguration.layout.TableLayoutData; | ||
| - | import rs.sol.soloist.server.server.SoloistServiceServlet; | ||
| - | |||
| - | public enum SubmitPerson implements Initializer{ | ||
| - | |||
| - | INSTANCE; | ||
| - | |||
| - | @Override | ||
| - | public void init() throws InitializerFailedException { | ||
| - | GUIApplicationComponent page = new GUIApplicationComponent(); | ||
| - | page.name.set(Text.fromString("SubmitPerson")); | ||
| - | SoloistServiceServlet.registerApplication(page); | ||
| - | page.context.set(DefaultContextInit.getRoot()); | ||
| - | |||
| - | GUIPanelComponent root = GUIPanelComponent.createFlow(page); | ||
| - | |||
| - | GUILabelComponent title = GUILabelComponent.create(root, "Submit Person"); | ||
| - | title.styleName.set(Text.fromString("titleStyle")); | ||
| - | |||
| - | GUIPanelComponent topPanel = GUIPanelComponent.createFlow(root); | ||
| - | topPanel.styleName.set(Text.fromString("topPanel")); | ||
| - | |||
| - | GUIPanelComponent table = GUIPanelComponent.createTable(topPanel); | ||
| - | |||
| - | int row = 0; | ||
| - | GUILabelComponent.create(table, "Name: ", row, 0); // instead of "row, 0" at the end, you could use "new TableLayoutDate(row, 0)" | ||
| - | GUIElementComponent nameInput = GUIElementComponent.createInput(table, "", Text.CLASSIFIER, row++, 1); // second parameter "" (name) | ||
| - | // is not important unless you use this component in the search form as a parameter | ||
| - | GUIInputKind.get(nameInput).initialValues.set(ElementDescriptor.create(Text.fromString("New Person"))); // initial value for the name field | ||
| - | |||
| - | GUILabelComponent.create(table, "Gender: ", row, 0); | ||
| - | GUIElementComponent genderInput = GUIElementComponent.createInput(table, "", Repository.getRepository().getEnumeration(Gender.FQ_TYPE_NAME), row++, 1); | ||
| - | // for enumeration one must fetch its type using Repository class, which is UML model reflection povider | ||
| - | |||
| - | GUILabelComponent.create(table, "Age: ", row, 0); | ||
| - | GUIElementComponent ageInput = GUIElementComponent.createInput(table, "", Integer.CLASSIFIER, row++, 1); | ||
| - | |||
| - | GUILabelComponent.create(table, "Date of birth: ", row, 0); | ||
| - | GUIElementComponent dateOfBirthInput = GUIElementComponent.createInput(table, "", Date.CLASSIFIER, row++, 1); | ||
| - | |||
| - | GUILabelComponent.create(table, "Height [m]: ", row, 0); | ||
| - | GUIElementComponent heightInput = GUIElementComponent.createInput(table, "", Real.CLASSIFIER, row++, 1); | ||
| - | |||
| - | GUILabelComponent.create(table, "Is married: ", row, 0); | ||
| - | GUIElementComponent isMarriedInput = GUIElementComponent.createInputCheckbox(table, "", "", true, new TableLayoutData(row++, 1)); // true is initial value | ||
| - | // if you wish to allow marriage status to be undefined, meaning three value combo (empty, yes and no) instead of two value checkbox use this: | ||
| - | // GUIElementComponent isMarriedInput2 = GUIElementComponent.createInput(table, "", Boolean.CLASSIFIER, row++, 1); | ||
| - | |||
| - | // take a look at the date picker in CSS | ||
| - | // also, take a look at .gwt-TextBox-validation_failed and .dateBoxFormatError | ||
| - | // these define how these input widgets react when invalid values are typed in, | ||
| - | // for example, if value "Java" is typed in the ageInput which is built to accept Integers | ||
| - | |||
| - | // now. let's create buttons | ||
| - | GUIPanelComponent hp = GUIPanelComponent.createHorizontal(topPanel); | ||
| - | |||
| - | GUIButtonComponent createButton = GUIButtonComponent.create(hp, "Create Person", new CreatePerson()); | ||
| - | createButton.confirmationRequired.set(Boolean.TRUE); | ||
| - | createButton.confirmationMessage.set(Text.fromString("Are you sure you want to create a person?")); | ||
| - | |||
| - | // let's now bind the button with input parameters' provider components | ||
| - | GUIComponentBinding.create(nameInput.value, createButton, CreatePerson.PROPERTIES.name); | ||
| - | GUIComponentBinding.create(ageInput.value, createButton, CreatePerson.PROPERTIES.age); | ||
| - | GUIComponentBinding.create(genderInput.value, createButton, CreatePerson.PROPERTIES.gender); | ||
| - | GUIComponentBinding.create(dateOfBirthInput.value, createButton, CreatePerson.PROPERTIES.dateOfBirth); | ||
| - | GUIComponentBinding.create(heightInput.value, createButton, CreatePerson.PROPERTIES.height); | ||
| - | GUIComponentBinding.create(isMarriedInput.value, createButton, CreatePerson.PROPERTIES.isMarried); | ||
| - | |||
| - | // let's reset input fields after command execution | ||
| - | GUIComponentBinding.create(createButton.commandExecuted, GUIInputKind.get(nameInput).reset); | ||
| - | GUIComponentBinding.create(createButton.commandExecuted, GUIInputKind.get(ageInput).reset); | ||
| - | GUIComponentBinding.create(createButton.commandExecuted, GUIInputKind.get(genderInput).reset); | ||
| - | GUIComponentBinding.create(createButton.commandExecuted, GUIInputKind.get(dateOfBirthInput).reset); | ||
| - | GUIComponentBinding.create(createButton.commandExecuted, GUIInputKind.get(heightInput).reset); | ||
| - | GUIComponentBinding.create(createButton.commandExecuted, GUIInputKind.get(isMarriedInput).reset); | ||
| - | |||
| - | // let's now create clear and reset form buttons | ||
| - | // note the difference between reset and clear, reset re-sets the initial values into the input fields, while clear actually makes them empty | ||
| - | GUIButtonComponent clearButton = GUIButtonComponent.create(hp, "Clear Form"); | ||
| - | GUIComponentBinding.create(clearButton.click, nameInput.clearValue); | ||
| - | GUIComponentBinding.create(clearButton.click, ageInput.clearValue); | ||
| - | GUIComponentBinding.create(clearButton.click, genderInput.clearValue); | ||
| - | GUIComponentBinding.create(clearButton.click, dateOfBirthInput.clearValue); | ||
| - | GUIComponentBinding.create(clearButton.click, heightInput.clearValue); | ||
| - | GUIComponentBinding.create(clearButton.click, isMarriedInput.clearValue); | ||
| - | |||
| - | GUIButtonComponent resetButton = GUIButtonComponent.create(hp, "Reset Form"); | ||
| - | GUIComponentBinding.create(resetButton.click, GUIInputKind.get(nameInput).reset); | ||
| - | GUIComponentBinding.create(resetButton.click, GUIInputKind.get(ageInput).reset); | ||
| - | GUIComponentBinding.create(resetButton.click, GUIInputKind.get(genderInput).reset); | ||
| - | GUIComponentBinding.create(resetButton.click, GUIInputKind.get(dateOfBirthInput).reset); | ||
| - | GUIComponentBinding.create(resetButton.click, GUIInputKind.get(heightInput).reset); | ||
| - | GUIComponentBinding.create(resetButton.click, GUIInputKind.get(isMarriedInput).reset); | ||
| - | } | ||
| - | } | ||
| - | </code> | ||
| - | |||
| package rs.sol.sampleapps; | package rs.sol.sampleapps; | ||
| Line 145: | Line 38: | ||
| import rs.sol.soloist.server.guiconfiguration.components.GUIPanelComponent; | import rs.sol.soloist.server.guiconfiguration.components.GUIPanelComponent; | ||
| import rs.sol.soloist.server.guiconfiguration.construction.GUIComponentBinding; | import rs.sol.soloist.server.guiconfiguration.construction.GUIComponentBinding; | ||
| - | import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIElementComponent; | + | import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIEdit; |
| - | import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUIListWidget; | + | |
| - | import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUISlotEditorKind; | + | |
| - | import rs.sol.soloist.server.guiconfiguration.elementcomponents.GUISlotValueInput; | + | |
| - | import rs.sol.soloist.server.guiconfiguration.layout.CellLayoutData; | + | |
| import rs.sol.soloist.server.guiconfiguration.layout.TableLayoutData; | import rs.sol.soloist.server.guiconfiguration.layout.TableLayoutData; | ||
| import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUIFindSingleInstanceSAPComponent; | import rs.sol.soloist.server.guiconfiguration.nonvisualcompoments.GUIFindSingleInstanceSAPComponent; | ||
| Line 167: | Line 56: | ||
| { | { | ||
| GUIApplicationComponent page = new GUIApplicationComponent(); | GUIApplicationComponent page = new GUIApplicationComponent(); | ||
| - | page.name.set(Text.fromString("AssociationEditor")); | + | page.setName("AssociationEditor"); |
| SoloistServiceServlet.registerApplication(page); | SoloistServiceServlet.registerApplication(page); | ||
| - | page.context.set(createContextAndStyles()); | + | page.setContext(createContextAndStyles()); |
| GUIPanelComponent root = GUIPanelComponent.createFlow(page); | GUIPanelComponent root = GUIPanelComponent.createFlow(page); | ||
| GUILabelComponent title = GUILabelComponent.create(root, "Association Editor"); | GUILabelComponent title = GUILabelComponent.create(root, "Association Editor"); | ||
| - | title.styleName.set(Text.fromString("titleStyle")); | + | title.setStyle("titleStyle"); |
| GUIPanelComponent topPanel = GUIPanelComponent.createFlow(root); | GUIPanelComponent topPanel = GUIPanelComponent.createFlow(root); | ||
| - | topPanel.styleName.set(Text.fromString("topPanel")); | + | topPanel.setStyle("topPanel"); |
| GUIPanelComponent table = GUIPanelComponent.createTable(topPanel); // panel with table layout | GUIPanelComponent table = GUIPanelComponent.createTable(topPanel); // panel with table layout | ||
| Line 183: | Line 72: | ||
| Person.FQ_TYPE_NAME, | Person.FQ_TYPE_NAME, | ||
| Person.FQPropertyNames.desc, | Person.FQPropertyNames.desc, | ||
| - | (ClassifierInstanceDescriptor)ElementDescriptor.create(Text.fromString(ObjectSpaceInit.JANNE_ROE_IDENTIFIER)), | + | (ClassifierInstanceDescriptor)ElementDescriptor.create(Text.fromString(ObjectSpaceInit.JANNE_ROE_IDENTIFIER))); |
| - | false); | + | |
| - | GUIElementComponent editList = GUIElementComponent.create(table, GUISlotEditorKind.create(Person.PROPERTIES.successfulAdvisers), new GUIListWidget(), GUISlotValueInput.create(Person.PROPERTIES.myBankAdvisers), new TableLayoutData(0, 0)); | + | GUIEdit editList = GUIEdit.createList(table, Person.PROPERTIES.successfulAdvisers, Person.PROPERTIES.myBankAdvisers); |
| - | GUIComponentBinding.create(findJanneRoe.value, GUISlotEditorKind.get(editList).element); | + | editList.setLayoutData(TableLayoutData.create(0, 0)); |
| - | GUIComponentBinding.create(findJanneRoe.value, GUISlotValueInput.get(editList).element); | + | GUIComponentBinding.create(findJanneRoe.opValue(), editList.ipElement()); |
| - | CellLayoutData.setSize(editList, "250px", "200px"); | + | GUIComponentBinding.create(findJanneRoe.opValue(), editList.ipSlotValueElement()); |
| - | editList.styleName.set(Text.fromString("listEditor")); | + | |
| + | editList.setSize("250px", "200px"); | ||
| + | editList.setStyle("listEditor"); | ||
| } | } | ||
| private GUIContext createContextAndStyles() { | private GUIContext createContextAndStyles() { | ||
| GUIContext context = new GUIContext(); | GUIContext context = new GUIContext(); | ||
| - | context.supercontext.set(DefaultContextInit.getRoot()); | + | DefaultContextInit.getRoot().addContext(context); |
| GUIObjectSetting person = GUIObjectSetting.create(context, Person.CLASSIFIER); | GUIObjectSetting person = GUIObjectSetting.create(context, Person.CLASSIFIER); | ||
| GUITextFeature.createName(person, Person.PROPERTIES.name); | GUITextFeature.createName(person, Person.PROPERTIES.name); | ||
| - | GUITextFeature.createSeparator(person, ":", true); | + | GUITextFeature.createFixedSeparator(person, ":"); |
| GUITextFeature.createDescription(person, Person.PROPERTIES.age); | GUITextFeature.createDescription(person, Person.PROPERTIES.age); | ||
| GUIPictureFeature.createSmallIcon(person, "images/icons/person.png"); | GUIPictureFeature.createSmallIcon(person, "images/icons/person.png"); | ||
| Line 207: | Line 97: | ||
| } | } | ||
| } | } | ||
| + | </code> | ||