001 package org.springframework.richclient.form; 002 003 import org.springframework.richclient.application.config.ApplicationObjectConfigurer; 004 import org.springframework.richclient.components.Focussable; 005 import org.springframework.richclient.widget.AbstractWidgetForm; 006 import org.springframework.richclient.util.RcpSupport; 007 import org.springframework.binding.form.FormModel; 008 import org.springframework.binding.form.HierarchicalFormModel; 009 import org.springframework.binding.value.ValueModel; 010 011 import javax.swing.*; 012 import java.awt.*; 013 014 /** 015 * Form implementation for the Focussable interface. 016 * 017 * @author Jan Hoskens 018 * 019 */ 020 public abstract class AbstractFocussableForm extends AbstractWidgetForm implements Focussable//, SecurityControllable 021 { 022 023 public static final String UNSAVEDCHANGES_WARNING_ID = "unsavedchanges.warning"; 024 025 public static final String UNSAVEDCHANGES_HASERRORS_WARNING_ID = "unsavedchanges.haserrors.warning"; 026 027 private JComponent focusControl; 028 029 private final Runnable focusRequestRunnable = new Runnable() 030 { 031 032 public void run() 033 { 034 if (focusControl != null) 035 focusControl.requestFocusInWindow(); 036 } 037 }; 038 039 /** 040 * Override to do nothing. Superclass registers a default command, but we are using a different system to 041 * define default commands. 042 */ 043 @Override 044 protected void handleEnabledChange(boolean enabled) 045 { 046 } 047 048 /** 049 * Registers the component that receives the focus when the form receives focus. 050 * 051 * @see #grabFocus 052 */ 053 public void setFocusControl(JComponent field) 054 { 055 this.focusControl = field; 056 } 057 058 public void grabFocus() 059 { 060 if (this.focusControl != null) 061 EventQueue.invokeLater(focusRequestRunnable); 062 } 063 064 /** 065 * @inheritDoc 066 */ 067 public AbstractFocussableForm() 068 { 069 super(); 070 } 071 072 /** 073 * @inheritDoc 074 */ 075 public AbstractFocussableForm(FormModel formModel, String formId) 076 { 077 super(formModel, formId); 078 } 079 080 /** 081 * @inheritDoc 082 */ 083 public AbstractFocussableForm(FormModel pageFormModel) 084 { 085 super(pageFormModel); 086 } 087 088 /** 089 * @inheritDoc 090 */ 091 public AbstractFocussableForm(HierarchicalFormModel parentFormModel, String formId, 092 String childFormObjectPropertyPath) 093 { 094 super(parentFormModel, formId, childFormObjectPropertyPath); 095 } 096 097 /** 098 * @inheritDoc 099 */ 100 public AbstractFocussableForm(HierarchicalFormModel parentFormModel, String formId, 101 ValueModel childFormObjectHolder) 102 { 103 super(parentFormModel, formId, childFormObjectHolder); 104 } 105 106 /** 107 * @inheritDoc 108 */ 109 public AbstractFocussableForm(HierarchicalFormModel parentFormModel, String formId) 110 { 111 super(parentFormModel, formId); 112 } 113 114 /** 115 * @inheritDoc 116 */ 117 public AbstractFocussableForm(Object formObject) 118 { 119 super(formObject); 120 } 121 122 /** 123 * @inheritDoc 124 */ 125 public AbstractFocussableForm(String formId) 126 { 127 super(formId); 128 } 129 130 public boolean canClose() 131 { 132 boolean userBreak = false; 133 int answer = JOptionPane.NO_OPTION; // by default no save is required. 134 135 // unless of course there are unsaved changes and we can commit (isAuthorized) 136 if (this.getFormModel().isEnabled() && this.getFormModel().isDirty() 137 && this.getCommitCommand().isAuthorized()) 138 { // then we ask the user to save the mess first: yes/no/cancel 139 answer = RcpSupport.showWarningDialog(this.getControl(), UNSAVEDCHANGES_WARNING_ID, 140 JOptionPane.YES_NO_CANCEL_OPTION); 141 142 switch (answer) 143 { 144 case JOptionPane.CANCEL_OPTION : 145 // backup the selection change so table and detail keep in sync 146 // gives problems (asks unsavedchanges twice) 147 userBreak = true; 148 break; 149 case JOptionPane.YES_OPTION : 150 if (this.getFormModel().getHasErrors() == true) 151 { 152 RcpSupport.showWarningDialog(this.getControl(), UNSAVEDCHANGES_HASERRORS_WARNING_ID); 153 userBreak = true; 154 break; 155 } 156 this.getCommitCommand().execute(); 157 break; 158 case JOptionPane.NO_OPTION : 159 { 160 this.revert(); // revert so no strange things happen (hopefully) 161 break; 162 } 163 } 164 } 165 166 return !userBreak; 167 } 168 169 @Override 170 protected void init() 171 { 172 // eerst wordt parent object constructor opgeroepen waarin deze init 173 // wordt opgeroepen. Gewone fields zijn dan nog niet gezet dus doe dat 174 // hier expliciet ipv in velddeclaratie. 175 // authorized = true; 176 // enabled = true; 177 // setSecurityControllerId(getId() + ".authorize"); 178 ((ApplicationObjectConfigurer) getApplicationServices().getService(ApplicationObjectConfigurer.class)) 179 .configure(this, getId()); 180 } 181 } 182