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.utils;
042:
043: import java.awt.Component;
044: import java.awt.Dialog;
045: import java.awt.event.ActionEvent;
046: import java.awt.event.ActionListener;
047: import java.sql.Types;
048: import java.util.Iterator;
049: import java.util.List;
050:
051: import javax.swing.AbstractAction;
052: import javax.swing.Action;
053: import javax.swing.InputMap;
054: import javax.swing.JComponent;
055: import javax.swing.JDialog;
056: import javax.swing.JOptionPane;
057: import javax.swing.JRootPane;
058: import javax.swing.KeyStroke;
059: import org.netbeans.api.progress.ProgressHandle;
060: import org.netbeans.api.progress.ProgressHandleFactory;
061: import org.netbeans.modules.sql.framework.model.DBColumn;
062: import org.netbeans.modules.sql.framework.model.SQLConstants;
063: import org.netbeans.modules.sql.framework.model.SQLDBColumn;
064: import org.netbeans.modules.sql.framework.model.SQLDBTable;
065: import org.netbeans.modules.sql.framework.model.SQLDefinition;
066: import org.netbeans.modules.sql.framework.model.SQLObject;
067: import org.netbeans.modules.sql.framework.model.TargetTable;
068: import org.netbeans.modules.sql.framework.model.utils.SQLObjectUtil;
069:
070: import com.sun.sql.framework.utils.StringUtil;
071: import org.netbeans.modules.sql.framework.model.DBTable;
072: import org.netbeans.modules.sql.framework.model.ForeignKey;
073:
074: /**
075: * Provides UI-related facilities.
076: *
077: * @author Wei Han, Ritesh Adval, Jonathan Giron
078: */
079:
080: public abstract class UIUtil {
081: private static KeyStroke KEY_STROKE_ESCAPE_RELEASED = KeyStroke
082: .getKeyStroke("released ESCAPE");
083: private static ProgressHandle progressBarDialog = null;
084: private static boolean progressBarStarted = false;
085:
086: private static class FilteredAction extends AbstractAction {
087: private Action endEditAction;
088: private JComponent comp;
089:
090: public FilteredAction(JComponent comp, Action tEndEditAction) {
091: this .comp = comp;
092: this .endEditAction = tEndEditAction;
093: }
094:
095: public void actionPerformed(ActionEvent e) {
096: if (!comp.hasFocus()) {
097: comp.getInputMap().put(KEY_STROKE_ESCAPE_RELEASED,
098: "cancel");
099: endEditAction.actionPerformed(e);
100: } else {
101: comp.getInputMap().remove(KEY_STROKE_ESCAPE_RELEASED);
102: }
103: }
104: }
105:
106: private static class DialogCloseListener implements ActionListener {
107: private Dialog dialog = null;
108:
109: public DialogCloseListener(Dialog tDialog) {
110: this .dialog = tDialog;
111: }
112:
113: public void actionPerformed(ActionEvent actionEvent) {
114: dialog.setVisible(false);
115: dialog
116: .getAccessibleContext()
117: .setAccessibleDescription(
118: "This dialog provides all UI related functionality");
119: }
120: }
121:
122: private static synchronized void initProgressDialog(String title) {
123: progressBarDialog = ProgressHandleFactory.createHandle(title);
124: }
125:
126: public static synchronized void startProgressDialog(String title,
127: String message) {
128: if (!progressBarStarted) {
129: initProgressDialog(title);
130: progressBarStarted = true;
131: progressBarDialog.setDisplayName(title);
132: progressBarDialog.start();
133: progressBarDialog.progress(message);
134: }
135: }
136:
137: public static synchronized void stopProgressDialog() {
138: if ((progressBarStarted) && (progressBarDialog != null)) {
139: progressBarStarted = false;
140: progressBarDialog.finish();
141: }
142: }
143:
144: /**
145: * Show "Yes/No" message box.
146: *
147: * @param parent - parent
148: * @param msg - msg
149: * @param title - title
150: * @return - selected option
151: */
152: public static int showYesAllDialog(Component parent, Object msg,
153: String title) {
154: String[] options = new String[] { "Yes", "No", };
155: return JOptionPane
156: .showOptionDialog(parent, msg, title,
157: JOptionPane.YES_NO_OPTION,
158: JOptionPane.QUESTION_MESSAGE, null, options,
159: options[1]);
160: }
161:
162: /**
163: * Generates HTML-formatted String containing detailed information on the given
164: * SQLDBColumn instance.
165: *
166: * @param column SQLDBColumn whose metadata are to be displayed in the tooltip
167: * @return String containing HTML-formatted column metadata
168: */
169: public static String getColumnToolTip(SQLDBColumn column) {
170: boolean pk = column.isPrimaryKey();
171: boolean fk = column.isForeignKey();
172: boolean indexed = column.isIndexed();
173:
174: StringBuilder strBuf = new StringBuilder(
175: "<html> <table border=0 cellspacing=0 cellpadding=0 >");
176: strBuf
177: .append("<tr> <td> Name </td> <td> : <b>");
178: strBuf.append(column.getName()).append("</b> </td> </tr>");
179: strBuf
180: .append("<tr> <td> Type </td> <td> : <b>");
181: strBuf.append(column.getJdbcTypeString()).append(
182: "</b> </td> </tr>");
183: strBuf
184: .append("<tr> <td> Precision </td> <td> : <b>");
185: strBuf.append(column.getPrecision()).append("</b> </td> </tr>");
186:
187: switch (column.getJdbcType()) {
188: case Types.CHAR:
189: case Types.DATE:
190: case Types.INTEGER:
191: case Types.SMALLINT:
192: case Types.TIME:
193: case Types.TIMESTAMP:
194: case Types.TINYINT:
195: case Types.VARCHAR:
196: // Do nothing - scale is meaningless for these types.
197: break;
198:
199: default:
200: strBuf
201: .append("<tr> <td> Scale </td> <td> : <b>");
202: strBuf.append(column.getScale()).append("</b> </td> </tr>");
203: }
204:
205: if (pk) {
206: strBuf
207: .append("<tr> <td> PK </td> <td> : <b> Yes </b> </td> </tr>");
208: }
209: if (fk) {
210: strBuf.append(
211: "<tr> <td> FK </td> <td> : <b>"
212: + getForeignKeyString(column)).append(
213: "</b>").append("</td> </tr>");
214: }
215:
216: if (indexed) {
217: strBuf
218: .append("<tr> <td> Indexed </td> <td> : <b> Yes </b> </td> </tr>");
219: }
220:
221: strBuf.append("</table> </html>");
222: return strBuf.toString();
223: }
224:
225: public static String getForeignKeyString(DBColumn column) {
226: String refString = column.getName() + " --> ";
227: StringBuilder str = new StringBuilder(refString);
228: DBTable table = column.getParent();
229: List list = table.getForeignKeys();
230:
231: Iterator it = list.iterator();
232: while (it.hasNext()) {
233: ForeignKey fk = (ForeignKey) it.next();
234: if (fk.contains(column)) {
235: List pkColumnList = fk.getPKColumnNames();
236: Iterator it1 = pkColumnList.iterator();
237: while (it1.hasNext()) {
238: String pkColName = (String) it1.next();
239: str.append(pkColName);
240: if (it1.hasNext()) {
241: str.append(", ");
242: }
243: }
244: }
245: }
246:
247: return str.toString();
248: }
249:
250: /**
251: * Gets fully-resolved (not fully-qualified) table name for the given SQLDBTable
252: * instance.
253: *
254: * @param table SQLDBTable whose name is to be resolved
255: * @return fully-resolved table name
256: */
257: public static String getResolvedTableName(SQLDBTable table) {
258: StringBuilder buf = new StringBuilder(16);
259:
260: String prefix = table.getTablePrefix();
261: if (!StringUtil.isNullString(prefix)) {
262: buf.append(prefix.trim());
263: }
264:
265: String userTableName = table.getUserDefinedTableName();
266: if (!StringUtil.isNullString(userTableName)) {
267: buf.append(userTableName.trim());
268: } else {
269: buf.append(table.getName().trim());
270: }
271:
272: return buf.toString();
273: }
274:
275: /**
276: * Generates HTML-formatted String containing detailed information on the given
277: * SQLDBTable instance.
278: *
279: * @param table SQLDBTable whose metadata are to be displayed in the tooltip
280: * @return String containing HTML-formatted table metadata
281: */
282: public static String getTableToolTip(SQLDBTable table) {
283: StringBuilder strBuf = new StringBuilder(
284: "<html> <table border=0 cellspacing=0 cellpadding=0 >");
285: boolean isUserDefinedTableName = !StringUtil.isNullString(table
286: .getUserDefinedTableName());
287: strBuf
288: .append("<tr> <td> Table </td> <td> : <b>");
289: if (isUserDefinedTableName) {
290: strBuf.append("<i>").append(
291: UIUtil.getResolvedTableName(table)).append("</i>");
292: } else {
293: strBuf.append(UIUtil.getResolvedTableName(table));
294: }
295: strBuf.append("</b> </td> </tr>");
296:
297: if (table.getAliasName() != null
298: && !table.getAliasName().trim().equals("")) {
299: strBuf
300: .append("<tr> <td> Alias </td> <td> : <b>");
301: strBuf.append(table.getAliasName()).append(
302: "</b> </td> </tr>");
303: }
304:
305: String schema = table.getUserDefinedSchemaName();
306: final boolean isUserDefinedSchema = !StringUtil
307: .isNullString(schema);
308: if (!isUserDefinedSchema) {
309: schema = table.getSchema();
310: }
311: if (!StringUtil.isNullString(schema)) {
312: strBuf
313: .append("<tr> <td> Schema </td> <td> : <b>");
314: if (isUserDefinedSchema) {
315: strBuf.append("<i>").append(schema.trim()).append(
316: "</i>");
317: } else {
318: strBuf.append(schema.trim());
319: }
320: strBuf.append("</b> </td> </tr>");
321: }
322:
323: String catalog = table.getUserDefinedCatalogName();
324: final boolean isUserDefinedCatalog = !StringUtil
325: .isNullString(catalog);
326: if (!isUserDefinedCatalog) {
327: catalog = table.getCatalog();
328: }
329: if (!StringUtil.isNullString(catalog)) {
330: strBuf
331: .append("<tr> <td> Catalog </td> <td> : <b>");
332: if (isUserDefinedCatalog) {
333: strBuf.append("<i>").append(catalog.trim()).append(
334: "</i>");
335: } else {
336: strBuf.append(catalog.trim());
337: }
338: strBuf.append("</b> </td> </tr>");
339: }
340:
341: strBuf
342: .append("<tr> <td> ConnectionURL </td> <td> : <b>");
343:
344: String URL = table.getParent().getModelName();
345: if (URL.length() > 40) {
346: strBuf.append("...").append(
347: URL.substring(URL.length() - 40));
348: } else {
349: strBuf.append(URL).append("</b> </td> </tr>");
350: }
351:
352: strBuf
353: .append("<tr> <td> DB Type </td> <td> : <b>");
354: strBuf
355: .append(
356: table.getParent().getConnectionDefinition()
357: .getDBType())
358: .append("</b> </td> </tr>");
359:
360: SQLObject tableObj = table;
361: if (tableObj.getObjectType() == SQLConstants.TARGET_TABLE) {
362: TargetTable tt = (TargetTable) tableObj;
363:
364: strBuf
365: .append("<tr> <td> Statement Type </td> <td> : <b>");
366: strBuf.append(tt.getStrStatementType()).append(
367: "</b> </td> </tr>");
368: }
369:
370: SQLDefinition def = SQLObjectUtil
371: .getAncestralSQLDefinition(table);
372: if (def != null) {
373: strBuf
374: .append("<tr> <td> Execution Strategy </td> <td> : <b>");
375: strBuf.append(def.getExecutionStrategyStr()).append(
376: "</b> </td> </tr>");
377: }
378:
379: String ffArg = table.getFlatFileLocationRuntimeInputName();
380: if (ffArg != null) {
381: strBuf
382: .append("<tr> <td> File Location Arg </td> <td> : <b>");
383: strBuf.append(ffArg).append("</b> </td> </tr>");
384: }
385:
386: strBuf.append("</table> </html>");
387: return strBuf.toString();
388: }
389:
390: public static void addEscapeListener(JRootPane rootPane,
391: ActionListener closeActionListener) {
392: if (closeActionListener != null) {
393: rootPane.registerKeyboardAction(closeActionListener,
394: KEY_STROKE_ESCAPE_RELEASED,
395: JComponent.WHEN_IN_FOCUSED_WINDOW);
396: }
397: }
398:
399: public static void addEscapeListener(JDialog dialog) {
400: ActionListener listener = new DialogCloseListener(dialog);
401: addEscapeListener(dialog.getRootPane(), listener);
402: }
403:
404: public static void addEscapeListener(JDialog dialog,
405: ActionListener listener) {
406: addEscapeListener(dialog.getRootPane(), listener);
407: }
408:
409: public static void makeJTableCloseOnDoubleEscape(JComponent table) {
410: KeyStroke esc = KeyStroke.getKeyStroke("ESCAPE");
411: InputMap map = table
412: .getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
413: Action endEditAction = table.getActionMap().get(map.get(esc));
414: Action newAction = new FilteredAction(table, endEditAction);
415: table.getActionMap().put("cancel", newAction);
416: }
417: }
|