package sim.util.gui; import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; import javax.swing.border.*; import java.awt.*; import java.util.*; import sim.util.*; /** A simple class designed to allow the user to modify a property in the form of a string, number, boolean value, or option. PropertyField lets you control the values which the user sets by subclassing the class and overriding the newValue(val) method filters all newly user-set values and "corrects" them. Programmatically set values (by calling setValue(...)) are not filtered through newValue by default. If you need to filter, you should do setValue(newValue(val));

You can optionally specify how the string will be presented to the user: as a text field, as a text field with a slider (requiring certain numerical constraints on the text field), as a list of options (also requiring certain numerical constraints), as a check box (requiring the string to hold boolean values ("true" or "false"), or as a read-only field with a button to press (which in turn calls the viewProperty() method, which you may override).

The specifics about how to present the user with these options is described in the constructor documentation and in the documentation for setValues(...).

PropertyFields can also be set to be either read-only or read/write by the user. When the user edits a read/write PropertyField, the text field changes color. If the user then presses RETURN, the result is submitted to newValue(...). If the user presses ESCAPE, the result is cancelled and reset. */ public class PropertyField extends JComponent { public JComboBox list = new JComboBox(); public JTextField valField = new JTextField(); public JCheckBox checkField = new JCheckBox(); public JButton viewButton = new JButton("View"); // optionally displayed instead of valField (array or Object) public JLabel viewLabel = new JLabel(); public JLabel optionalLabel = new JLabel(); static final int SLIDER_MAX = 800000; static final int SLIDER_WIDTH = 80; public JSlider slider = new JSlider(0,SLIDER_MAX) { public Dimension getMaximumSize() { return new Dimension(SLIDER_WIDTH, super.getMaximumSize().height); } public Dimension getPreferredSize() { return getMaximumSize(); } }; public Border valFieldBorder; public Border emptyBorder; public String currentValue; public boolean isReadWrite; public Object domain; public int displayState; public static final int SHOW_CHECKBOX = 0; public static final int SHOW_TEXTFIELD = 1; public static final int SHOW_VIEWBUTTON = 2; public static final int SHOW_SLIDER = 3; public static final int SHOW_LIST = 4; public Color defaultColor; public Color editedColor = new Color(225,225,255); public void setEditedColor(Color c) { editedColor = c; } public Color getEditedColor() { return editedColor; } public void submit() { if (edited) { setValue(newValue( valField.getText() )); } } public void update() { setValue(getValue()); } boolean edited = false; void setEdited(boolean edited) { this.edited = edited; if (edited) { valField.setBackground(editedColor); } else { valField.setBackground(isReadWrite ? defaultColor : checkField.getBackground()); } } public KeyListener listener = new KeyListener() { public void keyReleased(KeyEvent keyEvent) { } public void keyTyped(KeyEvent keyEvent) { } public void keyPressed(KeyEvent keyEvent) { if (keyEvent.getKeyCode() == KeyEvent.VK_ENTER) { submit(); } else if (keyEvent.getKeyCode() == KeyEvent.VK_ESCAPE) // reset { update(); } else { setEdited(true); } } }; public ChangeListener checkListener = new ChangeListener() { public void stateChanged (ChangeEvent e) { setValue(newValue( new Boolean(checkField.isSelected()).toString() )); } }; public ActionListener viewButtonListener = new ActionListener() { public void actionPerformed ( ActionEvent e ) { viewProperty(); } }; public FocusAdapter focusAdapter = new FocusAdapter() { public void focusLost ( FocusEvent e ) { submit(); } }; boolean sliding = false; public ChangeListener sliderListener = new ChangeListener() { public void stateChanged (ChangeEvent e) { if (domain != null && domain instanceof Interval) { double d = 0; Interval domain = (Interval)(PropertyField.this.domain); int i = slider.getValue(); if (domain.isDouble()) { double min = domain.getMin().doubleValue(); double max = domain.getMax().doubleValue(); d = (i / (double)SLIDER_MAX) * (max - min) + min; } else // long { long min = domain.getMin().longValue(); long max = domain.getMax().longValue(); d = (double)((long)((i / (double)SLIDER_MAX) * (max - min) + min)); // floor to an integer value } sliding = true; setValue(newValue("" + d)); sliding = false; } } }; public ActionListener listListener = new ActionListener() { public void actionPerformed ( ActionEvent e ) { if (!settingList) setValue(newValue(""+list.getSelectedIndex())); } }; boolean settingList = false; /** Sets the value, not filtering it through newValue(val) first. */ public void setValue(String val) { switch(displayState) { case SHOW_SLIDER: setEdited(false); if (!sliding) { slide(val); } valField.setText(val); break; case SHOW_TEXTFIELD: setEdited(false); valField.setText(val); break; case SHOW_CHECKBOX: if(val!=null && val.equals("true")) checkField.setSelected(true); else checkField.setSelected(false); break; case SHOW_VIEWBUTTON: viewLabel.setText(val); break; case SHOW_LIST: settingList = true; try { list.setSelectedIndex(Integer.parseInt(val)); } catch (Exception e) { settingList = false; throw new RuntimeException(""+e); } settingList = false; break; default: break; } currentValue = val; } void slide(String val) { try { if (domain instanceof Interval) { Interval domain = (Interval)(this.domain); double d = Double.parseDouble(val); double min = domain.getMin().doubleValue(); double max = domain.getMax().doubleValue(); int i = (int)((d - min) / (max - min) * SLIDER_MAX); slider.setValue(i); } } catch (Exception e) { } } /** Returns the most recently set value. */ public String getValue() { return currentValue; } /** Constructs a PropertyField as just a writeable, empty text field. */ public PropertyField() { this(null,"",true); } /** Constructs a PropertyField as a writeable text field with the provided initial value. */ public PropertyField(String initialValue) { this(null,initialValue,true); } /** Constructs a PropertyField as a text field with the provided initial value, either writeable or not. */ public PropertyField(String initialValue, boolean isReadWrite) { this(null,initialValue,isReadWrite); } /** Constructs a labelled PropertyField as a writeable text field with the provided initial value. */ public PropertyField(String label, String initialValue) { this(label,initialValue,true); } /** Constructs a labelled PropertyField as a text field with the provided initial value, either writeable or not. */ public PropertyField(String label, String initialValue, boolean isReadWrite) { this(label,initialValue,isReadWrite, null, SHOW_TEXTFIELD); } /** Constructs a PropertyField with an optional label, an initial value, a "writeable" flag, an optional domain (for the slider and list options), and a display form (checkboxes, view buttons, text fields, sliders, or lists).