package ij.gui;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import ij.*;
import ij.plugin.frame.Recorder;
import ij.plugin.ScreenGrabber;
import ij.plugin.filter.PlugInFilter;
import ij.plugin.filter.PlugInFilterRunner;
import ij.util.Tools;
import ij.macro.*;
public class GenericDialog extends Dialog implements ActionListener, TextListener,
FocusListener, ItemListener, KeyListener, AdjustmentListener, WindowListener {
public static final int MAX_SLIDERS = 25;
protected Vector numberField, stringField, checkbox, choice, slider, radioButtonGroups;
protected TextArea textArea1, textArea2;
protected Vector defaultValues,defaultText,defaultStrings,defaultChoiceIndexes;
protected Component theLabel;
private Button cancel, okay, no, help;
private String okLabel = " OK ";
private String cancelLabel = "Cancel";
private String helpLabel = "Help";
private boolean wasCanceled, wasOKed;
private int y;
private int nfIndex, sfIndex, cbIndex, choiceIndex, textAreaIndex, radioButtonIndex;
private GridBagLayout grid;
private GridBagConstraints c;
private boolean firstNumericField=true;
private boolean firstSlider=true;
private boolean invalidNumber;
private String errorMessage;
private boolean firstPaint = true;
private Hashtable labels;
private boolean macro;
private String macroOptions;
private int topInset, leftInset, bottomInset;
private boolean customInsets;
private int[] sliderIndexes;
private double[] sliderScales;
private Checkbox previewCheckbox; private Vector dialogListeners; private PlugInFilterRunner pfr; private String previewLabel = " Preview";
private final static String previewRunning = "wait...";
private boolean recorderOn; private boolean yesNoCancel;
private char echoChar;
private boolean hideCancelButton;
private boolean centerDialog = true;
private String helpURL;
private String yesLabel, noLabel;
private boolean smartRecording;
private Vector imagePanels;
public GenericDialog(String title) {
this(title, getParentFrame());
}
private static Frame getParentFrame() {
Frame parent = WindowManager.getCurrentImage()!=null?
(Frame)WindowManager.getCurrentImage().getWindow():IJ.getInstance()!=null?IJ.getInstance():new Frame();
if (IJ.isMacOSX() && IJ.isJava18()) {
ImageJ ij = IJ.getInstance();
if (ij!=null && ij.isActive())
parent = ij;
else
parent = null;
}
return parent;
}
public GenericDialog(String title, Frame parent) {
super(parent==null?new Frame():parent, title, true);
if (Prefs.blackCanvas) {
setForeground(SystemColor.controlText);
setBackground(SystemColor.control);
}
grid = new GridBagLayout();
c = new GridBagConstraints();
setLayout(grid);
macroOptions = Macro.getOptions();
macro = macroOptions!=null;
addKeyListener(this);
addWindowListener(this);
}
public void addNumericField(String label, double defaultValue, int digits) {
addNumericField(label, defaultValue, digits, 6, null);
}
public void addNumericField(String label, double defaultValue, int digits, int columns, String units) {
String label2 = label;
if (label2.indexOf('_')!=-1)
label2 = label2.replace('_', ' ');
Label theLabel = makeLabel(label2);
c.gridx = 0; c.gridy = y;
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
if (firstNumericField)
c.insets = getInsets(5, 0, 3, 0);
else
c.insets = getInsets(0, 0, 3, 0);
grid.setConstraints(theLabel, c);
add(theLabel);
if (numberField==null) {
numberField = new Vector(5);
defaultValues = new Vector(5);
defaultText = new Vector(5);
}
if (IJ.isWindows()) columns -= 2;
if (columns<1) columns = 1;
String defaultString = IJ.d2s(defaultValue, digits);
if (Double.isNaN(defaultValue))
defaultString = "";
TextField tf = new TextField(defaultString, columns);
if (IJ.isLinux()) tf.setBackground(Color.white);
tf.addActionListener(this);
tf.addTextListener(this);
tf.addFocusListener(this);
tf.addKeyListener(this);
numberField.addElement(tf);
defaultValues.addElement(new Double(defaultValue));
defaultText.addElement(tf.getText());
c.gridx = 1; c.gridy = y;
c.anchor = GridBagConstraints.WEST;
tf.setEditable(true);
firstNumericField = false;
if (units==null||units.equals("")) {
grid.setConstraints(tf, c);
add(tf);
} else {
Panel panel = new Panel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
panel.add(tf);
panel.add(new Label(" "+units));
grid.setConstraints(panel, c);
add(panel);
}
if (Recorder.record || macro)
saveLabel(tf, label);
y++;
}
private Label makeLabel(String label) {
if (IJ.isMacintosh())
label += " ";
return new Label(label);
}
private void saveLabel(Object component, String label) {
if (labels==null)
labels = new Hashtable();
if (label.length()>0) {
if (label.charAt(0)==' ')
label = label.trim();
labels.put(component, label);
}
}
public void addStringField(String label, String defaultText) {
addStringField(label, defaultText, 8);
}
public void addStringField(String label, String defaultText, int columns) {
String label2 = label;
if (label2.indexOf('_')!=-1)
label2 = label2.replace('_', ' ');
Label theLabel = makeLabel(label2);
c.gridx = 0; c.gridy = y;
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
boolean custom = customInsets;
if (stringField==null) {
stringField = new Vector(4);
defaultStrings = new Vector(4);
c.insets = getInsets(5, 0, 5, 0);
} else
c.insets = getInsets(0, 0, 5, 0);
grid.setConstraints(theLabel, c);
add(theLabel);
if (custom) {
if (stringField.size()==0)
c.insets = getInsets(5, 0, 5, 0);
else
c.insets = getInsets(0, 0, 5, 0);
}
TextField tf = new TextField(defaultText, columns);
if (IJ.isLinux()) tf.setBackground(Color.white);
tf.setEchoChar(echoChar);
echoChar = 0;
tf.addActionListener(this);
tf.addTextListener(this);
tf.addFocusListener(this);
tf.addKeyListener(this);
c.gridx = 1; c.gridy = y;
c.anchor = GridBagConstraints.WEST;
grid.setConstraints(tf, c);
tf.setEditable(true);
add(tf);
stringField.addElement(tf);
defaultStrings.addElement(defaultText);
if (Recorder.record || macro)
saveLabel(tf, label);
y++;
}
public void setEchoChar(char echoChar) {
this.echoChar = echoChar;
}
public void addCheckbox(String label, boolean defaultValue) {
addCheckbox(label, defaultValue, false);
}
private void addCheckbox(String label, boolean defaultValue, boolean isPreview) {
String label2 = label;
if (label2.indexOf('_')!=-1)
label2 = label2.replace('_', ' ');
if (checkbox==null) {
checkbox = new Vector(4);
c.insets = getInsets(15, 20, 0, 0);
} else
c.insets = getInsets(0, 20, 0, 0);
c.gridx = 0; c.gridy = y;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
Checkbox cb = new Checkbox(label2);
grid.setConstraints(cb, c);
cb.setState(defaultValue);
cb.addItemListener(this);
cb.addKeyListener(this);
add(cb);
checkbox.addElement(cb);
if (!isPreview &&(Recorder.record || macro)) saveLabel(cb, label);
if (isPreview) previewCheckbox = cb;
y++;
}
public void addPreviewCheckbox(PlugInFilterRunner pfr) {
if (previewCheckbox != null)
return;
ImagePlus imp = WindowManager.getCurrentImage();
if (imp!=null && imp.isComposite() && ((CompositeImage)imp).getMode()==IJ.COMPOSITE)
return;
this.pfr = pfr;
addCheckbox(previewLabel, false, true);
}
public void addPreviewCheckbox(PlugInFilterRunner pfr, String label) {
if (previewCheckbox!=null)
return;
previewLabel = label;
this.pfr = pfr;
addCheckbox(previewLabel, false, true);
}
public void addCheckboxGroup(int rows, int columns, String[] labels, boolean[] defaultValues) {
addCheckboxGroup(rows, columns, labels, defaultValues, null);
}
public void addCheckboxGroup(int rows, int columns, String[] labels, boolean[] defaultValues, String[] headings) {
Panel panel = new Panel();
int nRows = headings!=null?rows+1:rows;
panel.setLayout(new GridLayout(nRows, columns, 6, 0));
int startCBIndex = cbIndex;
if (checkbox==null)
checkbox = new Vector(12);
if (headings!=null) {
Font font = new Font("SansSerif", Font.BOLD, 12);
for (int i=0; i<columns; i++) {
if (i>headings.length-1 || headings[i]==null)
panel.add(new Label(""));
else {
Label label = new Label(headings[i]);
label.setFont(font);
panel.add(label);
}
}
}
int i1 = 0;
int[] index = new int[labels.length];
for (int row=0; row<rows; row++) {
for (int col=0; col<columns; col++) {
int i2 = col*rows+row;
if (i2>=labels.length) break;
index[i1] = i2;
String label = labels[i1];
if (label==null || label.length()==0) {
Label lbl = new Label("");
panel.add(lbl);
i1++;
continue;
}
if (label.indexOf('_')!=-1)
label = label.replace('_', ' ');
Checkbox cb = new Checkbox(label);
checkbox.addElement(cb);
cb.setState(defaultValues[i1]);
cb.addItemListener(this);
if (Recorder.record || macro)
saveLabel(cb, labels[i1]);
if (IJ.isLinux()) {
Panel panel2 = new Panel();
panel2.setLayout(new BorderLayout());
panel2.add("West", cb);
panel.add(panel2);
} else
panel.add(cb);
i1++;
}
}
c.gridx = 0; c.gridy = y;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.insets = getInsets(10, 0, 0, 0);
grid.setConstraints(panel, c);
add(panel);
y++;
}
public void addRadioButtonGroup(String label, String[] items, int rows, int columns, String defaultItem) {
Panel panel = new Panel();
int n = items.length;
panel.setLayout(new GridLayout(rows, columns, 0, 0));
CheckboxGroup cg = new CheckboxGroup();
for (int i=0; i<n; i++) {
Checkbox cb = new Checkbox(items[i],cg,items[i].equals(defaultItem));
cb.addItemListener(this);
panel.add(cb);
}
if (radioButtonGroups==null)
radioButtonGroups = new Vector();
radioButtonGroups.addElement(cg);
Insets insets = getInsets(5, 10, 0, 0);
if (label==null || label.equals("")) {
label = "rbg"+radioButtonGroups.size();
insets.top += 5;
} else {
setInsets(10, insets.left, 0);
addMessage(label);
insets.top = 2;
insets.left += 10;
}
c.gridx = 0; c.gridy = y;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(insets.top, insets.left, 0, 0);
grid.setConstraints(panel, c);
add(panel);
if (Recorder.record || macro)
saveLabel(cg, label);
y++;
}
public void addChoice(String label, String[] items, String defaultItem) {
String label2 = label;
if (label2.indexOf('_')!=-1)
label2 = label2.replace('_', ' ');
Label theLabel = makeLabel(label2);
c.gridx = 0; c.gridy = y;
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
if (choice==null) {
choice = new Vector(4);
defaultChoiceIndexes = new Vector(4);
c.insets = getInsets(5, 0, 5, 0);
} else
c.insets = getInsets(0, 0, 5, 0);
grid.setConstraints(theLabel, c);
add(theLabel);
Choice thisChoice = new Choice();
thisChoice.addKeyListener(this);
thisChoice.addItemListener(this);
for (int i=0; i<items.length; i++)
thisChoice.addItem(items[i]);
if (defaultItem!=null)
thisChoice.select(defaultItem);
else
thisChoice.select(0);
c.gridx = 1; c.gridy = y;
c.anchor = GridBagConstraints.WEST;
grid.setConstraints(thisChoice, c);
add(thisChoice);
choice.addElement(thisChoice);
int index = thisChoice.getSelectedIndex();
defaultChoiceIndexes.addElement(new Integer(index));
if (Recorder.record || macro)
saveLabel(thisChoice, label);
y++;
}
public void addMessage(String text) {
addMessage(text, null, null);
}
public void addMessage(String text, Font font) {
addMessage(text, font, null);
}
public void addMessage(String text, Font font, Color color) {
theLabel = null;
if (text.indexOf('\n')>=0)
theLabel = new MultiLineLabel(text);
else
theLabel = new Label(text);
c.gridx = 0; c.gridy = y;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.insets = getInsets(text.equals("")?0:10, 20, 0, 0);
c.fill = GridBagConstraints.HORIZONTAL;
grid.setConstraints(theLabel, c);
if (font!=null)
theLabel.setFont(font);
if (color!=null)
theLabel.setForeground(color);
add(theLabel);
c.fill = GridBagConstraints.NONE;
y++;
}
public void addTextAreas(String text1, String text2, int rows, int columns) {
if (textArea1!=null) return;
Panel panel = new Panel();
Font font = new Font("SansSerif", Font.PLAIN, 14);
textArea1 = new TextArea(text1,rows,columns,TextArea.SCROLLBARS_NONE);
if (IJ.isLinux()) textArea1.setBackground(Color.white);
textArea1.setFont(font);
textArea1.addTextListener(this);
panel.add(textArea1);
if (text2!=null) {
textArea2 = new TextArea(text2,rows,columns,TextArea.SCROLLBARS_NONE);
if (IJ.isLinux()) textArea2.setBackground(Color.white);
textArea2.setFont(font);
panel.add(textArea2);
}
c.gridx = 0; c.gridy = y;
c.gridwidth = 2;
c.anchor = GridBagConstraints.WEST;
c.insets = getInsets(15, 20, 0, 0);
grid.setConstraints(panel, c);
add(panel);
y++;
}
public void addSlider(String label, double minValue, double maxValue, double defaultValue) {
if (defaultValue<minValue) defaultValue=minValue;
if (defaultValue>maxValue) defaultValue=maxValue;
int columns = 4;
int digits = 0;
double scale = 1.0;
if ((maxValue-minValue)<=5.0 && (minValue!=(int)minValue||maxValue!=(int)maxValue||defaultValue!=(int)defaultValue)) {
scale = 20.0;
minValue *= scale;
maxValue *= scale;
defaultValue *= scale;
digits = 2;
}
String label2 = label;
if (label2.indexOf('_')!=-1)
label2 = label2.replace('_', ' ');
Label theLabel = makeLabel(label2);
c.gridx = 0; c.gridy = y;
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
c.insets = new Insets(0, 0, 3, 0);
grid.setConstraints(theLabel, c);
add(theLabel);
if (slider==null) {
slider = new Vector(5);
sliderIndexes = new int[MAX_SLIDERS];
sliderScales = new double[MAX_SLIDERS];
}
Scrollbar s = new Scrollbar(Scrollbar.HORIZONTAL, (int)defaultValue, 1, (int)minValue, (int)maxValue+1);
GUI.fix(s);
slider.addElement(s);
s.addAdjustmentListener(this);
s.setUnitIncrement(1);
if (numberField==null) {
numberField = new Vector(5);
defaultValues = new Vector(5);
defaultText = new Vector(5);
}
if (IJ.isWindows()) columns -= 2;
if (columns<1) columns = 1;
TextField tf = new TextField(IJ.d2s(defaultValue/scale, digits), columns);
if (IJ.isLinux()) tf.setBackground(Color.white);
tf.addActionListener(this);
tf.addTextListener(this);
tf.addFocusListener(this);
tf.addKeyListener(this);
numberField.addElement(tf);
sliderIndexes[slider.size()-1] = numberField.size()-1;
sliderScales[slider.size()-1] = scale;
defaultValues.addElement(new Double(defaultValue/scale));
defaultText.addElement(tf.getText());
tf.setEditable(true);
firstSlider = false;
Panel panel = new Panel();
GridBagLayout pgrid = new GridBagLayout();
GridBagConstraints pc = new GridBagConstraints();
panel.setLayout(pgrid);
pc.gridx = 0; pc.gridy = 0;
pc.gridwidth = 1;
pc.ipadx = 85;
pc.anchor = GridBagConstraints.WEST;
pgrid.setConstraints(s, pc);
panel.add(s);
pc.ipadx = 0; pc.gridx = 1;
pc.insets = new Insets(5, 5, 0, 0);
pc.anchor = GridBagConstraints.EAST;
pgrid.setConstraints(tf, pc);
panel.add(tf);
grid.setConstraints(panel, c);
c.gridx = 1; c.gridy = y;
c.gridwidth = 1;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(0, 0, 0, 0);
grid.setConstraints(panel, c);
add(panel);
y++;
if (Recorder.record || macro)
saveLabel(tf, label);
}
public void addPanel(Panel panel) {
addPanel(panel , GridBagConstraints.WEST, getInsets(5,0,0,0));
}
public void addPanel(Panel panel, int constraints, Insets insets) {
c.gridx = 0; c.gridy = y;
c.gridwidth = 2;
c.anchor = constraints;
c.insets = insets;
grid.setConstraints(panel, c);
add(panel);
y++;
}
public void addImage(ImagePlus image) {
ImagePanel imagePanel = new ImagePanel(image);
addPanel(imagePanel);
if (imagePanels==null)
imagePanels = new Vector();
imagePanels.add(imagePanel);
}
public void setInsets(int top, int left, int bottom) {
topInset = top;
leftInset = left;
bottomInset = bottom;
customInsets = true;
}
public void setOKLabel(String label) {
okLabel = label;
}
public void setCancelLabel(String label) {
cancelLabel = label;
}
public void setHelpLabel(String label) {
helpLabel = label;
}
public void setSmartRecording(boolean smartRecording) {
this.smartRecording = smartRecording;
}
public void enableYesNoCancel() {
enableYesNoCancel(" Yes ", " No ");
}
public void enableYesNoCancel(String yesLabel, String noLabel) {
this.yesLabel = yesLabel;
this.noLabel = noLabel;
yesNoCancel = true;
}
public void hideCancelButton() {
hideCancelButton = true;
}
Insets getInsets(int top, int left, int bottom, int right) {
if (customInsets) {
customInsets = false;
return new Insets(topInset, leftInset, bottomInset, 0);
} else
return new Insets(top, left, bottom, right);
}
public void addDialogListener(DialogListener dl) {
if (dialogListeners == null)
dialogListeners = new Vector();
dialogListeners.addElement(dl);
if (IJ.debugMode) IJ.log("GenericDialog: Listener added: "+dl);
}
public boolean wasCanceled() {
if (wasCanceled)
Macro.abort();
return wasCanceled;
}
public boolean wasOKed() {
return wasOKed || macro;
}
public double getNextNumber() {
if (numberField==null)
return -1.0;
TextField tf = (TextField)numberField.elementAt(nfIndex);
String theText = tf.getText();
String label=null;
if (macro) {
label = (String)labels.get((Object)tf);
theText = Macro.getValue(macroOptions, label, theText);
}
String originalText = (String)defaultText.elementAt(nfIndex);
double defaultValue = ((Double)(defaultValues.elementAt(nfIndex))).doubleValue();
double value;
boolean skipRecording = false;
if (theText.equals(originalText)) {
value = defaultValue;
if (smartRecording) skipRecording=true;
} else {
Double d = getValue(theText);
if (d!=null)
value = d.doubleValue();
else {
if (theText.startsWith("&")) theText = theText.substring(1);
Interpreter interp = Interpreter.getInstance();
value = interp!=null?interp.getVariable2(theText):Double.NaN;
if (Double.isNaN(value)) {
invalidNumber = true;
errorMessage = "\""+theText+"\" is an invalid number";
value = Double.NaN;
if (macro) {
IJ.error("Macro Error", "Numeric value expected in run() function\n \n"
+" Dialog box title: \""+getTitle()+"\"\n"
+" Key: \""+label.toLowerCase(Locale.US)+"\"\n"
+" Value or variable name: \""+theText+"\"");
}
}
}
}
if (recorderOn && !skipRecording) {
recordOption(tf, trim(theText));
}
nfIndex++;
return value;
}
private String trim(String value) {
if (value.endsWith(".0"))
value = value.substring(0, value.length()-2);
if (value.endsWith(".00"))
value = value.substring(0, value.length()-3);
return value;
}
private void recordOption(Object component, String value) {
String label = (String)labels.get(component);
if (value.equals("")) value = "[]";
Recorder.recordOption(label, value);
}
private void recordCheckboxOption(Checkbox cb) {
String label = (String)labels.get((Object)cb);
if (label!=null) {
if (cb.getState()) Recorder.recordOption(label);
else if (Recorder.getCommandOptions()==null)
Recorder.recordOption(" ");
}
}
protected Double getValue(String text) {
Double d;
try {d = new Double(text);}
catch (NumberFormatException e){
d = null;
}
return d;
}
public double parseDouble(String s) {
if (s==null) return Double.NaN;
double value = Tools.parseDouble(s);
if (Double.isNaN(value)) {
if (s.startsWith("&")) s = s.substring(1);
Interpreter interp = Interpreter.getInstance();
value = interp!=null?interp.getVariable2(s):Double.NaN;
}
return value;
}
public boolean invalidNumber() {
boolean wasInvalid = invalidNumber;
invalidNumber = false;
return wasInvalid;
}
public String getErrorMessage() {
return errorMessage;
}
public String getNextString() {
String theText;
if (stringField==null)
return "";
TextField tf = (TextField)(stringField.elementAt(sfIndex));
theText = tf.getText();
if (macro) {
String label = (String)labels.get((Object)tf);
theText = Macro.getValue(macroOptions, label, theText);
if (theText!=null && (theText.startsWith("&")||label.toLowerCase(Locale.US).startsWith(theText))) {
if (theText.startsWith("&")) theText = theText.substring(1);
Interpreter interp = Interpreter.getInstance();
String s = interp!=null?interp.getVariableAsString(theText):null;
if (s!=null) theText = s;
}
}
if (recorderOn) {
String s = theText;
if (s!=null&&s.length()>=3&&Character.isLetter(s.charAt(0))&&s.charAt(1)==':'&&s.charAt(2)=='\\')
s = s.replaceAll("\\\\", "\\\\\\\\"); if (!smartRecording || !s.equals((String)defaultStrings.elementAt(sfIndex)))
recordOption(tf, s);
else if (Recorder.getCommandOptions()==null)
Recorder.recordOption(" ");
}
sfIndex++;
return theText;
}
public boolean getNextBoolean() {
if (checkbox==null)
return false;
Checkbox cb = (Checkbox)(checkbox.elementAt(cbIndex));
if (recorderOn)
recordCheckboxOption(cb);
boolean state = cb.getState();
if (macro) {
String label = (String)labels.get((Object)cb);
String key = Macro.trimKey(label);
state = isMatch(macroOptions, key+" ");
}
cbIndex++;
return state;
}
boolean isMatch(String s1, String s2) {
if (s1.startsWith(s2))
return true;
s2 = " " + s2;
int len1 = s1.length();
int len2 = s2.length();
boolean match, inLiteral=false;
char c;
for (int i=0; i<len1-len2+1; i++) {
c = s1.charAt(i);
if (inLiteral && c==']')
inLiteral = false;
else if (c=='[')
inLiteral = true;
if (c!=s2.charAt(0) || inLiteral || (i>1&&s1.charAt(i-1)=='='))
continue;
match = true;
for (int j=0; j<len2; j++) {
if (s2.charAt(j)!=s1.charAt(i+j))
{match=false; break;}
}
if (match) return true;
}
return false;
}
public String getNextChoice() {
if (choice==null)
return "";
Choice thisChoice = (Choice)(choice.elementAt(choiceIndex));
String item = thisChoice.getSelectedItem();
if (macro) {
String label = (String)labels.get((Object)thisChoice);
item = Macro.getValue(macroOptions, label, item);
if (item!=null && item.startsWith("&")) item = getChoiceVariable(item);
}
if (recorderOn)
recordOption(thisChoice, item);
choiceIndex++;
return item;
}
public int getNextChoiceIndex() {
if (choice==null)
return -1;
Choice thisChoice = (Choice)(choice.elementAt(choiceIndex));
int index = thisChoice.getSelectedIndex();
if (macro) {
String label = (String)labels.get((Object)thisChoice);
String oldItem = thisChoice.getSelectedItem();
int oldIndex = thisChoice.getSelectedIndex();
String item = Macro.getValue(macroOptions, label, oldItem);
if (item!=null && item.startsWith("&")) item = getChoiceVariable(item);
thisChoice.select(item);
index = thisChoice.getSelectedIndex();
if (index==oldIndex && !item.equals(oldItem)) {
Interpreter interp = Interpreter.getInstance();
String s = interp!=null?interp.getStringVariable(item):null;
if (s==null)
IJ.error(getTitle(), "\""+item+"\" is not a valid choice for \""+label+"\"");
else
item = s;
}
}
if (recorderOn) {
int defaultIndex = ((Integer)(defaultChoiceIndexes.elementAt(choiceIndex))).intValue();
if (!(smartRecording&&index==defaultIndex)) {
String item = thisChoice.getSelectedItem();
if (!(item.equals("*None*")&&getTitle().equals("Merge Channels")))
recordOption(thisChoice, thisChoice.getSelectedItem());
}
}
choiceIndex++;
return index;
}
public String getNextRadioButton() {
if (radioButtonGroups==null)
return null;
CheckboxGroup cg = (CheckboxGroup)(radioButtonGroups.elementAt(radioButtonIndex));
radioButtonIndex++;
Checkbox checkbox = cg.getSelectedCheckbox();
String item = "null";
if (checkbox!=null)
item = checkbox.getLabel();
if (macro) {
String label = (String)labels.get((Object)cg);
item = Macro.getValue(macroOptions, label, item);
}
if (recorderOn)
recordOption(cg, item);
return item;
}
private String getChoiceVariable(String item) {
item = item.substring(1);
Interpreter interp = Interpreter.getInstance();
String s = interp!=null?interp.getStringVariable(item):null;
if (s==null) {
double value = interp!=null?interp.getVariable2(item):Double.NaN;
if (!Double.isNaN(value)) {
if ((int)value==value)
s = ""+(int)value;
else
s = ""+value;
}
}
if (s!=null)
item = s;
return item;
}
public String getNextText() {
String text;
if (textAreaIndex==0 && textArea1!=null) {
text = textArea1.getText();
textAreaIndex++;
if (macro)
text = Macro.getValue(macroOptions, "text1", text);
if (recorderOn) {
String text2 = text;
String cmd = Recorder.getCommand();
if (cmd!=null && cmd.equals("Convolve...")) {
text2 = text.replaceAll("\n","\\\\n");
if (!text.endsWith("\n")) text2 = text2 + "\\n";
} else
text2 = text.replace('\n',' ');
Recorder.recordOption("text1", text2);
}
} else if (textAreaIndex==1 && textArea2!=null) {
textArea2.selectAll();
text = textArea2.getText();
textAreaIndex++;
if (macro)
text = Macro.getValue(macroOptions, "text2", text);
if (recorderOn)
Recorder.recordOption("text2", text.replace('\n',' '));
} else
text = null;
return text;
}
public void showDialog() {
if (macro) {
dispose();
recorderOn = Recorder.record && Recorder.recordInMacros;
} else {
if (pfr!=null) pfr.setDialog(this);
Panel buttons = new Panel();
buttons.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 0));
cancel = new Button(cancelLabel);
cancel.addActionListener(this);
cancel.addKeyListener(this);
if (yesNoCancel) {
okLabel = yesLabel;
no = new Button(noLabel);
no.addActionListener(this);
no.addKeyListener(this);
}
okay = new Button(okLabel);
okay.addActionListener(this);
okay.addKeyListener(this);
boolean addHelp = helpURL!=null;
if (addHelp) {
help = new Button(helpLabel);
help.addActionListener(this);
help.addKeyListener(this);
}
if (IJ.isMacintosh()) {
if (addHelp) buttons.add(help);
if (yesNoCancel) buttons.add(no);
if (!hideCancelButton) buttons.add(cancel);
buttons.add(okay);
} else {
buttons.add(okay);
if (yesNoCancel) buttons.add(no);;
if (!hideCancelButton)
buttons.add(cancel);
if (addHelp) buttons.add(help);
}
c.gridx = 0; c.gridy = y;
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 2;
c.insets = new Insets(15, 0, 0, 0);
grid.setConstraints(buttons, c);
add(buttons);
if (IJ.isMacintosh())
setResizable(false);
pack();
setup();
if (centerDialog) GUI.center(this);
setVisible(true);
recorderOn = Recorder.record;
IJ.wait(50); }
if (!wasCanceled && dialogListeners!=null && dialogListeners.size()>0) {
resetCounters();
((DialogListener)dialogListeners.elementAt(0)).dialogItemChanged(this,null);
recorderOn = false;
}
resetCounters();
}
private void resetCounters() {
nfIndex = 0; sfIndex = 0;
cbIndex = 0;
choiceIndex = 0;
textAreaIndex = 0;
radioButtonIndex = 0;
invalidNumber = false;
}
public Vector getNumericFields() {
return numberField;
}
public Vector getStringFields() {
return stringField;
}
public Vector getCheckboxes() {
return checkbox;
}
public Vector getChoices() {
return choice;
}
public Vector getSliders() {
return slider;
}
public Vector getRadioButtonGroups() {
return radioButtonGroups;
}
public TextArea getTextArea1() {
return textArea1;
}
public TextArea getTextArea2() {
return textArea2;
}
public Component getMessage() {
return theLabel;
}
public Checkbox getPreviewCheckbox() {
return previewCheckbox;
}
public boolean isPreviewActive() {
return previewCheckbox!=null && previewCheckbox.getState();
}
public Button[] getButtons() {
Button[] buttons = new Button[3];
buttons[0] = okay;
buttons[1] = cancel;
buttons[2] = no;
return buttons;
}
public void previewRunning(boolean isRunning) {
if (previewCheckbox!=null) {
previewCheckbox.setLabel(isRunning ? previewRunning : previewLabel);
if (IJ.isMacOSX()) repaint(); }
}
public void centerDialog(boolean b) {
centerDialog = b;
}
public void setLocation(int x, int y) {
super.setLocation(x, y);
centerDialog = false;
}
public void setDefaultString(int index, String str) {
if (defaultStrings!=null && index>=0 && index<defaultStrings.size())
defaultStrings.set(index, str);
}
protected void setup() {
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source==okay || source==cancel | source==no) {
wasCanceled = source==cancel;
wasOKed = source==okay;
dispose();
} else if (source==help) {
if (hideCancelButton) {
if (helpURL!=null && helpURL.equals("")) {
notifyListeners(e);
return;
} else {
wasOKed = true;
dispose();
}
}
showHelp();
} else
notifyListeners(e);
}
public void textValueChanged(TextEvent e) {
notifyListeners(e);
if (slider==null) return;
Object source = e.getSource();
for (int i=0; i<slider.size(); i++) {
int index = sliderIndexes[i];
if (source==numberField.elementAt(index)) {
TextField tf = (TextField)numberField.elementAt(index);
double value = Tools.parseDouble(tf.getText());
if (!Double.isNaN(value)) {
Scrollbar sb = (Scrollbar)slider.elementAt(i);
sb.setValue((int)(value*sliderScales[i]));
}
}
}
}
public void itemStateChanged(ItemEvent e) {
notifyListeners(e);
}
public void focusGained(FocusEvent e) {
Component c = e.getComponent();
if (c instanceof TextField)
((TextField)c).selectAll();
}
public void focusLost(FocusEvent e) {
Component c = e.getComponent();
if (c instanceof TextField)
((TextField)c).select(0,0);
}
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
IJ.setKeyDown(keyCode);
if (keyCode==KeyEvent.VK_ENTER && textArea1==null && okay!=null && okay.isEnabled()) {
wasOKed = true;
if (IJ.isMacOSX())
accessTextFields();
dispose();
} else if (keyCode==KeyEvent.VK_ESCAPE) {
wasCanceled = true;
dispose();
IJ.resetEscape();
} else if (keyCode==KeyEvent.VK_W && (e.getModifiers()&Toolkit.getDefaultToolkit().getMenuShortcutKeyMask())!=0) {
wasCanceled = true;
dispose();
}
}
void accessTextFields() {
if (stringField!=null) {
for (int i=0; i<stringField.size(); i++)
((TextField)(stringField.elementAt(i))).getText();
}
if (numberField!=null) {
for (int i=0; i<numberField.size(); i++)
((TextField)(numberField.elementAt(i))).getText();
}
}
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
IJ.setKeyUp(keyCode);
int flags = e.getModifiers();
boolean control = (flags & KeyEvent.CTRL_MASK) != 0;
boolean meta = (flags & KeyEvent.META_MASK) != 0;
boolean shift = (flags & e.SHIFT_MASK) != 0;
if (keyCode==KeyEvent.VK_G && shift && (control||meta))
new ScreenGrabber().run("");
}
public void keyTyped(KeyEvent e) {}
public Insets getInsets() {
Insets i= super.getInsets();
return new Insets(i.top+10, i.left+10, i.bottom+10, i.right+10);
}
public synchronized void adjustmentValueChanged(AdjustmentEvent e) {
Object source = e.getSource();
for (int i=0; i<slider.size(); i++) {
if (source==slider.elementAt(i)) {
Scrollbar sb = (Scrollbar)source;
TextField tf = (TextField)numberField.elementAt(sliderIndexes[i]);
int digits = sliderScales[i]==1.0?0:2;
tf.setText(""+IJ.d2s(sb.getValue()/sliderScales[i],digits));
}
}
}
private void notifyListeners(AWTEvent e) {
if (dialogListeners==null)
return;
boolean everythingOk = true;
for (int i=0; everythingOk && i<dialogListeners.size(); i++)
try {
resetCounters();
if (!((DialogListener)dialogListeners.elementAt(i)).dialogItemChanged(this, e))
everythingOk = false; } catch (Exception err) { IJ.beep(); IJ.log("ERROR: "+err+"\nin DialogListener of "+dialogListeners.elementAt(i)+
"\nat "+(err.getStackTrace()[0])+"\nfrom "+(err.getStackTrace()[1])); }
boolean workaroundOSXbug = IJ.isMacOSX() && okay!=null && !okay.isEnabled() && everythingOk;
if (previewCheckbox!=null)
previewCheckbox.setEnabled(everythingOk);
if (okay!=null)
okay.setEnabled(everythingOk);
if (workaroundOSXbug)
repaint(); }
public void repaint() {
super.repaint();
if (imagePanels!=null) {
for (int i=0; i<imagePanels.size(); i++)
((ImagePanel)imagePanels.get(i)).repaint();
}
}
public void paint(Graphics g) {
super.paint(g);
if (firstPaint) {
if (numberField!=null && IJ.isMacOSX()) {
TextField tf = (TextField)(numberField.elementAt(0));
tf.setEditable(false);
tf.setEditable(true);
}
if (numberField==null && stringField==null)
okay.requestFocus();
firstPaint = false;
}
}
public void windowClosing(WindowEvent e) {
wasCanceled = true;
dispose();
}
public void addHelp(String url) {
helpURL = url;
}
void showHelp() {
if (helpURL.startsWith("<html>"))
new HTMLDialog(this, "", helpURL);
else {
String macro = "run('URL...', 'url="+helpURL+"');";
new MacroRunner(macro);
}
}
protected boolean isMacro() {
return macro;
}
public void windowActivated(WindowEvent e) {}
public void windowOpened(WindowEvent e) {}
public void windowClosed(WindowEvent e) {}
public void windowIconified(WindowEvent e) {}
public void windowDeiconified(WindowEvent e) {}
public void windowDeactivated(WindowEvent e) {}
}