001/* A top-level dialog window for editing Unit constraints. 002 003 Copyright (c) 2003-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 */ 027package ptolemy.vergil.unit; 028 029import java.awt.Dimension; 030import java.awt.Frame; 031import java.net.URL; 032import java.util.Vector; 033 034import javax.swing.DefaultCellEditor; 035import javax.swing.JButton; 036import javax.swing.JPanel; 037import javax.swing.JTable; 038import javax.swing.JTextField; 039import javax.swing.ListSelectionModel; 040import javax.swing.event.ListSelectionEvent; 041import javax.swing.event.ListSelectionListener; 042import javax.swing.table.AbstractTableModel; 043import javax.swing.table.TableColumn; 044 045import ptolemy.actor.gui.Configuration; 046import ptolemy.actor.gui.DialogTableau; 047import ptolemy.actor.gui.PtolemyDialog; 048import ptolemy.kernel.Entity; 049import ptolemy.kernel.util.ChangeListener; 050import ptolemy.kernel.util.ChangeRequest; 051import ptolemy.moml.MoMLChangeRequest; 052import ptolemy.moml.unit.UnitAttribute; 053import ptolemy.moml.unit.UnitEquation; 054 055/////////////////////////////////////////////////////////////////// 056//// UnitConstraintsDialog 057 058/** 059 Unit Constraints Dialog. 060 061 @author Rowland R Johnson 062 @version $Id$ 063 @since Ptolemy II 8.0 064 @Pt.ProposedRating Yellow (rowland) 065 @Pt.AcceptedRating Red (rowland) 066 */ 067@SuppressWarnings("serial") 068public class UnitConstraintsDialog extends PtolemyDialog 069 implements ChangeListener { 070 /** 071 * Construct a dialog that presents Unit constraints as a table. Each row 072 * of the table corresponds to one constraint. The user modifies the table 073 * to specify changes in the equations. 074 * <p> 075 * This dialog is is not modal. In particular, changes can be undone by 076 * clicking Edit->Undo, and the help screen can be manipulated while this 077 * dialog exists. The dialog is placed relative to the owner. 078 * 079 * @param tableau The object that, per the user, appears to be 080 * generating the dialog. 081 * @param owner The frame. 082 * @param target The object whose ports are being configured. 083 * @param configuration The configuration to use to open the help 084 * screen (or null if help is not supported). 085 */ 086 public UnitConstraintsDialog(DialogTableau tableau, Frame owner, 087 Entity target, Configuration configuration) { 088 super("Configure units for " + target.getName(), tableau, owner, target, 089 configuration); 090 091 Vector _constraintExpression = new Vector(); 092 UnitAttribute _unitConstraints = (UnitAttribute) target 093 .getAttribute("_unitConstraints"); 094 095 if (_unitConstraints != null) { 096 Vector _constraintExpressions = _unitConstraints 097 .getUnitConstraints().getConstraints(); 098 099 for (int i = 0; i < _constraintExpressions.size(); i++) { 100 UnitEquation uEq = (UnitEquation) _constraintExpressions.get(i); 101 String commonDesc = uEq.descriptiveForm(); 102 System.out.println("_constraint " + commonDesc); 103 _constraintExpression.add(commonDesc); 104 } 105 } 106 107 _unitsTable = new JTable(); 108 _unitsTable.setPreferredScrollableViewportSize(new Dimension(500, 70)); 109 setScrollableContents(_unitsTable); 110 111 ListSelectionModel rowSM = _unitsTable.getSelectionModel(); 112 rowSM.addListSelectionListener(_rowSelectionListener); 113 114 // Create the TableModel and set certain cell editors and renderers 115 _setupTableModel(_constraintExpression); 116 _unitsTable.setTableHeader(null); 117 pack(); 118 setVisible(true); 119 } 120 121 // The table model for the table. 122 class UnitsTableModel extends AbstractTableModel { 123 Vector _unitsDataTable; 124 125 public UnitsTableModel(Vector unitsExpression) { 126 _unitsDataTable = new Vector(unitsExpression); 127 } 128 129 @Override 130 public int getRowCount() { 131 return _unitsDataTable.size(); 132 } 133 134 @Override 135 public int getColumnCount() { 136 return 1; 137 } 138 139 @Override 140 public String getColumnName(int i) { 141 return "Constraint"; 142 } 143 144 @Override 145 public Object getValueAt(int row, int col) { 146 return _unitsDataTable.elementAt(row); 147 } 148 149 public void addNewConstraint() { 150 _unitsDataTable.add(""); 151 152 // Now tell the GUI so that it can update itself. 153 fireTableRowsInserted(getRowCount(), getRowCount()); 154 } 155 156 @Override 157 public boolean isCellEditable(int arg0, int arg1) { 158 return true; 159 } 160 161 @Override 162 public void setValueAt(Object value, int row, int col) { 163 _unitsDataTable.set(row, value); 164 _enableApplyButton(true); 165 _setDirty(true); 166 } 167 168 @Override 169 public String toString() { 170 StringBuffer retv = new StringBuffer(""); 171 172 if (_unitsDataTable.size() > 0) { 173 retv.append((String) _unitsDataTable.elementAt(0)); 174 175 for (int i = 1; i < _unitsDataTable.size(); i++) { 176 retv.append(";" + (String) _unitsDataTable.elementAt(i)); 177 } 178 } 179 180 return retv.toString(); 181 } 182 } 183 184 /* 185 * (non-Javadoc) 186 * 187 * @see ptolemy.kernel.util.ChangeListener#changeExecuted(ChangeRequest) 188 */ 189 @Override 190 public void changeExecuted(ChangeRequest change) { 191 // TODO Auto-generated method stub 192 } 193 194 /* 195 * (non-Javadoc) 196 * 197 * @see ptolemy.kernel.util.ChangeListener#changeFailed(ChangeRequest, 198 * Exception) 199 */ 200 @Override 201 public void changeFailed(ChangeRequest change, Exception exception) { 202 // TODO Auto-generated method stub 203 } 204 205 /** Apply the unit constraints to the model. 206 */ 207 protected void _apply() { 208 String expr = _unitsTableModel.toString(); 209 String moml = "<property name=\"_unitConstraints\" " 210 + "class = \"ptolemy.data.unit.UnitAttribute\" " + "value = \"" 211 + expr + "\"/>"; 212 213 MoMLChangeRequest request = new MoMLChangeRequest(this, getTarget(), 214 moml, null); 215 request.setUndoable(true); 216 217 // NOTE: There is no need to listen for completion 218 // or errors in this change request, since, in theory, 219 // it will just work. Will someone report the error 220 // if one occurs? I hope so... 221 getTarget().requestChange(request); 222 } 223 224 /* 225 * (non-Javadoc) 226 * 227 * @see ptolemy.actor.gui.PtolemyDialog#_createExtendedButtons() 228 */ 229 @Override 230 protected void _createExtendedButtons(JPanel _buttons) { 231 _commitButton = new JButton("Commit"); 232 _buttons.add(_commitButton); 233 _applyButton = new JButton("Apply"); 234 _buttons.add(_applyButton); 235 _addButton = new JButton("Add"); 236 _buttons.add(_addButton); 237 _removeButton = new JButton("Remove "); 238 _removeButton.setEnabled(false); 239 _buttons.add(_removeButton); 240 } 241 242 /** Enable or disable the apply button. 243 * @param enabled True if the apply button should be enabled. 244 */ 245 protected void _enableApplyButton(boolean enabled) { 246 _applyButton.setEnabled(enabled); 247 } 248 249 /** Return the help URL. 250 * @return The help URL 251 */ 252 @Override 253 protected URL _getHelpURL() { 254 URL helpURL = getClass().getClassLoader() 255 .getResource("ptolemy/actor/gui/doc/unitConstraintsDialog.htm"); 256 return helpURL; 257 } 258 259 /** Process a button press. Add and Apply buttons are handled 260 * here. Other button presses are handled by the superclass. 261 * @param button The button to process. 262 */ 263 @Override 264 protected void _processButtonPress(String button) { 265 if (button.equals("Add")) { 266 _unitsTableModel.addNewConstraint(); 267 } else if (button.equals("Apply")) { 268 _apply(); 269 } else { 270 super._processButtonPress(button); 271 } 272 } 273 274 private void _setupTableModel(Vector constraintExpressions) { 275 _unitsTableModel = new UnitsTableModel(constraintExpressions); 276 _unitsTable.setModel(_unitsTableModel); 277 278 TableColumn _constraintColumn = _unitsTable.getColumnModel() 279 .getColumn(0); 280 JTextField textField = new JTextField(); 281 final DefaultCellEditor constraintEditor = new DefaultCellEditor( 282 textField); 283 constraintEditor.setClickCountToStart(1); 284 _constraintColumn.setCellEditor(constraintEditor); 285 286 // textField.addFocusListener(new FocusAdapter() { 287 // public void focusLost(FocusEvent fe) { 288 // constraintEditor.stopCellEditing(); 289 // } 290 // }); 291 _enableApplyButton(false); 292 } 293 294 /////////////////////////////////////////////////////////////////// 295 //// private variables //// 296 private JButton _addButton; 297 298 private JButton _applyButton; 299 300 private JButton _commitButton; 301 302 private JButton _removeButton; 303 304 private ListSelectionListener _rowSelectionListener = new ListSelectionListener() { 305 /////////////////////////////////////////////////////////////////// 306 //// inner class //// 307 @Override 308 public void valueChanged(ListSelectionEvent e) { 309 if (e.getValueIsAdjusting()) { 310 return; 311 } 312 313 //Ignore extra messages. 314 ListSelectionModel lsm = (ListSelectionModel) e.getSource(); 315 316 if (lsm.isSelectionEmpty()) { 317 _removeButton.setText("Remove"); 318 _removeButton.setEnabled(false); 319 // _selectedRow = -1; 320 } else { 321 // _selectedRow = lsm.getMinSelectionIndex(); 322 _removeButton.setEnabled(true); 323 } 324 } 325 }; 326 327 // private int _selectedRow = -1; 328 329 private JTable _unitsTable; 330 331 private UnitsTableModel _unitsTableModel; 332}