001 // This file is part of the Attempto Java Packages. 002 // Copyright 2008-2009, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch). 003 // 004 // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the 005 // terms of the GNU Lesser General Public License as published by the Free Software Foundation, 006 // either version 3 of the License, or (at your option) any later version. 007 // 008 // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY 009 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 010 // PURPOSE. See the GNU Lesser General Public License for more details. 011 // 012 // You should have received a copy of the GNU Lesser General Public License along with the Attempto 013 // Java Packages. If not, see http://www.gnu.org/licenses/. 014 015 package ch.uzh.ifi.attempto.acewiki.gui.editor; 016 017 import nextapp.echo2.app.Alignment; 018 import nextapp.echo2.app.Column; 019 import nextapp.echo2.app.Component; 020 import nextapp.echo2.app.ContentPane; 021 import nextapp.echo2.app.Extent; 022 import nextapp.echo2.app.Font; 023 import nextapp.echo2.app.Grid; 024 import nextapp.echo2.app.Insets; 025 import nextapp.echo2.app.ResourceImageReference; 026 import nextapp.echo2.app.Row; 027 import nextapp.echo2.app.event.ActionEvent; 028 import nextapp.echo2.app.event.ActionListener; 029 import nextapp.echo2.app.layout.GridLayoutData; 030 import ch.uzh.ifi.attempto.acewiki.Wiki; 031 import ch.uzh.ifi.attempto.acewiki.core.ontology.OntologyElement; 032 import ch.uzh.ifi.attempto.acewiki.core.ontology.OntologyTextElement; 033 import ch.uzh.ifi.attempto.echocomp.GeneralButton; 034 import ch.uzh.ifi.attempto.echocomp.Label; 035 import ch.uzh.ifi.attempto.echocomp.MessageWindow; 036 import ch.uzh.ifi.attempto.echocomp.SolidLabel; 037 import ch.uzh.ifi.attempto.echocomp.TextField; 038 import ch.uzh.ifi.attempto.echocomp.WindowPane; 039 040 /** 041 * This abstract class contains the basic structure for forms to create and modify words 042 * (represented by ontology elements). 043 * 044 * @author Tobias Kuhn 045 */ 046 public abstract class FormPane extends ContentPane implements ActionListener { 047 048 private Wiki wiki; 049 private ActionListener actionListener; 050 051 private Column column; 052 private WindowPane window; 053 private Grid iconRow; 054 private GeneralButton okButton; 055 private GeneralButton cancelButton; 056 057 /** 058 * Initializes the form pane. 059 * 060 * @param window The host window. 061 * @param wiki The wiki instance. 062 * @param actionListener The actionlistener. 063 */ 064 protected FormPane(WindowPane window, Wiki wiki, ActionListener actionListener) { 065 this.window = window; 066 this.wiki = wiki; 067 this.actionListener = actionListener; 068 069 Grid grid = new Grid(1); 070 grid.setRowHeight(0, new Extent(330)); 071 grid.setRowHeight(1, new Extent(30)); 072 073 column = new Column(); 074 column.setInsets(new Insets(10, 20, 0, 0)); 075 column.setCellSpacing(new Extent(10)); 076 GridLayoutData gridLayout = new GridLayoutData(); 077 gridLayout.setAlignment(new Alignment(Alignment.LEFT, Alignment.TOP)); 078 column.setLayoutData(gridLayout); 079 grid.add(column); 080 081 iconRow = new Grid(2); 082 iconRow.setRowHeight(0, new Extent(110)); 083 iconRow.setColumnWidth(0, new Extent(100)); 084 iconRow.setInsets(new Insets(0, 0, 10, 20)); 085 column.add(iconRow); 086 087 Row footerRow = new Row(); 088 footerRow.setInsets(new Insets(10, 0, 0, 0)); 089 footerRow.add(new Label("* required field", Font.ITALIC, 11)); 090 grid.add(footerRow); 091 092 Row buttonBar = new Row(); 093 buttonBar.setAlignment(new Alignment(Alignment.RIGHT, Alignment.CENTER)); 094 buttonBar.setInsets(new Insets(10, 10, 10, 10)); 095 buttonBar.setCellSpacing(new Extent(5)); 096 okButton = new GeneralButton("OK", 70, this); 097 buttonBar.add(okButton); 098 cancelButton = new GeneralButton("Cancel", 70, this); 099 buttonBar.add(cancelButton); 100 grid.add(buttonBar); 101 102 add(grid); 103 } 104 105 /** 106 * Returns the wiki instance. 107 * 108 * @return The wiki instance. 109 */ 110 protected Wiki getWiki() { 111 return wiki; 112 } 113 114 /** 115 * This method should try to save the word with the current properties and should show 116 * error messages if this is not successful. In the case of success, one of the 117 * finished-methods has to be called. 118 * 119 * @see #finished(OntologyElement) 120 * @see #finished(OntologyElement, int) 121 */ 122 protected abstract void save(); 123 124 /** 125 * This method should be called when the saving process is finished successfully. 126 * 127 * @param el The created or modified ontology element. 128 */ 129 protected void finished(OntologyElement el) { 130 finished(el, 0); 131 } 132 133 /** 134 * This method should be called when the saving process is finished successfully. 135 * 136 * @param el The created or modified ontology element. 137 * @param wordNumber The word form id. 138 */ 139 protected void finished(OntologyElement el, int wordNumber) { 140 window.setVisible(false); 141 dispose(); 142 143 // a text element is used to store the ontology element and the word number in one object: 144 OntologyTextElement te = OntologyTextElement.createTextElement(el, wordNumber); 145 actionListener.actionPerformed(new ActionEvent(te, "")); 146 } 147 148 /** 149 * Adds a new row to the form. 150 * 151 * @param labelText The text for the label shown on the left hand side of the component. 152 * @param component The component, i.e. a text field. 153 * @param explanation An explanation text shown under the component. 154 * @param required Defines whether the component should be marked as required. 155 */ 156 protected void addRow(String labelText, Component component, String explanation, boolean required) { 157 Grid grid = new Grid(3); 158 grid.setInsets(new Insets(0, 0, 5, 0)); 159 grid.setColumnWidth(0, new Extent(140)); 160 grid.add(new SolidLabel(labelText, Font.ITALIC)); 161 if (component instanceof TextField) { 162 ((TextField) component).setWidth(new Extent(530)); 163 } 164 grid.add(component); 165 if (required) { 166 grid.add(new Label("*", Font.ITALIC, 11)); 167 } else { 168 grid.add(new Label()); 169 } 170 grid.add(new Label()); 171 grid.add(new Label(explanation, Font.ITALIC, 11)); 172 column.add(grid); 173 } 174 175 /** 176 * Sets the icon row. The icon row is shown at the top of the form and shows an icon of the 177 * ontological structure that is represented by the word. On the right hand side of the icon, 178 * an explanatory text is shown. 179 * 180 * @param iconName The name of the icon, one of "individual", "concept", or "role". 181 * @param text The explanatory text. 182 */ 183 protected void setIconRow(String iconName, String text) { 184 iconRow.removeAll(); 185 iconRow.add(new Label(new ResourceImageReference("ch/uzh/ifi/attempto/acewiki/gui/img/" + iconName + ".png"))); 186 iconRow.add(new Label(text, Font.ITALIC)); 187 } 188 189 /** 190 * Shows an error message. 191 * 192 * @param text The error text. 193 */ 194 protected void showErrorMessage(String text) { 195 wiki.showWindow(new MessageWindow("Error", text, window, "OK")); 196 } 197 198 public void actionPerformed(ActionEvent e) { 199 if (e.getSource() == cancelButton) { 200 window.setVisible(false); 201 dispose(); 202 } else { 203 save(); 204 } 205 } 206 207 /** 208 * Normalizes the string. All white spaces are replaced by underscores. Afterwards, leading and 209 * trailing underscores are removed and successive underscores are replaced by just one underscore. 210 * 211 * @param s The string to be normalized. 212 * @return The normalized string. 213 */ 214 protected static String normalize(String s) { 215 return s.replaceAll("\\s", "_").replaceAll("(_)+", "_").replaceAll("^_", "").replaceAll("_$", ""); 216 } 217 218 /** 219 * Returns true if the string is a valid to be used as a word form. The first character must be 220 * one of a-z, A-Z. The following characters have to be one of a-z, A-Z, 0-9, -, _. 221 * 222 * @param s The string to be checked for validity. 223 * @return true if the string is valid. 224 */ 225 protected static boolean isValidString(String s) { 226 if (s.length() == 0) return true; 227 boolean first = true; 228 for (byte b : s.getBytes()) { 229 if (first) { 230 first = false; 231 if (b >= 'a' && b <= 'z') continue; 232 if (b >= 'A' && b <= 'Z') continue; 233 return false; 234 } else { 235 if (b >= 'a' && b <= 'z') continue; 236 if (b >= 'A' && b <= 'Z') continue; 237 if (b >= '0' && b <= '9') continue; 238 if (b == '-') continue; 239 if (b == '_') continue; 240 return false; 241 } 242 } 243 return true; 244 } 245 246 }