Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /* ************************************************************************
  #
  #  DivConq
  #
  #  http://divconq.com/
  #
  #  Copyright:
  #    Copyright 2014 eTimeline, LLC. All rights reserved.
  #
 #  License:
 #    See the license.txt file in the project's top-level directory for details.
 #
 #  Authors:
 #    * Andy White
 #
 ************************************************************************ */
 package divconq.script.ui;
 
 import java.io.File;
 import java.util.List;
 
 import javax.swing.*;
 
 
 
 @SuppressWarnings("rawtypes")
 public class EditorPane extends JRootPane implements SyntaxConstantsIDebugger {
 	private static final long serialVersionUID = -162698015493544827L;
 	
 	protected RSyntaxTextArea editor = null;
 	protected JTextArea console = null;
 	protected JList stacklst = null;
 	protected StackListModel stackmodel = new StackListModel();
 	protected JList varslst = null;
 	protected JTextArea vardetail = null;
 	
 	protected TaskRun currrun = null;
 	protected Session fssession = null;
 	protected RecordStruct debuginfo = null;
 
 	protected JFileChooser fc = new JFileChooser(".");
 
 	protected File currfile = null;
 
 	protected JLabel statuslbl = new JLabel("Status: stopped");
 	protected SmallButton runbtn = null;
 	protected SmallButton stepbtn = null;
 	
 	protected Timer uitimer = null;
 	protected long lastinstrun = 0;
 	
	protected TaskLogger logfmt = new TaskLogger();
	@SuppressWarnings("unchecked")
	public EditorPane() {
		// -------------------------- LEFT --------------------------------
		// EDITOR
		this. = this.createTextArea();
		// scroll the editor
		RTextScrollPane edscroll = new RTextScrollPane(this.true);
		Gutter gutter = edscroll.getGutter();
		//URL url = this.getClass().getClassLoader().getResource("bookmark.png");		// review/remove or import location TODO
		//gutter.setBookmarkIcon(new ImageIcon(url));
		edscroll.setMinimumSize(new Dimension(300, 250));
		//edscroll.setPreferredSize(new Dimension(1000, 1000));
		// CONSOLE		
		JLabel conlbl = new JLabel("Console");
		conlbl.setBorder(BorderFactory.createEmptyBorder(4,8,2,8));
	    this. = new JTextArea();
	    
	    // show bottom of text automatically
	    // scroll the console
		conscroll.setMinimumSize(new Dimension(300, 250));
	    
		JPanel conPane = new JPanel();
		conPane.setLayout(new BoxLayout(conPane.));
		conPane.add(conlbl);
		conPane.add(conscroll);
	    
		final JSplitPane leftsplit = new JSplitPane(.edscrollconPane);		
		// -------------------------- RIGHT --------------------------------
		ImageIcon pbicon = new ImageIcon(this.getClass().getResource("/divconq/script/ui/media-playback-start.png"), "Run script");
		ImageIcon psicon = new ImageIcon(this.getClass().getResource("/divconq/script/ui/media-playback-stop.png"), "Stop script");
		ImageIcon sficon = new ImageIcon(this.getClass().getResource("/divconq/script/ui/media-seek-forward.png"), "Step into script");		
		Action stepact = new AbstractAction("Step"sficon) {
			private static final long serialVersionUID = 6291259738564026019L;
			public void actionPerformed(ActionEvent e) {
			}
		};
		Action runact = new AbstractAction("Run"pbicon) {
			private static final long serialVersionUID = -7125666000153246057L;
			public void actionPerformed(ActionEvent e) {
			}
		};
		Action stopact = new AbstractAction("Stop"psicon) {
			private static final long serialVersionUID = 1389157371678339040L;
			public void actionPerformed(ActionEvent e) {
				EditorPane.this.stop(true);
			}
		};
		JToolBar toolBar = new JToolBar();
		this. = new SmallButton(stepact"Step into script"); 
		toolBar.add(this.);
		this. = new SmallButton(runact"Run script");
		toolBar.add(this.);
		toolBar.add(new SmallButton(stopact"Stop script"));
		toolBar.addSeparator(new Dimension(24, 4));
		//toolBar.add(new JLabel(" | "));
		toolBar.add(this.);
		JLabel stacklbl = new JLabel("Stack");
		stacklbl.setBorder(BorderFactory.createEmptyBorder(4,8,2,8));
		this. = new JList(this.);
					int indexboolean isSelectedboolean cellHasFocus) {
				RecordStruct rec = (RecordStruct)value;
				JLabel lbl = new JLabel(rec.getFieldAsString("Command"));
				lbl.setOpaque(true);
				if (isSelected) {
		            lbl.setBackground(list.getSelectionBackground());
		            lbl.setForeground(list.getSelectionForeground());
		        } 
				else {
		        	lbl.setBackground(list.getBackground());
		        	lbl.setForeground(list.getForeground());
		        }
				return lbl;
			}
		});
			public void valueChanged(ListSelectionEvent e) {
				RecordStruct currinst = null;
				if (pos != -1)
				EditorPane.this..setModel(new VarsListModel((currinst == null) ? null : currinst.getFieldAsRecord("Variables")));
			}
		});
			public void mouseReleased(MouseEvent arg0) {
				if (idx != -1) {
					long line = currinst.getFieldAsInteger("Line") - 1;
					try {
						int pos = EditorPane.this..getLineStartOffset((int)line);
					catch (BadLocationException x) {
					}
				}
			}
		});
		JLabel varslbl = new JLabel("Selected Level Variables");
		varslbl.setBorder(BorderFactory.createEmptyBorder(4,8,2,8));
		this. = new JList();
			public void valueChanged(ListSelectionEvent e) {
				int pos = EditorPane.this..getSelectedIndex();
				if (pos != -1) {
					if (currvar != null)
						 EditorPane.this..setText(currvar);
				}
			}
		});
		JLabel vardlbl = new JLabel("Selected Variable Detail");
		vardlbl.setBorder(BorderFactory.createEmptyBorder(4,8,2,8));
	    this. = new JTextArea();
	    // scroll the console
	    
		JPanel debugPane = new JPanel();
		debugPane.setLayout(new BoxLayout(debugPane.));
		debugPane.add(toolBar);
		debugPane.add(stacklbl);
		debugPane.add(stackscroll);
		debugPane.add(varslbl);
		debugPane.add(varsscroll);
		debugPane.add(vardlbl);
		debugPane.add(varscroll);
		debugPane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10));
	    
		final JSplitPane bigsplit = new JSplitPane(.leftsplitdebugPane);
		this.getContentPane().add(bigsplit);
		// resizing
			public void componentShown(ComponentEvent arg0) {
				bigsplit.setDividerLocation(0.66);
				leftsplit.setDividerLocation(0.7);
			}
			public void componentResized(ComponentEvent arg0) {
				bigsplit.setDividerLocation(0.66);
				leftsplit.setDividerLocation(0.7);
			}
		});
	}
	public void start(TaskRun r) {
		this. = r;
		if (this. == null) {
			// TODO load last - better management
			this.setText(new File("./packages/dcTest/dcs/fileops-copy-2.dcs.xml"));
		}
		else {
			Activity act = (Activityr.getTask().getWork();
			act.setInDebugger(true);
			act.setDebugger(this);
			//this.console.setText(r.getLog());		// TODO just the messages
			r.getMessages().recordStream().forEach(entry -> this.log(entry));
			this. = act.getRunCount();
				public void log(OperationResult orRecordStruct entry) {
					EditorPane.this.log(entry);
				}
				public void step(OperationResult orint numint ofString name) {
					EditorPane.this..append("##### Step " + num + " of " + of + ": " + name + " #####\n");
				}
				public void progress(OperationResult orString msg) {
					EditorPane.this..append("***** " + msg + " *****\n");
				}
				public void amount(OperationResult orint v) {
					EditorPane.this..append(">>>>> " + v + "% <<<<<\n");
				}
			});
		}
        ActionListener taskPerformer = new ActionListener() {
            public void actionPerformed(ActionEvent evt) {
                //...Perform a task...
                //System.out.println("Reading SMTP Info.");
            	
            	EditorPane.this.updateDebuggerUI();
            }
        };
        
        this. = new Timer(1000, taskPerformer);
        this..start();
	}
	public void shutdown() {
		if (this. != null)
			this..stop();
	}
	public void prepTask(boolean debugmode) {
		this..setText("");
		this. = 0;
		Activity act = new Activity();
		act.setDebugMode(debugmode);
		act.setInDebugger(true);
		act.setDebugger(this);
		OperationResult compilelog = act.compile(this..getText());
		// update text pane in case includes where added - TODO make sure user does not save over their file with includes intact
		if (compilelog.hasErrors()) {
			JOptionPane.showMessageDialog(EditorPane.this"Error compiling script: " + compilelog.getMessage(), "Compile Error".);
			return;
		}
		Task task = new Task()
			.withTitle(act.getScript().getXml().getAttribute("Title""Debugging dcScript"))	
			.withTimeout(0)							// no timeout in editor mode
			.withWork(act);
		this. = new TaskRun(task);
			public void log(OperationResult orRecordStruct entry) {
				EditorPane.this.log(entry);
			}
			public void step(OperationResult orint numint ofString name) {
				EditorPane.this..append("##### Step " + num + " of " + of + ": " + name + " #####\n");
			}
			public void progress(OperationResult orString msg) {
				EditorPane.this..append("***** " + msg + " *****\n");
			}
			public void amount(OperationResult orint v) {
				EditorPane.this..append(">>>>> " + v + "% <<<<<\n");
			}
		});
	}
	public void log(RecordStruct entry) {
		this..append(this..formatLogEntry(entry) + "\n");
	}
	public void run() {
		if (this. == null)
			this.prepTask(false);
		if (this. == null)
			return;
		this..setText("Status: running");
		this..setEnabled(false);
		this..setEnabled(false);
	}
	public void step() {
		if (this. == null
			this.prepTask(true);
		if (this. == null)
			return;
		this. = 0;
		this..setText("Status: executing");
		this..setEditable(false);
		this..setEnabled(false);
		this..setEnabled(false);
	}
	public void updateDebuggerUI() {
		TaskRun run = this.;
		if (run != null) {
			Activity act = (Activityrun.getTask().getWork();
			// TODO maybe also every 5 seconds refresh?
			// only update UI if a new instruction has run
			//if (this.lastinstrun == act.getRunCount())
			//	return;
			this. = act.getDebugInfo();
			ListStruct stack = this..getFieldAsList("Stack");
			RecordStruct currinst = stack.getItemAsRecord(stack.getSize() - 1);
			long line = currinst.getFieldAsInteger("Line") - 1;
			try {
				int linemustbevisible = Math.max((int)line - 2, 0);
				// make sure at least a couple lines appear above the current instruction
				int viewpos = this..getLineStartOffset(linemustbevisible);
				Rectangle viewRect = this..modelToView(viewpos);
				if (!this..getVisibleRect().contains(viewRect)) {
				}
				else {
					// also try to make it so that at least a few lines show below current instruction
					linemustbevisible = (int)line + Math.min(this..getLineCount() - (int)line, 5);
					viewpos = this..getLineStartOffset(linemustbevisible);
					viewRect = this..modelToView(viewpos);
					if (!this..getVisibleRect().contains(viewRect)) 
				}
				int pos = this..getLineStartOffset((int)line);
			catch (BadLocationException x) {
			}
			this..update(stack);
			if (act.isDebugMode() && (this. < act.getRunCount())) {
				this..setText("Status: ready");
				this..setEnabled(true);
				this..setEnabled(true);
				this. = act.getRunCount();
			}
			if (act.isExitFlag()) {
				this..setText("Status: ready");
				this..setEnabled(true);
				this..setEnabled(true);
				..println("Script done. #" + act.getRuntime() + " - Code: " + run.getCode() + " - Message: " + run.getMessage());			
				this.stop(false);
			}
		}
	}
	public void console(String msg) {
		this..append(msg + "\n");
	}	
	protected Runnable uirefresher = new Runnable() {		
		public void run() {
		}
	};
	public void stepped() {
		if (SwingUtilities.isEventDispatchThread()) 
		else
			SwingUtilities.invokeLater(this.);
	}
	public void stop(boolean kill) {
		if (this. == null)
			return;
		if (kill)
			this..kill();
		else
		this. = null;
		this..setEditable(true);
		this..setText("Status: stopped");
		this..setEnabled(true);
		this..setEnabled(true);
	}
	private JMenuBar createMenuBar() {
		JMenuBar mb = new JMenuBar();
		JMenu menu = new JMenu("File");
		menu.add(new AbstractAction("New") {			
			private static final long serialVersionUID = 4212493611151700478L;
			public void actionPerformed(ActionEvent arg0) {
	        	EditorPane.this. = null;
	        	EditorPane.this..setText("");
		     }
		});
		menu.add(new AbstractAction("Open...") {			
			private static final long serialVersionUID = 4212493611151700478L;
			public void actionPerformed(ActionEvent arg0) {
		        int returnVal = EditorPane.this..showOpenDialog(EditorPane.this);
		        if (returnVal == .) {
		        	EditorPane.this.setText(.getSelectedFile());
		        } 		
		     }
		});
		menu.add(new AbstractAction("Save") {			
			private static final long serialVersionUID = 4212493611151700478L;
			public void actionPerformed(ActionEvent arg0) {
				if (EditorPane.this. == null) {
			        int returnVal = EditorPane.this..showSaveDialog(EditorPane.this);
			        if (returnVal != .
			        	return;
			        
			        EditorPane.this. = .getSelectedFile();
				}
				if (sres.hasErrors())
					JOptionPane.showMessageDialog(EditorPane.this"Error saving file: " + sres.getMessage(), "Save Error".);
			}
		});
		menu.add(new AbstractAction("Save As...") {			
			private static final long serialVersionUID = 4212493611151700478L;
			public void actionPerformed(ActionEvent arg0) {
		        int returnVal = EditorPane.this..showSaveDialog(EditorPane.this);
		        if (returnVal == .) {
		        	EditorPane.this. = .getSelectedFile();
					if (sres.hasErrors())
						JOptionPane.showMessageDialog(EditorPane.this"Error saving file: " + sres.getMessage(), "Save Error".);
		        } 		
			}
		});
		menu.add(new AbstractAction("Exit") {			
			private static final long serialVersionUID = 4212493611151700478L;
			public void actionPerformed(ActionEvent arg0) {
			}
		});
		mb.add(menu);
		menu = new JMenu("Themes");
		menu.add(new JMenuItem(new ThemeAction("Default""/default.xml")));		// TODO move these to better location in resources
		menu.add(new JMenuItem(new ThemeAction("Dark""/dark.xml")));
		menu.add(new JMenuItem(new ThemeAction("Eclipse""/eclipse.xml")));
		menu.add(new JMenuItem(new ThemeAction("Visual Studio""/vs.xml")));
		mb.add(menu);
		menu = new JMenu("Help");
		JMenuItem item = new JMenuItem(new AboutAction());
		menu.add(item);
		mb.add(menu);
		return mb;
	}

Creates the text area for this application.

Returns:
The text area.
		RSyntaxTextArea textArea = new RSyntaxTextArea(25, 70);
		textArea.setCaretPosition(0);
		textArea.setMarkOccurrences(true);
		textArea.setAntiAliasingEnabled(true);
		textArea.setCodeFoldingEnabled(true);
		//textArea.setFont(new Font("VeraMono.ttf", Font.PLAIN, 13));
		//for (int i=0; i<textArea.getSyntaxScheme().styles.length; i++) {
		//	if (textArea.getSyntaxScheme().styles[i]!=null) {
		//		textArea.getSyntaxScheme().styles[i].font = textArea.getFont();
		//	}
		//}
		return textArea;
	}

Focuses the text area.
	void focusTextArea() {
	}

Sets the content in the text area to that in the specified resource.

Parameters:
resource The resource to load.
	private void setText(File resource) {
		this..setText("");
		this. = resource;
		BufferedReader r = null;
		try {
					new FileInputStream(resource), "UTF-8"));
			this..read(rnull);
		catch (RuntimeException x) {
			throw x// FindBugs
		catch (Exception x) { 
			// TODO error
			this..setText("Type here to see syntax highlighting");
		}
		try {
			if (r != null)
				r.close();
		}
		catch (IOException x) { 
		}
	}
	private void setText(String src) {
		this. = null;
		this..setText(src);
	}
	public class VarsListModel extends AbstractListModel {
		private static final long serialVersionUID = 100623371649283278L;
		protected RecordStruct inst = null;
		protected List<Stringnames = new ArrayList<String>();
		public VarsListModel(RecordStruct inst) {
			this. = inst;
			if (this. == null)
				return;
			for (FieldStruct fld : this..getFields())
				this..add(fld.getName());
			Collections.sort(this.);
		}
		public String getFormatted(int pos) {
			String name = this..get(pos);
			Struct struct = this..getField(name);
			if (struct != null)
				if (struct instanceof CompositeStruct) {
					try {
						PrintStream ps = new PrintStream(os);
						((CompositeStructstruct).toBuilder(new JsonStreamBuilder(pstrue));
						return os.toString("UTF8");
					catch (Exception x) {
						// TODO
						..println("Error formatting structure: " + x);
					}
				}
				else
					return struct.toString();
			return "[null]";
		}
		public Object getElementAt(int pos) {
			String name = this..get(pos);
			return name + " = " + this..getField(name);
		}
		public int getSize() {
			return this..size();
		}
	}
	public class StackListModel extends AbstractListModel {
		private static final long serialVersionUID = 4548254186810085022L;
		protected ListStruct stack = null;
		public void update(ListStruct stack) {
			int selpos = EditorPane.this..getSelectedIndex();
			int changed = stack.getSize();
			if (this. != null)
				changed -= this..getSize();
			else
				changed = 0;
			this. = stack;
			if (changed < 0)
				this.fireIntervalRemoved(this, 0, Math.abs(changed));
			else
				this.fireIntervalAdded(this, 0, changed);
			selpos = selpos + changed;
			if (selpos < 0)
				selpos = 0;
		}
		public void clear() {
			if (this. == null)
				return;
			int changed = this..getSize();
			this. = null;
			if (changed > 0)
				this.fireIntervalRemoved(this, 0, changed);
		}
		public Object getElementAt(int pos) {
			return (this. == null) ? null : this..getItem(this..getSize() - pos - 1);
		}
		public int getSize() {
			return (this. == null) ? 0 : this..getSize();
		}		
	}
	private class AboutAction extends AbstractAction {
		private static final long serialVersionUID = 3311869625217732652L;
		public AboutAction() {
			super("About dcScript...");
		}
		public void actionPerformed(ActionEvent e) {
			JOptionPane.showMessageDialog(EditorPane.this,
					"<html><b>dcScript</b> - Next Gen JCL" +
					"<br>Version 0.8.1" +
					"<br><a href=\"http://divconq.com/\">divconq.com</a>" +
					"<br>Licensed under an Apache license",
					"About dcScript",
		}
	}
	private class ThemeAction extends AbstractAction {
		private static final long serialVersionUID = 7828839661874891753L;
		private String xml = null;
		public ThemeAction(String nameString xml) {
			super(name);
			this. = xml;
		}
		public void actionPerformed(ActionEvent e) {
			try {
				Theme theme = Theme.load(in);
				theme.apply();
			catch (IOException x) {
				// TODO
			}
		}
	}
	public class SmallButton extends JButton implements MouseListener {
		private static final long serialVersionUID = -1851724407908438330L;
		protected Border raised = null;
		protected Border lowered = null;
		protected Border inactive = null;
		public SmallButton(Action actString tip) {
			this. = new EmptyBorder(2, 2, 2, 2);
			this.setBorder(this.);
			this.setMargin(new Insets(1, 1, 1, 1));
			this.setToolTipText(tip);
			this.addMouseListener(this);
		}
		public float getAlignmentY() {
			return 0.5f;
		}
		public void mousePressed(MouseEvent e) {
		}
		public void mouseReleased(MouseEvent e) {
		}
		public void mouseClicked(MouseEvent e) {
		}
		public void mouseEntered(MouseEvent e) {
		}
		public void mouseExited(MouseEvent e) {
		}
	}