package com.babel17.netbeans; import com.babel17.naive.WriteOutput; import com.babel17.syntaxtree.Location; import java.awt.Color; import java.awt.EventQueue; import java.awt.event.ActionEvent; import org.openide.windows.IOProvider; import org.openide.windows.InputOutput; import org.openide.windows.OutputEvent; import org.openide.windows.OutputListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; import javax.swing.AbstractAction; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JEditorPane; import javax.swing.text.BadLocationException; import org.openide.cookies.EditorCookie; import org.openide.util.ImageUtilities; import org.openide.windows.IOColorLines; import org.openide.windows.IOColorPrint; import org.openide.filesystems.FileObject; import org.openide.loaders.DataObject; import org.openide.filesystems.FileUtil; import java.util.ArrayList; //import org.netbeans.swing.tabcontrol.TabbedContainer; public class WriteNetbeansOutput extends WriteOutput { InputOutput io; volatile boolean pleaseCancel = false; AbstractAction cancelAction = null; //String filename; public boolean pleaseCancel() { return pleaseCancel; } class CancelAction extends AbstractAction { JButton button = null; public CancelAction() { super(); putValue(NAME, "Run Babel-17 program"); String iconfile = "com/babel17/netbeans/stop.png"; putValue(SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconfile, true))); } public void actionPerformed(ActionEvent ev) { pleaseCancel = true; } } void println(String s, Color c) { println(s, c, null, false); } void println(String s, OutputListener l) { println(s, Color.BLUE, l, false); } void println(final String s, final Color c, final OutputListener l, final boolean important) { EventQueue.invokeLater(new Runnable() { public void run() { try { IOColorLines.println(io, s, l, important, c); } catch (IOException e) {} } }); } void print(final String s, final Color c, final OutputListener l, final boolean important) { EventQueue.invokeLater(new Runnable() { public void run() { try { IOColorPrint.print(io, s, l, important, c); } catch (IOException e) {} } }); } private static ArrayList<WriteNetbeansOutput> wnos = new ArrayList<WriteNetbeansOutput>(); public static WriteNetbeansOutput get() { synchronized (wnos) { for (WriteNetbeansOutput o : wnos) { if (o.activate()) { wnos.remove(o); return o; } } } return new WriteNetbeansOutput("Babel-17"); } private void park() { synchronized(wnos) { wnos.add(this); } } WriteNetbeansOutput(final String title) { EventQueue.invokeLater(new Runnable() { public void run() { cancelAction = new CancelAction(); AbstractAction[] actions = new AbstractAction[]{cancelAction}; io = IOProvider.getDefault().getIO(title, actions); io.select(); } }); //OutputWriter writer = io.getOut(); //IOColors.setColor(io, OutputType.OUTPUT, Color.blue); //io.select(); /*writer.println("IOColorPrint supported: "+IOColorPrint.isSupported(io)); writer.println("IOColorLines supported: "+IOColorLines.isSupported(io));*/ //writer.println("----------------------------------------------------------"); //io.setOutputVisible(true); } public boolean activate() { if (io.isClosed()) return false; else { pleaseCancel = false; cancelAction.setEnabled(true); io.select(); writeLine(""); writeLine("----------------------------------------------------------------------------------------------"); writeLine(""); return true; } } public void writeLineCommentary(String s) { println(s, Color.GRAY); } Color color(int red, int green, int blue) { return new Color(red / 255.0f, green / 255.0f, blue / 255.0f); } public void writeLineSuccess(String s) { println(s, color(0x2e, 0xab, 0x37), null, true); } public void writeLineError(String s) { //setColor(Color.red); println(s, color(0xb6, 0x0a, 0x0a), null, true); } public class L implements OutputListener { Location loc; public L(Location loc) { this.loc = loc; } public void outputLineCleared(OutputEvent ev) { } public void outputLineAction(OutputEvent ev) { openAt(loc); } public void outputLineSelected(OutputEvent ev) { } } public void writeLocMsg(String prefix, Location loc, String message) { //try { String tab = " "; if (prefix != null) { prefix = prefix + " "; while (tab.length() < prefix.length()) { tab = tab + " "; } } else prefix = ""; //IOColorPrint.print(io, "at "+loc, new L(loc), false, Color.black); print(prefix, Color.black, null, false); //if (loc.getSource().getFilename().equals(filename)) print("at "+loc, Color.blue, new L(loc), false); //else //print("at "+loc, Color.black, null, false); println(": "+message, Color.black); //writer.println("at " + loc, new L(loc), false); //setColor(Color.black); //IOColorPrint.print(io, tab+message, Color.black); //writer.println(tab + message, null, false); //println(tab+message, Color.BLACK); //NBOut.output("Babel-17", tab + message, Color.black); /*} catch (IOException e) { display(e.toString()); e.printStackTrace(); }*/ } public void writeLine(String s) { //setColor(Color.black); println(s, Color.black); } public void done() { //writer.close(); EventQueue.invokeLater(new Runnable() { public void run() { cancelAction.setEnabled(false); park(); } }); } public void openAt(final Location loc) { Babel17DataObject dobj = null; try { String filename = loc.getSource().getFilename(); FileObject fo = FileUtil.createData(new java.io.File(filename)); dobj = (Babel17DataObject) DataObject.find(fo); } catch (Exception e) { } if (dobj == null) return; final EditorCookie.Observable ec = dobj.getCookie(EditorCookie.Observable.class); if (ec != null) { org.netbeans.editor.Utilities.runInEventDispatchThread(new Runnable() { public void run() { final PropertyChangeListener me = new PropertyChangeListener() { public void propertyChange(PropertyChangeEvent evt) { final PropertyChangeListener me = this; EventQueue.invokeLater(new Runnable() { public void run() { final JEditorPane[] panes = ec.getOpenedPanes(); if ((panes != null) && (panes.length > 0)) { setPosition(panes[0], loc); ec.removePropertyChangeListener(me); } } }); } }; ec.addPropertyChangeListener(me); ec.open(); final JEditorPane[] panes = ec.getOpenedPanes(); if ((panes != null) && (panes.length > 0)) { setPosition(panes[0], loc); ec.removePropertyChangeListener(me); } } //Here we specify where the cursor will land: private void setPosition(JEditorPane pane, Location loc) { try { int col = loc.startColumn(); int line = loc.startLine(); //The whole text: String text = pane.getDocument().getText(0, pane.getDocument().getLength() - 1); //The place where we want the cursor to be: int index = 0; int c = 1; int l = 1; int len = text.length(); while (index < len) { if (l > line || l == line && c >= col) { pane.setCaretPosition(index); pane.requestFocusInWindow(); return; } char ch = text.charAt(index); if (ch == '\n') { c = 1; l++; index++; } else { c++; index++; } } pane.setCaretPosition(len - 1); pane.requestFocusInWindow(); } catch (BadLocationException ex) { } } }); } } }