001: /*
002: * Copyright (c) 2003-2007 JGoodies Karsten Lentzsch. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of JGoodies Karsten Lentzsch nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package com.jgoodies.validation.tutorial.basics;
032:
033: import java.beans.PropertyChangeEvent;
034: import java.beans.PropertyChangeListener;
035:
036: import javax.swing.*;
037:
038: import com.jgoodies.forms.builder.PanelBuilder;
039: import com.jgoodies.forms.layout.CellConstraints;
040: import com.jgoodies.forms.layout.FormLayout;
041: import com.jgoodies.validation.ValidationResult;
042: import com.jgoodies.validation.ValidationResultModel;
043: import com.jgoodies.validation.tutorial.shared.Order;
044: import com.jgoodies.validation.tutorial.shared.OrderModel;
045: import com.jgoodies.validation.tutorial.util.ExampleComponentFactory;
046: import com.jgoodies.validation.tutorial.util.IconFeedbackPanel;
047: import com.jgoodies.validation.tutorial.util.TutorialUtils;
048: import com.jgoodies.validation.view.ValidationComponentUtils;
049:
050: /**
051: * Demonstrates different styles how to indicate that a component
052: * contains invalid data:
053: * background changes if empty,
054: * background reflects the severity,
055: * overlaid icons reflect the severity.
056: *
057: * @author Karsten Lentzsch
058: * @version $Revision: 1.15 $
059: */
060: public final class ComponentFeedbackExample {
061:
062: private final OrderModel orderModel;
063:
064: private JTextField mandatoryOrderNoField;
065: private JTextField mandatoryOrderDateField;
066: private JTextField mandatoryDeliveryDateField;
067: private JTextArea mandatoryDeliveryNotesArea;
068: private JComponent mandatoryPanel;
069:
070: private JTextField severityOrderNoField;
071: private JTextField severityOrderDateField;
072: private JTextField severityDeliveryDateField;
073: private JTextArea severityDeliveryNotesArea;
074: private JComponent severityPanel;
075:
076: private JTextField iconOrderNoField;
077: private JTextField iconOrderDateField;
078: private JTextField iconDeliveryDateField;
079: private JTextArea iconDeliveryNotesArea;
080: private JComponent iconOverlayPanel;
081:
082: public static void main(String[] args) {
083: try {
084: UIManager
085: .setLookAndFeel("com.jgoodies.looks.plastic.PlasticXPLookAndFeel");
086: } catch (Exception e) {
087: // Likely Plastic is not in the classpath; ignore it.
088: }
089: JFrame frame = new JFrame();
090: frame.setTitle("Basics :: Component Feedback");
091: frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
092: JComponent panel = new ComponentFeedbackExample().buildPanel();
093: frame.getContentPane().add(panel);
094: frame.pack();
095: TutorialUtils.locateOnOpticalScreenCenter(frame);
096: frame.setVisible(true);
097: }
098:
099: // Instance Creation ******************************************************
100:
101: public ComponentFeedbackExample() {
102: orderModel = new OrderModel(new Order());
103: }
104:
105: // Component Creation and Initialization **********************************
106:
107: private void initComponents() {
108: mandatoryOrderNoField = ExampleComponentFactory
109: .createTextField(orderModel
110: .getModel(Order.PROPERTYNAME_ORDER_NO), false);
111: mandatoryOrderDateField = ExampleComponentFactory
112: .createDateField(orderModel
113: .getModel(Order.PROPERTYNAME_ORDER_DATE), true);
114: mandatoryDeliveryDateField = ExampleComponentFactory
115: .createDateField(orderModel
116: .getModel(Order.PROPERTYNAME_DELIVERY_DATE),
117: true);
118: mandatoryDeliveryNotesArea = ExampleComponentFactory
119: .createTextArea(orderModel
120: .getModel(Order.PROPERTYNAME_DELIVERY_NOTES),
121: false);
122:
123: severityOrderNoField = ExampleComponentFactory
124: .createTextField(orderModel
125: .getModel(Order.PROPERTYNAME_ORDER_NO), false);
126: severityOrderDateField = ExampleComponentFactory
127: .createDateField(orderModel
128: .getModel(Order.PROPERTYNAME_ORDER_DATE));
129: severityDeliveryDateField = ExampleComponentFactory
130: .createDateField(orderModel
131: .getModel(Order.PROPERTYNAME_DELIVERY_DATE),
132: true);
133: severityDeliveryNotesArea = ExampleComponentFactory
134: .createTextArea(orderModel
135: .getModel(Order.PROPERTYNAME_DELIVERY_NOTES),
136: false);
137:
138: iconOrderNoField = ExampleComponentFactory
139: .createTextField(orderModel
140: .getModel(Order.PROPERTYNAME_ORDER_NO), false);
141: iconOrderDateField = ExampleComponentFactory
142: .createDateField(orderModel
143: .getModel(Order.PROPERTYNAME_ORDER_DATE));
144: iconDeliveryDateField = ExampleComponentFactory
145: .createDateField(orderModel
146: .getModel(Order.PROPERTYNAME_DELIVERY_DATE),
147: true);
148: iconDeliveryNotesArea = ExampleComponentFactory.createTextArea(
149: orderModel.getModel(Order.PROPERTYNAME_DELIVERY_NOTES),
150: false);
151: }
152:
153: private void initComponentAnnotations() {
154: ValidationComponentUtils.setMandatory(mandatoryOrderNoField,
155: true);
156: ValidationComponentUtils.setMessageKey(mandatoryOrderNoField,
157: "Order.Order No");
158: ValidationComponentUtils.setMandatory(mandatoryOrderDateField,
159: true);
160: ValidationComponentUtils.setMessageKey(mandatoryOrderDateField,
161: "Order.Order Date");
162: ValidationComponentUtils.setMessageKey(
163: mandatoryDeliveryDateField, "Order.Delivery Date");
164: ValidationComponentUtils.setMessageKey(
165: mandatoryDeliveryNotesArea, "Order.Notes");
166:
167: ValidationComponentUtils.setMandatory(severityOrderNoField,
168: true);
169: ValidationComponentUtils.setMessageKey(severityOrderNoField,
170: "Order.Order No");
171: ValidationComponentUtils.setMandatory(severityOrderDateField,
172: true);
173: ValidationComponentUtils.setMessageKey(severityOrderDateField,
174: "Order.Order Date");
175: ValidationComponentUtils.setMessageKey(
176: severityDeliveryDateField, "Order.Delivery Date");
177: ValidationComponentUtils.setMessageKey(
178: severityDeliveryNotesArea, "Order.Notes");
179:
180: ValidationComponentUtils.setMandatory(iconOrderNoField, true);
181: ValidationComponentUtils.setMessageKey(iconOrderNoField,
182: "Order.Order No");
183: ValidationComponentUtils.setMandatory(iconOrderDateField, true);
184: ValidationComponentUtils.setMessageKey(iconOrderDateField,
185: "Order.Order Date");
186: ValidationComponentUtils.setMessageKey(iconDeliveryDateField,
187: "Order.Delivery Date");
188: ValidationComponentUtils.setMessageKey(iconDeliveryNotesArea,
189: "Order.Notes");
190: }
191:
192: private void initEventHandling() {
193: orderModel.getValidationResultModel()
194: .addPropertyChangeListener(
195: ValidationResultModel.PROPERTYNAME_RESULT,
196: new ValidationChangeHandler());
197: }
198:
199: // Building ***************************************************************
200:
201: /**
202: * Builds and returns the whole editor with 3 sections
203: * for the different validation times.
204: */
205: public JComponent buildPanel() {
206: initComponents();
207: initComponentAnnotations();
208: initEventHandling();
209:
210: mandatoryPanel = buildMandatoryPanel();
211: severityPanel = buildSeverityPanel();
212: iconOverlayPanel = buildIconOverlayPanel();
213:
214: FormLayout layout = new FormLayout("fill:pref:grow",
215: "p, 3dlu, p, 17dlu, p, 3dlu, p, 17dlu, p, 3dlu, p");
216:
217: PanelBuilder builder = new PanelBuilder(layout);
218: builder.setDefaultDialogBorder();
219: CellConstraints cc = new CellConstraints();
220:
221: builder.addSeparator(
222: "Background Indicates Blank Mandatory Fields", cc.xy(1,
223: 1));
224: builder.add(mandatoryPanel, cc.xy(1, 3));
225: builder.addSeparator("Background Indicates Invalid Input", cc
226: .xy(1, 5));
227: builder.add(severityPanel, cc.xy(1, 7));
228: builder.addSeparator("Icons Indicate Invalid Input", cc
229: .xy(1, 9));
230: builder.add(iconOverlayPanel, cc.xy(1, 11));
231:
232: // Synchronize the presentation with the current validation state.
233: // If you want to show no validation info before the user has typed
234: // anything in the form, use the commented EMPTY result
235: // instead of the model's validation result.
236: updateComponentTreeMandatoryAndSeverity(orderModel
237: .getValidationResultModel().getResult()
238: // ValidationResult.EMPTY
239: );
240:
241: return builder.getPanel();
242: }
243:
244: private JComponent buildMandatoryPanel() {
245: FormLayout layout = new FormLayout(
246: "right:max(65dlu;pref), 4dlu, 44dlu, 2dlu, 44dlu, 90dlu:grow",
247: "p, 3dlu, p, 3dlu, p, 3dlu, p");
248:
249: layout.setRowGroups(new int[][] { { 1, 3, 5, 7 } });
250: PanelBuilder builder = new PanelBuilder(layout);
251: CellConstraints cc = new CellConstraints();
252:
253: builder.addLabel("Order No", cc.xy(1, 1));
254: builder.add(mandatoryOrderNoField, cc.xyw(3, 1, 3));
255: builder.addLabel("Order-/Delivery Date", cc.xy(1, 3));
256: builder.add(mandatoryOrderDateField, cc.xy(3, 3));
257: builder.add(mandatoryDeliveryDateField, cc.xy(5, 3));
258: builder.add(new JScrollPane(mandatoryDeliveryNotesArea), cc
259: .xywh(3, 5, 4, 3));
260:
261: return builder.getPanel();
262: }
263:
264: private JComponent buildSeverityPanel() {
265: FormLayout layout = new FormLayout(
266: "right:max(65dlu;pref), 4dlu, 44dlu, 2dlu, 44dlu, 90dlu:grow",
267: "p, 3dlu, p, 3dlu, p, 3dlu, p");
268:
269: layout.setRowGroups(new int[][] { { 1, 3, 5, 7 } });
270: PanelBuilder builder = new PanelBuilder(layout);
271: CellConstraints cc = new CellConstraints();
272:
273: builder.addLabel("Order No", cc.xy(1, 1));
274: builder.add(severityOrderNoField, cc.xyw(3, 1, 3));
275: builder.addLabel("Order-/Delivery Date", cc.xy(1, 3));
276: builder.add(severityOrderDateField, cc.xy(3, 3));
277: builder.add(severityDeliveryDateField, cc.xy(5, 3));
278: builder.add(new JScrollPane(severityDeliveryNotesArea), cc
279: .xywh(3, 5, 4, 3));
280:
281: return builder.getPanel();
282: }
283:
284: private JComponent buildIconOverlayPanel() {
285: FormLayout layout = new FormLayout(
286: "right:max(65dlu;pref), 4dlu, 44dlu, 2dlu, 44dlu, 90dlu:grow",
287: "p, 3dlu, p, 3dlu, p, 3dlu, p, 4px"); // extra bottom space for icons
288:
289: layout.setRowGroups(new int[][] { { 1, 3, 5, 7 } });
290: PanelBuilder builder = new PanelBuilder(layout);
291: CellConstraints cc = new CellConstraints();
292:
293: builder.addLabel("Order No", cc.xy(1, 1));
294: builder.add(iconOrderNoField, cc.xyw(3, 1, 3));
295: builder.addLabel("Order-/Delivery Date", cc.xy(1, 3));
296: builder.add(iconOrderDateField, cc.xy(3, 3));
297: builder.add(iconDeliveryDateField, cc.xy(5, 3));
298: builder.addLabel("Notes", cc.xy(1, 5));
299: builder.add(new JScrollPane(iconDeliveryNotesArea), cc.xywh(3,
300: 5, 4, 3));
301:
302: return new IconFeedbackPanel(orderModel
303: .getValidationResultModel(), builder.getPanel());
304: }
305:
306: // Event Handling *********************************************************
307:
308: private void updateComponentTreeMandatoryAndSeverity(
309: ValidationResult result) {
310: ValidationComponentUtils
311: .updateComponentTreeMandatoryAndBlankBackground(mandatoryPanel);
312: ValidationComponentUtils.updateComponentTreeSeverityBackground(
313: severityPanel, result);
314: }
315:
316: /**
317: * Updates the component background in the mandatory panel and the
318: * validation background in the severity panel. Invoked whenever
319: * the observed validation result changes.
320: */
321: private final class ValidationChangeHandler implements
322: PropertyChangeListener {
323:
324: public void propertyChange(PropertyChangeEvent evt) {
325: updateComponentTreeMandatoryAndSeverity((ValidationResult) evt
326: .getNewValue());
327: }
328: }
329:
330: }
|