1 33 package net.sf.jga.swing.spreadsheet; 34 35 import java.awt.Component ; 36 import java.awt.Point ; 37 import java.awt.event.ActionEvent ; 38 import java.awt.event.MouseAdapter ; 39 import java.awt.event.MouseEvent ; 40 import java.io.File ; 41 import java.io.FileOutputStream ; 42 import java.io.IOException ; 43 import java.io.InputStream ; 44 import java.io.OutputStream ; 45 import java.net.MalformedURLException ; 46 import java.net.URL ; 47 import java.text.MessageFormat ; 48 import javax.swing.Action ; 49 import javax.swing.JFileChooser ; 50 import javax.swing.JMenuItem ; 51 import javax.swing.JOptionPane ; 52 import javax.swing.JPopupMenu ; 53 import net.sf.jga.fn.BinaryFunctor; 54 import net.sf.jga.fn.Generator; 55 import net.sf.jga.fn.UnaryFunctor; 56 import net.sf.jga.fn.adaptor.Constant; 57 import net.sf.jga.fn.adaptor.ConstantBinary; 58 import net.sf.jga.fn.adaptor.ConstantUnary; 59 import net.sf.jga.fn.adaptor.Identity; 60 import net.sf.jga.fn.adaptor.Project2nd; 61 import net.sf.jga.fn.property.InvokeNoArgMethod; 62 import net.sf.jga.parser.FunctorParser; 63 import net.sf.jga.parser.ParseException; 64 import net.sf.jga.swing.GenericAction; 65 66 73 74 public class Controller{ 75 76 private Spreadsheet _sheet; 78 79 private FunctorParser _parser; 81 82 private BinaryFunctor<String ,String ,String > _promptFn = 84 new ConstantBinary<String ,String ,String >(""); 85 86 private BinaryFunctor<String ,String ,Integer > _confirmFn = 88 new ConstantBinary<String ,String ,Integer >(null); 89 90 private BinaryFunctor<String , String , ?> _errorFn = 92 new ConstantBinary<String ,String ,String >(""); 93 94 private UnaryFunctor<Spreadsheet,Integer > _loadFn = 96 new ConstantUnary<Spreadsheet,Integer >(null); 97 98 private BinaryFunctor<Spreadsheet,Boolean ,Integer > _saveFn = 100 new ConstantBinary<Spreadsheet,Boolean ,Integer >(null); 101 102 public static final int YES_OPTION = JOptionPane.YES_OPTION; 103 public static final int NO_OPTION = JOptionPane.NO_OPTION; 104 public static final int CANCEL_OPTION = JOptionPane.CANCEL_OPTION; 105 106 107 110 public Controller(Spreadsheet sheet) { 111 _sheet = sheet; 112 _parser = new FunctorParser(); 113 _parser.bindThis(this); 114 } 115 116 117 122 public String prompt(String msg, String val) { return _promptFn.fn(msg, val); } 123 124 125 128 public void setPromptFunctor(BinaryFunctor<String ,String ,String > fn) { 129 _promptFn = fn; 130 } 131 132 133 137 138 public int confirm(String msg, String title) { return _confirmFn.fn(msg, title); } 139 140 141 144 145 public void setConfirmFunctor(BinaryFunctor<String ,String ,Integer > fn) { _confirmFn = fn; } 146 147 148 151 152 public void notify(String msg, String title) { _errorFn.fn(msg, title); } 153 154 155 158 public void setErrorFunctor(BinaryFunctor<String ,String ,?> fn) { _errorFn = fn; } 159 160 161 164 165 public int loadSheet(Spreadsheet sheet) { 166 return _loadFn.fn(sheet); 167 } 168 169 172 173 public void setLoadFunctor(UnaryFunctor<Spreadsheet,Integer > fn) { _loadFn = fn; } 174 175 176 179 180 public int saveSheet(Spreadsheet sheet, boolean prompt) { 181 return _saveFn.fn(sheet,prompt); 182 } 183 184 185 188 189 public void setSaveFunctor(BinaryFunctor<Spreadsheet,Boolean ,Integer > fn) { _saveFn = fn; } 190 191 195 198 public Action getFileNewCmd() { 199 return new GenericAction(parseAction("this.newWorksheet()"), "New"); 200 } 201 202 203 206 public Action getFileOpenCmd() { 207 return new GenericAction(parseAction("this.openFile()"), "Open"); 208 } 209 210 211 213 216 public Action getFileSaveCmd() { 217 return new GenericAction(parseAction("this.saveFile()"), "Save"); 218 } 219 220 221 223 226 public Action getFileSaveAsCmd() { 227 return new GenericAction(parseAction("this.saveFileAs()"), "Save As..."); 228 } 229 230 231 234 public Action getDefaultEditableCmd() { 235 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Editable"); 236 cmd.setEnabled(false); 237 return cmd; 238 } 239 240 243 public Action getDefaultTypeCmd() { 244 return new GenericAction(parseAction("this.setDefaultType()"), "Cell Type"); 245 } 246 247 250 public Action getDefaultValueCmd() { 251 return new GenericAction(parseAction("this.setDefaultValue()"), "Cell Value"); 252 } 253 254 257 public Action getDefaultFormatCmd() { 258 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Format"); 259 cmd.setEnabled(false); 260 return cmd; 261 } 262 263 266 public Action getDefaultRendererCmd() { 267 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Renderer"); 268 cmd.setEnabled(false); 269 return cmd; 270 } 271 272 275 public Action getDefaultEditorCmd() { 276 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Editor"); 277 cmd.setEnabled(false); 278 return cmd; 279 } 280 281 284 public Action getSheetColumnsCmd() { 285 return new GenericAction(parseAction("this.setColumnCount()"), "Set Column Count"); 286 } 287 288 291 public Action getSheetRowsCmd() { 292 return new GenericAction(parseAction("this.setRowCount()"), "Set Row Count"); 293 } 294 295 298 public Action getImportClassCmd() { 299 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Import Class"); 300 cmd.setEnabled(false); 301 return cmd; 302 } 303 304 307 public Action getCellRenameCmd() { 308 String cellNameExp = "this.setCellName(x.getSelectedRow(),x.getSelectedColumn())"; 309 try { 310 UnaryFunctor<ActionEvent ,Object > cellNameFn = 311 new Project2nd<ActionEvent ,Object >() 312 .generate2nd(_parser.parseUnary(cellNameExp, Spreadsheet.class).bind(_sheet)); 313 314 return new GenericAction(cellNameFn, "Set Name"); 315 } 316 catch (ParseException x) { 317 x.printStackTrace(); 318 GenericAction cmd = 319 new GenericAction(new ConstantUnary<ActionEvent ,Object >(null), "Set Name"); 320 cmd.setEnabled(false); 321 return cmd; 322 } 323 } 324 325 328 public Action getCellFormatCmd() { 329 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Set Format"); 330 cmd.setEnabled(false); 331 return cmd; 332 } 333 334 337 public Action getCellTypeCmd() { 338 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Set Type"); 339 cmd.setEnabled(false); 340 return cmd; 341 } 342 343 344 347 public Action getCellRendererCmd() { 348 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Set Renderer"); 349 cmd.setEnabled(false); 350 return cmd; 351 } 352 353 354 357 public Action getCellEditorCmd() { 358 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Set Editor"); 359 cmd.setEnabled(false); 360 return cmd; 361 } 362 363 364 367 public Action getCellValidatorCmd() { 368 GenericAction cmd = new GenericAction(new Identity<ActionEvent >(), "Set Validator"); 369 cmd.setEnabled(false); 370 return cmd; 371 } 372 373 377 380 public void setDefaultType() { 381 String prompt = "Enter default type for uninitialized cells"; 382 String name = _promptFn.fn(prompt, _sheet.getDefaultCellType().getName()); 383 if (name == null) 384 return; 385 386 try { 387 _sheet.setDefaultCellType(Class.forName(name)); 388 } 389 catch (ClassNotFoundException x) { 390 String fmt = "Class {0} not found"; 391 String msg = MessageFormat.format(fmt, new Object []{ x.getMessage() }); 392 _errorFn.fn(msg, "ClassNotFoundException"); 393 } 394 } 395 396 399 public void setColumnCount() { 400 String prompt = "Enter the number of columns"; 401 String countstr = _promptFn.fn(prompt, String.valueOf(_sheet.getColumnCount())); 402 if (countstr == null) 403 return; 404 405 try { 406 _sheet.setColumnCount(Integer.parseInt(countstr)); 407 } 408 catch (NumberFormatException x) { 409 String fmt = "{0} isn't a number"; 410 String msg = MessageFormat.format(fmt, new Object []{ countstr }); 411 _errorFn.fn(msg, "NumberFormatException"); 412 } 413 } 414 415 418 public void setRowCount() { 419 String prompt = "Enter the number of rows"; 420 String countstr = _promptFn.fn(prompt, String.valueOf(_sheet.getRowCount())); 421 if (countstr == null) 422 return; 423 424 try { 425 _sheet.setRowCount(Integer.parseInt(countstr)); 426 } 427 catch (NumberFormatException x) { 428 String fmt = "{0} isn't a number"; 429 String msg = MessageFormat.format(fmt, new Object []{ countstr }); 430 _errorFn.fn(msg, "NumberFormatException"); 431 } 432 } 433 434 439 442 public void setDefaultValue() { 443 String prompt = "Enter default value for uninitialized cells"; 444 String exp = _promptFn.fn(prompt, ""+_sheet.getDefaultCellValue()); 445 if (exp == null) 446 return; 447 448 try { 449 Generator gen = _sheet.getParser().parseGenerator(exp); 450 _sheet.setDefaultCellValue(gen.gen()); 451 } 452 catch (ParseException x) { 453 _errorFn.fn(x.getMessage(), getExceptionName(getRootCause(x))); 454 } 455 } 456 457 463 public void setCellName(int row, int col) { 464 String prompt = "Enter name for cell("+row+","+col+")"; 465 Cell cell = _sheet.getCellIfPresent(row, col); 466 String oldName = (cell != null) ? cell.getName() : ""; 467 String name = _promptFn.fn(prompt, oldName); 468 if (name != null && !name.equals(oldName)) 469 _sheet.setCellName(name, row, col); 470 } 471 472 473 477 480 public void newWorksheet() { 481 int ans = JOptionPane.YES_OPTION; 482 if (isSheetDirty()) { 483 ans = promptAndSave(); 484 } 485 486 if (ans != JOptionPane.CANCEL_OPTION) { 487 _sheet.clear(); 488 setSheetSource(null); 489 setSheetDirty(false); 490 } 491 } 492 493 494 497 public int openFile() { return loadSheet(_sheet); } 498 499 500 502 public int saveFile() { return saveSheet(_sheet, false); } 503 504 505 507 public int saveFileAs() { return saveSheet(_sheet, true); } 508 509 510 513 public int promptAndSave() { 514 String format = "save {0}?"; 515 Object name = getSheetSource(); 516 if (name == null) 517 name = "worksheet"; 518 519 String msg = MessageFormat.format(format, new Object []{ name }); 520 int ans = confirm(msg,msg); 521 if (ans == Controller.YES_OPTION) { 522 int choice = saveFile(); 523 if (choice == Controller.CANCEL_OPTION || choice == JFileChooser.ERROR_OPTION) { 524 ans = Controller.CANCEL_OPTION; 525 } 526 } 527 return ans; 528 } 529 530 534 private final String DIRTY_PROP = "dirty"; 535 536 public boolean isSheetDirty() { 537 Object dirtyProp = _sheet.getClientProperty(DIRTY_PROP); 538 return Boolean.TRUE.equals(dirtyProp); 539 } 540 541 public void setSheetDirty(boolean flag) { 542 _sheet.putClientProperty(DIRTY_PROP, Boolean.valueOf(flag)); 543 } 544 545 546 private final String SOURCE_PROP = "source"; 547 548 public URL getSheetSource() { 549 Object sourceURL = _sheet.getClientProperty(SOURCE_PROP); 550 if (sourceURL == null) 551 return null; 552 553 if (sourceURL instanceof URL ) 554 return (URL ) sourceURL; 555 556 try { 557 return new File (new File ("."), "worksheet1.hwks").toURL(); 558 } 559 catch (MalformedURLException x) { 560 x.printStackTrace(); 561 return null; 562 } 563 } 564 565 public void setSheetSource(URL url) { 566 _sheet.putClientProperty(SOURCE_PROP, url); 568 } 569 570 private UnaryFunctor<ActionEvent ,?> parseAction(String exp) { 571 try { 572 return new Project2nd<ActionEvent ,Object >() 573 .generate2nd(_parser.parseGenerator(exp)); 574 } 575 catch (ParseException x) { 576 x.printStackTrace(); 577 return null; 579 } 580 } 581 582 584 static Throwable getRootCause(Throwable t) { 585 for (Throwable t1 = t.getCause(); t1 != null; t1 = t.getCause()) 586 t = t1; 587 588 return t; 589 } 590 591 static String getExceptionName(Throwable t) { 592 String fqcn = t.getClass().getName(); 593 return fqcn.substring(fqcn.lastIndexOf(".") + 1); 594 } 595 } 596 | Popular Tags |