001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 */ 021package org.biojava.nbio.structure.align.gui; 022 023import org.biojava.nbio.structure.align.ce.ConfigStrucAligParams; 024 025import javax.swing.*; 026import java.awt.*; 027import java.awt.event.ActionEvent; 028import java.awt.event.ActionListener; 029import java.lang.reflect.Method; 030import java.util.ArrayList; 031import java.util.List; 032 033/** 034 * UI for {@link ConfigStrucAligParams}, for the AlignmentGUI. 035 * 036 * Visually parameters are displayed as a label and an input field such as a text box. 037 * The following methods are used to determine which properties are accessible: 038 * <ul> 039 * <li> {@link ConfigStrucAligParams#getUserConfigParameterNames() getUserConfigParameterNames()} 040 * Parameter labels 041 * <li> {@link ConfigStrucAligParams#getUserConfigParameters() getUserConfigParameters()} 042 * Parameter method names, to be prepended with 'set' or 'get' 043 * <li> {@link ConfigStrucAligParams#getUserConfigTypes() getUserConfigTypes()} 044 * Types for each parameter (Integer, Float, Boolean, Enum, String[]) 045 * <li> {@link ConfigStrucAligParams#getUserConfigHelp() getUserConfigHelp()} 046 * Alt text for each parameter 047 * </ul> 048 * 049 * @author Andreas Prlic 050 * 051 */ 052public class ParameterGUI extends JFrame{ 053 054 private static final long serialVersionUID = 723386061184110161L; 055 056 private ConfigStrucAligParams params ; 057 private List<Component> textFields; 058 059 /** 060 * Constructor for a ParameterGUI. Generalization for any type of 061 * Structural Alignment algorithm that implements the parameter interface. 062 * 063 * @param params parameter bean 064 * @param algorithm name of the algorithm 065 */ 066 @SuppressWarnings("rawtypes") 067 public ParameterGUI(ConfigStrucAligParams params, String algorithm) { 068 069 if (params == null) return; 070 this.params = params; 071 072 this.setTitle("Parameters for " + algorithm); 073 074 List<String> names = params.getUserConfigParameterNames(); 075 List<String> keys = params.getUserConfigParameters(); 076 List<Class> types = params.getUserConfigTypes(); 077 078 List<String> helps = params.getUserConfigHelp(); 079 080 // quick check for bugs in params 081 assert(names.size() == keys.size()); 082 assert(names.size() == types.size()); 083 assert(names.size() == helps.size()); 084 085 textFields = new ArrayList<Component>(); 086 Box vBox = Box.createVerticalBox(); 087 088 for (int i = 0 ; i < keys.size(); i++){ 089 Class type = types.get(i); 090 091 Box hBox = Box.createHorizontalBox(); 092 String name = names.get(i); 093 JLabel label = new JLabel(name); 094 String help = helps.get(i); 095 label.setToolTipText(help); 096 String key = keys.get(i); 097 Object value = getValue(key); 098 099 String data = value.toString(); 100 Component field; 101 if ( type.isEnum() ) { 102 Object[] values = type.getEnumConstants(); 103 JComboBox jcbox = new JComboBox(values); 104 jcbox.setSelectedItem(value); 105 field = jcbox; 106 107 } else if ( type == Boolean.class){ 108 109 String[] values = new String[]{"true","false"}; 110 JComboBox jcbox = new JComboBox(values); 111 if ( data.equalsIgnoreCase("false")) 112 jcbox.setSelectedIndex(1); 113 else 114 jcbox.setSelectedIndex(0); 115 116 field = jcbox; 117 118 //field.setToolTipText(help); 119 120 } else { 121 JTextField tfield = new JTextField(10); 122 123 if ( type == String[].class) { 124 String stuff = ""; 125 for ( String da : (String[]) value){ 126 stuff += da + " "; 127 } 128 data = stuff; 129 130 131 } 132 tfield.setText(data); 133 tfield.setToolTipText(help); 134 field = tfield; 135 } 136 137 hBox.add(label); 138 hBox.add(Box.createGlue()); 139 hBox.add(field); 140 141 vBox.add(hBox); 142 143 textFields.add(field); 144 145 } 146 147 148 JButton abort = new JButton("Cancel"); 149 abort.addActionListener(new ActionListener(){ 150 @Override 151 public void actionPerformed(ActionEvent event) { 152 destroy(); 153 dispose(); } 154 }); 155 156 JButton defaultB = new JButton("Default"); 157 defaultB.addActionListener(new ActionListener(){ 158 @Override 159 public void actionPerformed(ActionEvent event) { 160 setDefault(); 161 } 162 }); 163 164 JButton close = new JButton("Apply"); 165 166 close.addActionListener(new ActionListener(){ 167 @Override 168 public void actionPerformed(ActionEvent event) { 169 170 storeParameters(); 171 172 destroy(); 173 dispose(); } 174 }); 175 176 Box hBox = Box.createHorizontalBox(); 177 hBox.add(abort); 178 hBox.add(Box.createGlue()); 179 hBox.add(defaultB); 180 hBox.add(Box.createGlue()); 181 hBox.add(close); 182 183 vBox.add(hBox); 184 this.getContentPane().add(vBox); 185 this.pack(); 186 this.setVisible(true); 187 } 188 189 @SuppressWarnings({ "rawtypes" }) 190 protected void setDefault() { 191 params.reset(); 192 193 List<String> keys = params.getUserConfigParameters(); 194 List<Class> types = params.getUserConfigTypes(); 195 //List<String> names = params.getUserConfigParameterNames(); 196 for (int i = 0 ; i < keys.size(); i++){ 197 198 Class type = types.get(i); 199 Object data = getValue(keys.get(i)); 200 if( type.isEnum()) { 201 JComboBox field = (JComboBox) textFields.get(i); 202 field.setSelectedItem(data); 203 field.updateUI(); 204 } else if ( type == Boolean.class){ 205 JComboBox field = (JComboBox) textFields.get(i); 206 if ( data.toString().equalsIgnoreCase("false")) 207 field.setSelectedIndex(1); 208 else 209 field.setSelectedIndex(0); 210 field.updateUI(); 211 212 } else { 213 JTextField field = (JTextField)textFields.get(i); 214 if ( type.isArray()){ 215 String stuff = ""; 216 for ( String da : (String[]) data){ 217 stuff += da + " "; 218 } 219 220 field.setText(stuff); 221 } else { 222 223 field.setText(data.toString()); 224 } 225 field.updateUI(); 226 } 227 228 229 } 230 this.repaint(); 231 232 } 233 234 private void destroy(){ 235 //avoid memory leaks... 236 textFields = null; 237 params = null; 238 } 239 240 @SuppressWarnings("rawtypes") 241 protected void storeParameters() { 242 //List<String> names = params.getUserConfigParameterNames(); 243 List<String> keys = params.getUserConfigParameters(); 244 List<Class> types = params.getUserConfigTypes(); 245 246 for (int i = 0 ; i < keys.size(); i++){ 247 Class type = types.get(i); 248 String key = keys.get(i); 249 // String name = keys.get(i); 250 String value = null; 251 System.out.println(key); 252 if( type.isEnum() ) { 253 JComboBox field = (JComboBox) textFields.get(i); 254 Enum sel = (Enum)field.getSelectedItem(); 255 value = sel.name(); 256 } else if ( type == Boolean.class){ 257 JComboBox field = (JComboBox) textFields.get(i); 258 int sel = field.getSelectedIndex(); 259 Boolean flag = true; 260 if ( sel == 1 ) 261 flag = false; 262 value = flag.toString(); 263 } else { 264 JTextField field = (JTextField)textFields.get(i); 265 value = field.getText(); 266 } 267 268 setValue(key, type, value); 269 } 270 271 System.out.println("new parameters: " + params.toString()); 272 273 } 274 275 @SuppressWarnings({ "unchecked" }) 276 private void setValue(String name, Class type, String value) { 277 try { 278 String methodName = "set" + name; 279 280 Class paramC = params.getClass(); 281 282 Method m =paramC.getMethod(methodName,type); 283 284 285 Object data = null; 286 287 if ( type == Integer.class){ 288 data = Integer.parseInt(value); 289 } else if ( type == Double.class){ 290 data = Double.parseDouble(value); 291 } else if ( type == Float.class) { 292 data = Float.parseFloat(value); 293 } else if ( type == Boolean.class) { 294 data = Boolean.parseBoolean(value); 295 } else if ( type == Short.class) { 296 data = Short.parseShort(value); 297 } else if ( type == String[].class) { 298 data = value.split(" "); 299 } else if ( type.isEnum() ) { 300 data = Enum.valueOf(type, value); 301 } 302 303 if (data == null){ 304 System.err.println("Could not set value " + value + 305 " for field " + name); 306 return; 307 } 308 m.invoke(params, data); 309 310 311 } catch (Exception e){ 312 e.printStackTrace(); 313 314 } 315 316 } 317 318 @SuppressWarnings("unchecked") 319 private Object getValue(String name){ 320 // first try with get form 321 try { 322 String methodName = "get" + name; 323 324 Class paramC = params.getClass(); 325 326 Method m; 327 try { 328 //try boolean getter 329 m = paramC.getMethod(methodName,(Class[])null); 330 } catch(NoSuchMethodException e) { 331 //try boolean getter 332 methodName = "is" + name; 333 m = paramC.getMethod(methodName,(Class[])null); 334 } 335 336 Object value = m.invoke(params); 337 338 return value; 339 } catch (Exception e){ 340 e.printStackTrace(); 341 return null; 342 } 343 344 345 } 346}