001 /* 002 * Copyright 2007, 2012 Stephen Fisher and Junhyong Kim, University of 003 * Pennsylvania. 004 * 005 * This file is part of Glo-DB. 006 * 007 * Glo-DB is free software: you can redistribute it and/or modify it 008 * under the terms of the GNU General Public License as published by 009 * the Free Software Foundation, either version 3 of the License, or 010 * (at your option) any later version. 011 * 012 * Glo-DB is distributed in the hope that it will be useful, but 013 * WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * General Public License for more details. 016 * 017 * You should have received a copy of the GNU General Public License 018 * along with Glo-DB. If not, see <http://www.gnu.org/licenses/>. 019 * 020 * @(#)TrackBrowser.java 021 */ 022 023 package edu.upenn.gloDB.gui; 024 025 import edu.upenn.gloDB.*; 026 import java.awt.*; 027 import java.awt.event.*; 028 import javax.swing.*; 029 import javax.swing.event.*; 030 import java.util.StringTokenizer; 031 import java.util.HashMap; 032 import java.util.TreeSet; 033 import java.util.Set; 034 import java.util.Iterator; 035 import java.util.ArrayList; 036 037 /** 038 * Browse existing Tracks. 039 * 040 * @author Stephen Fisher 041 * @version $Id: TrackBrowser.java,v 1.1.2.20 2007/03/01 21:17:33 fisher Exp $ 042 */ 043 044 public class TrackBrowser { 045 private static BrowserFrame browserFrame = null; 046 047 public static JFrame show() { 048 return show(""); 049 } 050 051 public static JFrame show(String id) { 052 // only allow one instance of BrowserFrame 053 if (browserFrame == null) browserFrame = new BrowserFrame(); 054 055 browserFrame.selectTrack(id); 056 browserFrame.show(); 057 058 return browserFrame; 059 } 060 061 private static class BrowserFrame extends JFrame { 062 /** 063 * This is the total number of features that will be displayed in 064 * the feature list. 065 */ 066 private final long MAX_FEATURES = 40000; 067 068 private JComboBox trackCB; 069 private JList attributeL; 070 private JButton addAttributeB; 071 private JButton editAttributeB; 072 private JButton delAttributeB; 073 private JList sequenceL; 074 private JList featureL; 075 private JLabel statusBar; 076 077 private JLabel numFeaturesL = new JLabel(""); 078 private JLabel contiguousL = new JLabel(""); 079 private JLabel minL = new JLabel(""); 080 private JLabel maxL = new JLabel(""); 081 private JLabel lengthL = new JLabel(""); 082 083 private Track track; 084 private Object[] sequences; 085 private Object[] features; 086 087 BrowserFrame thisFrame; 088 089 // public BrowserFrame(String id) { 090 public BrowserFrame() { 091 super("Track Browser"); 092 // keep pointer to self so can 'dispose' Frame below 093 thisFrame = this; 094 095 setDefaultCloseOperation(HIDE_ON_CLOSE); 096 097 // ***** SETUP TRACK INFO ***** 098 JToolBar trackP = new JToolBar(); 099 trackP.setFloatable(false); 100 trackP.setBorder(BorderFactory.createEtchedBorder()); 101 // add Track ComboBox 102 trackCB = new JComboBox(ObjectHandles.getTrackList()); 103 trackCB.setEditable(false); 104 // selectTrack(""); 105 trackCB.addActionListener(new ActionListener() { 106 public void actionPerformed(ActionEvent e) { 107 String selection = (String) ((JComboBox) e.getSource()).getSelectedItem(); 108 trackSelected(selection); 109 } 110 }); 111 // add Buttons 112 JButton loadB = new JButton(new ImageIcon("icons/load.png")); 113 loadB.setToolTipText("Load"); 114 loadB.addMouseListener(new MouseAdapter() { 115 // add status bar text when mouse moves over button 116 public void mouseEntered(MouseEvent e) { statusBar.setText("Load track"); } 117 // clear status bar when mouse moves off button 118 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 119 }); 120 loadB.addActionListener(new ActionListener() { 121 public void actionPerformed(ActionEvent e) { 122 Cursor hourglassCursor = new Cursor(Cursor.WAIT_CURSOR); 123 setCursor(hourglassCursor); 124 Track track = GUITrackIO.loadTrack(); 125 Cursor normalCursor = new Cursor(Cursor.DEFAULT_CURSOR); 126 setCursor(normalCursor); 127 if (track != null) { 128 trackCB.setSelectedIndex(ObjectHandles.getTrackList().getIndexOf(track.getID())); 129 } 130 } 131 }); 132 JButton saveB = new JButton(new ImageIcon("icons/save.png")); 133 saveB.setToolTipText("Save"); 134 saveB.addMouseListener(new MouseAdapter() { 135 // add status bar text when mouse moves over button 136 public void mouseEntered(MouseEvent e) { statusBar.setText("Save track"); } 137 // clear status bar when mouse moves off button 138 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 139 }); 140 saveB.addActionListener(new ActionListener() { 141 public void actionPerformed(ActionEvent e) { 142 if (track != null) GUITrackIO.saveTrack(track.getID()); 143 } 144 }); 145 JButton viewB = new JButton(new ImageIcon("icons/view.png")); 146 viewB.setToolTipText("View Data"); 147 viewB.addMouseListener(new MouseAdapter() { 148 // add status bar text when mouse moves over button 149 public void mouseEntered(MouseEvent e) { statusBar.setText("View track data"); } 150 // clear status bar when mouse moves off button 151 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 152 }); 153 viewB.addActionListener(new ActionListener() { 154 public void actionPerformed(ActionEvent e) { 155 if (track != null) new ViewSequencePanel(); 156 } 157 }); 158 // add info "rename" button 159 JButton renameB= new JButton(new ImageIcon("icons/rename.png")); 160 renameB.setToolTipText("Rename"); 161 renameB.addMouseListener(new MouseAdapter() { 162 // add status bar text when mouse moves over button 163 public void mouseEntered(MouseEvent e) { statusBar.setText("Rename track"); } 164 // clear status bar when mouse moves off button 165 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 166 }); 167 renameB.addActionListener(new ActionListener() { 168 public void actionPerformed(ActionEvent e) { 169 if (track != null) { 170 String id = GUIUtils.renameTrack(track.getID()); 171 trackCB.setSelectedIndex(ObjectHandles.getTrackList().getIndexOf(id)); 172 } 173 } 174 }); 175 // add info "remove" button 176 JButton deleteB= new JButton(new ImageIcon("icons/delete.png")); 177 deleteB.setToolTipText("Delete"); 178 deleteB.addMouseListener(new MouseAdapter() { 179 // add status bar text when mouse moves over button 180 public void mouseEntered(MouseEvent e) { statusBar.setText("THIS WILL PERMANENTLY DELETE THE TRACK!"); } 181 // clear status bar when mouse moves off button 182 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 183 }); 184 deleteB.addActionListener(new ActionListener() { 185 public void actionPerformed(ActionEvent e) { 186 if (track == null) return; 187 188 String msg = "Are you sure you want to remove this track?\n"; 189 msg += "Track: " + track.getID(); 190 Object[] options = {"Delete Track", "Cancel"}; 191 int flag = JOptionPane.showOptionDialog(null, msg, 192 "Delete Confirmation", 193 JOptionPane.YES_NO_OPTION, 194 JOptionPane.QUESTION_MESSAGE, 195 null, 196 options, 197 options[1]); 198 if (flag == JOptionPane.YES_OPTION) { // "Delete" 199 Root.runCommand("removeTrack(\"" + track.getID() + "\")", true); 200 // ObjectHandles.removeTrack(track); 201 if (trackCB.getItemCount() > 0) { 202 trackCB.setSelectedIndex(0); 203 } else { 204 trackSelected(null); 205 } 206 } 207 } 208 }); 209 JButton closeB = new JButton(new ImageIcon("icons/close.png")); 210 closeB.setToolTipText("Close"); 211 closeB.addMouseListener(new MouseAdapter() { 212 // add status bar text when mouse moves over button 213 public void mouseEntered(MouseEvent e) { statusBar.setText("Close the track browser"); } 214 // clear status bar when mouse moves off button 215 public void mouseExited(MouseEvent e) { statusBar.setText(""); } 216 }); 217 closeB.addActionListener(new ActionListener() { 218 public void actionPerformed(ActionEvent e) { 219 thisFrame.hide(); 220 } 221 }); 222 // add Track Label 223 trackP.addSeparator(new Dimension(15, 0)); 224 trackP.add(loadB); 225 trackP.addSeparator(new Dimension(30, 25)); 226 trackP.add(saveB); 227 trackP.addSeparator(new Dimension(30, 25)); 228 trackP.add(new JLabel("Track: ")); 229 trackP.add(trackCB); 230 trackP.addSeparator(new Dimension(15, 0)); 231 trackP.add(viewB); 232 trackP.addSeparator(new Dimension(30, 25)); 233 trackP.add(renameB); 234 trackP.addSeparator(new Dimension(30, 25)); 235 trackP.add(deleteB); 236 trackP.addSeparator(new Dimension(30, 25)); 237 trackP.add(closeB); 238 trackP.addSeparator(new Dimension(15, 0)); 239 240 // ***** SETUP ATTRIBUTE INFO ***** 241 JPanel attributeP = new JPanel(new BorderLayout()); 242 // add attributes List 243 attributeL = new JList(); 244 attributeL.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 245 attributeL.addListSelectionListener(new ListSelectionListener() { 246 public void valueChanged(ListSelectionEvent e) { 247 if (e.getValueIsAdjusting()) return; 248 249 JList list = (JList) e.getSource(); 250 if (list.isSelectionEmpty()) { 251 // disable the "Delete" button if no selection 252 editAttributeB.setEnabled(false); 253 delAttributeB.setEnabled(false); 254 } else { 255 // enable the "Delete" button if something selected 256 editAttributeB.setEnabled(true); 257 delAttributeB.setEnabled(true); 258 } 259 } 260 }); 261 JScrollPane attributeSP = new JScrollPane(attributeL); 262 attributeP.add(attributeSP, BorderLayout.CENTER); 263 // add button sub-panel 264 JPanel attributeBP = new JPanel(new GridLayout(1,0,5,5)); 265 // add attributes "add" Button 266 addAttributeB = new JButton(new ImageIcon("icons/new.png")); 267 addAttributeB.setToolTipText("Add New Attribute"); 268 addAttributeB.addActionListener(new ActionListener() { 269 public void actionPerformed(ActionEvent e) { 270 if (track == null) return; 271 272 String[] labels = {" Key:", " Value:"}; 273 // use this to get the return value from FieldEditDialog 274 ArrayList textFields = new ArrayList(); 275 textFields.add(new JTextField(20)); 276 textFields.add(new JTextField(20)); 277 new FieldEditDialog("Add Attribute", labels, textFields); 278 279 // check "exit code" for FieldEditDialog, if false then exit 280 Boolean exitCode = (Boolean) textFields.get(textFields.size()-1); 281 if (! exitCode.booleanValue()) return; 282 283 JTextField tf = (JTextField) textFields.get(0); 284 String key = tf.getText(); 285 if (key.length() > 0) { // make sure a key is valid 286 tf = (JTextField) textFields.get(1); // get value 287 String value = tf.getText(); 288 String msg = "getTrack(\"" + track.getID() + "\")"; 289 msg += ".addAttribute(\"" + key + "\", \"" + value + "\")"; 290 Root.runCommand(msg, true); 291 updateAttributes(); 292 } 293 } 294 }); 295 attributeBP.add(addAttributeB); 296 // add attributes "edit" Button 297 editAttributeB = new JButton(new ImageIcon("icons/edit.png")); 298 editAttributeB.setToolTipText("Edit Attribute"); 299 editAttributeB.setEnabled(false); 300 editAttributeB.addActionListener(new ActionListener() { 301 public void actionPerformed(ActionEvent e) { 302 StringTokenizer st = new StringTokenizer((String) 303 attributeL.getSelectedValue(), 304 ":", true); 305 String key = st.nextToken(); 306 String value = st.nextToken(); // this is the ":" 307 value = st.nextToken(); // this is the actual value 308 value = value.substring(1, value.length()); // remove leading " " 309 // add any remaining tokens 310 while (st.hasMoreTokens()) { 311 value += st.nextToken(); 312 } 313 314 String[] labels = {" Key:", " Value:"}; 315 // use this to get the return value from FieldEditDialog 316 ArrayList textFields = new ArrayList(); 317 JTextField tf = new JTextField(20); 318 tf.setText(key); 319 tf.setEditable(false); 320 textFields.add(tf); 321 tf = new JTextField(20); 322 tf.setText(value); 323 textFields.add(tf); 324 new FieldEditDialog("Edit Attribute", labels, textFields); 325 326 // check "exit code" for FieldEditDialog, if false then exit 327 Boolean exitCode = (Boolean) textFields.get(textFields.size()-1); 328 if (! exitCode.booleanValue()) return; 329 330 tf = (JTextField) textFields.get(1); 331 String newValue = tf.getText(); 332 if (value.compareTo(newValue) != 0) { // make sure value changed 333 String msg = "getTrack(\"" + track.getID() + "\")"; 334 msg += ".addAttribute(\"" + key + "\", \"" + newValue + "\")"; 335 Root.runCommand(msg, true); 336 updateAttributes(); 337 } 338 } 339 }); 340 attributeBP.add(editAttributeB); 341 // add attributes "delete" Button 342 delAttributeB = new JButton(new ImageIcon("icons/delete.png")); 343 delAttributeB.setToolTipText("Delete Attribute"); 344 delAttributeB.setEnabled(false); 345 delAttributeB.addActionListener(new ActionListener() { 346 public void actionPerformed(ActionEvent e) { 347 String msg = "Are you sure you want to delete the following attribute?\n"; 348 msg += " " + attributeL.getSelectedValue(); 349 Object[] options = {"Delete Attribute", "Cancel"}; 350 int flag = JOptionPane.showOptionDialog(null, msg, 351 "Delete Confirmation", 352 JOptionPane.YES_NO_OPTION, 353 JOptionPane.QUESTION_MESSAGE, 354 null, 355 options, 356 options[1]); 357 if (flag == JOptionPane.YES_OPTION) { // "Delete" 358 StringTokenizer st = new StringTokenizer((String) 359 attributeL.getSelectedValue(), 360 ":"); 361 String key = st.nextToken(); 362 msg = "getTrack(\"" + track.getID() + "\")"; 363 msg += ".delAttribute(\"" + key + "\")"; 364 Root.runCommand(msg, true); 365 updateAttributes(); 366 } 367 } 368 }); 369 attributeBP.add(delAttributeB); 370 attributeP.add(attributeBP, BorderLayout.SOUTH); 371 // add attributes Label 372 attributeP.add(new JLabel(" Attributes:"), BorderLayout.NORTH); 373 // provide a preferred size for attributesP 374 attributeP.setPreferredSize(new Dimension(300, 200)); 375 376 // ***** SETUP TRACK SPECs ***** 377 JPanel infoP = new JPanel(new BorderLayout()); 378 // add info sub-panel 379 JPanel infoSP = new JPanel(new GridLayout(5,2,5,5)); 380 infoSP.add(new JLabel(" Min:")); 381 infoSP.add(minL); 382 infoSP.add(new JLabel(" Max:")); 383 infoSP.add(maxL); 384 infoSP.add(new JLabel(" Length:")); 385 infoSP.add(lengthL); 386 infoSP.add(new JLabel(" Num Features:")); 387 infoSP.add(numFeaturesL); 388 infoSP.add(new JLabel(" Contiguous:")); 389 infoSP.add(contiguousL); 390 infoP.add(infoSP, BorderLayout.CENTER); 391 // add button sub-panel 392 JPanel infoBP = new JPanel(new GridLayout(0,1,5,5)); 393 // add info "contiguous" button 394 JButton contiguousB = new JButton("Compute Contiguity"); 395 contiguousB.addActionListener(new ActionListener() { 396 public void actionPerformed(ActionEvent e) { 397 if (track != null) { 398 contiguousL.setText(Boolean.toString(track.isContiguous())); 399 } 400 } 401 }); 402 infoBP.add(contiguousB); 403 // add info "mergeContiguous" button 404 JButton mergeContiguousB = new JButton("Merge Contiguous"); 405 mergeContiguousB.addActionListener(new ActionListener() { 406 public void actionPerformed(ActionEvent e) { 407 if (track == null) return; 408 409 String msg = "Are you sure you want to merge all contiguous features?\n"; 410 msg += "This can not be undone."; 411 Object[] options = {"Merge", "Cancel"}; 412 int flag = JOptionPane.showOptionDialog(null, msg, 413 "Merge Confirmation", 414 JOptionPane.YES_NO_OPTION, 415 JOptionPane.QUESTION_MESSAGE, 416 null, 417 options, 418 options[1]); 419 if (flag == JOptionPane.YES_OPTION) { // "Merge" 420 // don't know why but the track order changes so 421 // need to reselect this track. thus save the 422 // ID and contiguous info. 423 String id = track.getID(); 424 String contiguous = contiguousL.getText(); 425 426 // XXX this should have a popup dialog that 427 // confirms this action 428 track.mergeContiguous(); 429 430 // reset the track 431 trackCB.setSelectedIndex(ObjectHandles.getTrackList().getIndexOf(id)); 432 contiguousL.setText(contiguous); 433 } 434 } 435 }); 436 infoBP.add(mergeContiguousB); 437 // add info "flip" button 438 /* 439 JButton flipB= new JButton("Flip Features"); 440 flipB.addActionListener(new ActionListener() { 441 public void actionPerformed(ActionEvent e) { 442 if (track == null) return; 443 GloDBUtils.printMsg("button not yet implemented"); 444 } 445 }); 446 infoBP.add(flipB); 447 */ 448 infoP.add(infoBP, BorderLayout.SOUTH); 449 450 // ***** SETUP SEQUENCE INFO ***** 451 JPanel sequenceP = new JPanel(new BorderLayout()); 452 // setup list of Sequences for selected Track 453 sequenceL = new JList(); 454 sequenceL.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 455 sequenceL.setToolTipText("Double click on a Sequence name to edit the item in a Sequence Browser"); 456 /* 457 sequenceL.addListSelectionListener(new ListSelectionListener() { 458 public void valueChanged(ListSelectionEvent e) { 459 if (e.getValueIsAdjusting()) return; 460 461 JList list = (JList) e.getSource(); 462 if (list.isSelectionEmpty()) { 463 statusBar.setText(""); 464 } else { 465 Sequence sequence = ObjectHandles.getSequence((String) sequences[list.getSelectedIndex()]); 466 String msg = "Sequence ID: " + sequence.getID(); 467 msg += " :: Length: " + sequence.length(); 468 msg += " :: Attributes: " + sequence.getAttributes(); 469 statusBar.setText(msg); 470 } 471 } 472 }); 473 */ 474 sequenceL.addMouseMotionListener(new MouseMotionListener() { 475 public void mouseMoved(MouseEvent e) { 476 int index = sequenceL.locationToIndex(e.getPoint()); 477 if (index > -1) { // make sure there is a valid item 478 Sequence sequence = ObjectHandles.getSequence((String) sequences[index]); 479 String msg = "Sequence ID: " + sequence.getID(); 480 if (sequence.isDataLoaded()) { 481 // only include length if data already 482 // loaded, else this will cause the 483 // Sequence data to be loaded which can 484 // take a long time 485 msg += " :: Length: " + sequence.length(); 486 } 487 msg += " :: Attributes: " + sequence.getAttributes(); 488 statusBar.setText(msg); 489 } 490 } 491 public void mouseDragged(MouseEvent e) { ; } 492 }); 493 sequenceL.addMouseListener(new MouseAdapter() { 494 // clear status bar when mouse moves out of sequenceL 495 public void mouseExited(MouseEvent e) { 496 statusBar.setText(""); 497 } 498 499 public void mouseClicked(MouseEvent e) { 500 if (e.getClickCount() == 2) { 501 int index = sequenceL.locationToIndex(e.getPoint()); 502 503 if (index > -1) { // make sure there is a valid item 504 // launch the Sequence Browser through Root so 505 // that the command gets added to the history. 506 String id = (String) sequences[index]; 507 String cmd = "sequenceBrowser(\"" + id + "\")"; 508 Root.runCommand(cmd, true); 509 /* 510 String msg = (ObjectHandles.getSequence((String) sequences[index])).toString(); 511 JOptionPane.showMessageDialog(null, msg, 512 "Sequence Viewer", 513 JOptionPane.INFORMATION_MESSAGE); 514 */ 515 } 516 } 517 } 518 }); 519 JScrollPane sequenceSP = new JScrollPane(sequenceL); 520 sequenceP.add(sequenceSP, BorderLayout.CENTER); 521 // add Sequence Label 522 sequenceP.add(new JLabel(" Sequences:"), BorderLayout.NORTH); 523 sequenceP.add(infoP, BorderLayout.SOUTH); 524 525 // ***** SETUP FEATURE INFO ***** 526 JPanel featureP = new JPanel(new BorderLayout()); 527 // setup list of Features for selected Track 528 featureL = new JList(); 529 featureL.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 530 featureL.setToolTipText("Double click on a Feature name to view the item's information"); 531 /* 532 featureL.addListSelectionListener(new ListSelectionListener() { 533 public void valueChanged(ListSelectionEvent e) { 534 if (e.getValueIsAdjusting()) return; 535 536 JList list = (JList) e.getSource(); 537 if (list.isSelectionEmpty()) { 538 GloDBUtils.printMsg("empty"); 539 } else { 540 GloDBUtils.printMsg(list.getSelectedIndex()); 541 } 542 } 543 }); 544 */ 545 featureL.addMouseListener(new MouseAdapter() { 546 public void mouseClicked(MouseEvent e) { 547 if (e.getClickCount() == 2) { 548 int index = featureL.locationToIndex(e.getPoint()); 549 if (index > -1) { // make sure there is a valid item 550 String msg = ((Feature) features[index]).toStringFull(); 551 JOptionPane.showMessageDialog(null, msg, 552 "Feature Viewer", 553 JOptionPane.INFORMATION_MESSAGE); 554 } 555 } 556 } 557 }); 558 JScrollPane featureSP = new JScrollPane(featureL); 559 featureP.add(featureSP, BorderLayout.CENTER); 560 // add Features Label 561 featureP.add(new JLabel(" Features:"), BorderLayout.NORTH); 562 563 // setup split pane for Sequence/Feature Panels 564 JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, 565 sequenceP, featureP); 566 splitPane.setOneTouchExpandable(true); 567 splitPane.setDividerLocation(200); 568 // provide minimum sizes for the two components in the split pane 569 Dimension minimumSize = new Dimension(150, 200); 570 sequenceP.setMinimumSize(minimumSize); 571 featureP.setMinimumSize(minimumSize); 572 // provide a preferred size for the split pane 573 splitPane.setPreferredSize(new Dimension(400, 200)); 574 575 // add status bar at bottom of window 576 JLabel statusBarSpacer = new JLabel(" "); 577 statusBar = new JLabel(" "); 578 JPanel statusBarP = new JPanel(false); 579 statusBarP.setBorder(BorderFactory.createLoweredBevelBorder()); 580 statusBarP.setLayout(new BorderLayout()); 581 statusBarP.add(statusBarSpacer, BorderLayout.WEST); 582 statusBarP.add(statusBar, BorderLayout.CENTER); 583 584 getContentPane().add(trackP, BorderLayout.NORTH); 585 getContentPane().add(attributeP, BorderLayout.WEST); 586 getContentPane().add(splitPane, BorderLayout.CENTER); 587 getContentPane().add(statusBarP, BorderLayout.SOUTH); 588 pack(); 589 590 // set the default window size 591 setSize(getSize().width + 100, getSize().height + 150); 592 593 // initialize the browser to the current Track 594 trackSelected((String) trackCB.getSelectedItem()); 595 596 // display the window 597 show(); 598 } 599 600 /** 601 * This will update the TrackBrowser for the currently selected 602 * Track. 603 */ 604 private void trackSelected(String id) { 605 if ((id == null) || (trackCB.getItemCount() == 0)) { 606 // if null item or empty list, then clear display 607 sequences = new Object[0]; 608 sequenceL.setListData(sequences); 609 features = new Object[0]; 610 featureL.setListData(features); 611 attributeL.setListData(new String[0]); 612 613 minL.setText(""); 614 maxL.setText(""); 615 lengthL.setText(""); 616 numFeaturesL.setText(""); 617 contiguousL.setText("uncomputed"); 618 619 // make sure this is reset if no items in list 620 track = null; 621 622 return; 623 } 624 625 track = ObjectHandles.getTrack(id); 626 627 updateAttributes(); 628 Set tmpSeq = track.getSourceSet(); 629 if (tmpSeq != null) { sequences = tmpSeq.toArray(); } 630 else { sequences = new Object[0]; } 631 sequenceL.setListData(sequences); 632 633 if (track.numFeatures() < MAX_FEATURES) { 634 TreeSet tmpFeat = track.getFeatures(); 635 if (tmpFeat != null) { features = tmpFeat.toArray(); } 636 else { features = new Object[0]; } 637 } else { 638 features = new Object[0]; 639 640 String msg = "Too many features to display in the feature selection list."; 641 GloDBUtils.printMsg(msg, GloDBUtils.WARNING); 642 } 643 featureL.setListData(features); 644 645 minL.setText(Integer.toString(track.getMin())); 646 maxL.setText(Integer.toString(track.getMax())); 647 lengthL.setText(Integer.toString(track.length())); 648 numFeaturesL.setText(Integer.toString(track.numFeatures())); 649 contiguousL.setText("uncomputed"); 650 } 651 652 /** 653 * This is separate from trackSelected() so it can be called 654 * separately for when the attributes are changed in the attribute 655 * panel. 656 */ 657 private void updateAttributes() { 658 // don't do anything if track not set 659 if (track == null) return; 660 661 HashMap attributes = track.getAttributes(); 662 if ((attributes == null) || (attributes.size() == 0)) { 663 attributeL.setListData(new String[0]); 664 } else { 665 String[] attributeArray = new String[attributes.size()]; 666 Set keys = attributes.keySet(); 667 int cnt = 0; 668 for (Iterator i = keys.iterator(); i.hasNext();) { 669 String key = (String) i.next(); 670 attributeArray[cnt] = key + ": " + attributes.get(key); 671 cnt++; 672 } 673 attributeL.setListData(attributeArray); 674 } 675 } 676 677 /** Displays the Sequence data. */ 678 class ViewSequencePanel extends JFrame { 679 ViewSequencePanel thisFrame; 680 681 public ViewSequencePanel() { 682 super("Sequence Data"); 683 684 // keep pointer to self so can 'dispose' Frame below 685 thisFrame = this; 686 687 setDefaultCloseOperation(DISPOSE_ON_CLOSE); 688 689 // setup text area to display data 690 JTextArea textArea = new JTextArea(track.getDataFASTA()); 691 if (textArea.getText().length() == 0) { 692 textArea.setText("No data, check sequence data source"); 693 } 694 textArea.setLineWrap(false); 695 textArea.setWrapStyleWord(false); 696 textArea.setEditable(false); 697 textArea.setFont(new Font("Courier", Font.PLAIN, 14)); 698 JScrollPane areaSP = new JScrollPane(textArea); 699 areaSP.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS); 700 areaSP.setPreferredSize(new Dimension(580, 300)); 701 702 // setup close button 703 JButton closeB = new JButton("Close Viewer"); 704 closeB.addActionListener(new ActionListener() { 705 public void actionPerformed(ActionEvent e) { 706 thisFrame.dispose(); 707 } 708 }); 709 710 getContentPane().setLayout(new BorderLayout()); 711 getContentPane().add(areaSP, BorderLayout.CENTER); 712 getContentPane().add(closeB, BorderLayout.SOUTH); 713 pack(); 714 715 // set the default window size 716 setSize(getSize().width + 100, getSize().height + 30); 717 718 // display the window 719 show(); 720 } 721 } 722 723 public void selectTrack(String id) { 724 if ((id.length() == 0) || (trackCB.getItemCount() == 0)) return; 725 int index = ObjectHandles.getTrackList().getIndexOf(id); 726 // only change selection if valid ID 727 if (index > -1) { 728 trackCB.setSelectedIndex(index); 729 } else { 730 GloDBUtils.printMsg("Invalid track id (\"" + id + "\").", GloDBUtils.WARNING); 731 } 732 } 733 } 734 } // TrackBrowser.java