001: /*BEGIN_COPYRIGHT_BLOCK
002: *
003: * Copyright (c) 2001-2007, JavaPLT group at Rice University (javaplt@rice.edu)
004: * All rights reserved.
005: *
006: * Redistribution and use in source and binary forms, with or without
007: * modification, are permitted provided that the following conditions are met:
008: * * Redistributions of source code must retain the above copyright
009: * notice, this list of conditions and the following disclaimer.
010: * * Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: * * Neither the names of DrJava, the JavaPLT group, Rice University, nor the
014: * names of its contributors may be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
018: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
019: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
020: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
021: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
022: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
023: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
024: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
025: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
026: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
027: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: * This software is Open Source Initiative approved Open Source Software.
030: * Open Source Initative Approved is a trademark of the Open Source Initiative.
031: *
032: * This file is part of DrJava. Download the current version of this project
033: * from http://www.drjava.org/ or http://sourceforge.net/projects/drjava/
034: *
035: * END_COPYRIGHT_BLOCK*/
036:
037: package edu.rice.cs.drjava.ui;
038:
039: import edu.rice.cs.drjava.DrJava;
040: import edu.rice.cs.drjava.config.OptionConstants;
041: import edu.rice.cs.drjava.config.OptionEvent;
042: import edu.rice.cs.drjava.config.OptionListener;
043: import edu.rice.cs.drjava.model.SingleDisplayModel;
044: import edu.rice.cs.drjava.model.compiler.CompilerModel;
045: import edu.rice.cs.drjava.model.compiler.CompilerErrorModel;
046: import edu.rice.cs.drjava.model.compiler.CompilerInterface;
047: import edu.rice.cs.drjava.model.compiler.NoCompilerAvailable;
048: import edu.rice.cs.util.UnexpectedException;
049: import edu.rice.cs.util.text.SwingDocument;
050: import edu.rice.cs.plt.iter.IterUtil;
051:
052: import javax.swing.*;
053: import javax.swing.text.BadLocationException;
054: import javax.swing.text.Position;
055: import java.awt.*;
056: import java.awt.event.ItemEvent;
057: import java.awt.event.ItemListener;
058: import java.io.File;
059: import java.util.Vector;
060:
061: /**
062: * The panel which houses the list of errors after an unsuccessful compilation.
063: * If the user clicks on the combobox, move the definitions cursor to the
064: * error in the source.
065: * If the cursor is moved onto a line with an error, select the appropriate
066: * error in the list but do not move the cursor.
067: *
068: * @version $Id: CompilerErrorPanel.java 4255 2007-08-28 19:17:37Z mgricken $
069: */
070: public class CompilerErrorPanel extends ErrorPanel {
071:
072: /** Whether a compile has occurred since the last compiler change. */
073: private boolean _compileHasOccurred;
074: private CompilerErrorListPane _errorListPane;
075: private final JComboBox _compilerChoiceBox;
076:
077: /** The list of files from the last compilation unit that were not compiled because they were not source files. */
078: private File[] _excludedFiles = new File[0];
079:
080: /** Constructor.
081: * @param model SingleDisplayModel in which we are running
082: * @param frame MainFrame in which we are displayed
083: */
084: public CompilerErrorPanel(SingleDisplayModel model, MainFrame frame) {
085: super (model, frame, "Compiler Output", "Compiler");
086: _compileHasOccurred = false;
087: _numErrors = 0;
088:
089: _errorListPane = new CompilerErrorListPane();
090: setErrorListPane(_errorListPane);
091:
092: /******** Initialize the drop-down compiler menu ********/
093: // Limitation: Only compiler choices are those that were available
094: // at the time this box was created.
095: // Also: The UI will go out of sync with reality if the active compiler
096: // is later changed somewhere else. This is because there is no way
097: // to listen on the active compiler.
098: final CompilerModel compilerModel = getModel()
099: .getCompilerModel();
100: Iterable<CompilerInterface> iter = getModel()
101: .getCompilerModel().getAvailableCompilers();
102: _compilerChoiceBox = new JComboBox(IterUtil.asArray(iter,
103: CompilerInterface.class));
104: _compilerChoiceBox.setEditable(false);
105: _compilerChoiceBox.setSelectedItem(compilerModel
106: .getActiveCompiler());
107: _compilerChoiceBox.addItemListener(new ItemListener() {
108: public void itemStateChanged(ItemEvent e) {
109: if (e.getStateChange() == ItemEvent.SELECTED) {
110: CompilerInterface compiler = (CompilerInterface) _compilerChoiceBox
111: .getSelectedItem();
112: compilerModel.setActiveCompiler(compiler);
113: compilerModel.resetCompilerErrors();
114: _compileHasOccurred = false;
115: reset();
116: }
117: }
118: });
119:
120: customPanel.add(_compilerChoiceBox, BorderLayout.NORTH);
121:
122: DrJava.getConfig().addOptionListener(
123: OptionConstants.JAVAC_LOCATION,
124: new CompilerLocationOptionListener<File>());
125: DrJava.getConfig().addOptionListener(
126: OptionConstants.EXTRA_COMPILERS,
127: new CompilerLocationOptionListener<Vector<String>>());
128: }
129:
130: /** The OptionListener for compiler LOCATIONs */
131: private class CompilerLocationOptionListener<T> implements
132: OptionListener<T> {
133:
134: public void optionChanged(OptionEvent<T> oce) {
135: _compilerChoiceBox.removeAllItems();
136: for (CompilerInterface c : getModel().getCompilerModel()
137: .getAvailableCompilers()) {
138: _compilerChoiceBox.addItem(c);
139: }
140: }
141: }
142:
143: /** Returns the CompilerErrorListPane that this panel manages. */
144: public CompilerErrorListPane getErrorListPane() {
145: return _errorListPane;
146: }
147:
148: /** Called when compilation begins. */
149: public void setCompilationInProgress() {
150: _errorListPane.setCompilationInProgress();
151: }
152:
153: public CompilerErrorModel getErrorModel() {
154: return getModel().getCompilerModel().getCompilerErrorModel();
155: }
156:
157: /** Clean up when the tab is closed. */
158: @Override
159: protected void _close() {
160: super ._close();
161: getModel().getCompilerModel().resetCompilerErrors();
162: reset();
163: }
164:
165: /** Reset the errors to the current error information immediately following compilation. */
166: public void reset(File[] excludedFiles) {
167: _excludedFiles = excludedFiles;
168: reset();
169: }
170:
171: /** Reset the errors to the current error information. */
172: public void reset() {
173: // _nextErrorButton.setEnabled(false);
174: // _prevErrorButton.setEnabled(false);
175: // Utilities.showDebug("Reset being called by CompilerErrorPanel");
176: _numErrors = getModel().getCompilerModel().getNumErrors();
177:
178: _errorListPane.updateListPane(true);
179: // _nextErrorButton.setEnabled(_errorListPane.hasNextError());
180: // _prevErrorButton.setEnabled(_errorListPane.hasPrevError());
181: }
182:
183: class CompilerErrorListPane extends ErrorPanel.ErrorListPane {
184:
185: protected void _updateWithErrors() throws BadLocationException {
186: SwingDocument doc = new SwingDocument();
187: if (_excludedFiles.length != 0) {
188: final StringBuilder msgBuffer = new StringBuilder(
189: "Compilation completed. The following files were not compiled:\n");
190: for (File f : _excludedFiles) {
191: if (f != null) {
192: msgBuffer.append(" ").append(f).append('\n');
193: } // do not print files from untitled docs
194: }
195: doc.append(msgBuffer.toString(), NORMAL_ATTRIBUTES);
196: }
197:
198: String failureName = "error";
199: if (getErrorModel().hasOnlyWarnings())
200: failureName = "warning";
201:
202: _updateWithErrors(failureName, "found", doc);
203: }
204:
205: /** Puts the error pane into "compilation in progress" state. */
206: public void setCompilationInProgress() {
207: _errorListPositions = new Position[0];
208: _compileHasOccurred = true;
209:
210: SwingDocument doc = new SwingDocument();
211:
212: try {
213: doc.insertString(0,
214: "Compilation in progress, please wait...",
215: NORMAL_ATTRIBUTES);
216: } catch (BadLocationException ble) {
217: throw new UnexpectedException(ble);
218: }
219:
220: setDocument(doc);
221: selectNothing();
222: }
223:
224: /** Used to show that the last compile was successful.
225: * @param done ignored: we assume that this is only called after compilation is completed
226: */
227: protected void _updateNoErrors(boolean done)
228: throws BadLocationException {
229: SwingDocument doc = new SwingDocument();
230: String message;
231: if (_compileHasOccurred) {
232: if (_excludedFiles.length == 0)
233: message = "Compilation completed.";
234: else {
235: final StringBuilder msgBuffer = new StringBuilder(
236: "Compilation completed. The following files were not compiled:\n");
237: for (File f : _excludedFiles) {
238: if (f != null) {
239: msgBuffer.append(" ").append(f).append(
240: '\n');
241: } // do not print files from untitled docs
242: }
243: message = msgBuffer.toString();
244: }
245: } else if (!getModel().getCompilerModel()
246: .getActiveCompiler().isAvailable())
247: message = "No compiler available.";
248: else
249: message = "Compiler ready: "
250: + getModel().getCompilerModel()
251: .getActiveCompiler().getDescription()
252: + ".";
253:
254: doc.insertString(0, message, NORMAL_ATTRIBUTES);
255: setDocument(doc);
256: _updateScrollButtons();
257: selectNothing();
258: }
259: }
260: }
|