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.util;
032:
033: import java.awt.Component;
034: import java.awt.Dimension;
035: import java.awt.event.ActionEvent;
036: import java.beans.PropertyChangeEvent;
037: import java.beans.PropertyChangeListener;
038: import java.lang.ref.WeakReference;
039: import java.util.LinkedList;
040: import java.util.List;
041:
042: import javax.swing.AbstractAction;
043: import javax.swing.Action;
044: import javax.swing.JOptionPane;
045: import javax.swing.SwingUtilities;
046:
047: import com.jgoodies.validation.ValidationResult;
048:
049: /**
050: * Consists only of static convenience methods used throughout
051: * the examples of the JGoodies Validation tutorial.
052: *
053: * @author Karsten Lentzsch
054: * @version $Revision: 1.10 $
055: */
056: public final class TutorialUtils {
057:
058: private static ValidationResult errorsResult;
059: private static ValidationResult warningsResult;
060: private static ValidationResult mixedResult;
061:
062: private TutorialUtils() {
063: // Suppresses default constructor, ensuring non-instantiability.
064: }
065:
066: // Misc *******************************************************************
067:
068: /**
069: * Returns a listener that writes bean property changes to the console.
070: * The log entry includes the PropertyChangeEvent's source, property name,
071: * old value, and new value.
072: *
073: * @return a debug listener that logs bean changes to the console
074: */
075: public static PropertyChangeListener createDebugPropertyChangeListener() {
076: PropertyChangeListener listener = new DebugPropertyChangeListener();
077: debugListeners.add(listener);
078: return listener;
079: }
080:
081: /**
082: * Creates and returns an Action that exists the system if performed.
083: *
084: * @return an Action that exists the system if performed
085: *
086: * @see System#exit(int)
087: */
088: public static Action getCloseAction() {
089: return new CloseAction();
090: }
091:
092: // Example Validation Results *********************************************
093:
094: /**
095: * Lazily creates and returns an example ValidationResult
096: * that contains only errors.
097: *
098: * @return a ValidationResult that contains only errors
099: */
100: public static ValidationResult getErrorsResult() {
101: if (errorsResult == null) {
102: errorsResult = new ValidationResult();
103: errorsResult.addError("The order no is mandatory.");
104: errorsResult.addError("The order date is mandatory.");
105: }
106: return errorsResult;
107: }
108:
109: /**
110: * Lazily creates and returns an example ValidationResult
111: * that contains errors and warnings.
112: *
113: * @return a ValidationResult that contains errors and warnings
114: */
115: public static ValidationResult getMixedResult() {
116: if (mixedResult == null) {
117: mixedResult = new ValidationResult();
118: mixedResult
119: .addWarning("The order no length shall be in [5, 10].");
120: mixedResult.addError("The order date is mandatory.");
121: }
122: return mixedResult;
123: }
124:
125: /**
126: * Lazily creates and returns an example ValidationResult
127: * that contains only warnings.
128: *
129: * @return a ValidationResult that contains only warnings
130: */
131: public static ValidationResult getWarningsResult() {
132: if (warningsResult == null) {
133: warningsResult = new ValidationResult();
134: warningsResult
135: .addWarning("The order no length shall be in [5, 10].");
136: warningsResult
137: .addWarning("The order date shall be in the future.");
138: }
139: return warningsResult;
140: }
141:
142: // Screen Position ********************************************************
143:
144: /**
145: * Locates the given component on the screen's center.
146: *
147: * @param component the component to be centered
148: */
149: public static void locateOnOpticalScreenCenter(Component component) {
150: Dimension paneSize = component.getSize();
151: Dimension screenSize = component.getToolkit().getScreenSize();
152: component.setLocation((screenSize.width - paneSize.width) / 2,
153: (int) ((screenSize.height - paneSize.height) * 0.45));
154: }
155:
156: /**
157: * Opens a message dialog that shows the validation result,
158: * things the user must fix, before the selection can change.
159: *
160: * @param headerText the text displayed above the validation message
161: * @param validationResult the validation result to be displayed
162: *
163: * @throws IllegalArgumentException if the validation result is empty
164: */
165: public static void showValidationMessage(ActionEvent e,
166: String headerText, ValidationResult validationResult) {
167: if (validationResult.isEmpty()) {
168: throw new IllegalArgumentException(
169: "The validation result must not be empty.");
170: }
171: Object eventSource = e.getSource();
172: Component parent = null;
173: if (eventSource instanceof Component) {
174: parent = SwingUtilities
175: .windowForComponent((Component) eventSource);
176: }
177: boolean error = validationResult.hasErrors();
178: String messageText = headerText + "\n\n"
179: + validationResult.getMessagesText() + "\n\n";
180: String titleText = "Validation "
181: + (error ? "Error" : "Warning");
182: int messageType = error ? JOptionPane.ERROR_MESSAGE
183: : JOptionPane.WARNING_MESSAGE;
184: JOptionPane.showMessageDialog(parent, messageText, titleText,
185: messageType);
186: }
187:
188: // Debug Listener *********************************************************
189:
190: /**
191: * Used to hold debug listeners, so they won't be removed by
192: * the garbage collector, even if registered by a listener list
193: * that is based on weak references.
194: *
195: * @see #createDebugPropertyChangeListener()
196: * @see WeakReference
197: */
198: private static List<PropertyChangeListener> debugListeners = new LinkedList<PropertyChangeListener>();
199:
200: /**
201: * Writes the source, property name, old/new value to the system console.
202: */
203: private static class DebugPropertyChangeListener implements
204: PropertyChangeListener {
205:
206: public void propertyChange(PropertyChangeEvent evt) {
207: System.out.println();
208: System.out.println("The source: " + evt.getSource());
209: System.out.println("changed '" + evt.getPropertyName()
210: + "' from '" + evt.getOldValue() + "' to '"
211: + evt.getNewValue() + "'.");
212: }
213: }
214:
215: // Actions ****************************************************************
216:
217: /**
218: * An Action that exists the System.
219: */
220: private static final class CloseAction extends AbstractAction {
221:
222: private CloseAction() {
223: super ("Close");
224: }
225:
226: public void actionPerformed(ActionEvent e) {
227: System.exit(0);
228: }
229: }
230:
231: }
|