001 /* 002 * CRIMSON 003 * Copyright (c) 2006, Stephen Fisher, Susan Davidson, and Junhyong Kim, 004 * University of Pennsylvania. 005 * 006 * This program is free software; you can redistribute it and/or 007 * modify it under the terms of the GNU General Public License as 008 * published by the Free Software Foundation; either version 2 of the 009 * License, or (at your option) any later version. 010 * 011 * This program is distributed in the hope that it will be useful, but 012 * WITHOUT ANY WARRANTY; without even the implied warranty of 013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 014 * General Public License for more details. 015 * 016 * You should have received a copy of the GNU General Public License 017 * along with this program; if not, write to the Free Software 018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 019 * 02110-1301 USA. 020 * 021 * @(#)QueryManager.java 022 */ 023 024 package edu.upenn.crimson.gui; 025 026 import edu.upenn.crimson.*; 027 import edu.upenn.crimson.io.*; 028 import java.awt.*; 029 import java.awt.event.*; 030 import javax.swing.*; 031 import javax.swing.event.*; 032 import javax.swing.border.Border; 033 import java.io.File; 034 035 /** 036 * Browse existing Queries. 037 * 038 * @author Stephen Fisher 039 * @version $Id: QueryManager.java,v 1.44 2007/06/14 19:48:42 fisher Exp $ 040 */ 041 042 public class QueryManager { 043 private static PanelFrame panelFrame = null; 044 045 /** Only allow one instance of PanelFrame. */ 046 public static JFrame show() { 047 if (panelFrame == null) panelFrame = new PanelFrame(); 048 panelFrame.setVisible(true); 049 return panelFrame; 050 } 051 052 private static class PanelFrame extends JFrame { 053 /** List of all queries in current database. */ 054 private JTable table; 055 private QueryTableModel tableModel; 056 057 /** Reference to the selected query. */ 058 private Query query = null; 059 private String treeID = ""; 060 private JLabel notesL = new JLabel(""); 061 062 private JTextField fileNameTF = new JTextField(10); 063 private JButton fileBrowseB; 064 private JCheckBox fileIntSeqCB = new JCheckBox("Include Internal Sequence"); 065 // start = 1, min = 1, max = 100, step = 1 066 private JSpinner fileRepeatS = new JSpinner(new SpinnerNumberModel(1, 1, 100, 1)); 067 068 private JButton newB; 069 private JButton copyB; 070 private JButton loadB; 071 private JButton publishB; 072 private JButton importB; 073 private JButton exportB; 074 private JButton viewB; 075 private JButton editB; 076 private JButton runB; 077 private JButton deleteB; 078 private JButton closeB; 079 private JLabel statusBar; 080 081 PanelFrame thisFrame; 082 083 public PanelFrame() { 084 super("Query Manager"); 085 086 // keep pointer to self so can 'dispose' Frame below 087 thisFrame = this; 088 089 setDefaultCloseOperation(DISPOSE_ON_CLOSE); 090 091 // if no database connection then error 092 if (! Database.isOpen()) { 093 CrimsonUtils.printError("Must open a database before opening the query manager."); 094 setVisible(false); 095 return; 096 } 097 098 // ************************************************* 099 // CREATE VARIOUS BORDERS 100 Border emptyBorder = BorderFactory.createEmptyBorder(5,5,5,5); 101 Border loweredBorder = BorderFactory.createLoweredBevelBorder(); 102 Border raisedBorder = BorderFactory.createRaisedBevelBorder(); 103 Border etchedBorder = BorderFactory.createEtchedBorder(); 104 Border etchedPadBorder5 = 105 BorderFactory.createCompoundBorder(etchedBorder, emptyBorder); 106 Border loweredPadBorder5 = 107 BorderFactory.createCompoundBorder(loweredBorder, emptyBorder); 108 Border etchedPadBorder10 = 109 BorderFactory.createCompoundBorder(etchedBorder, 110 BorderFactory.createEmptyBorder(0,10,10,10)); 111 Border raisedPadBorder = 112 BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(1,1,2,1), 113 raisedBorder); 114 115 // ************************************************* 116 // TOOLBAR SETUP 117 JToolBar toolBar = new JToolBar(); 118 toolBar.setFloatable(false); 119 JToolBar toolBarR = new JToolBar(); 120 toolBarR.setFloatable(false); 121 // add Buttons 122 newB = new JButton(new ImageIcon("icons/new.png")); 123 newB.setToolTipText("New"); 124 newB.addMouseListener(new MouseAdapter() { 125 // add status bar text when mouse moves over button 126 public void mouseEntered(MouseEvent e) { statusBar.setText("Create a new query"); } 127 // clear status bar when mouse moves off button 128 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 129 }); 130 newB.addActionListener(new ActionListener() { 131 public void actionPerformed(ActionEvent e) { 132 QueryUtils.newQuery(); 133 } 134 }); 135 loadB = new JButton(new ImageIcon("icons/load.png")); 136 loadB.setToolTipText("Load"); 137 loadB.addMouseListener(new MouseAdapter() { 138 // add status bar text when mouse moves over button 139 public void mouseEntered(MouseEvent e) { statusBar.setText("Load specified query from the database."); } 140 // clear status bar when mouse moves off button 141 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 142 }); 143 loadB.addActionListener(new ActionListener() { 144 public void actionPerformed(ActionEvent e) { 145 QueryUtils.loadQuery(); 146 } 147 }); 148 publishB = new JButton(new ImageIcon("icons/publish.png")); 149 publishB.setToolTipText("Publish"); 150 publishB.setEnabled(false); 151 publishB.addMouseListener(new MouseAdapter() { 152 // add status bar text when mouse moves over button 153 public void mouseEntered(MouseEvent e) { statusBar.setText("Save the selected query to the database."); } 154 // clear status bar when mouse moves off button 155 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 156 }); 157 publishB.addActionListener(new ActionListener() { 158 public void actionPerformed(ActionEvent e) { 159 if (query == null) return; 160 QueryUtils.publishQuery(query.getID()); 161 } 162 }); 163 importB = new JButton(new ImageIcon("icons/import.png")); 164 importB.setToolTipText("Import"); 165 importB.addMouseListener(new MouseAdapter() { 166 // add status bar text when mouse moves over button 167 public void mouseEntered(MouseEvent e) { statusBar.setText("Import a query from a text file."); } 168 // clear status bar when mouse moves off button 169 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 170 }); 171 importB.addActionListener(new ActionListener() { 172 public void actionPerformed(ActionEvent e) { 173 QueryUtils.importQuery(); 174 } 175 }); 176 exportB = new JButton(new ImageIcon("icons/export.png")); 177 exportB.setToolTipText("Export"); 178 exportB.setEnabled(false); 179 exportB.addMouseListener(new MouseAdapter() { 180 // add status bar text when mouse moves over button 181 public void mouseEntered(MouseEvent e) { statusBar.setText("Export the selected query to a text file."); } 182 // clear status bar when mouse moves off button 183 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 184 }); 185 exportB.addActionListener(new ActionListener() { 186 public void actionPerformed(ActionEvent e) { 187 if (query == null) return; 188 QueryUtils.exportQuery(query.getID()); 189 } 190 }); 191 viewB = new JButton(new ImageIcon("icons/view.png")); 192 viewB.setToolTipText("View"); 193 viewB.setEnabled(false); 194 viewB.addMouseListener(new MouseAdapter() { 195 // add status bar text when mouse moves over button 196 public void mouseEntered(MouseEvent e) { statusBar.setText("View the selected query."); } 197 // clear status bar when mouse moves off button 198 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 199 }); 200 viewB.addActionListener(new ActionListener() { 201 public void actionPerformed(ActionEvent e) { 202 if (query == null) return; 203 Root.runCommand("viewQuery(\"" + query.getID() + "\")"); 204 } 205 }); 206 copyB = new JButton(new ImageIcon("icons/copy.png")); 207 copyB.setToolTipText("Duplicate"); 208 copyB.setEnabled(false); 209 copyB.addMouseListener(new MouseAdapter() { 210 // add status bar text when mouse moves over button 211 public void mouseEntered(MouseEvent e) { statusBar.setText("Duplicate the selected query"); } 212 // clear status bar when mouse moves off button 213 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 214 }); 215 copyB.addActionListener(new ActionListener() { 216 public void actionPerformed(ActionEvent e) { 217 // clone the query and then open in edit window 218 if (query == null) return; 219 String id = QueryUtils.getQueryID(ObjectHandles.randomQueryID(query.getID() + "_")); 220 if (! CrimsonUtils.isEmpty(id)) query.clone(id); 221 } 222 }); 223 editB = new JButton(new ImageIcon("icons/edit.png")); 224 editB.setToolTipText("Edit"); 225 editB.setEnabled(false); 226 editB.addMouseListener(new MouseAdapter() { 227 // add status bar text when mouse moves over button 228 public void mouseEntered(MouseEvent e) { statusBar.setText("Edit the selected query"); } 229 // clear status bar when mouse moves off button 230 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 231 }); 232 editB.addActionListener(new ActionListener() { 233 public void actionPerformed(ActionEvent e) { 234 if (query == null) return; 235 // QueryUtils.editQuery(query.getID()); 236 Root.runCommand("editQuery(\"" + query.getID() + "\")", false); 237 new QueryEditor(query, fileNameTF.getText(), 238 fileIntSeqCB.isSelected(), 239 ((Integer) fileRepeatS.getValue()).intValue()); 240 } 241 }); 242 runB = new JButton(new ImageIcon("icons/run.png")); 243 runB.setToolTipText("Run query"); 244 runB.addMouseListener(new MouseAdapter() { 245 // add status bar text when mouse moves over button 246 public void mouseEntered(MouseEvent e) { statusBar.setText("Run the selected query"); } 247 // clear status bar when mouse moves off button 248 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 249 }); 250 runB.addActionListener(new ActionListener() { 251 public void actionPerformed(ActionEvent e) { 252 if (query == null) return; 253 254 QueryUtils.runQuery(query.getID(), fileNameTF.getText(), 255 fileIntSeqCB.isSelected(), 256 ((Integer) fileRepeatS.getValue()).intValue()); 257 /* 258 String cmd = "runQuery(\"" + query.getID() + "\", \""; 259 cmd += fileNameTF.getText() + "\", "; 260 cmd += (fileIntSeqCB.isSelected()) ? "1, " : "0, "; 261 cmd += ((Integer) fileRepeatS.getValue()).toString() + ")"; 262 Root.runCommand(cmd); 263 */ 264 } 265 }); 266 deleteB= new JButton(new ImageIcon("icons/delete.png")); 267 deleteB.setToolTipText("Delete Tree"); 268 deleteB.setEnabled(false); 269 deleteB.addMouseListener(new MouseAdapter() { 270 // add status bar text when mouse moves over button 271 public void mouseEntered(MouseEvent e) { statusBar.setText("PERMANENTLY DELETE THE SELECTED QUERY"); } 272 // clear status bar when mouse moves off button 273 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 274 }); 275 deleteB.addActionListener(new ActionListener() { 276 public void actionPerformed(ActionEvent e) { 277 if (query == null) return; 278 QueryUtils.deleteQuery(query.getID()); 279 } 280 }); 281 closeB = new JButton(new ImageIcon("icons/close.png")); 282 closeB.setToolTipText("Close"); 283 closeB.addMouseListener(new MouseAdapter() { 284 // add status bar text when mouse moves over button 285 public void mouseEntered(MouseEvent e) { statusBar.setText("Close the query manager"); } 286 // clear status bar when mouse moves off button 287 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 288 }); 289 closeB.addActionListener(new ActionListener() { 290 public void actionPerformed(ActionEvent e) { 291 thisFrame.setVisible(false); 292 } 293 }); 294 // add ToolBar 295 toolBar.addSeparator(new Dimension(15, 0)); 296 toolBar.add(newB); 297 toolBar.addSeparator(new Dimension(30, 25)); 298 toolBar.add(copyB); 299 toolBar.addSeparator(new Dimension(30, 25)); 300 toolBar.add(loadB); 301 toolBar.addSeparator(new Dimension(30, 25)); 302 toolBar.add(publishB); 303 toolBar.addSeparator(new Dimension(30, 25)); 304 toolBar.add(importB); 305 toolBar.addSeparator(new Dimension(30, 25)); 306 toolBar.add(exportB); 307 toolBar.addSeparator(new Dimension(30, 25)); 308 toolBar.add(viewB); 309 toolBar.addSeparator(new Dimension(30, 25)); 310 toolBar.add(editB); 311 toolBar.addSeparator(new Dimension(30, 25)); 312 toolBar.add(runB); 313 toolBar.addSeparator(new Dimension(15, 0)); 314 toolBarR.addSeparator(new Dimension(15, 0)); 315 toolBarR.add(deleteB); 316 toolBarR.addSeparator(new Dimension(30, 25)); 317 toolBarR.add(closeB); 318 toolBarR.addSeparator(new Dimension(15, 0)); 319 // END TOOLBAR SETUP 320 // ************************************************* 321 322 // ************************************************* 323 // TABLE SETUP 324 tableModel = ObjectHandles.getQueryTableModel(); 325 table = new JTable(tableModel); 326 table.setPreferredScrollableViewportSize(new Dimension(500, 70)); 327 table.setColumnSelectionAllowed(false); 328 // table.setShowGrid(true); 329 // table.setShowHorizontalLines(true); 330 table.setShowVerticalLines(false); 331 // this should disallow rearranging cols 332 table.setDragEnabled(false); 333 // add the table to a scrollPane 334 JScrollPane tableSP = new JScrollPane(table); 335 tableSP.setBorder(etchedBorder); 336 /* 337 TableColumn column = null; 338 for (int i = 0; i < tableModel.getColumnCount(); i++) { 339 column = table.getColumnModel().getColumn(i); 340 // first 2 columns should be smaller 341 if (i < 2) column.setPreferredWidth(10); 342 else column.setPreferredWidth(100); 343 } 344 */ 345 346 // ***** SETUP TABLE LISTENER ***** 347 DefaultListSelectionModel dlsm = new DefaultListSelectionModel(); 348 table.setSelectionModel(dlsm); 349 // only allow single item selection 350 dlsm.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 351 dlsm.addListSelectionListener(new ListSelectionListener() { 352 public void valueChanged(ListSelectionEvent e) { 353 if (e.getValueIsAdjusting()) return; 354 355 if ((table.getRowCount() > 0) 356 && (table.getSelectedRowCount() > 0)) { 357 // an item is selected 358 query = tableModel.getRow(table.getSelectedRow()); 359 treeID = query.getTreeID(); 360 361 // setup notesL 362 notesL.setText(" " + query.getNotes()); 363 // notesL.setCaretPosition(0); // move cursor to begin of field 364 365 publishB.setEnabled(true); 366 exportB.setEnabled(true); 367 copyB.setEnabled(true); 368 viewB.setEnabled(true); 369 editB.setEnabled(true); 370 deleteB.setEnabled(true); 371 runB.setEnabled(true); 372 } else { 373 query = null; 374 treeID = ""; 375 376 // empty notesTF 377 notesL.setText(""); 378 379 publishB.setEnabled(false); 380 exportB.setEnabled(false); 381 copyB.setEnabled(false); 382 viewB.setEnabled(false); 383 editB.setEnabled(false); 384 deleteB.setEnabled(false); 385 runB.setEnabled(false); 386 } 387 } 388 }); 389 // END TABLE SETUP 390 // ************************************************* 391 392 // ************************************************* 393 // QUERY NOTES INFO SETUP 394 JPanel notesP = new JPanel(new BorderLayout()); 395 notesP.setBorder(etchedPadBorder5); 396 notesP.add(new JLabel("Notes: "), BorderLayout.WEST); 397 notesL.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(0,0,0,5), 398 loweredBorder)); 399 notesP.add(notesL, BorderLayout.CENTER); 400 // END QUERY NOTES INFO SETUP 401 // ************************************************* 402 403 // ************************************************* 404 // FILE INFO SETUP 405 JPanel fileInfoP = new JPanel(new BorderLayout()); 406 fileInfoP.setBorder(emptyBorder); 407 408 // file browse button 409 fileBrowseB = new JButton("Browse..."); 410 fileBrowseB.addMouseListener(new MouseAdapter() { 411 // add status bar text when mouse moves over button 412 public void mouseEntered(MouseEvent e) { statusBar.setText("Browse the operating system for a file to store the query."); } 413 // clear status bar when mouse moves off button 414 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 415 }); 416 fileBrowseB.addActionListener(new ActionListener() { 417 public void actionPerformed(ActionEvent e) { 418 String name = fileNameTF.getText(); 419 420 if (CrimsonUtils.isEmpty(name)) { 421 // no current name so use queryID and 422 // treeID to create a default name 423 if (query != null) { 424 name = query.getID(); 425 if (! CrimsonUtils.isEmpty(query.getTreeID())) { 426 name += "_" + query.getTreeID(); 427 } 428 } 429 } 430 File file = GUIUtils.saveFileChooser("Select Output NEXUS File", name, null); 431 fileNameTF.setText(GUIUtils.getFilename(file)); 432 } 433 }); 434 435 // Output filename 436 JPanel fileP = new JPanel(new GridLayout(0,1,0,5)); 437 fileP.setBorder(BorderFactory.createTitledBorder(etchedBorder, "Output File")); 438 fileNameTF.setBorder(loweredBorder); 439 fileP.add(fileNameTF); 440 fileP.add(fileBrowseB); 441 fileInfoP.add(fileP, BorderLayout.NORTH); 442 443 // Number of Repeats 444 JPanel fileRepeatP = new JPanel(new GridLayout(0,1,0,5)); 445 fileRepeatP.setBorder(BorderFactory.createTitledBorder(etchedBorder, "Number of Query Runs")); 446 fileRepeatS.setBorder(loweredBorder); 447 fileRepeatP.add(fileRepeatS); 448 449 JPanel fileCtrlP = new JPanel(new GridLayout(0,1,0,5)); 450 fileCtrlP.add(fileIntSeqCB); 451 fileCtrlP.add(fileRepeatP); 452 fileInfoP.add(fileCtrlP, BorderLayout.SOUTH); 453 // END FILE INFO SETUP 454 // ************************************************* 455 456 // ************************************************* 457 // STATUS BAR SETUP 458 JLabel statusBarSpacer = new JLabel(" "); 459 statusBar = new JLabel(" "); 460 JPanel statusBarP = new JPanel(false); 461 statusBarP.setBorder(loweredBorder); 462 statusBarP.setLayout(new BorderLayout()); 463 statusBarP.add(statusBarSpacer, BorderLayout.WEST); 464 statusBarP.add(statusBar, BorderLayout.CENTER); 465 // END STATUS BAR SETUP 466 // ************************************************* 467 468 // setup options panel 469 JPanel optionsP = new JPanel(new BorderLayout()); 470 optionsP.setBorder(etchedPadBorder5); 471 optionsP.add(fileInfoP, BorderLayout.CENTER); 472 473 // setup main panel 474 JPanel listP = new JPanel(new BorderLayout()); 475 listP.add(tableSP, BorderLayout.CENTER); 476 listP.add(optionsP, BorderLayout.EAST); 477 listP.add(notesP, BorderLayout.SOUTH); 478 479 // this will keep the toolbar on the left and right edges 480 Box box = Box.createHorizontalBox(); 481 box.add(toolBar); 482 box.add(Box.createHorizontalGlue()); 483 box.add(toolBarR); 484 485 getContentPane().add(box, BorderLayout.NORTH); 486 getContentPane().add(listP, BorderLayout.CENTER); 487 getContentPane().add(statusBarP, BorderLayout.SOUTH); 488 pack(); 489 490 // set the default window size 491 setSize(getSize().width, getSize().height + 100); 492 493 // display the window 494 setVisible(true); 495 } 496 } 497 } // QueryManager.java 498