KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > jga > swing > spreadsheet > Application


1 // ============================================================================
2
// $Id: Application.java,v 1.8 2005/08/02 23:45:21 davidahall Exp $
3
// Copyright (c) 2004-2005 David A. Hall
4
// ============================================================================
5
// The contents of this file are subject to the Common Development and
6
// Distribution License (CDDL), Version 1.0 (the License); you may not use this
7
// file except in compliance with the License. You should have received a copy
8
// of the the License along with this file: if not, a copy of the License is
9
// available from Sun Microsystems, Inc.
10
//
11
// http://www.sun.com/cddl/cddl.html
12
//
13
// From time to time, the license steward (initially Sun Microsystems, Inc.) may
14
// publish revised and/or new versions of the License. You may not use,
15
// distribute, or otherwise make this file available under subsequent versions
16
// of the License.
17
//
18
// Alternatively, the contents of this file may be used under the terms of the
19
// GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which
20
// case the provisions of the LGPL are applicable instead of those above. If you
21
// wish to allow use of your version of this file only under the terms of the
22
// LGPL, and not to allow others to use your version of this file under the
23
// terms of the CDDL, indicate your decision by deleting the provisions above
24
// and replace them with the notice and other provisions required by the LGPL.
25
// If you do not delete the provisions above, a recipient may use your version
26
// of this file under the terms of either the CDDL or the LGPL.
27
//
28
// This library is distributed in the hope that it will be useful,
29
// but WITHOUT ANY WARRANTY; without even the implied warranty of
30
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
31
// ============================================================================
32

33 package net.sf.jga.swing.spreadsheet;
34
35 import java.awt.BorderLayout JavaDoc;
36 import java.awt.Component JavaDoc;
37 import java.awt.Container JavaDoc;
38 import java.awt.Dimension JavaDoc;
39 import java.awt.Insets JavaDoc;
40 import java.awt.Point JavaDoc;
41 import java.awt.event.ActionEvent JavaDoc;
42 import java.awt.event.MouseAdapter JavaDoc;
43 import java.awt.event.MouseEvent JavaDoc;
44 import java.awt.event.WindowAdapter JavaDoc;
45 import java.awt.event.WindowEvent JavaDoc;
46 import java.io.File JavaDoc;
47 import java.io.FileInputStream JavaDoc;
48 import java.io.FileOutputStream JavaDoc;
49 import java.io.IOException JavaDoc;
50 import java.io.InputStream JavaDoc;
51 import java.io.PrintStream JavaDoc;
52 import java.net.MalformedURLException JavaDoc;
53 import java.net.URL JavaDoc;
54 import java.text.MessageFormat JavaDoc;
55 import javax.swing.AbstractAction JavaDoc;
56 import javax.swing.Action JavaDoc;
57 import javax.swing.Icon JavaDoc;
58 import javax.swing.JFileChooser JavaDoc;
59 import javax.swing.JFrame JavaDoc;
60 import javax.swing.JLabel JavaDoc;
61 import javax.swing.JMenu JavaDoc;
62 import javax.swing.JMenuBar JavaDoc;
63 import javax.swing.JMenuItem JavaDoc;
64 import javax.swing.JOptionPane JavaDoc;
65 import javax.swing.JPopupMenu JavaDoc;
66 import javax.swing.JScrollPane JavaDoc;
67 import javax.swing.UIManager JavaDoc;
68 import javax.swing.event.AncestorEvent JavaDoc;
69 import javax.swing.event.AncestorListener JavaDoc;
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 /**
89  * An application wrapper for Spreadsheet, providing a main method to
90  * allow for standalone use.
91  * <p>
92  * Copyright &copy; 2004-2005 David A. Hall
93  * @author <a HREF="mailto:davidahall@users.sf.net">David A. Hall</a>
94  */

