001/* 002 * Copyright (c) 2005 Peter Palotas, Fredrik Johansson, Einar Pehrson, 003 * Sebastian Kekkonen, Lars Magnus Lang, 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 */ 023package csheets.ext.assertion.ui; 024 025import java.awt.BorderLayout; 026import java.awt.Color; 027import java.awt.Component; 028import java.awt.Dimension; 029import java.awt.event.ActionEvent; 030 031import javax.swing.BorderFactory; 032import javax.swing.Box; 033import javax.swing.BoxLayout; 034import javax.swing.JButton; 035import javax.swing.JLabel; 036import javax.swing.JPanel; 037import javax.swing.JTextArea; 038import javax.swing.JTextField; 039import javax.swing.border.TitledBorder; 040 041import csheets.core.Cell; 042import csheets.ext.assertion.AssertableCell; 043import csheets.ext.assertion.AssertableCellListener; 044import csheets.ext.assertion.Assertion; 045import csheets.ext.assertion.AssertionExtension; 046import csheets.ui.ctrl.FocusOwnerAction; 047import csheets.ui.ctrl.SelectionEvent; 048import csheets.ui.ctrl.SelectionListener; 049import csheets.ui.ctrl.UIController; 050 051/** 052 * A panel for adding or editing an assertion for a cell 053 * @author Bjorn Lanneskog 054 * @author Einar Pehrson 055 */ 056@SuppressWarnings("serial") 057public 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}