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.db.sql.visualeditor.querybuilder;
042:
043: import javax.swing.JPanel;
044: import javax.swing.JComponent;
045: import javax.swing.JSplitPane;
046: import javax.swing.JScrollPane;
047: import javax.swing.JLabel;
048:
049: import javax.swing.table.DefaultTableModel;
050:
051: import javax.swing.event.*;
052:
053: import java.awt.Color;
054: import java.awt.GridBagLayout;
055: import java.awt.GridBagConstraints;
056: import java.awt.event.*;
057:
058: import org.openide.util.NbBundle;
059:
060: import org.netbeans.modules.db.sql.visualeditor.Log;
061:
062: /**
063: *
064: * @author Sanjay Dhamankar
065: */
066: public class QueryBuilderPane extends JSplitPane {
067:
068: // Variables
069:
070: private boolean DEBUG = false;
071:
072: private int DIVIDER_SIZE = 7;
073:
074: // Make these package access, so components can access each other
075: // through here
076:
077: private QueryBuilderResultTable _queryBuilderResultTable;
078: private QueryBuilderGraphFrame _queryBuilderGraphFrame;
079: private QueryBuilderInputTable _queryBuilderInputTable;
080: private QueryBuilderSqlTextArea _queryBuilderSqlTextArea;
081:
082: private QueryBuilder _queryBuilder;
083:
084: private JLabel qbitLabel;
085: private JLabel qbstaLabel;
086: private JLabel qbgfLabel;
087:
088: // Use these to store the current state and to avoid the expensive
089: // recursive calls
090: private boolean graphScrollPaneEnabled;
091: private boolean qbInputTableSPEnabled;
092:
093: private JScrollPane graphScrollPane;
094: private JScrollPane qbInputTableSP;
095:
096: private JPanel bottomPanel;
097: private JPanel buttonPanel;
098: private boolean _keyTyped = false;
099:
100: JComponent _sceneView; // Needed for drop
101:
102: // Constructor
103:
104: public QueryBuilderPane(QueryBuilder queryBuilder) {
105:
106: /*
107: ---------------------------------------------------------
108: | graphScrollPane |
109: ---------------------------------------------------------
110: ---------------------------------------------------------
111: | qbInputTableSP |
112: ---------------------------------------------------------
113: ---------------------------------------------------------
114: | qbSqlTextAreaSP |
115: ---------------------------------------------------------
116: ---------------------------------------------------------
117: | qbResultTableSP |
118: ---------------------------------------------------------
119:
120: firstSplitPane ==> qbSqlTextAreaSP and qbResultTableSP
121: secondSplitPane ==> qbInputTableSP and firstSplitPane
122: this ==> graphScrollPane and secondSplitPane
123: */
124:
125: super (JSplitPane.VERTICAL_SPLIT);
126: Log.getLogger().entering("QueryBuilderPane", "constructor",
127: queryBuilder); // NOTIFYDESCRIPTOR
128:
129: _queryBuilder = queryBuilder;
130:
131: graphScrollPaneEnabled = true;
132: qbInputTableSPEnabled = true;
133:
134: // This causes system-wide changes in some LookAndFeels on Linux
135: // // Make sure we have nice window decorations.
136: // JFrame.setDefaultLookAndFeelDecorated(true);
137: // JDialog.setDefaultLookAndFeelDecorated(true);
138:
139: // Create the four panes that provide the main functionality
140:
141: _queryBuilderInputTable = new QueryBuilderInputTable(
142: _queryBuilder);
143: _queryBuilderInputTable.setFocusable(true);
144: _queryBuilderInputTable.getAccessibleContext()
145: .setAccessibleName(
146: NbBundle.getMessage(QueryBuilderPane.class,
147: "QBP_QBIT_a11yName"));
148: _queryBuilderInputTable.getAccessibleContext()
149: .setAccessibleDescription(
150: NbBundle.getMessage(QueryBuilderPane.class,
151: "QBP_QBIT_a11yDescription"));
152: qbitLabel = new JLabel();
153: qbitLabel.setText(NbBundle.getMessage(QueryBuilderPane.class,
154: "QBP_QBIT_label"));
155: qbitLabel.setLabelFor(_queryBuilderInputTable);
156:
157: _queryBuilderSqlTextArea = new QueryBuilderSqlTextArea(
158: _queryBuilder);
159: _queryBuilderSqlTextArea.setFocusable(true);
160: _queryBuilderSqlTextArea.getAccessibleContext()
161: .setAccessibleName(
162: NbBundle.getMessage(QueryBuilderPane.class,
163: "QBP_QBSTA_a11yName"));
164: _queryBuilderSqlTextArea.getAccessibleContext()
165: .setAccessibleDescription(
166: NbBundle.getMessage(QueryBuilderPane.class,
167: "QBP_QBSTA_a11yDescription"));
168: qbstaLabel = new JLabel();
169: qbstaLabel.setText(NbBundle.getMessage(QueryBuilderPane.class,
170: "QBP_QBSTA_label"));
171: qbstaLabel.setLabelFor(_queryBuilderSqlTextArea);
172:
173: _queryBuilderResultTable = new QueryBuilderResultTable(
174: _queryBuilder);
175: _queryBuilderResultTable.setFocusable(true);
176:
177: // When constructing the diagram pane, pass in the other three panes
178: // (or their models)
179: // ToDo: revisit this decision.
180: _queryBuilderGraphFrame = new QueryBuilderGraphFrame(
181: _queryBuilder, _queryBuilderInputTable,
182: _queryBuilderSqlTextArea,
183: (DefaultTableModel) _queryBuilderResultTable.getModel());
184: _queryBuilderGraphFrame.setFocusable(true);
185: _queryBuilderGraphFrame.getAccessibleContext()
186: .setAccessibleName(
187: NbBundle.getMessage(QueryBuilderPane.class,
188: "QBP_QBGF_a11yName"));
189: _queryBuilderGraphFrame.getAccessibleContext()
190: .setAccessibleDescription(
191: NbBundle.getMessage(QueryBuilderPane.class,
192: "QBP_QBGF_a11yDescription"));
193: qbgfLabel = new JLabel();
194: qbgfLabel.setText(NbBundle.getMessage(QueryBuilderPane.class,
195: "QBP_QBGF_label"));
196: qbgfLabel.setLabelFor(_queryBuilderGraphFrame);
197:
198: QBGraphScene scene = new QBGraphScene(_queryBuilderGraphFrame);
199: JComponent sceneView = scene.createView();
200:
201: _queryBuilderGraphFrame.initScene(scene, sceneView);
202:
203: // Wrap the diagram into a scroll pane, and make it the
204: // top component in the split pane
205: graphScrollPane = new JScrollPane(_sceneView);
206: graphScrollPane.setMinimumSize(new java.awt.Dimension(this
207: .getWidth(), 40));
208: this .setTopComponent(graphScrollPane);
209:
210: JSplitPane firstSplitPane = new JSplitPane(
211: JSplitPane.VERTICAL_SPLIT);
212: JSplitPane secondSplitPane = new JSplitPane(
213: JSplitPane.VERTICAL_SPLIT);
214:
215: // Create a JPanel for the bottom pane, and add the other three panes
216: // to it (input table, text query, result table)
217: bottomPanel = new JPanel();
218: GridBagLayout gridbag = new GridBagLayout();
219: GridBagConstraints c = new GridBagConstraints();
220: c.gridwidth = 1;
221: c.gridheight = 1;
222: c.weightx = 1;
223: c.weighty = 1;
224: c.fill = GridBagConstraints.BOTH;
225:
226: bottomPanel.setLayout(gridbag);
227:
228: // Wrap the input table in a scroll pane, and add to bottom panel
229: qbInputTableSP = new JScrollPane(_queryBuilderInputTable,
230: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
231: JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
232: qbInputTableSP.getViewport().setBackground(Color.white);
233: qbInputTableSP.setMinimumSize(new java.awt.Dimension(this
234: .getWidth(), 40));
235: c.gridx = 0;
236: c.gridy = 0;
237: gridbag.setConstraints(qbInputTableSP, c);
238:
239: // Wrap the SQL text area in a scroll pane, and add to bottom panel
240: JScrollPane qbSqlTextAreaSP = new JScrollPane(
241: _queryBuilderSqlTextArea,
242: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
243: JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
244: c.gridx = 0;
245: c.gridy = 1;
246: gridbag.setConstraints(qbSqlTextAreaSP, c);
247: qbSqlTextAreaSP.setMinimumSize(new java.awt.Dimension(this
248: .getWidth(), 40));
249: // ToDo: Should we do: qbSqlTextAreaSP.setBackground(Color.white);
250:
251: // Wrap the result table in a scroll pane, and add to bottom panel
252: // JScrollPane qbResultTableSP = new JScrollPane(_queryBuilderGraphFrame,
253: JScrollPane qbResultTableSP = new JScrollPane(
254: _queryBuilderResultTable,
255: JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
256: JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
257: qbResultTableSP.getViewport().setBackground(Color.white);
258: qbResultTableSP.setMinimumSize(new java.awt.Dimension(this
259: .getWidth(), 40));
260: c.gridx = 0;
261: c.gridy = 3;
262: gridbag.setConstraints(qbResultTableSP, c);
263:
264: firstSplitPane.setTopComponent(qbSqlTextAreaSP);
265: firstSplitPane.setBottomComponent(qbResultTableSP);
266: firstSplitPane.setDividerSize(DIVIDER_SIZE);
267: firstSplitPane.setOneTouchExpandable(true);
268: firstSplitPane.setResizeWeight(0.5);
269:
270: secondSplitPane.setTopComponent(qbInputTableSP);
271: secondSplitPane.setBottomComponent(firstSplitPane);
272: secondSplitPane.setDividerSize(DIVIDER_SIZE);
273: secondSplitPane.setOneTouchExpandable(true);
274: secondSplitPane.setResizeWeight(0.5);
275:
276: this .setBottomComponent(secondSplitPane);
277: this .setDividerSize(DIVIDER_SIZE);
278: this .setResizeWeight(0.5);
279: this .setOneTouchExpandable(true);
280: this .setVisible(true);
281: }
282:
283: /**
284: * Return the query builder result table
285: */
286: QueryBuilderResultTable getQueryBuilderResultTable() {
287: return _queryBuilderResultTable;
288: }
289:
290: /**
291: * Return the query builder graph frame
292: */
293: QueryBuilderGraphFrame getQueryBuilderGraphFrame() {
294: return _queryBuilderGraphFrame;
295: }
296:
297: /**
298: * Return the query builder input table
299: */
300: QueryBuilderInputTable getQueryBuilderInputTable() {
301: return _queryBuilderInputTable;
302: }
303:
304: /**
305: * Return the query builder sql text area
306: */
307: QueryBuilderSqlTextArea getQueryBuilderSqlTextArea() {
308: return _queryBuilderSqlTextArea;
309: }
310:
311: /**
312: * Clear each of the panes or their models
313: */
314: void clear() {
315: Log.getLogger().entering("QueryBuilderPane", "clear"); // NOTIFYDESCRIPTOR
316:
317: _queryBuilderInputTable.clearModel();
318: _queryBuilderSqlTextArea.clear();
319: _queryBuilderResultTable.clearModel();
320:
321: // We used to clear the graph by explicitly removing nodes and edges, but that causes
322: // CurrentModificationExceptions. Instead, re-create the scene. Should be faster anyway.
323: // _queryBuilderGraphFrame.clearGraph();
324: QBGraphScene scene = new QBGraphScene(_queryBuilderGraphFrame);
325: JComponent sceneView = scene.createView();
326: _queryBuilderGraphFrame.initScene(scene, sceneView);
327: graphScrollPane.setViewportView(sceneView);
328: }
329:
330: /**
331: * Enable / Disable the container and its children.
332: */
333: public void setEnableContainer(java.awt.Container c, boolean value) {
334: java.awt.Component[] components = c.getComponents();
335: for (int i = 0; i < components.length; i++) {
336: components[i].setEnabled(value);
337: if (components[i] instanceof java.awt.Container) {
338: setEnableContainer((java.awt.Container) components[i],
339: value);
340: }
341: }
342: }
343:
344: /**
345: * Enable / Disable the graph scrolled pane and its children.
346: * We store the state to avoid the expensive recursive call to
347: * setEnableContainer.
348: */
349: /*
350: public void setQueryBuilderGraphFrameEnabled ( boolean value )
351: {
352: if ( graphScrollPaneEnabled == value ) return;
353: if ( graphScrollPane != null ) {
354: setEnableContainer ( graphScrollPane , value );
355: graphScrollPaneEnabled = value;
356: }
357: }
358: */
359:
360: /**
361: * Enable / Disable the input table scrolled pane and its children.
362: * We store the state to avoid the expensive recursive call to
363: * setEnableContainer.
364: */
365: public void setQueryBuilderInputTableEnabled(boolean value) {
366: if (qbInputTableSPEnabled == value)
367: return;
368: if (qbInputTableSP != null) {
369: setEnableContainer(qbInputTableSP, value);
370: qbInputTableSPEnabled = value;
371: }
372: }
373: }
|