001 /*
002 * Copyright (c) 2005 Peter Palotas, Fredrik Johansson, Einar Pehrson,
003 * Sebastian Kekkonen, Lars Magnus Lång, Malin Johansson and Sofia Nilsson
004 *
005 * This file is part of
006 * CleanSheets Extension for Assertions
007 *
008 * CleanSheets Extension for Assertions is free software; you can
009 * redistribute it and/or modify it under the terms of the GNU General Public
010 * License as published by the Free Software Foundation; either version 2 of
011 * the License, or (at your option) any later version.
012 *
013 * CleanSheets Extension for Assertions is distributed in the hope that
014 * it will be useful, but WITHOUT ANY WARRANTY; without even the implied
015 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
016 * See the GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with CleanSheets Extension for Assertions; if not, write to the
020 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
021 * Boston, MA 02111-1307 USA
022 */
023 package csheets.ext.assertion.ui;
024
025 import java.awt.BorderLayout;
026 import java.awt.Color;
027 import java.awt.Component;
028 import java.awt.Dimension;
029 import java.awt.event.ActionEvent;
030
031 import javax.swing.BorderFactory;
032 import javax.swing.Box;
033 import javax.swing.BoxLayout;
034 import javax.swing.JButton;
035 import javax.swing.JLabel;
036 import javax.swing.JPanel;
037 import javax.swing.JTextArea;
038 import javax.swing.JTextField;
039 import javax.swing.border.TitledBorder;
040
041 import csheets.core.Cell;
042 import csheets.ext.assertion.AssertableCell;
043 import csheets.ext.assertion.AssertableCellListener;
044 import csheets.ext.assertion.Assertion;
045 import csheets.ext.assertion.AssertionExtension;
046 import csheets.ui.ctrl.FocusOwnerAction;
047 import csheets.ui.ctrl.SelectionEvent;
048 import csheets.ui.ctrl.SelectionListener;
049 import csheets.ui.ctrl.UIController;
050
051 /**
052 * A panel for adding or editing an assertion for a cell
053 * @author Björn Lanneskog
054 * @author Einar Pehrson
055 */
056 @SuppressWarnings("serial")
057 public class AssertionPanel extends JPanel implements SelectionListener,
058 AssertableCellListener {
059
060 /** The assertion controller */
061 private AssertionController controller;
062
063 /** The assertable cell currently being displayed in the panel */
064 private AssertableCell cell;
065
066 /** The label on which the status of the assertion is displayed */
067 private JLabel statusLabel = new JLabel();
068
069 /** The text field in which the assertion of the cell is displayed.*/
070 private JTextField usField = new JTextField();
071
072 /**A label showing the system-generated assertion*/
073 private JLabel sgLabel = new JLabel();
074
075 /**
076 * Creates a new assertion panel.
077 * @param uiController the user interface controller
078 */
079 public AssertionPanel(UIController uiController) {
080 // Configures panel
081 super(new BorderLayout());
082 setName(AssertionExtension.NAME);
083
084 // Creates controller
085 controller = new AssertionController(uiController);
086 uiController.addSelectionListener(this);
087
088 // Creates system-generated assertion components
089 JPanel sgPanel = new JPanel();
090 sgPanel.setPreferredSize(new Dimension(130, 60));
091 sgPanel.add(sgLabel);
092
093 // Creates user-specified assertion components
094 ApplyAction applyAction = new ApplyAction();
095 JButton applyButton = new JButton(applyAction);
096 usField.setPreferredSize(new Dimension(120, 24));
097 usField.setMaximumSize(new Dimension(1000, 24));
098 usField.addActionListener(applyAction);
099 usField.setAlignmentX(Component.CENTER_ALIGNMENT);
100 applyButton.setAlignmentX(Component.CENTER_ALIGNMENT);
101 statusLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
102
103 // Lays out user-specified assertion components
104 JPanel usPanel = new JPanel();
105 usPanel.setLayout(new BoxLayout(usPanel, BoxLayout.PAGE_AXIS));
106 usPanel.setPreferredSize(new Dimension(130, 120));
107 usPanel.add(usField);
108 usPanel.add(Box.createRigidArea(new Dimension(120, 4)));
109 usPanel.add(applyButton);
110 usPanel.add(Box.createRigidArea(new Dimension(120, 12)));
111 usPanel.add(statusLabel);
112 usPanel.add(Box.createRigidArea(new Dimension(120, 12)));
113
114 // Creates assertion syntax components
115 JPanel syntaxPanel = new JPanel();
116 JTextArea syntaxArea = new JTextArea("");
117 // "Operators: > < >= <=\nOR\nEXCEPT\nINTEGER"
118 syntaxArea.setPreferredSize(new Dimension(120, 100));
119 syntaxArea.setLineWrap(true);
120 syntaxArea.setEditable(false);
121 syntaxArea.setBackground(getBackground());
122 syntaxPanel.add(syntaxArea);
123
124 // Adds borders
125 TitledBorder border = BorderFactory.createTitledBorder("System-generated");
126 border.setTitleJustification(TitledBorder.CENTER);
127 sgPanel.setBorder(border);
128 border = BorderFactory.createTitledBorder("User-specified");
129 border.setTitleJustification(TitledBorder.CENTER);
130 usPanel.setBorder(border);
131 border = BorderFactory.createTitledBorder("Syntax");
132 border.setTitleJustification(TitledBorder.CENTER);
133 // syntaxPanel.setBorder(border);
134
135 // Adds panels
136 JPanel northPanel = new JPanel(new BorderLayout());
137 northPanel.add(sgPanel, BorderLayout.NORTH);
138 northPanel.add(usPanel, BorderLayout.SOUTH);
139 add(northPanel, BorderLayout.NORTH);
140 add(syntaxPanel, BorderLayout.CENTER);
141 }
142
143 /**
144 * Updates the assertion field and status label when the active cell of
145 * the application is changed.
146 * @param event the selection event that was fired
147 */
148 public void selectionChanged(SelectionEvent event) {
149 Cell cell = event.getCell();
150 if (cell != null) {
151 AssertableCell activeCell
152 = (AssertableCell)cell.getExtension(AssertionExtension.NAME);
153 activeCell.addAssertableCellListener(this);
154 assertionsChanged(activeCell);
155 } else {
156 usField.setText("");
157 statusLabel.setText("");
158 sgLabel.setText("");
159 }
160
161 // Stops listening to previous active cell
162 if (event.getPreviousCell() != null)
163 ((AssertableCell)event.getPreviousCell().getExtension(AssertionExtension.NAME))
164 .removeAssertableCellListener(this);
165 }
166
167 /**
168 * Updates the assertion field and status label when the assertion of the
169 * active cell is changed.
170 * @param cell the cell whose assertion changed
171 */
172 public void assertionsChanged(AssertableCell cell) {
173 // Stores the cell for use when applying assertion
174 this.cell = cell;
175
176 // Initializes colors and text
177 Color usColor = Color.BLACK;
178 Color sgColor = Color.BLACK;
179 String usStatus = "";
180
181 // Updates system-generated assertion label
182 if (cell.isSGAsserted()) {
183 sgLabel.setText(cell.getSGAssertion().toString());
184 sgColor = AssertionController.getAssertionResultColor(cell.assertSG());
185 } else
186 sgLabel.setText("No assertion");
187
188 // Updates the text field and validates the assertion, if any
189 if (cell.isUSAsserted()) {
190 usField.setText(cell.getUSAssertion().toString());
191 Assertion.Result result = cell.assertUS();
192
193 // Determines the status message
194 usColor = AssertionController.getAssertionResultColor(result);
195 switch (result) {
196 case OK:
197 usStatus += "Valid";
198 break;
199 case NAN:
200 usStatus += "Non-numeric value";
201 break;
202 case FAILED:
203 usStatus += "Illegal value";
204 break;
205 case NO_DATA:
206 usStatus += "No value";
207 break;
208 }
209
210 // Compares assertions
211 Assertion.ComparisonResult compResult = cell.assertAssertions();
212 switch (compResult) {
213 case NON_EQUAL:
214 usColor = new Color(0.7f, 0.0f, 0f);
215 usStatus = "Conflicting assertions";
216 break;
217 case ILLEGAL_INTERVAL:
218 sgLabel.setText(compResult.getErrorMsg());
219 break;
220 }
221 } else {
222 usField.setText("");
223 usStatus = "No assertion";
224 }
225
226 // Updates the label
227 sgLabel.setForeground(sgColor);
228 statusLabel.setForeground(usColor);
229 statusLabel.setText(usStatus);
230 }
231
232 /**
233 * An action used to apply changes made in the assertion field.
234 */
235 protected class ApplyAction extends FocusOwnerAction {
236
237 /**
238 * Creates a new apply action.
239 */
240 public ApplyAction() {}
241
242 protected String getName() {
243 return "Apply";
244 }
245
246 public void actionPerformed(ActionEvent e) {
247 if (cell != null)
248 if (controller.setAssertion(cell, usField.getText().trim()))
249 focusOwner.repaint();
250 }
251 }
252 }