package ij.measure;
import ij.plugin.filter.Analyzer;
import ij.plugin.frame.Recorder;
import ij.plugin.*;
import ij.*;
import ij.gui.*;
import ij.text.*;
import java.awt.*;
import java.awt.event.*;


/** This class implements the Apply Macro command in tables.
* @author Michael Schmid
*/
public class ResultsTableMacros implements Runnable, DialogListener, ActionListener, KeyListener {
	private static String NAME = "TableMacro.ijm";
	private String defaultMacro = "Sin=sin(row*0.1);\nCos=cos(row*0.1);\nSqr=Sin*Sin+Cos*Cos;";
	private GenericDialog gd;
	private ResultsTable rt, rtBackup;
	private Button runButton, resetButton, openButton, saveButton;
	private String title;
	private int runCount;
	private TextArea ta;

	public ResultsTableMacros(ResultsTable rt) {
		this.rt = rt;
		title = rt!=null?rt.getTitle():null;
		Thread thread = new Thread(this, "ResultTableMacros");
		thread.start();
	}

	private void showDialog() {
		if (rt==null)
			rt = Analyzer.getResultsTable();
		if (rt==null || rt.size()==0) {
			IJ.error("Results Table required");
			return;
		}
		String[] temp = rt.getHeadingsAsVariableNames();
		String[] variableNames = new String[temp.length+2];
		variableNames[0] = "Insert...";
		variableNames[1] = "row";
		for (int i=2; i

Macro Equations for Results Tables

    "+ "
  • The macro, or a selection, is applied to each row of the table."+ "
  • A new variable starting with an Uppercase character creates
    a new column."+ "
  • A new variable starting with a lowercase character is temporary."+ "
  • The variable row (row index) is pre-defined.\n"+ "
  • String operations are supported for the 'Label' column only (if
    enabled"+ "with Analyze>Set Measurements>Display Label)."+ "
  • Click \"Run\", or press "+(IJ.isMacOSX()?"cmd":"ctrl") + "-r, to apply the macro code to the table."+ "
  • Select a line and press "+(IJ.isMacOSX()?"cmd":"ctrl") + "-r to apply a line of macro code."+ "
  • Click \"Reset\" to revert to the original version of the table."+ "
  • The code is saved at macros/TableMacro.ijm, and the
    \"Apply Macro\" command is recorded, when you click \"OK\"."+ "
  • All Table. macro functions (such as Table.size) refer to the
    current (frontmost) table unless the table name is given."+ "
"); gd.addDialogListener(this); gd.showDialog(); if (gd.wasCanceled()) { // dialog cancelled? rt = rtBackup; updateDisplay(); return; } if (runCount==0) applyMacro(); if (Recorder.record) { String macro = getMacroCode(); macro = macro.replaceAll("\n", " "); if (Recorder.scriptMode()) { Recorder.recordCall("title = \""+title+"\";"); Recorder.recordCall("frame = WindowManager.getFrame(title);"); Recorder.recordCall("rt = frame.getResultsTable();"); Recorder.recordCall("rt.applyMacro(\""+macro+"\");"); Recorder.recordCall("rt.show(title);"); } else { if (title.equals("Results")) Recorder.record("Table.applyMacro", macro); else Recorder.record("Table.applyMacro", macro, title); } } IJ.saveString(ta.getText(), IJ.getDir("macros")+NAME); } private void applyMacro() { String code = getMacroCode(); rt.applyMacro(code); updateDisplay(); runCount++; } private String getMacroCode() { int start = ta.getSelectionStart(); int end = ta.getSelectionEnd(); return start==end?ta.getText():ta.getSelectedText(); } public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) { final String variableName = gd.getNextChoice(); if (e!=null && (e.getSource() instanceof Choice) && !variableName.equals("Insert...")) { final int pos = ta.getCaretPosition(); ((Choice)e.getSource()).select(0); final TextArea textArea = ta; new Thread(new Runnable() { public void run() { IJ.wait(100); textArea.insert(variableName, pos); textArea.setCaretPosition(pos+variableName.length()); textArea.requestFocus(); }}).start(); } return true; } public void actionPerformed(ActionEvent e) { Object source = e.getSource(); if (source==runButton) { applyMacro(); } else if (source==resetButton) { rt = (ResultsTable)rtBackup.clone(); updateDisplay(); } else if (source==openButton) { String macro = IJ.openAsString(null); if (macro==null) return; if (macro.startsWith("Error: ")) { IJ.error(macro); return; } else ta.setText(macro); } else if (source==saveButton) { ta.selectAll(); String macro = ta.getText(); ta.select(0, 0); IJ.saveString(macro, null); } } public void keyPressed(KeyEvent e) { int flags = e.getModifiers(); boolean control = (flags & KeyEvent.CTRL_MASK) != 0; boolean meta = (flags & KeyEvent.META_MASK) != 0; int keyCode = e.getKeyCode(); if (keyCode==KeyEvent.VK_R && (control||meta)) applyMacro(); if (keyCode==KeyEvent.VK_Z && (control||meta)) { rt = (ResultsTable)rtBackup.clone(); updateDisplay(); } } private void updateDisplay() { if (title!=null) rt.show(title); } public void keyReleased(KeyEvent e) { } public void keyTyped(KeyEvent e) { } private String getMacro() { String macro = IJ.openAsString(IJ.getDir("macros")+NAME); if (macro==null || macro.startsWith("Error:")) return defaultMacro; else { macro = macro.replaceAll("rowNumber", "row"); macro = macro.replaceAll("rowIndex", "row"); return macro; } } public void run() { rtBackup = (ResultsTable)rt.clone(); showDialog(); } }

Ads help maintain this website.