package ij.gui;
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.*;
import ij.io.OpenDialog;
import java.awt.*;
import java.io.*;
import java.awt.event.*;
import java.util.*;
import java.awt.datatransfer.*;
import java.awt.dnd.*;
public class GenericDialog extends Dialog implements ActionListener, TextListener,
FocusListener, ItemListener, KeyListener, AdjustmentListener, WindowListener {
protected Vector numberField, stringField, checkbox, choice, slider, radioButtonGroups;
protected TextArea textArea1, textArea2;
protected Vector defaultValues,defaultText,defaultStrings,defaultChoiceIndexes;
protected Component theLabel;
private Button okay;
private Button cancel;
private Button no, help;
private String helpLabel = "Help";
private boolean wasCanceled, wasOKed;
private int nfIndex, sfIndex, cbIndex, choiceIndex, textAreaIndex, radioButtonIndex;
private GridBagConstraints c;
private boolean firstNumericField=true;
private boolean firstSlider=true;
private boolean invalidNumber;
private String errorMessage;
private Hashtable labels;
private boolean macro;
private String macroOptions;
private boolean addToSameRow;
private boolean addToSameRowCalled;
private int topInset, leftInset, bottomInset;
private boolean customInsets;
private Vector sliderIndexes, sliderScales, sliderDigits;
private Checkbox previewCheckbox; private Vector dialogListeners; private PlugInFilterRunner pfr; private String previewLabel = " Preview";
private final static String previewRunning = "wait...";
private boolean recorderOn; private char echoChar;
private boolean hideCancelButton;
private boolean centerDialog = true;
private String helpURL;
private boolean smartRecording;
private Vector imagePanels;
protected static GenericDialog instance;
private boolean firstPaint = true;
private boolean fontSizeSet;
private boolean showDialogCalled;
private boolean optionsRecorded; private Label lastLabelAdded;
private int[] windowIDs;
private String[] windowTitles;
public GenericDialog(String title) {
this(title, null);
}
private static Frame getParentFrame() {
return null;
}
public GenericDialog(String title, Frame parent) {
super(parent, title, true);
ImageJ ij = IJ.getInstance();
if (ij!=null) setFont(ij.getFont());
okay = new Button(" OK ");
cancel = new Button("Cancel");
if (Prefs.blackCanvas) {
setForeground(SystemColor.controlText);
setBackground(SystemColor.control);
}
GridBagLayout 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 decimalPlaces = (int)defaultValue==defaultValue?0:3;
int columnWidth = decimalPlaces==3?8:6;
addNumericField(label, defaultValue, decimalPlaces, columnWidth, null);
}
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 fieldLabel = makeLabel(label2);
this.lastLabelAdded = fieldLabel;
if (addToSameRow) {
c.gridx = GridBagConstraints.RELATIVE;
c.insets.left = 10;
} else {
c.gridx = 0; c.gridy++;
if (firstNumericField)
c.insets = getInsets(5, 0, 3, 0); else
c.insets = getInsets(0, 0, 3, 0);
}
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
add(fieldLabel, c);
if (addToSameRow) {
c.insets.left = 0;
addToSameRow = false;
}
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;
boolean scientificNotationAsNeeded = false;
if (digits<0) {
digits = -digits;
scientificNotationAsNeeded = true;
}
String defaultString = IJ.d2s(defaultValue, digits);
if (scientificNotationAsNeeded)
defaultString = ij.measure.ResultsTable.d2s(defaultValue, digits);
if (Double.isNaN(defaultValue))
defaultString = "";
TextField tf = newTextField(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(Double.valueOf(defaultValue));
defaultText.addElement(tf.getText());
c.gridx = GridBagConstraints.RELATIVE;
c.anchor = GridBagConstraints.WEST;
tf.setEditable(true);
firstNumericField = false;
if (units==null||units.equals("")) {
add(tf, c);
} else {
Panel panel = new Panel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
panel.add(tf);
panel.add(new Label(" "+units));
add(panel, c);
}
if (Recorder.record || macro)
saveLabel(tf, label);
}
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)
label = Macro.trimKey(label.trim());
if (label.length()>0 && hasLabel(label)) { label += "_0";
for (int n=1; hasLabel(label); n++) { label = label.substring(0, label.lastIndexOf('_')); label += "_"+n;
}
}
labels.put(component, label);
}
private boolean hasLabel(String label) {
for (Object o : labels.keySet())
if (labels.get(o).equals(label)) return true;
return false;
}
public void addStringField(String label, String defaultText) {
addStringField(label, defaultText, 8);
}
public void addStringField(String label, String defaultText, int columns) {
if (addToSameRow && label.equals("_"))
label = "";
String label2 = label;
if (label2.indexOf('_')!=-1)
label2 = label2.replace('_', ' ');
Label fieldLabel = makeLabel(label2);
this.lastLabelAdded = fieldLabel;
boolean custom = customInsets;
if (addToSameRow) {
c.gridx = GridBagConstraints.RELATIVE;
addToSameRow = false;
} else {
c.gridx = 0; c.gridy++;
if (stringField==null)
c.insets = getInsets(5, 0, 5, 0); else
c.insets = getInsets(0, 0, 5, 0);
}
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
add(fieldLabel, c);
if (stringField==null) {
stringField = new Vector(4);
defaultStrings = new Vector(4);
}
TextField tf = newTextField(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 = GridBagConstraints.RELATIVE;
c.anchor = GridBagConstraints.WEST;
c.gridwidth = columns <= 8 ? 1 : GridBagConstraints.REMAINDER;
c.insets.left = 0;
tf.setEditable(true);
add(tf, c);
stringField.addElement(tf);
defaultStrings.addElement(defaultText);
tf.setDropTarget(null);
new DropTarget(tf, new TextDropTarget(tf));
if (Recorder.record || macro)
saveLabel(tf, label);
}
public void setEchoChar(char echoChar) {
this.echoChar = echoChar;
}
public void addDirectoryField(String label, String defaultPath) {
int columns = defaultPath!=null?Math.max(defaultPath.length(),25):25;
if (columns>50) columns=50;
addDirectoryField(label, defaultPath, columns);
}
public void addDirectoryField(String label, String defaultPath, int columns) {
defaultPath = IJ.addSeparator(defaultPath);
addStringField(label, defaultPath, columns);
if (GraphicsEnvironment.isHeadless())
return;
TextField text = (TextField)stringField.lastElement();
GridBagLayout layout = (GridBagLayout)getLayout();
GridBagConstraints constraints = layout.getConstraints(text);
Button button = new TrimmedButton("Browse",IJ.isMacOSX()?10:0);
BrowseButtonListener listener = new BrowseButtonListener(label, text, "dir");
button.addActionListener(listener);
Panel panel = new Panel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
panel.add(text);
panel.add(button);
layout.setConstraints(panel, constraints);
add(panel);
if (Recorder.record || macro)
saveLabel(panel, label);
}
public void addFileField(String label, String defaultPath) {
int columns = defaultPath!=null?Math.max(defaultPath.length(),25):25;
addFileField(label, defaultPath, columns);
}
public void addFileField(String label, String defaultPath, int columns) {
addStringField(label, defaultPath, columns);
if (GraphicsEnvironment.isHeadless())
return;
TextField text = (TextField)stringField.lastElement();
GridBagLayout layout = (GridBagLayout)getLayout();
GridBagConstraints constraints = layout.getConstraints(text);
Button button = new TrimmedButton("Browse",IJ.isMacOSX()?10:0);
BrowseButtonListener listener = new BrowseButtonListener(label, text, "file");
button.addActionListener(listener);
Panel panel = new Panel();
panel.setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0));
panel.add(text);
panel.add(button);
layout.setConstraints(panel, constraints);
add(panel);
if (Recorder.record || macro)
saveLabel(panel, label);
}
public void addButton(String label, ActionListener listener) {
if (GraphicsEnvironment.isHeadless())
return;
Button button = new Button(label);
button.addActionListener(listener);
button.addKeyListener(this);
GridBagLayout layout = (GridBagLayout)getLayout();
Panel panel = new Panel();
addPanel(panel);
GridBagConstraints constraints = layout.getConstraints(panel);
remove(panel);
layout.setConstraints(button, constraints);
add(button);
}
public void addImageChoice(String label, String defaultImage) {
if (windowTitles==null) {
windowIDs = WindowManager.getIDList();
if (windowIDs==null)
windowIDs = new int[0];
windowTitles = new String[windowIDs.length];
for (int i=0; i<windowIDs.length; i++) {
ImagePlus image = WindowManager.getImage(windowIDs[i]);
windowTitles[i] = image==null ? "" : image.getTitle();
}
}
addChoice(label, windowTitles, defaultImage);
}
public ImagePlus getNextImage() {
int index = getNextChoiceIndex();
return index<0 ? null : WindowManager.getImage(windowIDs[index]);
}
public <E extends Enum<E>> void addEnumChoice(String label, Enum<E> defaultItem) {
Class<E> enumClass = defaultItem.getDeclaringClass();
E[] enums = enumClass.getEnumConstants();
String[] items = new String[enums.length];
for (int i = 0; i < enums.length; i++) {
items[i] = enums[i].name();
}
this.addChoice(label, items, defaultItem.name());
}
public <E extends Enum<E>> E getNextEnumChoice(Class<E> enumClass) {
String choiceString = this.getNextChoice();
return Enum.valueOf(enumClass, choiceString);
}
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 (addToSameRow) {
c.gridx = GridBagConstraints.RELATIVE;
c.insets.left = 10;
addToSameRow = false;
} else {
c.gridx = 0; c.gridy++;
if (checkbox==null)
c.insets = getInsets(15, 20, 0, 0); else
c.insets = getInsets(0, 20, 0, 0);
}
c.anchor = GridBagConstraints.WEST;
c.gridwidth = 2;
if (checkbox==null)
checkbox = new Vector(4);
Checkbox cb = new Checkbox(label2);
cb.setState(defaultValue);
cb.addItemListener(this);
cb.addKeyListener(this);
add(cb, c);
c.insets.left = 0;
checkbox.addElement(cb);
if (!isPreview &&(Recorder.record || macro)) saveLabel(cb, label);
if (isPreview) previewCheckbox = cb;
}
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++;
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.insets = getInsets(10, 0, 0, 0);
addToSameRow = false;
add(panel, c);
}
public void addRadioButtonGroup(String label, String[] items, int rows, int columns, String defaultItem) {
addToSameRow = false;
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++;
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.insets = new Insets(insets.top, insets.left, 0, 0);
add(panel, c);
if (Recorder.record || macro)
saveLabel(cg, label);
}
public void addChoice(String label, String[] items, String defaultItem) {
String label2 = label;
if (label2.indexOf('_')!=-1)
label2 = label2.replace('_', ' ');
Label fieldLabel = makeLabel(label2);
this.lastLabelAdded = fieldLabel;
if (addToSameRow) {
c.gridx = GridBagConstraints.RELATIVE;
addToSameRow = false;
} else {
c.gridx = 0; c.gridy++;
if (choice==null)
c.insets = getInsets(5, 0, 5, 0);
else
c.insets = getInsets(0, 0, 5, 0);
}
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
if (choice==null) {
choice = new Vector(4);
defaultChoiceIndexes = new Vector(4);
}
add(fieldLabel, c);
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 = GridBagConstraints.RELATIVE;
c.anchor = GridBagConstraints.WEST;
add(thisChoice, c);
choice.addElement(thisChoice);
int index = thisChoice.getSelectedIndex();
defaultChoiceIndexes.addElement(Integer.valueOf(index));
if (Recorder.record || macro)
saveLabel(thisChoice, label);
}
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);
if (addToSameRow) {
c.gridx = GridBagConstraints.RELATIVE;
addToSameRow = false;
} else {
c.gridx = 0; c.gridy++;
c.insets = getInsets("".equals(text)?0:10, 20, 0, 0); }
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.fill = GridBagConstraints.HORIZONTAL;
if (font!=null) {
if (Prefs.getGuiScale()>1.0)
font = font.deriveFont((float)(font.getSize()*Prefs.getGuiScale()));
theLabel.setFont(font);
}
if (color!=null)
theLabel.setForeground(color);
add(theLabel, c);
c.fill = GridBagConstraints.NONE;
}
public void addTextAreas(String text1, String text2, int rows, int columns) {
if (textArea1!=null) return;
Panel panel = new Panel();
int scrollbars = TextArea.SCROLLBARS_NONE;
if (text1!=null && text1.endsWith("SCROLLBARS_BOTH")) {
scrollbars = TextArea.SCROLLBARS_BOTH;
text1 = text1.substring(0, text1.length()-15);
}
if (text1!=null && text1.endsWith("SCROLLBARS_VERTICAL_ONLY")) {
scrollbars = TextArea.SCROLLBARS_VERTICAL_ONLY;
text1 = text1.substring(0, text1.length()-24);
}
Font font = new Font("SansSerif", Font.PLAIN, (int)(14*Prefs.getGuiScale()));
textArea1 = new TextArea(text1,rows,columns,scrollbars);
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,scrollbars);
if (IJ.isLinux()) textArea2.setBackground(Color.white);
textArea2.setFont(font);
panel.add(textArea2);
}
c.gridx = 0; c.gridy++;
c.gridwidth = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.WEST;
c.insets = getInsets(15, 20, 0, 0);
addToSameRow = false;
add(panel, c);
}
public void addSlider(String label, double minValue, double maxValue, double defaultValue) {
if (defaultValue<minValue) defaultValue=minValue;
if (defaultValue>maxValue) defaultValue=maxValue;
int digits = 0;
double scale = 1.0;
if ((maxValue-minValue)<=5.0 && (minValue!=(int)minValue||maxValue!=(int)maxValue||defaultValue!=(int)defaultValue)) {
scale = 50.0;
minValue *= scale;
maxValue *= scale;
defaultValue *= scale;
digits = 2;
}
addSlider( label, minValue, maxValue, defaultValue, scale, digits);
}
public void addSlider(String label, double minValue, double maxValue, double defaultValue, double stepSize) {
if ( stepSize <= 0 ) stepSize = 1;
int digits = digits(stepSize);
if (digits==1 && "Angle:".equals(label))
digits = 2;
double scale = 1.0 / Math.abs( stepSize );
if ( scale <= 0 ) scale = 1;
if ( defaultValue < minValue ) defaultValue = minValue;
if ( defaultValue > maxValue ) defaultValue = maxValue;
minValue *= scale;
maxValue *= scale;
defaultValue *= scale;
addSlider(label, minValue, maxValue, defaultValue, scale, digits);
}
private static int digits(double d) {
if (d == (int)d)
return 0;
String s = Double.toString(d);
int ePos = s.indexOf("E");
if (ePos==-1)
ePos = s.indexOf("e");
int dotPos = s.indexOf( "." );
int digits = 0;
if (ePos==-1 )
digits = s.substring(dotPos+1).length();
else {
String number = s.substring( dotPos + 1, ePos );
if (!number.equals( "0" ))
digits += number.length( );
digits = digits - Integer.valueOf(s.substring(ePos+1));
}
return digits;
}
private void addSlider(String label, double minValue, double maxValue, double defaultValue, double scale, int digits) {
int columns = 4 + digits - 2;
if ( columns < 4 ) columns = 4;
if (minValue<0.0) columns++;
String mv = IJ.d2s(maxValue,0);
if (mv.length()>4 && digits==0)
columns += mv.length()-4;
String label2 = label;
if (label2.indexOf('_')!=-1)
label2 = label2.replace('_', ' ');
Label fieldLabel = makeLabel(label2);
this.lastLabelAdded = fieldLabel;
if (addToSameRow) {
c.gridx = GridBagConstraints.RELATIVE;
c.insets.bottom += 3;
addToSameRow = false;
} else {
c.gridx = 0; c.gridy++;
c.insets = getInsets(0, 0, 3, 0); }
c.anchor = GridBagConstraints.EAST;
c.gridwidth = 1;
add(fieldLabel, c);
if (slider==null) {
slider = new Vector(5);
sliderIndexes = new Vector(5);
sliderScales = new Vector(5);
sliderDigits = new Vector(5);
}
Scrollbar s = new Scrollbar(Scrollbar.HORIZONTAL, (int)defaultValue, 1, (int)minValue, (int)maxValue+1);
GUI.fixScrollbar(s);
slider.addElement(s);
s.addAdjustmentListener(this);
s.setUnitIncrement(1);
if (IJ.isMacOSX())
s.addKeyListener(this);
s.addMouseWheelListener(new MouseWheelListener() {
public void mouseWheelMoved(MouseWheelEvent e) {
Scrollbar sb = (Scrollbar)e.getSource();
int value = sb.getValue() + e.getWheelRotation();
sb.setValue(value);
for (int i=0; i<slider.size(); i++) {
if (sb==slider.elementAt(i)) {
int index = ((Integer)sliderIndexes.get(i)).intValue();
TextField tf = (TextField)numberField.elementAt(index);
double scale = ((Double)sliderScales.get(i)).doubleValue();
int digits = ((Integer)sliderDigits.get(i)).intValue();
tf.setText(""+IJ.d2s(sb.getValue()/scale,digits));
}
}
}
});
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 = newTextField(IJ.d2s(defaultValue/scale,digits),columns);
tf.addActionListener(this);
tf.addTextListener(this);
tf.addFocusListener(this);
tf.addKeyListener(this);
numberField.addElement(tf);
sliderIndexes.add(Integer.valueOf(numberField.size()-1));
sliderScales.add(Double.valueOf(scale));
sliderDigits.add(Integer.valueOf(digits));
defaultValues.addElement(Double.valueOf(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;
panel.add(s, pc);
pc.ipadx = 0; pc.gridx = 1;
pc.insets = new Insets(5, 5, 0, 0);
pc.anchor = GridBagConstraints.EAST;
panel.add(tf, pc);
c.gridx = GridBagConstraints.RELATIVE;
c.gridwidth = 1;
c.anchor = GridBagConstraints.WEST;
c.insets.left = 0;
c.insets.bottom -= 3;
add(panel, c);
if (Recorder.record || macro)
saveLabel(tf, label);
}
private TextField newTextField(String txt, int columns) {
if (IJ.isLinux())
return new TrimmedTextField(txt,columns);
else
return new TextField(txt,columns);
}
public void addPanel(Panel panel) {
addPanel(panel, GridBagConstraints.WEST, addToSameRow ? c.insets : getInsets(5,0,0,0));
}
public void addPanel(Panel panel, int constraints, Insets insets) {
if (addToSameRow) {
c.gridx = GridBagConstraints.RELATIVE;
addToSameRow = false;
} else {
c.gridx = 0; c.gridy++;
}
c.gridwidth = 2;
c.anchor = constraints;
c.insets = insets;
add(panel, c);
}
public void addImage(ImagePlus image) {
if (image==null)
return;
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 addToSameRow() {
addToSameRow = true;
addToSameRowCalled = true;
}
public void setOKLabel(String label) {
okay.setLabel(label);
}
public void setCancelLabel(String label) {
cancel.setLabel(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) {
okay.setLabel(yesLabel);
if (no != null)
no.setLabel(noLabel);
else if (noLabel!=null)
no = new Button(noLabel);
}
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);
}
public boolean wasCanceled() {
if (wasCanceled && !Thread.currentThread().getName().endsWith("Script_Macro$"))
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 = Double.valueOf(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();
String label = labels!=null?(String)labels.get((Object)tf):"";
boolean numberExpected = theText!=null && theText.length()>0
&& (Character.isDigit(theText.charAt(0))||theText.startsWith("-"));
if (macro) {
theText = Macro.getValue(macroOptions, label, theText);
if (theText!=null && (theText.startsWith("&")||numberExpected||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 && !label.equals("")) {
String s = theText;
if (s!=null&&s.length()>=3&&Character.isLetter(s.charAt(0))&&s.charAt(1)==':'&&s.charAt(2)=='\\')
s = s.replaceAll("\\\\", "/"); s = Recorder.fixString(s);
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 = null;
String key = "text1";
if (textAreaIndex==0 && textArea1!=null) {
text = textArea1.getText();
if (macro)
text = Macro.getValue(macroOptions, "text1", text);
} else if (textAreaIndex==1 && textArea2!=null) {
text = textArea2.getText();
if (macro)
text = Macro.getValue(macroOptions, "text2", text);
key = "text2";
}
textAreaIndex++;
if (recorderOn && text!=null) {
String text2 = text;
String cmd = Recorder.getCommand();
if (cmd!=null && cmd.equals("Calibrate..."))
text2 = text2.replace('\n',' ');
if (cmd!=null && cmd.equals("Convolve...")){
if (!text2.endsWith("\n"))
text2 += "\n";
}
text2 = Recorder.fixString(text2);
Recorder.recordOption(key, text2);
}
return text;
}
public void showDialog() {
showDialogCalled = true;
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));
okay.addActionListener(this);
okay.addKeyListener(this);
if (!hideCancelButton) {
cancel.addActionListener(this);
cancel.addKeyListener(this);
}
if (no != null) {
no.addActionListener(this);
no.addKeyListener(this);
}
boolean addHelp = helpURL!=null;
if (addHelp) {
help.setLabel(helpLabel);
help.addActionListener(this);
help.addKeyListener(this);
}
if (IJ.isWindows() || Prefs.dialogCancelButtonOnRight) {
buttons.add(okay);
if (no != null) buttons.add(no);;
if (!hideCancelButton)
buttons.add(cancel);
if (addHelp) buttons.add(help);
} else {
if (addHelp) buttons.add(help);
if (no != null) buttons.add(no);
if (!hideCancelButton) buttons.add(cancel);
buttons.add(okay);
}
if (addToSameRow) {
c.gridx = GridBagConstraints.RELATIVE;
} else {
c.gridx = 0; c.gridy++;
}
c.anchor = GridBagConstraints.EAST;
c.gridwidth = addToSameRowCalled?GridBagConstraints.REMAINDER:2;
c.insets = new Insets(15, 0, 0, 0);
add(buttons, c);
instance = this;
Font font = getFont();
if (!fontSizeSet && font!=null && Prefs.getGuiScale()!=1.0) {
fontSizeSet = true;
setFont(font.deriveFont((float)(font.getSize()*Prefs.getGuiScale())));
}
pack();
if (okay!=null && numberField==null && stringField==null && checkbox==null
&& choice==null && slider==null && radioButtonGroups==null && textArea1==null)
okay.requestFocusInWindow();
setup();
if (centerDialog)
GUI.centerOnImageJScreen(this);
setVisible(true); }
}
void finalizeRecording() {
if (optionsRecorded)
return;
optionsRecorded = true;
if (!wasCanceled && dialogListeners!=null && dialogListeners.size()>0) {
try {
resetCounters();
((DialogListener)dialogListeners.elementAt(0)).dialogItemChanged(this,null);
} catch (Exception err) { IJ.beep(); IJ.log("ERROR: "+err+"\nin DialogListener of "+dialogListeners.elementAt(0)+
"\nat "+(err.getStackTrace()[0])+"\nfrom "+(err.getStackTrace()[1]));
}
recorderOn = false;
}
resetCounters();
}
@Override
public void setFont(Font font) {
super.setFont(!fontSizeSet&&Prefs.getGuiScale()!=1.0&&font!=null?font.deriveFont((float)(font.getSize()*Prefs.getGuiScale())):font);
fontSizeSet = true;
}
public 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() {
return new Button[] {okay, cancel, no, help};
}
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 = ((Integer)sliderIndexes.get(i)).intValue();
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);
double scale = ((Double)sliderScales.get(i)).doubleValue();
sb.setValue((int)(value*scale));
}
}
}
}
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) {
Component component = e.getComponent();
int keyCode = e.getKeyCode();
IJ.setKeyDown(keyCode);
if ((component instanceof Scrollbar) && (keyCode==KeyEvent.VK_LEFT||keyCode==KeyEvent.VK_RIGHT)) {
Scrollbar sb = (Scrollbar)component;
int value = sb.getValue();
if (keyCode==KeyEvent.VK_RIGHT)
sb.setValue(value+1);
else
sb.setValue(value-1);
for (int i=0; i<slider.size(); i++) {
if (sb==slider.elementAt(i)) {
int index = ((Integer)sliderIndexes.get(i)).intValue();
TextField tf = (TextField)numberField.elementAt(index);
double scale = ((Double)sliderScales.get(i)).doubleValue();
int digits = ((Integer)sliderDigits.get(i)).intValue();
tf.setText(""+IJ.d2s(sb.getValue()/scale,digits));
}
}
notifyListeners(e);
return;
}
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;
int index = ((Integer)sliderIndexes.get(i)).intValue();
TextField tf = (TextField)numberField.elementAt(index);
double scale = ((Double)sliderScales.get(i)).doubleValue();
int digits = ((Integer)sliderDigits.get(i)).intValue();
tf.setText(""+IJ.d2s(sb.getValue()/scale,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 (this instanceof NonBlockingGenericDialog)
Recorder.resetCommandOptions();
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]));
}
}
resetCounters();
boolean workaroundOSXbug = IJ.isMacOSX() && okay!=null && !okay.isEnabled() && everythingOk;
if (everythingOk && recorderOn)
optionsRecorded = true;
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 && IJ.isMacOSX() && IJ.isJava18()) { EventQueue.invokeLater(new Runnable() {
public void run() {
IJ.wait(50);
Dimension size = getSize();
if (size!=null)
setSize(size.width+2,size.height+2);
firstPaint = false;
}
});
}
}
public void windowClosing(WindowEvent e) {
wasCanceled = true;
dispose();
}
public void addHelp(String url) {
help = new Button(helpLabel);
helpURL = url;
}
void showHelp() {
if (helpURL.startsWith("<html>")) {
String title = getTitle()+" "+helpLabel;
if (this instanceof NonBlockingGenericDialog)
new HTMLDialog(title, helpURL, false); else
new HTMLDialog(this, title, helpURL); } else {
String macro = "call('ij.plugin.BrowserLauncher.open', '"+helpURL+"');";
new MacroRunner(macro); }
}
protected boolean isMacro() {
return macro;
}
public static GenericDialog getInstance() {
return instance;
}
public void dispose() {
super.dispose();
instance = null;
if (!macro) {
recorderOn = Recorder.record;
IJ.wait(25);
}
resetCounters();
finalizeRecording();
resetCounters();
}
public Label getLabel() {
return lastLabelAdded;
}
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) {}
@SuppressWarnings("unchecked")
static String getString(DropTargetDropEvent event)
throws IOException, UnsupportedFlavorException {
String text = null;
DataFlavor fileList = DataFlavor.javaFileListFlavor;
if (event.isDataFlavorSupported(fileList)) {
event.acceptDrop(DnDConstants.ACTION_COPY);
java.util.List<File> list = (java.util.List<File>)event.getTransferable().getTransferData(fileList);
text = list.get(0).getAbsolutePath();
}
else if (event.isDataFlavorSupported(DataFlavor.stringFlavor)) {
event.acceptDrop(DnDConstants.ACTION_COPY);
text = (String)event.getTransferable()
.getTransferData(DataFlavor.stringFlavor);
if (text.startsWith("file://"))
text = text.substring(7);
text = stripSuffix(stripSuffix(text, "\n"),
"\r").replaceAll("%20", " ");
}
else {
event.rejectDrop();
return null;
}
event.dropComplete(text != null);
return text;
}
static String stripSuffix(String s, String suffix) {
return !s.endsWith(suffix) ? s :
s.substring(0, s.length() - suffix.length());
}
static class TextDropTarget extends DropTargetAdapter {
TextField text;
DataFlavor flavor = DataFlavor.stringFlavor;
public TextDropTarget(TextField text) {
this.text = text;
}
@Override
public void drop(DropTargetDropEvent event) {
try {
text.setText(getString(event));
} catch (Exception e) { e.printStackTrace(); }
}
}
private class BrowseButtonListener implements ActionListener {
private String label;
private TextField textField;
private String mode;
public BrowseButtonListener(String label, TextField textField, String mode) {
this.label = label;
this.textField = textField;
this.mode = mode;
}
public void actionPerformed(ActionEvent e) {
String path = null;
if (mode.equals("dir")) {
path = IJ.getDir("Select a Folder");
} else {
OpenDialog od = new OpenDialog("Select a File", null);
String directory = od.getDirectory();
String name = od.getFileName();
if (name!=null)
path = directory+name;
}
if (path!=null)
this.textField.setText(path);
}
}
private class TrimmedTextField extends TextField {
public TrimmedTextField(String text, int columns) {
super(text, columns);
}
public Dimension getMinimumSize() {
Dimension d = super.getMinimumSize();
if (d!=null) {
d.width = d.width;
d.height = d.height*3/4;
}
return d;
}
public Dimension getPreferredSize() {
return getMinimumSize();
}
}
}