95
96 public class Application {
97
98     private JFrame JavaDoc _frame;
99
100     private Spreadsheet _sheet;
101        
102     private FunctorParser _parser;
103         
104     private Controller _controller;
105
106     private JFileChooser JavaDoc _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 JavaDoc>(Controller.class,"SheetDirty",
116                                                                     Boolean.TYPE)
117                                     .bind(_controller, Boolean.TRUE));
118         
119         // TODO: RunnabableFunctor?
120
createUI(_sheet, _controller);
121     }
122
123    
124     public Spreadsheet makeDefaultSheet() {
125         Spreadsheet sheet = new Spreadsheet(16,16);
126         sheet.setPreferredScrollableViewportSize(new Dimension JavaDoc(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 JavaDoc popupMenu = new JPopupMenu JavaDoc("Popup Menu");
138         popupMenu.add(new JMenuItem JavaDoc(controller.getCellRenameCmd()));
139         popupMenu.add(new JMenuItem JavaDoc(controller.getCellFormatCmd()));
140         popupMenu.add(new JMenuItem JavaDoc(controller.getCellTypeCmd()));
141
142         // Add a rightclick mouse listener with a 'standard' popup menu
143
sheet.addMouseListener(new MouseAdapter JavaDoc() {
144                 public void mousePressed(MouseEvent JavaDoc e) {
145                     // Right clicking should update selection
146
if (e.getButton() == e.BUTTON3) {
147                         Spreadsheet sht = (Spreadsheet) e.getComponent();
148                         Point JavaDoc 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 JavaDoc e) {
160                     if (e.isPopupTrigger()) {
161                         popupMenu.show(e.getComponent(), e.getX(), e.getY());
162                     }
163                 }
164             });
165         
166         // Setup a status bar, and wire it to the spreadsheet's status functor
167
JLabel JavaDoc statusLabel = new JLabel JavaDoc("cell(0,0)");
168         sheet.setStatusHandler(new SetProperty(JLabel JavaDoc.class, "Text", String JavaDoc.class)
169                                .bind1st(statusLabel));
170
171         // Setup the outer frame
172
_frame = new JFrame JavaDoc("Application");
173         _frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
174         _frame.addWindowListener(new WindowAdapter JavaDoc() {
175                 public void windowClosing(WindowEvent JavaDoc e) {
176                     closeWorksheet();
177 // System.out.println("Calling System.exit()");
178
System.exit(0);
179                 }
180             });
181         
182         // wire up the various functors that implement user interaction
183
controller.setLoadFunctor(buildLoadFunctor());
184         controller.setSaveFunctor(buildSaveFunctor());
185         controller.setErrorFunctor(buildErrorFunctor());
186         controller.setPromptFunctor(buildPromptFunctor());
187         controller.setConfirmFunctor(buildConfirmFunctor());
188               
189         // Setup the frame's content pane
190
Container JavaDoc rootPane = _frame.getContentPane();
191         rootPane.setLayout(new BorderLayout JavaDoc(5,5));
192
193         JScrollPane JavaDoc pane = new JScrollPane JavaDoc(sheet);
194         rootPane.add(pane, BorderLayout.CENTER);
195         rootPane.add(statusLabel, BorderLayout.SOUTH);
196
197         // Setup the frame's menu
198
JMenu JavaDoc fileMenu = new JMenu JavaDoc("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 JavaDoc defaultMenu = new JMenu JavaDoc("Default");
206         defaultMenu.add(controller.getDefaultEditableCmd());
207         defaultMenu.add(controller.getDefaultTypeCmd());
208         defaultMenu.add(controller.getDefaultValueCmd());
209 // defaultMenu.add(controller.getDefaultFormatCmd());
210
// defaultMenu.add(controller.getDefaultRendererCmd());
211
// defaultMenu.add(controller.getDefaultEditorCmd());
212

213         JMenu JavaDoc sheetMenu = new JMenu JavaDoc("Worksheet");
214         sheetMenu.add(controller.getSheetColumnsCmd());
215         sheetMenu.add(controller.getSheetRowsCmd());
216         sheetMenu.add(defaultMenu);
217         sheetMenu.add(controller.getImportClassCmd());
218         
219         JMenu JavaDoc cellMenu = new JMenu JavaDoc("Cell");
220         cellMenu.add(controller.getCellRenameCmd());
221 // cellMenu.add(controller.getCellTypeCmd());
222
// cellMenu.add(controller.getCellFormatCmd());
223
// cellMenu.add(controller.getCellValidatorCmd());
224
// cellMenu.add(controller.getCellRendererCmd());
225
// cellMenu.add(controller.getCellEditorCmd());
226

227         JMenuBar JavaDoc menu = new JMenuBar JavaDoc();
228         menu.add(fileMenu);
229         menu.add(sheetMenu);
230         menu.add(cellMenu);
231
232         // show the frame
233
_frame.setJMenuBar(menu);
234         _frame.pack();
235         _frame.show();
236     }
237    
238     // ----------------------
239
// Spreadsheet UI Methods
240
// ----------------------
241

242     /**
243      * Returns an Action that closes the spreadsheet.
244      */

245     public Action JavaDoc getFileExitCmd() {
246         UnaryFunctor<ActionEvent JavaDoc,?> fn = new Project2nd<ActionEvent JavaDoc,Object JavaDoc>()
247             .generate2nd(new InvokeNoArgMethod(Application.class,"closeWorksheet").bind(this));
248
249         return new GenericAction(fn, "Exit");
250     }
251
252     // ----------------------
253
// Spreadsheet IO Methods
254
// ----------------------
255

256     public int loadFile(Spreadsheet sheet) {
257         if(getChooser().showOpenDialog(_frame) != JFileChooser.APPROVE_OPTION)
258             return Controller.CANCEL_OPTION;
259         
260         File JavaDoc file = getChosenFile();
261         if (file == null)
262             return Controller.CANCEL_OPTION;
263
264         try {
265             FileInputStream JavaDoc fis = new FileInputStream JavaDoc(file);
266             sheet.readSpreadsheet(fis);
267             _controller.setSheetSource(file.toURL());
268             return Controller.YES_OPTION;
269         }
270         catch (IOException JavaDoc 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 JavaDoc hint = _controller.getSheetSource();
279         if (promptForName || hint == null)
280             if (getChooser().showSaveDialog(_frame) != JFileChooser.APPROVE_OPTION)
281                 return Controller.CANCEL_OPTION;
282         
283         File JavaDoc file = getChosenFile();
284         if (file != null) {
285             try {
286                 FileOutputStream JavaDoc fos = new FileOutputStream JavaDoc(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 JavaDoc x) {
294                 Throwable JavaDoc t = _controller.getRootCause(x);
295                 _controller.notify(x.getMessage(), _controller.getExceptionName(t));
296             }
297         }
298         
299         return Controller.CANCEL_OPTION;
300     }
301
302     // ============================================================
303
// ============================================================
304

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 JavaDoc getChooser() {
319         if (_chooser != null)
320             return _chooser;
321
322         File JavaDoc pwd = new File JavaDoc(".");
323         _chooser = new JFileChooser JavaDoc(pwd);
324
325 // // Note: source for ExampleFileFilter can be found in FileChooserDemo,
326
// // under the demo/jfc directory in the Java 2 SDK, Standard Edition.
327
// ExampleFileFilter filter = new ExampleFileFilter();
328
// filter.addExtension("jpg");
329
// filter.setDescription("JPG & GIF Images");
330
// chooser.setFileFilter(filter);
331

332         return _chooser;
333     }
334
335
336     private File JavaDoc getChosenFile() {
337         File JavaDoc dir = _chooser.getCurrentDirectory();
338         if (dir == null)
339             return null;
340      
341         return _chooser.getSelectedFile();
342     }
343
344
345     // =========================
346
// protected API
347
// =========================
348

349     protected Controller getController() { return _controller; }
350     
351     // =========================
352
// Implementation Details
353
// =========================
354

355     public BinaryFunctor<String JavaDoc,String JavaDoc,String JavaDoc> buildPromptFunctor() {
356         // This gets a little hairy. We have have to manually assemble the arguments
357
// to the JOptionPane.showInputDialog class since we want to bind to the component
358
// that is available here and leave the two arguments to the caller.
359
InvokeMethod<JOptionPane JavaDoc,String JavaDoc> showInput =
360             new InvokeMethod<JOptionPane JavaDoc,String JavaDoc>( JOptionPane JavaDoc.class, "showInputDialog",
361                                              new Class JavaDoc[]{Component JavaDoc.class,Object JavaDoc.class,Object JavaDoc.class});
362         
363         ApplyBinary<String JavaDoc,String JavaDoc> threeArgs =
364             new ApplyBinary<String JavaDoc,String JavaDoc>(new BinaryFunctor[]
365                { new ConstantBinary<String JavaDoc,String JavaDoc,Component JavaDoc>(_frame),
366                  new Project1st<String JavaDoc,String JavaDoc>(),
367                  new Project2nd<String JavaDoc,String JavaDoc>()
368                });
369             
370         return showInput.bind1st(null).compose(threeArgs);
371     }
372
373     
374     public BinaryFunctor<String JavaDoc,String JavaDoc,?> buildErrorFunctor() {
375         // This is fairly similar to the PromptFunctor. This one requires
376
// four parms, two of which are constants.
377
InvokeMethod<JOptionPane JavaDoc,?> showError =
378             new InvokeMethod<JOptionPane JavaDoc,Object JavaDoc>(JOptionPane JavaDoc.class, "showMessageDialog",
379                                                  new Class JavaDoc[]{Component JavaDoc.class, Object JavaDoc.class,
380                                                              String JavaDoc.class, Integer.TYPE});
381
382         ApplyBinary<String JavaDoc,String JavaDoc> fourArgs =
383             new ApplyBinary<String JavaDoc,String JavaDoc>(new BinaryFunctor[]
384                { new ConstantBinary<String JavaDoc,String JavaDoc,Component JavaDoc>(_frame),
385                  new Project1st<String JavaDoc,String JavaDoc>(),
386                  new Project2nd<String JavaDoc,String JavaDoc>(),
387                  new ConstantBinary<String JavaDoc,String JavaDoc,Integer JavaDoc>(JOptionPane.ERROR_MESSAGE)
388                });
389
390         return showError.bind1st(null).compose(fourArgs);
391     }
392
393     
394     public BinaryFunctor<String JavaDoc,String JavaDoc,Integer JavaDoc> buildConfirmFunctor() {
395         InvokeMethod showConfirm =
396             new InvokeMethod(JOptionPane JavaDoc.class, "showConfirmDialog",
397                              new Class JavaDoc[]{Component JavaDoc.class, Object JavaDoc.class, String JavaDoc.class, Integer.TYPE});
398
399         ApplyBinary<String JavaDoc,String JavaDoc> fourArgs =
400             new ApplyBinary<String JavaDoc,String JavaDoc>(new BinaryFunctor[]
401                { new ConstantBinary<String JavaDoc,String JavaDoc,Component JavaDoc>(_frame),
402                  new Project1st<String JavaDoc,Boolean JavaDoc>(),
403                  new Project2nd<String JavaDoc,Boolean JavaDoc>(),
404                  new ConstantBinary<String JavaDoc,String JavaDoc,Integer JavaDoc>(JOptionPane.YES_NO_CANCEL_OPTION)
405                });
406
407         return showConfirm.bind1st(null).compose(fourArgs);
408     }
409
410     
411     public BinaryFunctor<Spreadsheet,Boolean JavaDoc,Integer JavaDoc> buildSaveFunctor() {
412         InvokeMethod<Application,Integer JavaDoc> getSave =
413             new InvokeMethod<Application,Integer JavaDoc>(Application.class,"saveFile",
414                                            new Class JavaDoc[]{Spreadsheet.class,Boolean.TYPE});
415         return getSave.bind1st(this).compose(new ArrayBinary<Spreadsheet,Boolean JavaDoc>());
416     }
417
418
419     public UnaryFunctor<Spreadsheet,Integer JavaDoc> buildLoadFunctor() {
420         InvokeMethod<Application,Integer JavaDoc> getLoad =
421             new InvokeMethod<Application,Integer JavaDoc>(Application.class,"loadFile",
422                                                  new Class JavaDoc[]{Spreadsheet.class});
423         return getLoad.bind1st(this).compose(new ArrayUnary<Spreadsheet>());
424     }
425
426     // ------------------------
427
// Standalone entry point
428
// ------------------------
429

430     static public void main(String JavaDoc[] args) {
431         printStartupHeader();
432
433         try {
434             UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
435         }
436         catch (Exception JavaDoc x) {
437             // TODO: log this instead of simply dumping it
438
System.err.println("Error loading L&F:" +x);
439         }
440         
441         // TODO: do command line processing
442

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