|
From: Lieven D. (JIRA) <no...@sp...> - 2008-11-12 15:32:41
|
[ http://jira.springframework.org/browse/RCP-567?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Lieven Doclo resolved RCP-567.
------------------------------
Resolution: Fixed
see FormLayoutFormBuilder
> New form builder for creating complex forms.
> --------------------------------------------
>
> Key: RCP-567
> URL: http://jira.springframework.org/browse/RCP-567
> Project: Spring Rich Client Project
> Issue Type: Improvement
> Components: Core
> Affects Versions: 1.0.0
> Environment: Windwos XP
> Reporter: Brad Maupin
> Fix For: 1.1.0
>
> Attachments: orderform.jpg
>
>
> The provided TableFormBuilder is only useful for very simple forms. I was able to create a form builder that extends AbstractFormBuilder and uses the jGoodies DefaultFormBuilder for layout. The main advantage of the jGoodies form builder is the ability to override the default layout's column span and orientation in a cell on a control by control basis. It is also nice to be able to specify the column and row definitions each in one (long) string. The builder also allowed me to create a complex form that also resized sensibly (which was a major priority).
> Here is my form builder. It has the provisions to create the complex form in the attached screen shot. The functionality it provides was catered to my needs and therefore I'd expect it to be changed as necessary to be general and follow common guidelines. The "add" methods create labels for the new controls and the "cell" methods only perform layout. Column spans can be overridden by either specifying a column span value other than 1 and by using CellConstraints. The use of CellConstraints also provides the means to override cell alignment for the control being layed out. For convenience the column span value can be specified to "extend to the last column". The builder will automatically commit the row when the column span is specified as such.
> One minor downside to this implementation is that gap column and row sizes must be specified. This impl does allow defining different gaps. The builder could easy insert the gap values into the row spec, but my form requires specifying the column gaps since they are not regularly placed.
> [code]
> import javax.swing.JButton;
> import javax.swing.JComponent;
> import javax.swing.JLabel;
> import javax.swing.JPanel;
> import net.mobileworkforce.maui.app.MauiApplication;
> import org.springframework.richclient.form.binding.Binding;
> import org.springframework.richclient.form.binding.BindingFactory;
> import org.springframework.richclient.form.builder.AbstractFormBuilder;
> import org.springframework.richclient.form.builder.FormComponentInterceptor;
> import org.springframework.util.Assert;
> import com.jgoodies.forms.builder.DefaultFormBuilder;
> import com.jgoodies.forms.layout.CellConstraints;
> import com.jgoodies.forms.layout.FormLayout;
> import com.jgoodies.forms.layout.CellConstraints.Alignment;
> public class MauiFormBuilder extends AbstractFormBuilder {
>
> public static final int COL_SPAN_ALL = 0;
> protected FormLayout layout;
> protected DefaultFormBuilder builder;
> protected CellConstraints cc = new CellConstraints();
> protected FormComponentInterceptor interceptor;
> private String formName = null;
> protected MauiFormBuilder(BindingFactory bindingFactory, String colSpec, String rowSpec) {
> super(bindingFactory);
> layout = new FormLayout(colSpec, rowSpec);
> builder = new DefaultFormBuilder(layout);
> interceptor = getFormComponentInterceptor();
> }
> public JPanel getForm() {
> return builder.getPanel();
> }
>
> public void setFormPropertyName(String name) {
> formName = name;
> }
>
> public JComponent[] add(Binding binding, int colSpan, int rowSpan) {
> Assert.notNull(binding, "binding is null");
> Assert.isTrue(getFormModel() == binding.getFormModel(),
> "Binding's form model must match FormBuilder's form model");
> JComponent component = binding.getControl();
> processComponent(binding.getProperty(), component);
> final JLabel label = createLabelFor(binding.getProperty(), component);
> builder.append(label);
> boolean newRow = false;
> if (colSpan == COL_SPAN_ALL) {
> colSpan = builder.getColumnCount() - builder.getColumn() + 1;
> newRow = true;
> }
> builder.setRowSpan(rowSpan);
> builder.append(component, colSpan);
> builder.setRowSpan(1);
> if (newRow) {
> row();
> }
> return new JComponent[] { label, component };
> }
> public JComponent[] add(Binding binding, int colSpan) {
> return add(binding, colSpan, 1);
> }
>
> public JComponent[] add(String fieldName) {
> return add(fieldName, 1);
> }
> public JComponent[] add(String fieldName, int colSpan) {
> return add(createDefaultBinding(fieldName), colSpan);
> }
>
> public JComponent cellWithLabel(String labelProperty, JComponent component, int colSpan) {
> boolean newRow = false;
> if (colSpan == COL_SPAN_ALL) {
> colSpan = builder.getColumnCount() - builder.getColumn() + 1 - 2;
> newRow = true;
> }
> processComponent(labelProperty, component);
> final JLabel label = createLabelFor(labelProperty, component);
> builder.append(label);
> builder.append(component, colSpan);
> if (newRow) {
> row();
> }
> return label;
> }
>
> public MauiFormBuilder cell(JComponent component) {
> builder.append(component);
> return this;
> }
>
> public MauiFormBuilder cell(JComponent component, int colSpan) {
> return cell(component, cc.xyw(1, 1, colSpan));
> }
> public MauiFormBuilder cell(String fieldName, JComponent component, int colSpan) {
> processComponent(fieldName, component);
> return cell(component, cc.xyw(1, 1, colSpan));
> }
> public MauiFormBuilder cell(JComponent component, int colSpan, int rowSpan) {
> return cell(component, cc.xywh(1, 1, colSpan, rowSpan));
> }
>
> public MauiFormBuilder cell(String fieldName, JComponent component, int colSpan, int rowSpan) {
> processComponent(fieldName, component);
> return cell(component, cc.xywh(1, 1, colSpan, rowSpan));
> }
>
> public MauiFormBuilder cell(JComponent component, CellConstraints c) {
> c.gridX = builder.getColumn();
> c.gridY = builder.getRow();
> boolean newRow = false;
> if (c.gridWidth == COL_SPAN_ALL) {
> c.gridWidth = builder.getColumnCount() - builder.getColumn() + 1;
> newRow = true;
> }
> builder.add(component, c);
> if (newRow) {
> row();
> } else {
> builder.nextColumn(c.gridWidth);
> }
> return this;
> }
>
> public MauiFormBuilder cell(String fieldName, JComponent component, CellConstraints c) {
> processComponent(fieldName, component);
> return cell(component, c);
> }
>
> public void row() {
> builder.nextLine(2);
> }
>
> public void setColumn(int column) {
> builder.setColumn(column);
> }
>
> public CellConstraints cellConstraints(int colSpan, int rowSpan, Alignment colAlign, Alignment rowAlign) {
> return cc.xywh(1, 1, colSpan, rowSpan, colAlign, rowAlign);
> }
> public CellConstraints cellConstraints(int colSpan, Alignment colAlign, Alignment rowAlign) {
> return cc.xywh(1, 1, colSpan, 1, colAlign, rowAlign);
> }
> public CellConstraints cellConstraints(int colSpan, Alignment colAlign) {
> return cc.xywh(1, 1, colSpan, 1, colAlign, CellConstraints.DEFAULT);
> }
> public void processComponent(String fieldName, JComponent component) {
> if (interceptor != null) {
> interceptor.processComponent(fieldName, component);
> }
> if (formName != null) {
> String property = formName + "." + fieldName + ".caption";
> String tooltip = MauiApplication.getMessage(property);
> if (tooltip != null) {
> component.setToolTipText(tooltip);
> }
> }
> }
>
> public JLabel createLabel(String fieldName) {
> return createLabelFor(fieldName, null);
> }
>
> public JButton createButton(String fieldName) {
> JButton button = getComponentFactory().createButton("");
> getFormModel().getFieldFace(fieldName).configure(button);
> processComponent(fieldName, button);
> return button;
> }
>
> }
> [/code]
> The following is the code to create the attached complex form. I also used formLayoutMaker to visually create the form's layout.
> [code]
> public JPanel createFormControl() {
> FormModel formModel = getFormModel();
>
> //columns 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
> String colSpec = "right:30dlu,3dlu,5dlu,100dlu,3dlu,right:50dlu,3dlu,10dlu,10dlu,50dlu,3dlu,right:30dlu,3dlu,10dlu,3dlu,right:65dlu,3dlu,10dlu,3dlu,right:40dlu,3dlu,right:min(10dlu;pref):grow,3dlu,max(50dlu;pref)";
> //rows 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
> String rowSpec = "pref,3dlu,pref,3dlu,pref,3dlu,pref,3dlu,pref,3dlu,150dlu:grow,3dlu,pref,3dlu,fill:40dlu,3dlu,pref,3dlu,pref,3dlu,pref";
> MauiFormBuilder builder = new MauiFormBuilder(getBindingFactory(), colSpec, rowSpec);
>
> mfgImage = new JPanel();
> cmdClear = builder.createButton("cmdClear");
> cmdDelete = builder.createButton("cmdDelete");
> cmdSubmit = builder.createButton("cmdSubmit");
> cmdSave = builder.createButton("cmdSave");
> cmdCancel = builder.createButton("cmdCancel");
> lblSignature = builder.createLabel("capture");
> lblNotes = builder.createLabel("note");
>
> //1
> builder.cell(mfgImage, 5, 3);
> cboMfg = new ManufacturerComboBox();
> MauiComboBoxBinding cbBinding = new MauiComboBoxBinding(formModel, "order.manufacturer", cboMfg);
> builder.add(cbBinding, 7);
> cboShowCustOf = new SalesRepComboBox();
> cbBinding = new MauiComboBoxBinding(formModel, "order.showCustomersOfSalesRep", cboShowCustOf);
> builder.cellWithLabel("showCustOf", cboShowCustOf, MauiFormBuilder.COL_SPAN_ALL);
>
> //3
> builder.setColumn(6);
> cboCustomer = new CustomerComboBox(order.getShowCustomersOfSalesRep());
> //this keeps the control size to a minimum - otherwise the form is very wide because the control sizes to fit its data (long)
> Dimension d = cboCustomer.getPreferredSize();
> d.width = 300;
> cboCustomer.setPreferredSize(d);
> cbBinding = new MauiComboBoxBinding(formModel, "order.customer", cboCustomer);
> builder.add(cbBinding, MauiFormBuilder.COL_SPAN_ALL);
>
> //5
> builder.setColumn(6);
> cboShipTo = new LocationComboBox(order.getCustomer());
> cbBinding = new MauiComboBoxBinding(formModel, "order.shipToLocation", cboShipTo);
> builder.add(cbBinding, MauiFormBuilder.COL_SPAN_ALL);
>
> //7
> builder.setColumn(6);
> txtPO = (JTextField) builder.add("order.purchaseOrderNumber", 7)[1];
>
> SalesRepresentative defaultSalesRep = getCustomerManufacturerSalesRep(order.getCustomer());
> cboSalesRep = new SalesRepComboBox(order.getCustomer(), defaultSalesRep);
> cbBinding = new MauiComboBoxBinding(formModel, "order.salesRepresentative", cboSalesRep);
> builder.add(cbBinding, MauiFormBuilder.COL_SPAN_ALL);
>
> //9
> builder.setColumn(6);
> cboSurgeon = new SurgeonComboBox();
> builder.add(new ComboBoxBinding(cboSurgeon, formModel, "order.surgeonName"), 3);
> txtPatient = (JTextField) builder.add("order.patientName", 5)[1];
> builder.add("order.surgeryDate", MauiFormBuilder.COL_SPAN_ALL);
>
> //11
> LineItemsBinding lib = new LineItemsBinding(formModel, "genericLineItems");
> builder.cell(lib.getControl(), MauiFormBuilder.COL_SPAN_ALL);
>
> //13
> builder.cell(lblSignature, builder.cellConstraints(2, CellConstraints.LEFT, CellConstraints.BOTTOM));
> builder.setColumn(12);
> builder.cell(lblNotes, builder.cellConstraints(1, CellConstraints.LEFT, CellConstraints.BOTTOM));
> builder.setColumn(24);
> builder.cell(cmdDelete);
> builder.row();
>
> //15
> SignatureBinding sb = new SignatureBinding(formModel, "capture");
> capture = (Capture)sb.getControl();
> builder.cell("capture", capture, 10, 3);
> builder.setColumn(12);
> JComponent notesCtrl = createNotesBinding(formModel, builder);
> builder.cell(notesCtrl, MauiFormBuilder.COL_SPAN_ALL);
>
> //17
> builder.setColumn(16);
> ToggleButtonBinding tb = new ToggleButtonBinding(new JCheckBox(), formModel, "sendEmailFax");
> builder.cell("sendEmailFax", tb.getControl(), builder.cellConstraints(6, CellConstraints.RIGHT));
> builder.setColumn(24);
> builder.cell(cmdSubmit);
> builder.row();
>
> //19
> cboTitle = createTitleCombo();
> builder.add(new ComboBoxBinding(cboTitle, formModel, "title"), 6);
> builder.cell(cmdClear);
> builder.setColumn(24);
> builder.cell(cmdSave);
> builder.row();
>
> //21
> cboName = createNameCombo();
> builder.add(new ComboBoxBinding(cboName, formModel, "printedName"), 6);
> builder.setColumn(24);
> builder.cell(cmdCancel);
>
> return builder.getForm();
> }
> [/code]
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: http://jira.springframework.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
|