source: main/trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java@ 32706

Last change on this file since 32706 was 22807, checked in by ak19, 14 years ago

Fixed a bug in GLI where we weren't able to delete a collection just built (even without any docs in it) and which had just been closed. The reason was that the build_log file was never properly closed until a new collection was opened, at which point we could finally delete the previously closed collection. Now on CollectionManager.closeCollection(), GLI ensures that any currently active build_log in OptionsPane is closed (which calls the new close method in AppendLineOnlyFileDocument.

  • Property svn:keywords set to Author Date Id Revision
File size: 25.9 KB
Line 
1/**
2 *#########################################################################
3 *
4 * A component of the Gatherer application, part of the Greenstone digital
5 * library suite from the New Zealand Digital Library Project at the
6 * University of Waikato, New Zealand.
7 *
8 * <BR><BR>
9 *
10 * Author: John Thompson, Greenstone Digital Library, University of Waikato
11 *
12 * <BR><BR>
13 *
14 * Copyright (C) 1999 New Zealand Digital Library Project
15 *
16 * <BR><BR>
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * <BR><BR>
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * <BR><BR>
31 *
32 * You should have received a copy of the GNU General Public License
33 * along with this program; if not, write to the Free Software
34 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
35 *########################################################################
36 */
37package org.greenstone.gatherer.gui;
38
39import java.awt.*;
40import java.awt.event.*;
41import java.io.*;
42import java.util.*;
43import javax.swing.*;
44import javax.swing.event.*;
45import javax.swing.text.*;
46import org.greenstone.gatherer.Configuration;
47import org.greenstone.gatherer.DebugStream;
48import org.greenstone.gatherer.Dictionary;
49import org.greenstone.gatherer.Gatherer;
50import org.greenstone.gatherer.cdm.Argument;
51import org.greenstone.gatherer.cdm.ArgumentControl;
52import org.greenstone.gatherer.collection.ScriptOptions;
53import org.greenstone.gatherer.collection.Collection;
54import org.greenstone.gatherer.collection.CollectionManager;
55import org.greenstone.gatherer.util.AppendLineOnlyFileDocument;
56import org.greenstone.gatherer.util.AppendLineOnlyFileDocumentOwner;
57import org.greenstone.gatherer.util.StaticStrings;
58
59/** This class serves as the data holder for all subclasses of option panes, such as Import options or All options. It also contains methods for creating each of the option lines as they would appear in the subpane. Futhermore it has a method for considering all the arguments and generating a <strong>String[]</strong> to allow you to pass them to the <strong>GShell</strong>.
60 * @author John Thompson, Greenstone Digital Library, University of Waikato
61 * @version 2.2
62 */
63public class OptionsPane
64 extends JPanel
65 implements AppendLineOnlyFileDocumentOwner, MouseListener {
66
67 static final public char SUCCESSFUL = 's';
68 static final public char UNSUCCESSFUL = 'u';
69 static final public char CANCELLED = 'c';
70 static final public char UNKNOWN = 'x';
71 static final public char SCHEDULED = 'd';
72
73 static private int BUILD = 0;
74 static private int IMPORT = 1;
75 static private int SCHEDULE = 2;
76 static private int MINIMUM_ROWS = 15;
77
78 /** All process messages are written to this log text area. */
79 public JTextArea log_textarea = null;
80
81 private ArrayList current_controls;
82
83 /** The <strong>ScriptOptions</strong> data object contains all the option settings we wish to persist between Gatherer sessions (and thus is stored in <strong>Collection</strong>). */
84 private ScriptOptions build_options = null;
85 private ScriptOptions import_options = null;
86 private ScriptOptions schedule_options = null;
87
88 private FileEntry file_entry = null;
89
90 /** the log pane - we only create it once now, not each time */
91 private JPanel log_pane = null;
92 /** the list of previous log messages */
93 private JList log_list = null;
94 private Vector writing_documents;
95
96
97 /** 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. */
98 public OptionsPane(ScriptOptions import_options, ScriptOptions build_options, ScriptOptions schedule_options) {
99 this.build_options = build_options;
100 this.import_options = import_options;
101 this.schedule_options = schedule_options;
102 this.current_controls = new ArrayList();
103 this.writing_documents = new Vector();
104 this.setComponentOrientation(Dictionary.getOrientation());
105
106 // Have to do this here, not in display, as the message log view may not have been displayed yet.
107 log_textarea = new JTextArea();
108 log_textarea.setComponentOrientation(Dictionary.getOrientation());
109 log_textarea.setEditable(false);
110 }
111
112 /** This method creates the panel with all the build only options on it.
113 * @param pane a JPanel which already has previous arguments available on it, to allow for lower moes to concatenate all of the arguments together
114 * @return a JPanel which can be used to display all the build only options
115 * @see org.greenstone.gatherer.Configuration#EXPERT_MODE
116 * @see org.greenstone.gatherer.Configuration#getColor
117 * @see org.greenstone.gatherer.Configuration#getMode
118 * @see org.greenstone.gatherer.Gatherer#config
119 * @see org.greenstone.gatherer.cdm.Argument
120 * @see org.greenstone.gatherer.collection.BuildOptions#getBuildArgument
121 * @see org.greenstone.gatherer.collection.BuildOptions#getBuildArgumentCount
122 * @see org.greenstone.gatherer.collection.BuildOptions#getBuildValue
123 * @see org.greenstone.gatherer.collection.BuildOptions#getBuildValueEnabled
124 * @see org.greenstone.gatherer.gui.OptionsPane.MyArgumentControl
125 */
126 public JPanel buildBuild(JPanel pane) {
127 // Reset the arguments
128 if(pane == null) {
129 current_controls.clear();
130 }
131 ArrayList build_arguments = new ArrayList();
132 int current_mode = Configuration.getMode();
133 int total_build_argument_count = build_options.getArgumentCount();
134
135 for(int i = 0; i < total_build_argument_count; i++) {
136 // Retrieve the argument so we know how to format the control.
137 Argument argument = build_options.getArgument(i);
138
139 if(!argument.isHiddenGLI() && argument.getModeLevel() <= current_mode) {
140 // Now attempt to retrieve any existing value for this argument.
141 boolean enabled = build_options.getValueEnabled(argument.getName());
142 String value = build_options.getValue(argument.getName());
143 MyArgumentControl argument_control = new MyArgumentControl(BUILD, argument, enabled, value);
144 build_arguments.add(argument_control);
145 }
146 }
147 current_controls.addAll(build_arguments);
148
149 // Now that we know how many arguments there are we can build the pane to view them on. Modes lower than EXPERT can provide a previous pane on which to add the arguments.
150 if(pane == null || current_mode >= Configuration.EXPERT_MODE) {
151 pane = new JPanel();
152 pane.setComponentOrientation(Dictionary.getOrientation());
153 pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
154 pane.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
155 int argument_count = build_arguments.size();
156 // If in any of the higher detail modes, and assuming we don't want super phat argument controls, we better ensure there is a minimum number of lines in the grid layout
157 if(current_mode >= Configuration.EXPERT_MODE) {
158 if(argument_count < MINIMUM_ROWS) {
159 argument_count = MINIMUM_ROWS;
160 }
161 pane.setLayout(new GridLayout(argument_count, 1, 5, 5));
162 }
163 // Otherwise we're just going to throw them on one after another and chuck it in a scroll pane anyway
164 else {
165 // use GridLayout with 0 rows == as many rows as needed. Unfortunately, rows will
166 // grow fat if space too large, but we don't know how many rows we'll need yet.
167 pane.setLayout(new GridLayout(0, 1, 5, 5));
168 }
169 }
170
171 for(int j = 0; j < build_arguments.size(); j++) {
172 pane.add((JComponent)build_arguments.get(j));
173 }
174 pane.addMouseListener(this);
175 build_arguments = null;
176 return pane;
177 }
178
179 /**Wendy's attempt at writing a buildSchedule Jpanel. */
180 public JPanel buildSchedule(JPanel pane) {
181 //reset the arguments
182 if(pane == null) {
183 current_controls.clear();
184 }
185
186 ArrayList schedule_arguments = new ArrayList();
187 int current_mode = Configuration.getMode();
188
189 int total_schedule_argument_count = schedule_options.getArgumentCount();
190
191 for(int i = 0; i < total_schedule_argument_count; i++) {
192 // Retrieve the argument so we know how to format the control.
193 Argument argument = schedule_options.getArgument(i);
194
195 if(!argument.isHiddenGLI() && argument.getModeLevel() <= current_mode) {
196 // Now attempt to retrieve any existing value for this argument.
197 boolean enabled = schedule_options.getValueEnabled(argument.getName());
198 String value = schedule_options.getValue(argument.getName());
199 MyArgumentControl argument_control = new MyArgumentControl(SCHEDULE, argument, enabled, value);
200 schedule_arguments.add(argument_control);
201 }
202 }
203 current_controls.addAll(schedule_arguments);
204
205 // Now that we know how many arguments there are we can build the pane to view them on. Modes lower than EXPERT can provide a previous pane on which to add the arguments.
206 if(pane == null || current_mode >= Configuration.EXPERT_MODE) {
207 pane = new JPanel();
208 pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
209 pane.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
210 int argument_count = schedule_arguments.size();
211 // If in any of the higher detail modes, and assuming we don't want super phat argument controls, we better ensure there is a minimum number of lines in the grid layout
212 if(current_mode >= Configuration.EXPERT_MODE) {
213 if(argument_count < MINIMUM_ROWS) {
214 argument_count = MINIMUM_ROWS;
215 }
216 pane.setLayout(new GridLayout(argument_count, 1, 5, 5));
217 }
218 // Otherwise we're just going to throw them on one after another and chuck it in a scroll pane anyway
219 else {
220 // use GridLayout with 0 rows == as many rows as needed. Unfortunately, rows will
221 // grow fat if space too large, but we don't know how many rows we'll need yet.
222 pane.setLayout(new GridLayout(0, 1, 5, 5));
223 }
224 }
225
226 for(int j = 0; j < schedule_arguments.size(); j++) {
227 pane.add((JComponent)schedule_arguments.get(j));
228 }
229 pane.addMouseListener(this);
230 schedule_arguments = null;
231 return pane;
232
233 }
234
235 /** This method creates the panel with all the import only options on it.
236 * @param pane a JPanel which already has previous arguments available on it, to allow for lower moes to concatenate all of the arguments together
237 * @return a JPanel which can be used to display all the build only options
238 * @see org.greenstone.gatherer.Configuration#EXPERT_MODE
239 * @see org.greenstone.gatherer.Configuration#getColor
240 * @see org.greenstone.gatherer.Configuration#getMode
241 * @see org.greenstone.gatherer.Gatherer#config
242 * @see org.greenstone.gatherer.cdm.Argument
243 * @see org.greenstone.gatherer.collection.BuildOptions#getImportArgument
244 * @see org.greenstone.gatherer.collection.BuildOptions#getImportArgumentCount
245 * @see org.greenstone.gatherer.collection.BuildOptions#getImportValue
246 * @see org.greenstone.gatherer.collection.BuildOptions#getImportValueEnabled
247 * @see org.greenstone.gatherer.gui.OptionsPane.ArgumentControl
248 */
249 public JPanel buildImport(JPanel pane) {
250 // Reset the arguments
251 if(pane == null) {
252 current_controls.clear();
253 }
254 ArrayList import_arguments = new ArrayList();
255 int current_mode = Configuration.getMode();
256 int total_import_argument_count = import_options.getArgumentCount();
257 for(int i = 0; i < total_import_argument_count; i++) {
258 // Retrieve the argument so we know how to format the control.
259 Argument argument = import_options.getArgument(i);
260 if(!argument.isHiddenGLI() && argument.getModeLevel() <= current_mode) {
261 // Now attempt to retrieve any existing value for this argument.
262 boolean enabled = import_options.getValueEnabled(argument.getName());
263 String value = import_options.getValue(argument.getName());
264 MyArgumentControl argument_control = new MyArgumentControl(IMPORT, argument, enabled, value);
265 import_arguments.add(argument_control);
266 }
267 }
268 current_controls.addAll(import_arguments);
269 // Now that we know how many arguments there are we can build the pane to view them on. Modes lower than EXPERT can provide a previous pane on which to add the arguments.
270 if(pane == null || current_mode >= Configuration.EXPERT_MODE) {
271 pane = new JPanel();
272 pane.setComponentOrientation(Dictionary.getOrientation());
273 pane.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
274 pane.setBackground(Configuration.getColor("coloring.collection_tree_background", false));
275 int argument_count = import_arguments.size();
276 // If in any of the higher detail modes, and assuming we don't want super phat argument controls, we better ensure there is a minimum number of lines in the grid layout
277 if(current_mode >= Configuration.EXPERT_MODE) {
278 if(argument_count < MINIMUM_ROWS) {
279 argument_count = MINIMUM_ROWS;
280 }
281 pane.setLayout(new GridLayout(argument_count, 1, 5, 5));
282 }
283 // Otherwise we're just going to throw them on one after another and chuck it in a scroll pane anyway
284 else {
285 // use GridLayout with 0 rows == as many rows as needed. Unfortunately, rows will
286 // grow fat if space too large, but we don't know how many rows we'll need yet.
287 pane.setLayout(new GridLayout(0, 1, 5, 5));
288 }
289 }
290
291 for(int j = 0; j < import_arguments.size(); j++) {
292 pane.add((JComponent)import_arguments.get(j));
293 }
294 pane.addMouseListener(this);
295 import_arguments = null;
296 return pane;
297 }
298
299 /** This method is used to build a panel based on the message log, which is nothing like any of the other panels.
300 * @return A <strong>JPanel</strong> containing a scrollable text area which represents the shell process message log.
301 */
302 public JPanel buildLog() {
303 // we now save the log pane
304 if (log_pane == null) {
305 log_pane = new JPanel(new BorderLayout());
306 log_pane.setComponentOrientation(Dictionary.getOrientation());
307 // Build a list of the log files available, ordering by last modified. Log files are like build_log.date.txt
308 DefaultListModel contents = new DefaultListModel();
309 File log_directory = new File(CollectionManager.getLoadedCollectionLogDirectoryPath());
310 File children[] = log_directory.listFiles();
311 for(int i = 0; children != null && i < children.length; i++) {
312 String filename = children[i].getName();
313 if(filename.startsWith("build_log.") && filename.endsWith(".txt") ) {
314 String datestamp = filename.substring(filename.indexOf(".") + 1, filename.lastIndexOf(".")).toLowerCase();
315 if(datestamp.indexOf("s") == -1 && datestamp.indexOf("u") == -1 && datestamp.indexOf("c") == -1 && datestamp.indexOf("x") == -1) {
316 FileEntry entry = new FileEntry(children[i].getName(), children[i].getAbsolutePath());
317 // We are about to insert it. But where.
318 boolean found = false;
319 for(int j = 0; !found && j < contents.size(); j++) {
320 FileEntry sibling = (FileEntry) contents.getElementAt(j);
321 int order = entry.compareTo(sibling);
322 if(order > 0) {
323 contents.insertElementAt(entry, j);
324 found = true;
325 }
326 }
327 if(!found) {
328 contents.addElement(entry);
329 }
330 }
331 }
332 }
333
334 log_list = new JList(contents);
335 log_list.setComponentOrientation(Dictionary.getOrientation());
336 log_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
337 log_list.setLayoutOrientation(JList.VERTICAL);
338 log_list.setPreferredSize(new Dimension(600, 100));
339 log_list.setVisibleRowCount(3);
340 log_list.addListSelectionListener(new LogListListener());
341
342 JLabel log_history_label = new JLabel(Dictionary.get("OptionsPane.LogHistory"));
343 log_history_label.setComponentOrientation(Dictionary.getOrientation());
344 JPanel log_history_pane = new JPanel();
345 log_history_pane.setComponentOrientation(Dictionary.getOrientation());
346 log_history_pane.setPreferredSize(new Dimension(600, 100));
347 log_history_pane.setLayout(new BorderLayout());
348 log_history_pane.add(log_history_label, BorderLayout.NORTH);
349 JScrollPane scrol_tmp=new JScrollPane(log_list);
350 scrol_tmp.setComponentOrientation(Dictionary.getOrientation());
351 log_history_pane.add(scrol_tmp, BorderLayout.CENTER);
352
353 scrol_tmp=new JScrollPane(log_textarea);
354 scrol_tmp.setComponentOrientation(Dictionary.getOrientation());
355 log_pane.add(scrol_tmp, BorderLayout.CENTER);
356 log_pane.add(log_history_pane, BorderLayout.SOUTH);
357 }
358 return log_pane;
359 }
360
361 public AppendLineOnlyFileDocument createNewLogDocument() {
362 long time = System.currentTimeMillis();
363 StringBuffer name = new StringBuffer();
364 name.append("build_log.");
365 name.append(time);
366 name.append(".txt");
367 // just in case there is no log directory
368 File file = new File(CollectionManager.getLoadedCollectionLogDirectoryPath() + name.toString());
369 File parent_file = file.getParentFile();
370 parent_file.mkdirs();
371 parent_file = null;
372 // create the file entry and add it to the list at pos 0 - it will always be the newest one created
373 file_entry = new FileEntry(name.toString(), file.getAbsolutePath());
374 ((DefaultListModel)log_list.getModel()).add(0, file_entry);
375 log_list.setSelectedIndex(0);
376 // Finally retrieve and return the document associated with this file entry
377 return file_entry.getDocument();
378 }
379
380 /** ensure the current build_log file has finished transferring from memory to disk, and that the random access
381 * file is properly closed when a collection is closed. Else we can't delete the just-closed collection since the
382 * build_log file resource is still kept open. */
383 public void closeCurrentLogDocument() {
384 if(file_entry == null) {
385 return;
386 }
387 AppendLineOnlyFileDocument buildDoc = file_entry.getDocument();
388 if(buildDoc != null) {
389 buildDoc.close();
390 }
391 }
392
393
394 /** Attempts to discover the latest document count.
395 * @return An <strong>int</strong> detailing the number of documents in this collection.
396 */
397 public int getDocumentCount() {
398 if(Gatherer.c_man.ready()) {
399 int count = Gatherer.c_man.getCollection().getDocumentCount();
400 if(count != 0) {
401 return count;
402 }
403 }
404 return 1;
405 }
406
407 /** 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. */
408 public void remove(AppendLineOnlyFileDocument document) {
409 writing_documents.remove(document);
410 }
411
412 public void resetFileEntry() {
413 if(file_entry != null) {
414 file_entry.reset();
415 }
416 }
417
418 /** Given a panel containing ArgumentControls, update the values associated with them. */
419 public void update(JPanel panel) {
420 if(panel == log_pane) {
421 return;
422 }
423
424 for(int i = 0; i < panel.getComponentCount(); i++) {
425 Component component = panel.getComponent(i);
426 if(component instanceof MyArgumentControl) {
427 ((MyArgumentControl)component).update();
428 }
429 }
430 }
431
432 /** Implementation side-effect
433 * @param e a MouseEvent
434 */
435 public void mouseClicked(MouseEvent e) {}
436
437 /** Implementation side-effect
438 * @param e a MouseEvent
439 */
440 public void mouseEntered(MouseEvent e) {}
441
442 /** Implemented to ensure that, by the time the mouse pointer leaves the current build options screen, ang changes to the value the JSpinners have been commited
443 * @param e a MouseEvent
444 */
445 public void mouseExited(MouseEvent e) {
446 // Loop through the controls, and if the current control is a JSpinner, commit its current editing
447 for(int i = 0; i < current_controls.size(); i++) {
448 MyArgumentControl control = (MyArgumentControl) current_controls.get(i);
449 JComponent value_control = control.getValueControl();
450 if(value_control instanceof JSpinner) {
451 try {
452 ((JSpinner)value_control).commitEdit();
453 }
454 catch(Exception exception) {
455 DebugStream.println("Exception in OptionsPane.mouseExited() - unexpected");
456 DebugStream.printStackTrace(exception);
457 }
458 }
459 value_control = null;
460 control = null;
461 }
462 }
463
464 /** Implementation side-effect
465 * @param e a MouseEvent
466 */
467 public void mousePressed(MouseEvent e) {}
468
469 /** Implementation side-effect
470 * @param e a MouseEvent
471 */
472 public void mouseReleased(MouseEvent e) {}
473
474 private class MyArgumentControl
475 extends ArgumentControl {
476 private int type;
477
478 public MyArgumentControl(int type, Argument argument, boolean enable, String value) {
479 super(argument, enable, value);
480 this.type = type;
481 }
482
483 /** Update the values stored in the collection so as to remember the current state of this argument. */
484 public void update() {
485 String name = getArgumentName();
486 boolean enable = isEnabled();
487 String value = getValue();
488 // If this argument was a flag, but is now disabled, remove from the build options altogether
489 if(!enable && value == null) {
490 if(type == BUILD) {
491 build_options.removeValue(name);
492 }
493 else if(type == SCHEDULE) {
494 schedule_options.removeValue(name);
495 }
496 else {
497 import_options.removeValue(name);
498 }
499 }
500 // Otherwise update the argument value
501 else {
502 if(type == BUILD) {
503 build_options.setValue(name, enable, value);
504 }
505 else if(type == SCHEDULE) {
506 schedule_options.setValue(name, enable, value);
507 }
508 else {
509 import_options.setValue(name, enable, value);
510 }
511 }
512 }
513 }
514
515 /** Holds a File which has a particular naming convention build_log.date.txt also keeps a Date corresponding to the date in its name*/
516 private class FileEntry {
517
518 private AppendLineOnlyFileDocument current_document;
519 private Date date;
520 private long last_modified;
521 private String display;
522 private String filename;
523 private String filepath;
524
525 public FileEntry(String filename, String filepath) {
526 this.date = null;
527 this.display = null;
528 this.filename = filename;
529 this.filepath = filepath;
530 this.last_modified = 0L;
531 }
532
533 /** returns 0 if the dates are the same, -ve number if the current FileEntry is earlier than the fe FileEntry ...*/
534 public int compareTo(FileEntry file_entry) {
535 Date our_date = getDate();
536 Date other_date = file_entry.getDate();
537 return our_date.compareTo(other_date);
538 }
539
540 public Date getDate() {
541 if(date == null) {
542 // Need to exclude first '.'
543 int first_index = filename.indexOf(".") + 1;
544 // Need to exclude the last '.'
545 int last_index = filename.lastIndexOf(".");
546 if(first_index > 0 && last_index > 0 && first_index < last_index) {
547 String date_string = filename.substring(first_index, last_index);
548 date = new Date(Long.parseLong(date_string));
549 }
550 else {
551 date = new Date(); // Current date
552 }
553 }
554 return date;
555 }
556
557 public AppendLineOnlyFileDocument getDocument() {
558 if(current_document == null) {
559 current_document = new AppendLineOnlyFileDocument(filepath);
560 }
561 return current_document;
562 }
563
564 public void reset() {
565 display = null;
566 }
567
568 /** we only want the date out of the file name, not the whole path */
569 public String toString() {
570 File file = new File(filename);
571 if(display == null) {
572 last_modified = file.lastModified();
573 StringBuffer d = new StringBuffer();
574 Date date = getDate();
575 d.append(date.toString());
576 char success = UNKNOWN;
577 File the_file = new File(filepath);
578 if(the_file.exists()) {
579 try {
580 FileInputStream in = new FileInputStream(the_file);
581 success = (char) in.read();
582 in.close();
583 in = null;
584 }
585 catch(Exception error) {
586 ///ystem.err.println("Log '" + filepath + "' not found!");
587 ///atherer.printStackTrace(error);
588 }
589 }
590 the_file = null;
591 switch (success) {
592 case SUCCESSFUL:
593 d.append(Dictionary.get("OptionsPane.Successful"));
594 break;
595 case UNSUCCESSFUL:
596 d.append(Dictionary.get("OptionsPane.Unsuccessful"));
597 break;
598 case CANCELLED:
599 d.append(Dictionary.get("OptionsPane.Cancelled"));
600 break;
601 case SCHEDULED:
602 d.append(Dictionary.get("OptionsPane.Scheduled"));
603 break;
604 default:
605 d.append(Dictionary.get("OptionsPane.Unknown"));
606 }
607 display = d.toString();
608 }
609 return display;
610 }
611 }
612
613 /** a ListSelectionListener that triggers the load of a newly selected log */
614 private class LogListListener implements ListSelectionListener {
615
616 public void valueChanged(ListSelectionEvent e) {
617 if (!e.getValueIsAdjusting()) { // we get two events for one change in list selection - use the false one ( the second one)
618 ///ystem.err.println("Log change detected.");
619 JList source = (JList)e.getSource();
620 file_entry = (FileEntry) source.getSelectedValue();
621 // First we determine if the old log has been completely written to file
622 Document document = log_textarea.getDocument();
623 ///ystem.err.println(" * current document: " + document);
624 ///ystem.err.println(" * new document: " + file_entry.getDocument());
625 // If we are dealing with the same document don't do anything.
626 if(document != file_entry.getDocument()) {
627 if(document instanceof AppendLineOnlyFileDocument) {
628 AppendLineOnlyFileDocument append_line_only_file_document = (AppendLineOnlyFileDocument) document;
629 if(append_line_only_file_document.isStillWriting()) {
630 ///ystem.err.println("Current log is still active... finishing.");
631 writing_documents.add(append_line_only_file_document); // We have to maintain a reference until they are all done.
632 append_line_only_file_document.setOwner(OptionsPane.this);
633 append_line_only_file_document.setExit();
634 }
635 else {
636 ///ystem.err.println("Current log is complete. Nothing to do.");
637 }
638 }
639 // Load the new log
640 log_textarea.setDocument(file_entry.getDocument());
641 }
642 }
643 }
644 }
645
646}
Note: See TracBrowser for help on using the repository browser.