001/*
002 * Copyright (c) 2003-2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: welker $'
006 * '$Date: 2010-05-06 05:21:26 +0000 (Thu, 06 May 2010) $' 
007 * '$Revision: 24234 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029
030package org.ecoinformatics.seek.querybuilder;
031
032import java.awt.Component;
033import java.awt.Point;
034import java.awt.Rectangle;
035import java.awt.event.AdjustmentEvent;
036import java.awt.event.AdjustmentListener;
037import java.util.Vector;
038
039import javax.swing.JInternalFrame;
040import javax.swing.JScrollPane;
041import javax.swing.ListModel;
042import javax.swing.RepaintManager;
043import javax.swing.SwingUtilities;
044import javax.swing.event.TableModelEvent;
045import javax.swing.event.TableModelListener;
046
047import org.kepler.objectmanager.data.DataType;
048import org.kepler.objectmanager.data.db.DSTableFieldDef;
049import org.kepler.objectmanager.data.db.DSTableFieldIFace;
050import org.kepler.objectmanager.data.db.DSTableIFace;
051import org.kepler.objectmanager.data.db.DSTableKeyIFace;
052
053/**
054 * Extends JInternalFrame and contains a list of the fields. This object needs
055 * to tell its parent the DesktopPane when it moves so the desktop can size
056 * appropriately and paint
057 */
058public class DBTableFrame extends JInternalFrame implements AdjustmentListener,
059                TableModelListener, DSTableIFace {
060        protected int mId = 0;
061        protected DSTableIFace mTableDef = null;
062        protected DBTableList mList = null;
063        protected JScrollPane mScrollPane = null;
064
065        protected DBTableListModel mModel = null;
066
067        protected Rectangle mListBnds = null;
068        protected int mValue = -1;
069        protected boolean mBoundsChanging = false;
070        protected TableModelListener mTableModelListener = null;
071
072        /**
073         * Default Constructor
074         * 
075         */
076        public DBTableFrame(DSTableIFace aTableDef, int aId) {
077                mId = aId;
078                mTableDef = aTableDef;
079                setDoubleBuffered(true);
080                this.setTitle(mTableDef.getName());
081
082                setResizable(true);
083
084                mModel = new DBTableListModel(this);
085                Vector fields = aTableDef.getFields();
086                if (fields != null && fields.size() > 0) {
087                        DSTableFieldDef fieldDef = new DSTableFieldDef("",
088                                        DBUIUtils.ALL_FIELDS, DataType.STR, null);
089                        fieldDef.setTable(aTableDef);
090                        mModel.add(new DBTableField(fieldDef, this));
091
092                        DSTableKeyIFace primaryKey = aTableDef.getPrimaryKey();
093                        if (primaryKey != null) {
094                                mModel.add(primaryKey);
095                        }
096
097                        for (int i = 0; i < fields.size(); i++) {
098                                DSTableFieldIFace fld = (DSTableFieldIFace) fields.elementAt(i);
099                                if (fld instanceof DSTableKeyIFace) {
100                                        DSTableKeyIFace key = (DSTableKeyIFace) fields.elementAt(i);
101                                        if (key.getKeyType() != DSTableKeyIFace.PRIMARYKEY) {
102                                                mModel.add(fld);
103                                        }
104                                } else {
105                                        mModel.add(fld);
106                                }
107                        }
108                }
109
110                mList = new DBTableList(mModel);
111                mList.setDoubleBuffered(true);
112
113                // Or in two steps:
114                mScrollPane = new JScrollPane();
115                mScrollPane.getViewport().setView(mList);
116                mScrollPane.setDoubleBuffered(true);
117                setContentPane(mScrollPane);
118                mScrollPane.getVerticalScrollBar().addAdjustmentListener(this);
119        }
120
121        /**
122         * Finalize/Cleanup
123         */
124        public void finalize() {
125                mTableModelListener = null;
126        }
127
128        /**
129         * Sets a single listener of TableModel Changes
130         * 
131         * @param aL
132         *            a listener
133         */
134        public void setTableModelListener(TableModelListener aL) {
135                mTableModelListener = aL;
136        }
137
138        /**
139         * @return the unique id of the object
140         */
141        public int getId() {
142                return mId;
143        }
144
145        /**
146         * Uses to set the "Joins" data structure
147         * 
148         * @param aJoins
149         *            The data structure representing all the "joins"
150         */
151        public void setJoins(DBTableJoin aJoins) {
152                mList.setJoins(aJoins);
153        }
154
155        /**
156         * Returns a field item given an index
157         * 
158         * @param aInx
159         *            the index
160         * @return DBTableField
161         */
162        public DBTableField getField(int aInx) {
163                return (aInx > 0 && aInx < mModel.getSize()) ? (DBTableField) mModel
164                                .getElementAt(aInx) : null;
165        }
166
167        /**
168         * Returns the current value of the vertical scrollbar for the JList
169         * 
170         * @return current scrollbar value
171         */
172        public int getScrollValue() {
173                return mScrollPane.getVerticalScrollBar().getValue();
174        }
175
176        /**
177         * Return the bounds of the JList item in the frame
178         * 
179         * @return The bounds of the JList item in the frame
180         */
181        public Rectangle getListBounds() {
182                if (mListBnds == null) {
183                        mListBnds = mList.getBounds();
184                        Component parent = mList.getParent();
185                        while (parent != this) {
186                                Point pnt = parent.getLocation();
187                                mListBnds.translate(pnt.x, pnt.y);
188                                if (parent.getClass() == JScrollPane.class) {
189                                        mListBnds.height = parent.getBounds().height;
190                                }
191                                parent = parent.getParent();
192                        }
193                        mListBnds.y += getScrollValue();
194                }
195                return mListBnds;
196        }
197
198        /**
199         * Gets the ListModel
200         * 
201         * @return the lis model
202         */
203        public ListModel getModel() {
204                return mModel;
205        }
206
207        /**
208         * Returns the DBTableList object (GUI)
209         * 
210         * @return table list
211         */
212        public DBTableList getList() {
213                return mList;
214        }
215
216        /**
217         * Returns the ScrollPane for the List
218         * 
219         * @return the scroll pane
220         */
221        public JScrollPane getScrollPane() {
222                return mScrollPane;
223        }
224
225        /**
226         * Makes sure the Parent object gets correctly resized
227         * 
228         */
229        protected void resizeParent() {
230                DBTableDesktopPane parent = (DBTableDesktopPane) super.getParent();
231                if (parent != null && parent.getParent() != null) {
232                        parent.getParent().validate();
233                }
234        }
235
236        /**
237         * Makes sure the entire DesktopPane gets "dirtied" so it all get repainted
238         * 
239         */
240        void dirtyAll() {
241                DBTableDesktopPane parent = (DBTableDesktopPane) super.getParent();
242                if (parent != null) {
243                        RepaintManager mgr = RepaintManager.currentManager(parent);
244                        // mgr.addDirtyRegion((JComponent)parent, r.x, r.y, r.width,
245                        // r.height);
246                        mgr.markCompletelyDirty(parent);
247                }
248        }
249
250        /**
251         * Overrides the super class so we can adjust the size of the DesktopPane
252         * when a * a TableFrame is moved or resized
253         */
254        public void setBounds(int x, int y, int w, int h) {
255                mBoundsChanging = true;
256                DBTableDesktopPane parent = (DBTableDesktopPane) super.getParent();
257                if (parent != null) {
258
259                        Rectangle r = super.getBounds();
260                        if (r.x != x || r.y != y) {
261                                if (mTableModelListener != null)
262                                        mTableModelListener.tableChanged(null);
263
264                                // do the following on the gui thread
265                                SwingUtilities.invokeLater(new Runnable() {
266                                        public void run() {
267                                                dirtyAll();
268                                        }
269                                });
270                        }
271
272                        Rectangle parentBnds = parent.getBounds();
273                        int farX = r.x + r.width;
274                        int farY = r.y + r.height;
275                        if (farX > parentBnds.width || farY > parentBnds.height) {
276                                // do the following on the gui thread
277                                SwingUtilities.invokeLater(new Runnable() {
278                                        public void run() {
279                                                resizeParent();
280                                        }
281                                });
282                        }
283                }
284                super.setBounds(x, y, w, h);
285                mBoundsChanging = false;
286        }
287
288        /**
289         * Overrides the super class so we can adjust the size of the DesktopPane
290         * when a TableFrame is moved or resized
291         */
292        public void setBounds(java.awt.Rectangle r) {
293                setBounds(r.x, r.y, r.width, r.height);
294        }
295
296        /**
297         * Overrides the super class so we can adjust the size of the DesktopPane
298         * when a * a TableFrame is moved or resized
299         */
300        /*
301         * public void setLocation(int x, int y) { super.setLocation(x, y); }
302         */
303
304        /**
305         * Overrides the super class so we can adjust the size of the DesktopPane
306         * when a * a TableFrame is moved or resized
307         */
308        /*
309         * public void setLocation(Point p) { super.setLocation(p); }
310         */
311
312        // ----------------------------------------------------
313        // ------------ AdjustmentListener ------------------
314        // ----------------------------------------------------
315        /**
316         * Makes sure the Join lines gets drawn by dirtying
317         */
318        public void adjustmentValueChanged(AdjustmentEvent e) {
319                SwingUtilities.invokeLater(new Runnable() {
320                        public void run() {
321                                dirtyAll();
322                        }
323                });
324        }
325
326        // ----------------------------------------------------
327        // ------------ TableModelListener ------------------
328        // ----------------------------------------------------
329        /**
330         * If the Model changes make sure everything is redrawn
331         */
332        public void tableChanged(TableModelEvent e) {
333                SwingUtilities.invokeLater(new Runnable() {
334                        public void run() {
335                                dirtyAll();
336                        }
337                });
338        }
339
340        // ----------------------------------------------------
341        // ----------------- DSTableIFace ---------------------
342        // ----------------------------------------------------
343        /**
344         * Returns the name of the table
345         * 
346         * @return string
347         */
348        public String getName() {
349                return mTableDef != null ? mTableDef.getName() : "";
350        }
351
352        /**
353         * Returns the mapped name of the table
354         * 
355         * @return string
356         */
357        public String getMappedName() {
358                return getName();
359        }
360
361        /**
362         * Returns a Vector of the fields in the table
363         * 
364         * @return vector of field objects
365         */
366        public Vector getFields() {
367                if (mList != null) {
368                        return ((DBTableListModel) mList.getModel()).getFields();
369                }
370                return null;
371        }
372
373        /**
374         * Returns a the Primary Key Definition for the table
375         * 
376         * @return pointer to a key interface
377         */
378        public DSTableKeyIFace getPrimaryKey() {
379                return mTableDef != null ? mTableDef.getPrimaryKey() : null;
380        }
381}