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.Color; 033import java.awt.Component; 034import java.awt.Point; 035import java.awt.datatransfer.DataFlavor; 036import java.awt.dnd.DnDConstants; 037import java.awt.dnd.DropTarget; 038import java.awt.dnd.DropTargetDragEvent; 039import java.awt.dnd.DropTargetDropEvent; 040import java.awt.dnd.DropTargetEvent; 041import java.awt.dnd.DropTargetListener; 042import java.awt.event.MouseAdapter; 043import java.awt.event.MouseEvent; 044import java.util.Enumeration; 045import java.util.Vector; 046 047import javax.swing.DefaultCellEditor; 048import javax.swing.JCheckBox; 049import javax.swing.JComboBox; 050import javax.swing.JMenuItem; 051import javax.swing.JPopupMenu; 052import javax.swing.JTable; 053import javax.swing.table.TableCellEditor; 054import javax.swing.table.TableCellRenderer; 055 056/** 057 * The JTable abstract base class for rendering portions (or all) of the select 058 * statement. 059 * 060 */ 061public abstract class DBSelectTableUIBase extends JTable implements 062 DropTargetListener { 063 protected DBSelectTableModelBase mModel = null; 064 protected DataFlavor[] mDataFlavor = new DataFlavor[1]; 065 protected int mAceptableActions = DnDConstants.ACTION_COPY_OR_MOVE; 066 protected DropTarget mDropTarget = new DropTarget(this, mAceptableActions, 067 this); 068 069 protected Vector mListeners = new Vector(); 070 071 protected JCheckBox mIsDisplayedCheckbox = null; 072 073 protected JComboBox mTablesComboBox = null; 074 protected JComboBox mFieldsComboBox = null; 075 protected JComboBox mBoolOpers = null; 076 077 protected String mDragTableName = ""; 078 079 protected boolean mCheckOkToDrop = true; 080 protected boolean mOkToDrop = true; 081 082 private static final int INCLUDECLOWIDTH = 100; 083 084 /** 085 * Constructs a Table "View" which allows DBTable items to be dropped onto 086 * it 087 * 088 */ 089 public DBSelectTableUIBase() { 090 } 091 092 /* 093 * sets tyhe listener to null 094 */ 095 public void finalize() { 096 mListeners = null; 097 } 098 099 /** 100 * Perform the drop action for the sub-class of choice 101 * 102 * @param e 103 * the ebent 104 */ 105 protected abstract void doDrop(DropTargetDropEvent e); 106 107 /** 108 * Notification that an model item was added. 109 * 110 * @param aItem 111 * the item to be added 112 */ 113 protected void itemWasAdded(DBSelectTableModelItem aItem) { 114 if (mListeners != null) { 115 for (Enumeration ef = mListeners.elements(); ef.hasMoreElements();) { 116 ((DBSelectTableFieldChangedListener) ef.nextElement()) 117 .notifyFieldChanged(); 118 } 119 } 120 } 121 122 /** 123 * Adds listener 124 * 125 * @param aListener 126 * listener to be added 127 * 128 */ 129 public void addFieldChangeListener( 130 DBSelectTableFieldChangedListener aListener) { 131 if (aListener != null) 132 mListeners.add(aListener); 133 } 134 135 /** 136 * Sets a single listener for this object, remove it by setting it to null 137 * 138 * @param aListener 139 * listener to be added 140 * 141 */ 142 public void removeFieldChangeListener( 143 DBSelectTableFieldChangedListener aListener) { 144 if (aListener != null) 145 mListeners.remove(aListener); 146 } 147 148 /** 149 * Receices this notification before the editor is paced in the cell 150 * 151 * @param aRow 152 * row of cell 153 * @param aColumn 154 * coloumn of cell 155 */ 156 public TableCellEditor getCellEditor(int aRow, int aColumn) { 157 // fill the comboboxes that will be used for the cell 158 if (aColumn == 0) { 159 fillTableCombobox(aRow); 160 161 } else if (aColumn == 1) { 162 fillFieldCombobox(aRow); 163 } 164 return super.getCellEditor(aRow, aColumn); 165 } 166 167 /** 168 * Fill the table combobox, note that if all the fields have been already 169 * used the table won't show in the list unless they are editting a row 170 * containing that table name 171 * 172 * @param aRow 173 * the row of the item 174 */ 175 protected void fillTableCombobox(int aRow) { 176 mTablesComboBox.removeAllItems(); 177 Vector tableNames = mModel.getAvailableTableNames(aRow); 178 for (Enumeration ef = tableNames.elements(); ef.hasMoreElements();) { 179 mTablesComboBox.addItem((String) ef.nextElement()); 180 } 181 } 182 183 /** 184 * Fill the fields combobox with any field names for that table that have 185 * not been used. BUT! Remember to include the name of the item that is 186 * currently being editted 187 * 188 * @param aRow 189 * the row of the item 190 * 191 */ 192 protected void fillFieldCombobox(int aRow) { 193 mFieldsComboBox.removeAllItems(); 194 String tableName = mModel.getFieldForRow(aRow).getTableName(); 195 Vector fieldNames = mModel.getAvailableFieldNames(tableName); 196 for (Enumeration ef = fieldNames.elements(); ef.hasMoreElements();) { 197 mFieldsComboBox.addItem((String) ef.nextElement()); 198 } 199 } 200 201 /** 202 * Set the data model into the table 203 * 204 * @param aModel 205 * the table data model 206 */ 207 public void setModel(DBSelectTableModelBase aModel) { 208 if (aModel != null) 209 super.setModel(aModel); 210 mModel = aModel; 211 } 212 213 /** 214 * Creates and Installs cell editors, must be called AFTER setting the model 215 */ 216 public void installEditors() { 217 mIsDisplayedCheckbox = new JCheckBox(); 218 219 if (mModel != null && mModel.getSchema() != null) { 220 // Use the combo box as the editor in the "Favorite Color" column. 221 mTablesComboBox = new JComboBox(); 222 mTablesComboBox.setBackground(Color.WHITE); 223 mFieldsComboBox = new JComboBox(); 224 mFieldsComboBox.setBackground(Color.WHITE); 225 mBoolOpers = new JComboBox(); 226 mBoolOpers.setBackground(Color.WHITE); 227 228 mTablesComboBox.addItem(" "); 229 DBUIUtils.fillTableCombobox(mModel.getSchema(), mTablesComboBox); 230 setRowHeight(mTablesComboBox.getPreferredSize().height); 231 232 getColumn("Table").setCellEditor( 233 new DefaultCellEditor(mTablesComboBox)); 234 getColumn("Table").setCellRenderer(new JComboBoxCellRenderer()); 235 getColumn("Field").setCellEditor( 236 new DefaultCellEditor(mFieldsComboBox)); 237 getColumn("Field").setCellRenderer(new JComboBoxCellRenderer()); 238 getColumn(DBSelectTableModelStd.INCLUDESELECTION) 239 .setPreferredWidth(INCLUDECLOWIDTH); 240 241 } 242 } 243 244 /** 245 * Indicates whether the items can be dropped 246 * 247 * @param aTableName 248 * the table name 249 * @param aFieldName 250 * the field name 251 * @return true if is can be dropped, otherwise false 252 */ 253 private boolean okToDrop(String aTableName, String aFieldName) { 254 255 Vector fieldNames = mModel.getAvailableFieldNames(aTableName); 256 for (Enumeration et = fieldNames.elements(); et.hasMoreElements();) { 257 String tblFieldName = (String) et.nextElement(); 258 if (tblFieldName.equals(aFieldName)) { 259 return true; 260 } 261 } 262 return false; 263 } 264 265 // -------------------------------------------------------------- 266 // ------------------ Drop Target Methods ----------------------- 267 // -------------------------------------------------------------- 268 269 /** 270 * Checks to see if it is the right type of object 271 */ 272 public void dragEnter(DropTargetDragEvent e) { 273 if (!isDragOk(e)) { 274 e.rejectDrag(); 275 return; 276 } 277 } 278 279 /** 280 * Stubbed 281 */ 282 public void dragExit(DropTargetEvent dropTargetEvent) { 283 } 284 285 /** 286 * Checks to see if it is the right type of object 287 */ 288 public void dragOver(DropTargetDragEvent e) { 289 290 if (!isDragOk(e)) { 291 e.rejectDrag(); 292 return; 293 } 294 } 295 296 /** 297 * Checks to make sure the transaferable is OK to be dropped 298 * 299 * @param e 300 * current D&D event 301 * @return whether it can be dropped 302 */ 303 private boolean isDragOk(DropTargetDragEvent e) { 304 if (!e.isDataFlavorSupported(mDataFlavor[0])) { 305 return false; 306 } 307 308 // the actions specified when the source 309 // created the DragGestureRecognizer 310 int sa = e.getSourceActions(); 311 312 // we're saying that these actions are necessary 313 if ((sa & mAceptableActions) == 0) 314 return false; 315 316 // System.out.println("isDragOk: "+e.getSourceActions() + 317 // " mAceptableActions "+mAceptableActions +" "+(((e.getSourceActions() 318 // & mAceptableActions) != 0))); 319 return true; 320 } 321 322 /** 323 * Stubbed 324 */ 325 public void dropActionChanged(DropTargetDragEvent dropTargetDragEvent) { 326 } 327 328 /** 329 * Allows DBTable items to be droped and then creates a new "row" in the 330 * table representing the item 331 */ 332 public synchronized void drop(DropTargetDropEvent e) { 333 doDrop(e); 334 } 335 336 /* 337 * This calss will render at table cell as JComboBox 338 */ 339 protected class JComboBoxCellRenderer implements TableCellRenderer { 340 public Component getTableCellRendererComponent(JTable table, 341 Object Value, boolean isSelected, boolean hasFocus, int row, 342 int column) { 343 // System.out.println("value in ===================== is "+Value); 344 String[] itemList = new String[1]; 345 if (Value == null) { 346 itemList[0] = ""; 347 } else { 348 itemList[0] = Value.toString(); 349 } 350 JComboBox renderer = new JComboBox(itemList); 351 renderer.setSelectedIndex(0); 352 renderer.setBackground(Color.WHITE); 353 return renderer; 354 } 355 } 356 357 /* 358 * This class will add listener to pop up a right click menu - deleting this 359 * row 360 */ 361 protected class PopupListener extends MouseAdapter { 362 // on the Mac, popups are triggered on mouse pressed, while 363 // mouseReleased triggers them on the PC; use the trigger flag to 364 // record a trigger, but do not show popup until the 365 // mouse released event 366 private boolean trigger = false; 367 private DBSelectTableUIBase table; 368 369 public PopupListener(DBSelectTableUIBase table) { 370 this.table = table; 371 } 372 373 /** 374 * Description of the Method 375 * 376 *@param e 377 * Description of the Parameter 378 */ 379 public void mousePressed(MouseEvent e) { 380 // maybeShowPopup(e); 381 if (e.isPopupTrigger()) { 382 trigger = true; 383 } 384 } 385 386 /** 387 * Description of the Method 388 * 389 *@param e 390 * Description of the Parameter 391 */ 392 public void mouseReleased(MouseEvent e) { 393 maybeShowPopup(e); 394 } 395 396 /** 397 * Description of the Method 398 * 399 *@param e 400 * Description of the Parameter 401 */ 402 private void maybeShowPopup(MouseEvent e) { 403 if ((e.isPopupTrigger()) || (trigger) && table != null 404 && mModel != null) { 405 // System.out.println("start in myabe show popup"); 406 trigger = false; 407 int selectedRow = table 408 .rowAtPoint(new Point(e.getX(), e.getY())); 409 // System.out.println("the selected row number is "+selectedRow); 410 int rowLength = mModel.getRowCount(); 411 // System.out.println("the row number in the model is "+rowLength); 412 // the last row wouldn't popup a deletion menu because 413 // it is 414 if ((selectedRow != rowLength - 1)) { 415 DBSelectTableModelStd stdModel = (DBSelectTableModelStd) mModel; 416 // System.out.println("in generate pop menu (pass selected != rowLength"); 417 DBSelectTableModelDeleteAction deleteAction = new DBSelectTableModelDeleteAction( 418 "Delete", table, stdModel, selectedRow); 419 JPopupMenu popup = new JPopupMenu(); 420 ; 421 JMenuItem deletionMenuItem = new JMenuItem(deleteAction); 422 deletionMenuItem.setBackground(Color.LIGHT_GRAY); 423 popup.add(deletionMenuItem); 424 popup.show(e.getComponent(), e.getX(), e.getY()); 425 426 } 427 } 428 } 429 } 430 431}