001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.sql.framework.ui.view.graph;
042:
043: import java.awt.BorderLayout;
044: import java.awt.Container;
045: import java.awt.FlowLayout;
046: import java.awt.Frame;
047: import java.awt.GridBagConstraints;
048: import java.awt.GridBagLayout;
049: import java.awt.Insets;
050: import java.awt.event.ActionEvent;
051: import java.awt.event.ActionListener;
052: import java.awt.event.ItemEvent;
053: import java.awt.event.ItemListener;
054: import java.awt.event.KeyAdapter;
055: import java.awt.event.KeyEvent;
056: import java.awt.event.WindowAdapter;
057: import java.awt.event.WindowEvent;
058: import java.sql.Types;
059: import java.util.List;
060:
061: import javax.swing.JButton;
062: import javax.swing.JComboBox;
063: import javax.swing.JDialog;
064: import javax.swing.JFrame;
065: import javax.swing.JLabel;
066: import javax.swing.JPanel;
067: import javax.swing.JSpinner;
068: import javax.swing.SpinnerNumberModel;
069: import javax.swing.SwingUtilities;
070: import javax.swing.WindowConstants;
071: import javax.swing.border.EmptyBorder;
072: import javax.swing.event.ChangeEvent;
073: import javax.swing.event.ChangeListener;
074:
075: import net.java.hulp.i18n.Logger;
076: import org.netbeans.modules.etl.logger.Localizer;
077: import org.netbeans.modules.etl.logger.LogUtil;
078: import org.netbeans.modules.sql.framework.common.jdbc.SQLUtils;
079:
080: /**
081: * Configures type, precision and scale (as appropriate) of a cast as operator.
082: *
083: * @author Jonathan Giron
084: * @version $Revision$
085: */
086: public class CastAsDialog extends JDialog implements ActionListener {
087:
088: /* Array of Strings representing available SQL datatypes */
089: public static final String[] DISPLAY_NAMES;
090:
091: /* Action command string representing OK user option */
092: private static final String CMD_OK = "ok"; //NOI18N
093:
094: /* Action command string representing Cancel user option */
095: private static final String CMD_CANCEL = "cancel"; //NOI18N
096: private static final SpinnerNumberModel PRECISION_MODEL = new SpinnerNumberModel(
097: 1, 1, 38, 1);
098: private static final SpinnerNumberModel SCALE_MODEL = new SpinnerNumberModel(
099: 0, 0, Integer.MAX_VALUE, 1);
100: private static final Integer MAX_NUMBER_PRECISION = new Integer(100);
101: private static final Integer MAX_CHAR_PRECISION = new Integer(
102: Integer.MAX_VALUE);
103: private static final Integer ZERO = new Integer(0);
104: private static final Integer ONE = new Integer(1);
105: private static transient final Logger mLogger = LogUtil
106: .getLogger(CastAsDialog.class.getName());
107: private static transient final Localizer mLoc = Localizer.get();
108:
109: static {
110: List types = SQLUtils.getSupportedCastTypes();
111:
112: // Now populated DISPLAY_NAMES with contents of the restricted list.
113: DISPLAY_NAMES = (String[]) types.toArray(new String[types
114: .size()]);
115: }
116:
117: /* Holds available SQL types */
118: private JComboBox mTypesBox = new JComboBox(DISPLAY_NAMES);
119:
120: /* Holds precision/length value */
121: private JSpinner mPrecLength = new JSpinner();
122: /* Holds scale value */
123: private JSpinner mScale = new JSpinner();
124: /* OK dialog button */
125: private JButton mOkButton;
126:
127: /* Cancel dialog button */
128: private JButton mCancelButton;
129:
130: /* Indicates whether user canceled dialog box */
131: private boolean mIsCanceled = true;
132:
133: /**
134: * Creates a new LiteralDialog object.
135: *
136: * @param title
137: * @param modal
138: */
139: public CastAsDialog(Frame parent, String title, boolean modal) {
140: super (parent, title, modal);
141:
142: try {
143: String nbBundle1 = mLoc.t("PRSR001: Ok");
144: mOkButton = new JButton(Localizer.parse(nbBundle1)); //NOI18N
145: mOkButton.getAccessibleContext().setAccessibleName(
146: Localizer.parse(nbBundle1));
147: String nbBundle2 = mLoc.t("PRSR001: Cancel");
148: mCancelButton = new JButton(Localizer.parse(nbBundle2)); //NOI18N
149: mCancelButton.getAccessibleContext().setAccessibleName(
150: Localizer.parse(nbBundle2));
151:
152: initComponents();
153: } catch (Exception e) {
154: e.printStackTrace();
155: }
156: }
157:
158: @SuppressWarnings("deprecation")
159: @Override
160: public void show() {
161: pack();
162: // this.setResizable(false);
163: this .setResizable(true);
164: this .setLocationRelativeTo(null);
165: mOkButton.requestFocus();
166: super .show();
167: }
168:
169: /**
170: * Exposes standalone test entry-point.
171: *
172: * @param args command-line arguments
173: */
174: public static void main(String args[]) {
175: JFrame win = new JFrame("main"); //NOI18N
176: win.setSize(100, 100);
177: win.setVisible(true);
178: win
179: .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
180:
181: CastAsDialog dia = new CastAsDialog(win, "Testing", true); //NOI18N
182: dia.setVisible(true);
183: dia
184: .setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
185: }
186:
187: public void setJdbcTypeEditable(boolean editable) {
188: mTypesBox.setEnabled(editable);
189: }
190:
191: /**
192: * Gets user-selected JDBC datatype for this cast-as operator.
193: *
194: * @return JDBC datatype, as enumerated in java.sql.Types
195: */
196: public int getJdbcType() {
197: return SQLUtils.getStdJdbcType((String) mTypesBox
198: .getSelectedItem());
199: }
200:
201: /**
202: * Sets user-selected JDBC datatype for this cast-as operator.
203: *
204: * @param newType new JDBC datatype, as enumerated in java.sql.Types
205: */
206: public void setJdbcType(int newType) {
207: mTypesBox.setSelectedItem(SQLUtils.getStdSqlType(newType));
208: updatePrecisionModel();
209: updateScaleModel();
210: }
211:
212: /**
213: * Gets current precision value in dialog.
214: *
215: * @return current precision - possibly 0 if selected datatype does not allow for a
216: * precision to be specified
217: */
218: public int getPrecision() {
219: Integer value = (Integer) PRECISION_MODEL.getValue();
220: return (mPrecLength.isEnabled() && value != null) ? value
221: .intValue() : 0;
222: }
223:
224: /**
225: * Sets current precision value in dialog, subject to model limits.
226: *
227: * @param newValue new value for precision
228: */
229: public void setPrecision(int newValue) {
230: Integer newValueObj = new Integer(newValue);
231: Integer maxValueObj = (Integer) PRECISION_MODEL.getMaximum();
232:
233: newValueObj = setBoundedValue(newValueObj, ONE, maxValueObj);
234: PRECISION_MODEL.setValue(newValueObj);
235: }
236:
237: /**
238: * Gets current scale value in dialog.
239: *
240: * @return current scale - possibly 0 if selected datatype does not allow for a
241: * precision to be specified
242: */
243: public int getScale() {
244: Integer value = (Integer) SCALE_MODEL.getValue();
245: return (mScale.isEnabled() && value != null) ? value.intValue()
246: : 0;
247: }
248:
249: /**
250: * Sets current scale value in dialog, subject to model limits.
251: *
252: * @param newValue new value for scale
253: */
254: public void setScale(int newValue) {
255: Integer newValueObj = new Integer(newValue);
256: Integer maxValueObj = (Integer) SCALE_MODEL.getMaximum();
257:
258: newValueObj = setBoundedValue(newValueObj, ZERO, maxValueObj);
259: SCALE_MODEL.setValue(newValueObj);
260: }
261:
262: private Integer setBoundedValue(Integer value, Integer min,
263: Integer max) {
264: if (value.compareTo(max) > 0) {
265: value = max;
266: } else if (value.compareTo(min) < 0) {
267: value = min;
268: }
269:
270: return value;
271: }
272:
273: /**
274: * Indicates whether user canceled this dialog box.
275: *
276: * @return true if user canceled dialog box, false otherwise.
277: */
278: public boolean isCanceled() {
279: return mIsCanceled;
280: }
281:
282: /**
283: * @param e ActionEvent to handle.
284: */
285: public void actionPerformed(ActionEvent e) {
286: if (CMD_CANCEL.equals(e.getActionCommand())) { //NOI18N
287: mIsCanceled = true;
288: this .setVisible(false);
289: } else if (CMD_OK.equals(e.getActionCommand())) { //NOI18N
290: if (checkForm()) {
291: mIsCanceled = false;
292: this .setVisible(false);
293: } else {
294: SwingUtilities.invokeLater(new Runnable() {
295:
296: public void run() {
297: mTypesBox.requestFocusInWindow();
298: }
299: });
300: }
301: }
302: }
303:
304: private void buttonActionPerformed(Object source) {
305: if (source.equals(mCancelButton)) {
306: mIsCanceled = true;
307: this .setVisible(false);
308: } else if (source.equals(mOkButton)) {
309: if (checkForm()) {
310: mIsCanceled = false;
311: this .setVisible(false);
312: }
313: }
314: }
315:
316: /*
317: * Creates button pane for this dialog. @return Container containing control buttons.
318: */
319: private Container getButtonPane() {
320: JPanel buttonPanel = new JPanel();
321: buttonPanel.setLayout(new FlowLayout(FlowLayout.TRAILING, 10,
322: 10));
323: mOkButton.requestFocus();
324: buttonPanel.add(mOkButton);
325: buttonPanel.add(mCancelButton);
326:
327: return buttonPanel;
328: }
329:
330: private boolean checkForm() {
331: // return CastAsDialog.isValidLiteral(mInput.getText(), SQLUtils.getStdJdbcType((String) mTypesBox.getSelectedItem()));
332: return true;
333: }
334:
335: private void initEventHandle() {
336: mOkButton.setActionCommand(CMD_OK); // NOI18N
337: mCancelButton.setActionCommand(CMD_CANCEL); // NOI18N
338:
339: mOkButton.addActionListener(this );
340: mCancelButton.addActionListener(this );
341:
342: ButtonKeyAdapter bKeyAdapter = new ButtonKeyAdapter();
343: mOkButton.addKeyListener(bKeyAdapter);
344: mCancelButton.addKeyListener(bKeyAdapter);
345:
346: this .addWindowListener(new WindowAdapter() {
347:
348: public void windowClosing(WindowEvent e) {
349: mIsCanceled = true;
350: }
351: });
352: }
353:
354: private void initComponents() throws Exception {
355: Container contentPane = this .getContentPane();
356: contentPane.setLayout(new BorderLayout(0, 0));
357:
358: JPanel formPanel = new JPanel();
359: formPanel.setBorder(new EmptyBorder(25, 25, 0, 25));
360:
361: GridBagLayout gridBag = new GridBagLayout();
362: GridBagConstraints constraints = new GridBagConstraints();
363: formPanel.setLayout(gridBag);
364:
365: Insets leftInsets = new Insets(0, 0, 5, 5);
366: Insets rightInsets = new Insets(0, 5, 5, 0);
367:
368: constraints.fill = GridBagConstraints.HORIZONTAL;
369: constraints.anchor = GridBagConstraints.WEST;
370: constraints.gridx = 0;
371: constraints.gridy = 0;
372: constraints.weightx = 1.0;
373: constraints.weighty = 0.0;
374: constraints.gridheight = 1;
375: constraints.gridwidth = 1;
376: constraints.insets = leftInsets;
377:
378: String nbBundle3 = mLoc.t("PRSR001: Type:");
379: JLabel typeLabel = new JLabel(Localizer.parse(nbBundle3)); //NOI18N
380: typeLabel.getAccessibleContext().setAccessibleName(
381: Localizer.parse(nbBundle3));
382: gridBag.setConstraints(typeLabel, constraints);
383: formPanel.add(typeLabel);
384:
385: constraints.gridx = 1;
386: constraints.insets = rightInsets;
387: constraints.weightx = 0.0;
388: gridBag.setConstraints(mTypesBox, constraints);
389: formPanel.add(mTypesBox);
390:
391: constraints.gridx = 0;
392: constraints.gridy = 1;
393: constraints.insets = leftInsets;
394: constraints.weightx = 1.0;
395: String nbBundle4 = mLoc.t("PRSR001: Precision/length:");
396: JLabel precLengthLabel = new JLabel(Localizer.parse(nbBundle4)); //NOI18N
397: precLengthLabel.getAccessibleContext().setAccessibleName(
398: Localizer.parse(nbBundle4));
399: gridBag.setConstraints(precLengthLabel, constraints);
400: formPanel.add(precLengthLabel);
401:
402: mPrecLength.setModel(PRECISION_MODEL);
403: mPrecLength.setEnabled(true);
404: mPrecLength.addChangeListener(new PrecisionChangeListener());
405: constraints.gridx = 1;
406: constraints.insets = rightInsets;
407: constraints.weightx = 0.0;
408: gridBag.setConstraints(mPrecLength, constraints);
409: formPanel.add(mPrecLength);
410:
411: constraints.gridx = 0;
412: constraints.gridy = 2;
413: constraints.insets = leftInsets;
414: constraints.weightx = 1.0;
415: String nbBundle5 = mLoc.t("PRSR001: Scale:");
416: JLabel scaleLabel = new JLabel(Localizer.parse(nbBundle5)); //NOI18N
417: scaleLabel.getAccessibleContext().setAccessibleName(
418: Localizer.parse(nbBundle5));
419: gridBag.setConstraints(scaleLabel, constraints);
420: formPanel.add(scaleLabel);
421:
422: mScale.setModel(SCALE_MODEL);
423: mScale.setEnabled(false);
424: constraints.gridx = 1;
425: constraints.insets = rightInsets;
426: constraints.weightx = 0.0;
427: gridBag.setConstraints(mScale, constraints);
428: formPanel.add(mScale);
429:
430: initEventHandle();
431: contentPane.add(formPanel, BorderLayout.CENTER);
432: contentPane.add(getButtonPane(), BorderLayout.SOUTH);
433: this .setDefaultCloseOperation(WindowConstants.HIDE_ON_CLOSE);
434:
435: mTypesBox.addItemListener(new TypeChangeItemListener());
436: }
437:
438: private void updatePrecisionModel() {
439: int type = SQLUtils.getStdJdbcType((String) mTypesBox
440: .getSelectedItem());
441: if (SQLUtils.isPrecisionRequired(type)) {
442: mPrecLength.setEnabled(true);
443: switch (type) {
444: case Types.NUMERIC:
445: case Types.DECIMAL:
446: Integer currentVal = (Integer) PRECISION_MODEL
447: .getValue();
448: if (currentVal.compareTo(MAX_NUMBER_PRECISION) > 0) {
449: PRECISION_MODEL.setValue(MAX_NUMBER_PRECISION);
450: }
451: PRECISION_MODEL.setMaximum(MAX_NUMBER_PRECISION);
452: break;
453:
454: default:
455: mPrecLength.setEnabled(true);
456: PRECISION_MODEL.setMaximum(MAX_CHAR_PRECISION);
457: break;
458: }
459: } else {
460: mPrecLength.setEnabled(false);
461: }
462: }
463:
464: private void updateScaleModel() {
465: int type = SQLUtils.getStdJdbcType((String) mTypesBox
466: .getSelectedItem());
467: if (SQLUtils.isScaleRequired(type)) {
468: mScale.setEnabled(true);
469: Integer currentVal = (Integer) SCALE_MODEL.getValue();
470: Integer currentPrecision = (Integer) PRECISION_MODEL
471: .getValue();
472: if (currentVal.compareTo(currentPrecision) > 0) {
473: SCALE_MODEL.setValue(currentPrecision);
474: }
475: SCALE_MODEL.setMaximum(currentPrecision);
476: } else {
477: mScale.setEnabled(false);
478: }
479: }
480:
481: class TypeChangeItemListener implements ItemListener {
482:
483: public void itemStateChanged(ItemEvent e) {
484: CastAsDialog.this .updatePrecisionModel();
485: CastAsDialog.this .updateScaleModel();
486: }
487: }
488:
489: class PrecisionChangeListener implements ChangeListener {
490:
491: public void stateChanged(ChangeEvent e) {
492: CastAsDialog.this .updateScaleModel();
493: }
494: }
495:
496: class ButtonKeyAdapter extends KeyAdapter {
497:
498: public void keyPressed(KeyEvent evt) {
499: if (evt.getKeyCode() == KeyEvent.VK_ENTER) {
500: buttonActionPerformed(evt.getSource());
501: }
502: }
503: }
504: }
|