- Timestamp:
- 2003-08-18T14:10:31+12:00 (21 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java
r5033 r5164 42 42 import javax.swing.*; 43 43 import javax.swing.event.*; 44 import javax.swing.text.*; 44 45 import org.greenstone.gatherer.Gatherer; 45 46 import org.greenstone.gatherer.cdm.Argument; … … 49 50 import org.greenstone.gatherer.collection.CollectionManager; 50 51 import org.greenstone.gatherer.msm.ElementWrapper; 52 import org.greenstone.gatherer.util.AppendLineOnlyFileDocument; 53 import org.greenstone.gatherer.util.AppendLineOnlyFileDocumentOwner; 51 54 import org.greenstone.gatherer.util.Utility; 52 55 //import org.w3c.dom.*; … … 55 58 * @version 2.2 56 59 */ 57 final public class OptionsPane 58 extends JPanel { 60 public class OptionsPane 61 extends JPanel 62 implements AppendLineOnlyFileDocumentOwner { 63 64 static final public char SUCCESSFUL = 's'; 65 static final public char UNSUCCESSFUL = 'u'; 66 static final public char CANCELLED = 'c'; 67 static final public char UNKNOWN = 'x'; 68 69 /** All process messages are written to this log text area. */ 70 public JTextArea log_textarea = null; 71 59 72 /** The <strong>BuildOptions</strong> data object contains all the option settings we wish to persist between Gatherer sessions (and thus is stored in <strong>Collection</strong>). */ 60 73 private BuildOptions build_options = null; 74 75 private FileEntry file_entry = null; 61 76 /** the log pane - we only create it once now, not each time */ 62 77 private JPanel log_pane = null; 63 78 /** the list of previous log messages */ 64 79 private JList log_list = null; 65 /** whether that currently showing log is changed or not */ 66 private boolean is_log_changed = false; 67 /** the list entry that is currently displayed */ 68 private FileEntry displayed_log = null; 69 /** a listener for changes in the log text */ 70 private LogChangeListener log_change_listener = null; 71 /** All process messages are written to this log text area. */ 72 private JTextArea log_display = null; 73 74 static final public char SUCCESSFUL = 's'; 75 static final public char UNSUCCESSFUL = 'u'; 76 static final public char CANCELLED = 'c'; 80 private Vector writing_documents; 77 81 78 82 static private int BUILD = 0; … … 88 92 89 93 /** The default constructor creates the few session length options, but either retrieves the rest from the current collection, or creates a default set of options. */ 90 public OptionsPane(JTextArea message_log, BuildOptions build_options) { 91 this.log_display = new JTextArea(message_log.getDocument()); 94 public OptionsPane(BuildOptions build_options) { 92 95 this.build_options = build_options; 93 this.log_change_listener = new LogChangeListener(); 94 //this.target_pane = target_pane; 95 } 96 97 /** creates a new log from the text in log. The new file is named 98 * build_log.<current time>.txt. A new FileEntry is added to teh log list 99 * and made selected. A fresh listener is added to teh document */ 100 public void addNewLog(char success) { 101 ///ystem.out.println("add new log"); 102 103 // create the file name 104 long time = System.currentTimeMillis(); 105 StringBuffer name = new StringBuffer(); 106 name.append("build_log."); 107 name.append(time); 108 name.append(success); 109 name.append(".txt"); 110 File f = new File(Gatherer.c_man.getCollectionLog()+name.toString()); 111 // just in case there is no log directory 112 File parent_file = f.getParentFile(); 113 parent_file.mkdirs(); 114 115 // save the log text to the file 116 saveLogFile(f); 117 is_log_changed=false; 118 log_display.getDocument().addDocumentListener(log_change_listener); 119 120 // create the file entry and add it to the list at pos 0 - it will always be the newest one created 121 FileEntry fe = new FileEntry(f); 122 ((DefaultListModel)log_list.getModel()).add(0, fe); 123 log_list.setSelectedIndex(0); 124 displayed_log = fe; 125 96 this.writing_documents = new Vector(); 97 98 // Have to do this here, not in display, as the message log view may not have been displayed yet. 99 log_textarea = new JTextArea(); 100 log_textarea.setEditable(false); 126 101 } 127 102 … … 134 109 pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 135 110 int build_argument_count = build_options.getBuildArgumentCount(); 136 pane.setLayout(new GridLayout(build_argument_count, 1, 0, 0)); 137 int total_height = PANE_SIZE.height; 111 pane.setPreferredSize(new Dimension(ROW_SIZE.width, ROW_SIZE.height * build_argument_count)); 138 112 for(int i = 0; i < build_argument_count; i++) { 139 113 // Retrieve the argument so we know how to format the control. … … 143 117 String value = build_options.getBuildValue(argument.getName()); 144 118 ArgumentControl argument_control = new ArgumentControl(BUILD, argument, enabled, value); 145 total_height = total_height - argument_control.getPreferredSize().height;146 119 pane.add(argument_control); 147 }148 if(total_height > 0) {149 JPanel filler = new JPanel();150 filler.setPreferredSize(new Dimension(100, total_height));151 filler.setSize(filler.getPreferredSize());152 pane.add(filler);153 120 } 154 121 return pane; … … 162 129 pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); 163 130 int import_argument_count = build_options.getImportArgumentCount(); 164 pane.setLayout(new GridLayout(import_argument_count, 1, 0, 0)); 165 int total_height = PANE_SIZE.height; 131 pane.setPreferredSize(new Dimension(ROW_SIZE.width, ROW_SIZE.height * import_argument_count)); 166 132 for(int i = 0; i < import_argument_count; i++) { 167 133 // Retrieve the argument so we know how to format the control. … … 171 137 String value = build_options.getImportValue(argument.getName()); 172 138 ArgumentControl argument_control = new ArgumentControl(IMPORT, argument, enabled, value); 173 total_height = total_height - argument_control.getPreferredSize().height;174 139 pane.add(argument_control); 175 }176 if(total_height > 0) {177 JPanel filler = new JPanel();178 filler.setPreferredSize(new Dimension(100, total_height));179 filler.setSize(filler.getPreferredSize());180 pane.add(filler);181 140 } 182 141 return pane; … … 195 154 File children[] = log_directory.listFiles(); 196 155 for(int i = 0; children != null && i < children.length; i++) { 197 if(children[i].getName().startsWith("build_log") &&children[i].getName().endsWith(".txt") ) {198 FileEntry entry = new FileEntry(children[i] );156 if(children[i].getName().startsWith("build_log") && children[i].getName().endsWith(".txt") ) { 157 FileEntry entry = new FileEntry(children[i].getName(), children[i].getAbsolutePath()); 199 158 // We are about to insert it. But where. 200 159 boolean found = false; 201 for(int j = 0; j < contents.size(); j++) {160 for(int j = 0; !found && j < contents.size(); j++) { 202 161 FileEntry sibling = (FileEntry) contents.getElementAt(j); 203 162 int order = entry.compareTo(sibling); … … 205 164 contents.insertElementAt(entry, j); 206 165 found = true; 207 break;208 166 } 209 167 } … … 217 175 log_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 218 176 log_list.setLayoutOrientation(JList.VERTICAL); 177 log_list.setPreferredSize(new Dimension(600, 100)); 219 178 log_list.setVisibleRowCount(3); 220 179 log_list.addListSelectionListener(new LogListListener()); 221 180 222 JScrollPane list_scroller = new JScrollPane(log_list);223 224 // If log is not empty and we have something in displayed_log - make that element selected225 if (log_display.getText().length()>0 && displayed_log != null) {226 int index = contents.indexOf(displayed_log);227 if (index != -1) {228 log_list.setSelectedIndex(index);229 }230 231 }232 233 log_pane.add(new JScrollPane(log_display), BorderLayout.CENTER);234 181 JLabel log_history_label = new JLabel(get("LogHistory")); 235 182 JPanel log_history_pane = new JPanel(); 236 183 log_history_pane.setPreferredSize(new Dimension(600, 100)); 237 184 log_history_pane.setLayout(new BorderLayout()); 238 185 log_history_pane.add(log_history_label, BorderLayout.NORTH); 239 log_history_pane.add( list_scroller, BorderLayout.SOUTH);186 log_history_pane.add(new JScrollPane(log_list), BorderLayout.CENTER); 240 187 188 log_pane.add(new JScrollPane(log_textarea), BorderLayout.CENTER); 241 189 log_pane.add(log_history_pane, BorderLayout.SOUTH); 242 190 } 243 191 return log_pane; 192 } 193 194 public AppendLineOnlyFileDocument createNewLogDocument() { 195 long time = System.currentTimeMillis(); 196 StringBuffer name = new StringBuffer(); 197 name.append("build_log."); 198 name.append(time); 199 name.append(".txt"); 200 // just in case there is no log directory 201 File file = new File(Gatherer.c_man.getCollectionLog() + name.toString()); 202 File parent_file = file.getParentFile(); 203 parent_file.mkdirs(); 204 parent_file = null; 205 // create the file entry and add it to the list at pos 0 - it will always be the newest one created 206 file_entry = new FileEntry(name.toString(), file.getAbsolutePath()); 207 ((DefaultListModel)log_list.getModel()).add(0, file_entry); 208 log_list.setSelectedIndex(0); 209 // Finally retrieve and return the document associated with this file entry 210 return file_entry.getDocument(); 244 211 } 245 212 … … 265 232 } 266 233 /** Attempts to discover the latest document count. 267 268 234 * @return An <strong>int</strong> detailing the number of documents in this collection. 235 */ 269 236 public int getDocumentCount() { 270 237 if(Gatherer.c_man.ready()) { … … 277 244 } 278 245 279 /** Loads a new log into the log text - saves the currently showing one, 280 * and loads the new one, adding a fresh listener to the document 281 * Note, we need to remove any listener before making the changes, then 282 * add a listener back in 283 */ 284 public void loadSelectedLog(FileEntry fe) { 285 ///ystem.out.println("load selected log"); 286 if(displayed_log != null) { 287 if (is_log_changed) { 288 saveLogFile(displayed_log.getFile()); 289 } else { 290 log_display.getDocument().removeDocumentListener(log_change_listener); 291 } 292 } 293 294 displayed_log = fe; 295 if (fe != null) { 296 log_display.setText(fe.getFileText()); 297 } else { 298 log_display.setText(""); 299 } 300 is_log_changed=false; 301 log_display.getDocument().addDocumentListener(log_change_listener); 302 303 } 304 305 /** Neutralizes the log list - saves any unsaved changes to the current log 306 * clears the log text, unselects the log list, and adds a fresh listener 307 * to the log's document 308 * Note, we need to remove any listener before making the changes, then 309 * add a listener back in */ 310 public void resetLogList() { 311 ///ystem.out.println("reset log"); 312 if (is_log_changed) { 313 saveLogFile(displayed_log.getFile()); 314 } else { 315 log_display.getDocument().removeDocumentListener(log_change_listener); 316 } 317 log_display.setText(""); 318 displayed_log = null; 319 if (log_list != null) { 320 log_list.clearSelection(); 321 } 322 is_log_changed=false; 323 log_display.getDocument().addDocumentListener(log_change_listener); 324 325 } 326 327 /** saves the current text in log to the File specified */ 328 public void saveLogFile(File file) { 329 330 try { 331 BufferedWriter out = new BufferedWriter(new FileWriter(file)); // uses the default encoding 332 String log_text = log_display.getText(); 333 // set teh return delims to true, then swap them for newLine() (platform dependent) - having return delims set to false seemed to not get empty strings so that empty lines were not preserved. 334 StringTokenizer t = new StringTokenizer(log_text, "\n", true); 335 while (t.hasMoreTokens()) { 336 String token = t.nextToken(); 337 if (token.equals("\n")) { 338 out.newLine(); 339 } else { 340 out.write(token, 0, token.length()); 341 } 342 343 } 344 out.close(); 345 346 } catch(Exception e) { 347 System.out.println("Error in saving log file: "+file.toString()); 348 e.printStackTrace(); 349 } 350 351 352 } 353 246 /** Called by our magic log documents after they have finished writing themselves to file, whereapon it is no longer necessary to hold a reference to them. */ 247 public void remove(AppendLineOnlyFileDocument document) { 248 writing_documents.remove(document); 249 } 250 251 public void resetFileEntry() { 252 if(file_entry != null) { 253 file_entry.reset(); 254 } 255 } 354 256 355 257 /** Given a panel containing ArgumentControls, update the values associated with them. */ … … 591 493 } 592 494 593 /** holds a File which has a particular naming convention 594 * build_log.date.txt 595 * also keeps a Date corresponding to the date in its name*/ 495 /** Holds a File which has a particular naming convention build_log.date.txt also keeps a Date corresponding to the date in its name*/ 596 496 private class FileEntry { 597 497 598 private Date date=null; 599 private File file=null; 600 private String display=null; 601 public FileEntry(File f) { 602 this.file=f; 603 this.date = getDateFromFileName(); 604 this.display = createDisplayText(); 605 498 private Date date; 499 private long last_modified; 500 private String display; 501 private String filename; 502 private String filepath; 503 504 public FileEntry(String filename, String filepath) { 505 this.date = null; 506 this.display = null; 507 this.filename = filename; 508 this.filepath = filepath; 509 this.last_modified = 0L; 606 510 } 607 511 608 512 /** returns 0 if the dates are the same, -ve number if the current FileEntry is earlier than the fe FileEntry ...*/ 609 public int compareTo(FileEntry fe) { 610 Date d = fe.getDate(); 611 return date.compareTo(d); 513 public int compareTo(FileEntry file_entry) { 514 Date our_date = getDate(); 515 Date other_date = file_entry.getDate(); 516 return our_date.compareTo(other_date); 612 517 } 613 518 614 519 public Date getDate() { 615 return this.date; 616 } 617 public File getFile() { 618 return this.file; 619 } 620 /** returns the contents of the file */ 621 public String getFileText() { 622 if (!this.file.exists()) { 623 return ""; 624 } 625 StringBuffer contents = new StringBuffer(); 626 try { 627 BufferedReader in = new BufferedReader(new FileReader(this.file)); 628 String line; 629 630 while ((line = in.readLine()) != null) { 631 contents.append(line); 632 contents.append("\n"); 633 } 634 } catch (FileNotFoundException fnfe) { 635 Gatherer.println("Error: log file not found: "+ this.file.toString()); 636 return ""; 637 } catch (IOException ioe) { 638 Gatherer.println("Error: exception occurred when trying to read in file "+this.file.toString()+", "+ioe.getMessage()); 639 640 } 641 642 return contents.toString(); 643 } 520 if(date == null) { 521 // Need to exclude first '.' 522 int first_index = filename.indexOf(".") + 1; 523 // Need to exclude the last '.' 524 int last_index = filename.lastIndexOf("."); 525 if(first_index > 0 && last_index > 0 && first_index < last_index) { 526 String date_string = filename.substring(first_index, last_index); 527 date = new Date(Long.parseLong(date_string)); 528 } 529 else { 530 date = new Date(); // Current date 531 } 532 } 533 return date; 534 } 535 536 public AppendLineOnlyFileDocument getDocument() { 537 return new AppendLineOnlyFileDocument(filepath); 538 } 539 540 public void reset() { 541 display = null; 542 } 543 644 544 /** we only want the date out of the file name, not the whole path */ 645 545 public String toString() { 646 return this.display; 647 } 648 /** creates the display text for the list */ 649 private String createDisplayText() { 650 StringBuffer d = new StringBuffer(); 651 d.append(date.toString()); 652 //char success= this.file.getName().charAt(23); 653 String filename = this.file.getName(); 654 int index = filename.lastIndexOf(".") - 1; 655 if(index >= 0) { 656 char success = filename.charAt(index); 657 switch (success) { 658 case OptionsPane.SUCCESSFUL: 659 d.append(get("Successful")); 660 break; 661 case OptionsPane.UNSUCCESSFUL: 662 d.append(get("Unsuccessful")); 663 break; 664 case OptionsPane.CANCELLED: 665 d.append(get("Cancelled")); 666 break; 667 } 668 } 669 return d.toString(); 670 } 671 /** extracts the date from the file name, which is of the form 'build_log.'<long>[scu]'.txt' */ 672 private Date getDateFromFileName() { 673 String name = this.file.getName(); 674 // Need to exclude first '.' 675 int first_index = name.indexOf(".") + 1; 676 // Need to exclude state letter before last '.' 677 int last_index = name.lastIndexOf(".") - 1; 678 if(first_index > 0 && last_index > 0 && first_index < last_index) { 679 String date_string = name.substring(first_index, last_index); 680 return new Date(Long.parseLong(date_string)); 681 } 682 else { 683 return new Date(); // Current date 684 } 685 } 686 687 688 } 689 690 /** A DocumentListener that listens for changes in the log_display document 691 * if a change is registered, the flag is_log_changed is set to true, 692 * and the listener removes itself from log_display 693 * Because we only want to register user's changes, the listener must be removed before the system makes any changes, and then put back. For example, each time we switchlogs to display, a remove event and an insert event are sent. We dont want to register these as changes to the document, so the listener must be removed before the switch, and added back afterwards */ 694 private class LogChangeListener implements DocumentListener { 695 696 public void changedUpdate(DocumentEvent e) { 697 ///ystem.out.println("changed update"); 698 registerChange(); 699 } 700 public void insertUpdate(DocumentEvent e) { 701 ///ystem.out.println("insert update"); 702 registerChange(); 703 } 704 public void removeUpdate(DocumentEvent e) { 705 ///ystem.out.println("remove update"); 706 registerChange(); 707 } 708 709 private void registerChange() { 710 ///ystem.err.println("a change in the doc occurred, removing the listener"); 711 is_log_changed = true; 712 log_display.getDocument().removeDocumentListener(this); 713 } 714 } 715 716 /** a ListSelectionListener that triggers the load of a newly selected 717 log */ 546 File file = new File(filename); 547 if(display == null) { 548 last_modified = file.lastModified(); 549 StringBuffer d = new StringBuffer(); 550 Date date = getDate(); 551 d.append(date.toString()); 552 char success = UNKNOWN; 553 try { 554 FileInputStream in = new FileInputStream(new File(filepath)); 555 success = (char) in.read(); 556 in.close(); 557 in = null; 558 } 559 catch(Exception error) { 560 error.printStackTrace(); 561 } 562 switch (success) { 563 case SUCCESSFUL: 564 d.append(get("Successful")); 565 break; 566 case UNSUCCESSFUL: 567 d.append(get("Unsuccessful")); 568 break; 569 case CANCELLED: 570 d.append(get("Cancelled")); 571 break; 572 default: 573 d.append(get("Unknown")); 574 } 575 display = d.toString(); 576 } 577 return display; 578 } 579 } 580 581 /** a ListSelectionListener that triggers the load of a newly selected log */ 718 582 private class LogListListener implements ListSelectionListener { 719 583 … … 721 585 if (!e.getValueIsAdjusting()) { // we get two events for one change in list selection - use the false one ( the second one) 722 586 JList source = (JList)e.getSource(); 723 FileEntry fe = (FileEntry) source.getSelectedValue(); 724 loadSelectedLog(fe); 587 file_entry = (FileEntry) source.getSelectedValue(); 588 // First we determine if the old log has been completely written to file 589 Document document = log_textarea.getDocument(); 590 if(document instanceof AppendLineOnlyFileDocument) { 591 AppendLineOnlyFileDocument append_line_only_file_document = (AppendLineOnlyFileDocument) document; 592 if(append_line_only_file_document.isStillWriting()) { 593 writing_documents.add(append_line_only_file_document); // We have to maintain a reference until they are all done. 594 append_line_only_file_document.setOwner(OptionsPane.this); 595 append_line_only_file_document.setExit(); 596 } 597 } 598 // Load the new log 599 log_textarea.setDocument(file_entry.getDocument()); 725 600 } 726 601 }
Note:
See TracChangeset
for help on using the changeset viewer.