1 33 package net.sf.jga.swing.spreadsheet; 34 35 import java.awt.BorderLayout ; 36 import java.awt.Component ; 37 import java.awt.Container ; 38 import java.awt.Dimension ; 39 import java.awt.Insets ; 40 import java.awt.Point ; 41 import java.awt.event.ActionEvent ; 42 import java.awt.event.MouseAdapter ; 43 import java.awt.event.MouseEvent ; 44 import java.awt.event.WindowAdapter ; 45 import java.awt.event.WindowEvent ; 46 import java.io.File ; 47 import java.io.FileInputStream ; 48 import java.io.FileOutputStream ; 49 import java.io.IOException ; 50 import java.io.InputStream ; 51 import java.io.PrintStream ; 52 import java.net.MalformedURLException ; 53 import java.net.URL ; 54 import java.text.MessageFormat ; 55 import javax.swing.AbstractAction ; 56 import javax.swing.Action ; 57 import javax.swing.Icon ; 58 import javax.swing.JFileChooser ; 59 import javax.swing.JFrame ; 60 import javax.swing.JLabel ; 61 import javax.swing.JMenu ; 62 import javax.swing.JMenuBar ; 63 import javax.swing.JMenuItem ; 64 import javax.swing.JOptionPane ; 65 import javax.swing.JPopupMenu ; 66 import javax.swing.JScrollPane ; 67 import javax.swing.UIManager ; 68 import javax.swing.event.AncestorEvent ; 69 import javax.swing.event.AncestorListener ; 70 import net.sf.jga.fn.BinaryFunctor; 71 import net.sf.jga.fn.Generator; 72 import net.sf.jga.fn.UnaryFunctor; 73 import net.sf.jga.fn.adaptor.ApplyBinary; 74 import net.sf.jga.fn.adaptor.ConstantBinary; 75 import net.sf.jga.fn.adaptor.ConstantUnary; 76 import net.sf.jga.fn.adaptor.Identity; 77 import net.sf.jga.fn.adaptor.Project1st; 78 import net.sf.jga.fn.adaptor.Project2nd; 79 import net.sf.jga.fn.property.ArrayBinary; 80 import net.sf.jga.fn.property.ArrayUnary; 81 import net.sf.jga.fn.property.InvokeMethod; 82 import net.sf.jga.fn.property.InvokeNoArgMethod; 83 import net.sf.jga.fn.property.SetProperty; 84 import net.sf.jga.parser.FunctorParser; 85 import net.sf.jga.parser.ParseException; 86 import net.sf.jga.swing.GenericAction; 87 88 95 96 public class Application { 97 98 private JFrame _frame; 99 100 private Spreadsheet _sheet; 101 102 private FunctorParser _parser; 103 104 private Controller _controller; 105 106 private JFileChooser _chooser; 107 108 public Application() { 109 _sheet = makeDefaultSheet(); 110 _parser = new FunctorParser(); 111 _parser.bindThis(this); 112 113 _controller = new Controller(_sheet); 114 115 _sheet.setUpdateHandler(new SetProperty<Controller,Boolean >(Controller.class,"SheetDirty", 116 Boolean.TYPE) 117 .bind(_controller, Boolean.TRUE)); 118 119 createUI(_sheet, _controller); 121 } 122 123 124 public Spreadsheet makeDefaultSheet() { 125 Spreadsheet sheet = new Spreadsheet(16,16); 126 sheet.setPreferredScrollableViewportSize(new Dimension (400,250)); 127 sheet.setEditableByDefault(true); 128 129 sheet.setRowSelectionInterval(0,0); 130 sheet.setColumnSelectionInterval(0,0); 131 132 return sheet; 133 } 134 135 136 public final void createUI(final Spreadsheet sheet, Controller controller) { 137 final JPopupMenu popupMenu = new JPopupMenu ("Popup Menu"); 138 popupMenu.add(new JMenuItem (controller.getCellRenameCmd())); 139 popupMenu.add(new JMenuItem (controller.getCellFormatCmd())); 140 popupMenu.add(new JMenuItem (controller.getCellTypeCmd())); 141 142 sheet.addMouseListener(new MouseAdapter () { 144 public void mousePressed(MouseEvent e) { 145 if (e.getButton() == e.BUTTON3) { 147 Spreadsheet sht = (Spreadsheet) e.getComponent(); 148 Point p = e.getPoint(); 149 int row = sht.rowAtPoint(p); 150 int col = sht.columnAtPoint(p); 151 sht.setRowSelectionInterval(row,row); 152 sht.setColumnSelectionInterval(col,col); 153 154 if (e.isPopupTrigger()) { 155 popupMenu.show(e.getComponent(), p.x, p.y); 156 } 157 } 158 } 159 public void mouseReleased(MouseEvent e) { 160 if (e.isPopupTrigger()) { 161 popupMenu.show(e.getComponent(), e.getX(), e.getY()); 162 } 163 } 164 }); 165 166 JLabel statusLabel = new JLabel ("cell(0,0)"); 168 sheet.setStatusHandler(new SetProperty(JLabel .class, "Text", String .class) 169 .bind1st(statusLabel)); 170 171 _frame = new JFrame ("Application"); 173 _frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); 174 _frame.addWindowListener(new WindowAdapter () { 175 public void windowClosing(WindowEvent e) { 176 closeWorksheet(); 177 System.exit(0); 179 } 180 }); 181 182 controller.setLoadFunctor(buildLoadFunctor()); 184 controller.setSaveFunctor(buildSaveFunctor()); 185 controller.setErrorFunctor(buildErrorFunctor()); 186 controller.setPromptFunctor(buildPromptFunctor()); 187 controller.setConfirmFunctor(buildConfirmFunctor()); 188 189 Container rootPane = _frame.getContentPane(); 191 rootPane.setLayout(new BorderLayout (5,5)); 192 193 JScrollPane pane = new JScrollPane (sheet); 194 rootPane.add(pane, BorderLayout.CENTER); 195 rootPane.add(statusLabel, BorderLayout.SOUTH); 196 197 JMenu fileMenu = new JMenu ("File"); 199 fileMenu.add(controller.getFileNewCmd()); 200 fileMenu.add(controller.getFileOpenCmd()); 201 fileMenu.add(controller.getFileSaveCmd()); 202 fileMenu.add(controller.getFileSaveAsCmd()); 203 fileMenu.add(getFileExitCmd()); 204 205 JMenu defaultMenu = new JMenu ("Default"); 206 defaultMenu.add(controller.getDefaultEditableCmd()); 207 defaultMenu.add(controller.getDefaultTypeCmd()); 208 defaultMenu.add(controller.getDefaultValueCmd()); 209 213 JMenu sheetMenu = new JMenu ("Worksheet"); 214 sheetMenu.add(controller.getSheetColumnsCmd()); 215 sheetMenu.add(controller.getSheetRowsCmd()); 216 sheetMenu.add(defaultMenu); 217 sheetMenu.add(controller.getImportClassCmd()); 218 219 JMenu cellMenu = new JMenu ("Cell"); 220 cellMenu.add(controller.getCellRenameCmd()); 221 227 JMenuBar menu = new JMenuBar (); 228 menu.add(fileMenu); 229 menu.add(sheetMenu); 230 menu.add(cellMenu); 231 232 _frame.setJMenuBar(menu); 234 _frame.pack(); 235 _frame.show(); 236 } 237 238 242 245 public Action getFileExitCmd() { 246 UnaryFunctor<ActionEvent ,?> fn = new Project2nd<ActionEvent ,Object >() 247 .generate2nd(new InvokeNoArgMethod(Application.class,"closeWorksheet").bind(this)); 248 249 return new GenericAction(fn, "Exit"); 250 } 251 252 256 public int loadFile(Spreadsheet sheet) { 257 if(getChooser().showOpenDialog(_frame) != JFileChooser.APPROVE_OPTION) 258 return Controller.CANCEL_OPTION; 259 260 File file = getChosenFile(); 261 if (file == null) 262 return Controller.CANCEL_OPTION; 263 264 try { 265 FileInputStream fis = new FileInputStream (file); 266 sheet.readSpreadsheet(fis); 267 _controller.setSheetSource(file.toURL()); 268 return Controller.YES_OPTION; 269 } 270 catch (IOException x) { 271 _controller.notify(x.getMessage(), _controller.getExceptionName(x)); 272 return Controller.CANCEL_OPTION; 273 } 274 } 275 276 277 public int saveFile(Spreadsheet sheet, boolean promptForName) { 278 URL hint = _controller.getSheetSource(); 279 if (promptForName || hint == null) 280 if (getChooser().showSaveDialog(_frame) != JFileChooser.APPROVE_OPTION) 281 return Controller.CANCEL_OPTION; 282 283 File file = getChosenFile(); 284 if (file != null) { 285 try { 286 FileOutputStream fos = new FileOutputStream (file); 287 _controller.setSheetSource(file.toURL()); 288 _sheet.writeSpreadsheet(fos); 289 fos.close(); 290 _controller.setSheetDirty(false); 291 return Controller.YES_OPTION; 292 } 293 catch (IOException x) { 294 Throwable t = _controller.getRootCause(x); 295 _controller.notify(x.getMessage(), _controller.getExceptionName(t)); 296 } 297 } 298 299 return Controller.CANCEL_OPTION; 300 } 301 302 305 306 public void closeWorksheet() { 307 int ans = Controller.YES_OPTION; 308 if (_controller.isSheetDirty()) { 309 ans = _controller.promptAndSave(); 310 } 311 312 if (ans != Controller.CANCEL_OPTION) { 313 _frame.dispose(); 314 } 315 } 316 317 318 private JFileChooser getChooser() { 319 if (_chooser != null) 320 return _chooser; 321 322 File pwd = new File ("."); 323 _chooser = new JFileChooser (pwd); 324 325 332 return _chooser; 333 } 334 335 336 private File getChosenFile() { 337 File dir = _chooser.getCurrentDirectory(); 338 if (dir == null) 339 return null; 340 341 return _chooser.getSelectedFile(); 342 } 343 344 345 349 protected Controller getController() { return _controller; } 350 351 355 public BinaryFunctor<String ,String ,String > buildPromptFunctor() { 356 InvokeMethod<JOptionPane ,String > showInput = 360 new InvokeMethod<JOptionPane ,String >( JOptionPane .class, "showInputDialog", 361 new Class []{Component .class,Object .class,Object .class}); 362 363 ApplyBinary<String ,String > threeArgs = 364 new ApplyBinary<String ,String >(new BinaryFunctor[] 365 { new ConstantBinary<String ,String ,Component >(_frame), 366 new Project1st<String ,String >(), 367 new Project2nd<String ,String >() 368 }); 369 370 return showInput.bind1st(null).compose(threeArgs); 371 } 372 373 374 public BinaryFunctor<String ,String ,?> buildErrorFunctor() { 375 InvokeMethod<JOptionPane ,?> showError = 378 new InvokeMethod<JOptionPane ,Object >(JOptionPane .class, "showMessageDialog", 379 new Class []{Component .class, Object .class, 380 String .class, Integer.TYPE}); 381 382 ApplyBinary<String ,String > fourArgs = 383 new ApplyBinary<String ,String >(new BinaryFunctor[] 384 { new ConstantBinary<String ,String ,Component >(_frame), 385 new Project1st<String ,String >(), 386 new Project2nd<String ,String >(), 387 new ConstantBinary<String ,String ,Integer >(JOptionPane.ERROR_MESSAGE) 388 }); 389 390 return showError.bind1st(null).compose(fourArgs); 391 } 392 393 394 public BinaryFunctor<String ,String ,Integer > buildConfirmFunctor() { 395 InvokeMethod showConfirm = 396 new InvokeMethod(JOptionPane .class, "showConfirmDialog", 397 new Class []{Component .class, Object .class, String .class, Integer.TYPE}); 398 399 ApplyBinary<String ,String > fourArgs = 400 new ApplyBinary<String ,String >(new BinaryFunctor[] 401 { new ConstantBinary<String ,String ,Component >(_frame), 402 new Project1st<String ,Boolean >(), 403 new Project2nd<String ,Boolean >(), 404 new ConstantBinary<String ,String ,Integer >(JOptionPane.YES_NO_CANCEL_OPTION) 405 }); 406 407 return showConfirm.bind1st(null).compose(fourArgs); 408 } 409 410 411 public BinaryFunctor<Spreadsheet,Boolean ,Integer > buildSaveFunctor() { 412 InvokeMethod<Application,Integer > getSave = 413 new InvokeMethod<Application,Integer >(Application.class,"saveFile", 414 new Class []{Spreadsheet.class,Boolean.TYPE}); 415 return getSave.bind1st(this).compose(new ArrayBinary<Spreadsheet,Boolean >()); 416 } 417 418 419 public UnaryFunctor<Spreadsheet,Integer > buildLoadFunctor() { 420 InvokeMethod<Application,Integer > getLoad = 421 new InvokeMethod<Application,Integer >(Application.class,"loadFile", 422 new Class []{Spreadsheet.class}); 423 return getLoad.bind1st(this).compose(new ArrayUnary<Spreadsheet>()); 424 } 425 426 430 static public void main(String [] args) { 431 printStartupHeader(); 432 433 try { 434 UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName()); 435 } 436 catch (Exception x) { 437 System.err.println("Error loading L&F:" +x); 439 } 440 441 443 new Application(); 444 } 445 446 447 static private void printStartupHeader() { 448 System.out.println(""); 449 System.out.println("/**"); 450 System.out.println(" * A Java Hacker's Worksheet"); 451 System.out.println(" * Copyright (c) 2004-2005 David A. Hall"); 452 System.out.println(" */"); 453 System.out.println(""); 454 } 455 } 456 | Popular Tags |