001 /* 002 * Copyright 2002-2004 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 005 * use this file except in compliance with the License. You may obtain a copy of 006 * the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 012 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 013 * License for the specific language governing permissions and limitations under 014 * the License. 015 */ 016 package org.springframework.richclient.dialog; 017 018 import java.awt.Window; 019 import java.awt.event.FocusAdapter; 020 import java.awt.event.FocusEvent; 021 import java.beans.PropertyChangeListener; 022 023 import javax.swing.JComponent; 024 import javax.swing.JFormattedTextField; 025 import javax.swing.SwingUtilities; 026 import javax.swing.text.JTextComponent; 027 028 import org.springframework.binding.form.ValidatingFormModel; 029 import org.springframework.rules.closure.Closure; 030 import org.springframework.rules.constraint.Constraint; 031 import org.springframework.richclient.core.Message; 032 import org.springframework.richclient.form.FormGuard; 033 import org.springframework.richclient.form.FormModelHelper; 034 import org.springframework.richclient.form.SimpleValidationResultsReporter; 035 import org.springframework.richclient.form.binding.swing.SwingBindingFactory; 036 import org.springframework.richclient.layout.TableLayoutBuilder; 037 import org.springframework.util.Assert; 038 039 /** 040 * Simple input application dialog consisting of a label and a text field for 041 * accepting input. 042 * 043 * @author Keith Donald 044 */ 045 public class InputApplicationDialog extends ApplicationDialog implements Messagable { 046 047 private String inputLabelMessage = "dialog.input"; 048 049 private JComponent inputField; 050 051 private Constraint inputConstraint; 052 053 private Closure finishAction; 054 055 private MessagePane reporter; 056 057 private ValidatingFormModel formModel; 058 059 public InputApplicationDialog(Object bean, String propertyName) { 060 this(bean, propertyName, true); 061 } 062 063 public InputApplicationDialog(Object bean, String propertyName, boolean bufferChanges) { 064 this(FormModelHelper.createFormModel(bean, bufferChanges), propertyName); 065 } 066 067 public InputApplicationDialog(ValidatingFormModel formModel, String propertyName) { 068 this(); 069 this.formModel = formModel; 070 setInputField(new SwingBindingFactory(formModel).createBinding(propertyName).getControl()); 071 } 072 073 public InputApplicationDialog() { 074 this(null, null, CloseAction.DISPOSE); 075 } 076 077 public InputApplicationDialog(String title, Window parent) { 078 this(title, parent, CloseAction.DISPOSE); 079 } 080 081 public InputApplicationDialog(String title, Window parent, CloseAction closeAction) { 082 super(title, parent, closeAction); 083 setResizable(true); 084 } 085 086 public void setInputField(JComponent field) { 087 Assert.notNull(field); 088 this.inputField = field; 089 } 090 091 public void setInputLabelMessage(String inputLabel) { 092 Assert.hasText(inputLabel, "The input label is required"); 093 this.inputLabelMessage = inputLabel; 094 } 095 096 public void setInputConstraint(Constraint constraint) { 097 this.inputConstraint = constraint; 098 } 099 100 public void setFinishAction(Closure procedure) { 101 this.finishAction = procedure; 102 } 103 104 protected MessagePane createMessagePane() { 105 return new DefaultMessageAreaPane(); 106 } 107 108 private MessagePane getMessagePane() { 109 if (reporter == null) { 110 reporter = createMessagePane(); 111 112 if (this.formModel != null) { 113 new SimpleValidationResultsReporter(formModel.getValidationResults(), reporter); 114 FormGuard formGuard = new FormGuard(formModel); 115 formGuard.addGuarded(this, FormGuard.FORMERROR_GUARDED); 116 } 117 } 118 return reporter; 119 } 120 121 protected JComponent createDialogContentPane() { 122 TableLayoutBuilder layoutBuilder = new TableLayoutBuilder(); 123 124 if (this.inputField == null) { 125 this.inputField = getComponentFactory().createTextField(); 126 } 127 // work around for bug in JFormattedTextField text field for selectAll 128 if (inputField instanceof JFormattedTextField) { 129 SelectAllBugFixer selectAllBugFixer = new SelectAllBugFixer(); 130 inputField.addFocusListener(selectAllBugFixer); 131 } 132 133 layoutBuilder.cell(createInputLabel(), TableLayoutBuilder.DEFAULT_LABEL_ATTRIBUTES); 134 layoutBuilder.labelGapCol(); 135 layoutBuilder.cell(inputField); 136 137 layoutBuilder.unrelatedGapRow(); 138 layoutBuilder.cell(getMessagePane().getControl()); 139 140 layoutBuilder.relatedGapRow(); 141 layoutBuilder.separator(""); 142 return layoutBuilder.getPanel(); 143 } 144 145 protected JComponent createInputLabel() { 146 return getComponentFactory().createLabelFor(inputLabelMessage, getInputField()); 147 } 148 149 protected boolean onFinish() { 150 if (checkInputConstraint()) { 151 onFinish(getInputValue()); 152 return true; 153 } 154 return false; 155 } 156 157 private boolean checkInputConstraint() { 158 if (inputConstraint != null) 159 return inputConstraint.test(getInputValue()); 160 161 return true; 162 } 163 164 private Object getInputValue() { 165 if (inputField instanceof JFormattedTextField) { 166 return ((JFormattedTextField)inputField).getValue(); 167 } 168 else if (inputField instanceof JTextComponent) { 169 return ((JTextComponent)inputField).getText(); 170 } 171 else { 172 throw new IllegalStateException("Input field type not supported"); 173 } 174 } 175 176 protected void onFinish(Object inputValue) { 177 if (formModel != null) { 178 formModel.commit(); 179 } 180 if (finishAction != null) { 181 finishAction.call(inputValue); 182 } 183 } 184 185 public ValidatingFormModel getFormModel() { 186 return formModel; 187 } 188 189 /** 190 * @return Returns the inputField. 191 */ 192 public JComponent getInputField() { 193 return inputField; 194 } 195 196 private static class SelectAllBugFixer extends FocusAdapter { 197 public void focusGained(final FocusEvent evt) { 198 SwingUtilities.invokeLater(new Runnable() { 199 public void run() { 200 ((JFormattedTextField)evt.getComponent()).selectAll(); 201 } 202 }); 203 } 204 } 205 206 public void setMessage(Message message) { 207 getMessagePane().setMessage(message); 208 } 209 210 public void addPropertyChangeListener(PropertyChangeListener listener) { 211 getMessagePane().addPropertyChangeListener(listener); 212 } 213 214 public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { 215 getMessagePane().addPropertyChangeListener(propertyName, listener); 216 } 217 218 public void removePropertyChangeListener(PropertyChangeListener listener) { 219 getMessagePane().removePropertyChangeListener(listener); 220 } 221 222 public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { 223 getMessagePane().removePropertyChangeListener(propertyName, listener); 224 } 225 }