1   package main;
2   
3   import intellego.Intellego;
4   import util.*;
5   import interfaces.*;
6   import real.*;
7   import NetBeansResources.*;
8   
9   import java.awt.*;
10  import java.lang.*;
11  import java.awt.event.*;
12  import javax.swing.*;
13  import java.io.*;
14  import java.net.*;
15  import javax.swing.*;
16  import java.beans.*;
17  
18  /** Provides a simple textual code editor
19   * @author Graham Ritchie
20   * @modifyer Simon Zienkiewicz
21   */
22  public class CodeEditor extends JInternalFrame
23  { 
24      static final int xOffset = 30, yOffset = 30;
25      static int openFrameCount = 0;
26      
27      /** the current file open in the Code Editor */    
28      private File currentFile;
29      
30      /** The name and directory of the current open file. */    
31      private String currentFileName;
32      
33      /** The contents of the file up to the last save point. */    
34      private String oldFileContents;
35      /** The current contents including changes made from the last save point of the file. */    
36      private String newFileContents;
37      
38      /** The current file's directory */    
39      private File currentDir;
40      
41      /** The editor pane within the current frame. */    
42      private JEditorPane codePane;
43      
44      /** A timer used to display saving messages to the user. */    
45      private Timer saveTimer;
46      /** The name of the current open file */    
47      private String fileString;
48  
49      /** Creates a new instance of CodeEditor */    
50      public CodeEditor() 
51      {
52          super("Code Editor: (no file)",true,true,true,true);
53          this.setFrameIcon(new ImageIcon("images/code.gif"));
54      ++openFrameCount;
55          
56          
57          // create the code editor GUI and put it in the window...
58          
59              // add the menu bar
60              setJMenuBar(createMenuBar());
61          
62              // create and add the editor pane
63              codePane=new JEditorPane();
64              codePane.setCaretColor(Color.white);
65              codePane.setVisible(true);
66              codePane.setEditable(true);
67              codePane.setBackground(Color.darkGray);
68              codePane.setForeground(Color.white);
69              
70              
71              this.setDefaultCloseOperation(this.DO_NOTHING_ON_CLOSE);
72              
73              
74              //setup save timer
75              saveTimer = new Timer(3000,new TListener());
76          
77              // put it in a scroll pane
78              JScrollPane codeScrollPane = new JScrollPane(codePane);
79              codeScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
80              codeScrollPane.setPreferredSize(new Dimension(400,400));
81              codeScrollPane.setMinimumSize(new Dimension(20,20));
82              (codeScrollPane.getVerticalScrollBar()).setBackground(Color.DARK_GRAY);
83              (codeScrollPane.getHorizontalScrollBar()).setBackground(Color.DARK_GRAY);
84              codeScrollPane.setBackground(Color.DARK_GRAY);
85          
86              // and add this to a main content pane
87              JPanel contentPane = new JPanel();
88              BoxLayout box = new BoxLayout(contentPane, BoxLayout.X_AXIS);
89              contentPane.setLayout(box);
90              contentPane.add(codeScrollPane);
91              setContentPane(contentPane);
92          
93              // set the window size
94              setSize(400,600);
95  
96              // and set the window's location.
97              setLocation(xOffset*openFrameCount, yOffset*openFrameCount);
98      }
99      
100     //Modified by: Simon Zienkiewicz
101     /** Creates a menubar for the Code Editor
102      * @return the created menu bar
103      */    
104     private JMenuBar createMenuBar()
105     {
106     JMenuBar menuBar = new JMenuBar();
107         
108         // create the file menu
109         JMenu fileMenu = new JMenu("File");
110         fileMenu.setBackground(Color.darkGray);
111         fileMenu.setForeground(Color.lightGray);
112         fileMenu.setMnemonic(KeyEvent.VK_F);
113         
114         
115         // create the file menu items
116         ImageIcon newI = new ImageIcon("images/new.gif");
117         Image image1 = (newI.getImage().getScaledInstance(18,18,0));
118         ImageIcon newIc = new ImageIcon(image1);
119         
120         JMenuItem newFile = new JMenuItem(" New",newIc);
121         newFile.setBackground(Color.darkGray);
122         newFile.setForeground(Color.lightGray);
123         newFile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,ActionEvent.CTRL_MASK));
124         
125         ImageIcon openI = new ImageIcon("images/open.gif");
126         Image image2 = (openI.getImage().getScaledInstance(18,18,0));
127         ImageIcon openIc = new ImageIcon(image2);
128         
129         JMenuItem open = new JMenuItem(" Open",openIc);
130         open.setBackground(Color.darkGray);
131         open.setForeground(Color.lightGray);
132         open.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,ActionEvent.CTRL_MASK));
133         
134         ImageIcon saveI = new ImageIcon("images/save.gif");
135         Image image3 = (saveI.getImage().getScaledInstance(18,18,0));
136         ImageIcon saveIc = new ImageIcon(image3);
137         
138         JMenuItem save=new JMenuItem(" Save",saveIc);
139         save.setBackground(Color.darkGray);
140         save.setForeground(Color.lightGray);
141         save.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,ActionEvent.CTRL_MASK));
142         
143         JMenuItem saveAs=new JMenuItem("        Save As");
144         saveAs.setBackground(Color.darkGray);
145         saveAs.setForeground(Color.lightGray);
146                 
147         JMenuItem close = new JMenuItem("        Exit");
148         close.setBackground(Color.darkGray);
149         close.setForeground(Color.lightGray);
150         close.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_E,ActionEvent.CTRL_MASK));
151         
152         // create the action listeners
153         newFile.addActionListener(new ActionListener() 
154         {
155             public void actionPerformed(ActionEvent e) 
156             {
157                 createNewFile();
158             }
159         });
160         
161         open.addActionListener(new ActionListener() 
162         {
163             public void actionPerformed(ActionEvent e) 
164             {
165                 openFile(); 
166             }
167         });
168         
169         save.addActionListener(new ActionListener() 
170         {
171             public void actionPerformed(ActionEvent e) 
172             {
173                 saveFile();
174             }
175         });
176         
177         saveAs.addActionListener(new ActionListener() 
178         {
179             public void actionPerformed(ActionEvent e) 
180             {
181                 saveFileAs();
182             }
183         });
184         
185         close.addActionListener(new ActionListener() 
186         {
187             public void actionPerformed(ActionEvent e) 
188             {
189                 closeFile();
190             }
191         });
192         
193         // add the menu items to the menu
194         fileMenu.addSeparator();
195         fileMenu.add(newFile);
196         fileMenu.addSeparator();
197         fileMenu.add(open);
198         fileMenu.addSeparator();
199         fileMenu.add(save);
200         fileMenu.add(saveAs);
201         fileMenu.addSeparator();
202         fileMenu.add(close);
203             
204         // create the lejos menu
205         JMenu lejosMenu = new JMenu("leJOS");
206         lejosMenu.setMnemonic(KeyEvent.VK_J);
207         lejosMenu.setBackground(Color.darkGray);
208         lejosMenu.setForeground(Color.lightGray);
209     
210         // create the lejos menu items
211         ImageIcon rcxI = new ImageIcon("images/RCX.jpg");
212         Image image7 = (rcxI.getImage().getScaledInstance(20,26,0));
213         ImageIcon rcxIc = new ImageIcon(image7);
214         
215         JMenuItem compile = new JMenuItem("   Compile",rcxIc);
216         compile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5,0));
217         
218         ImageIcon linkI = new ImageIcon("images/irtower.gif");
219         Image image5 = (linkI.getImage().getScaledInstance(26,26,0));
220         ImageIcon linkIc = new ImageIcon(image5);
221         
222         JMenuItem download = new JMenuItem("Link & Upload",linkIc);
223         download.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F6,0));
224         JMenuItem firmwaredl = new JMenuItem("Upload Lejos Firmware");
225         firmwaredl.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F7,0));
226         //set colors
227         compile.setBackground(Color.darkGray);
228         compile.setForeground(Color.lightGray);
229         download.setBackground(Color.darkGray);
230         download.setForeground(Color.lightGray);
231         firmwaredl.setBackground(Color.darkGray);
232         firmwaredl.setForeground(Color.lightGray);
233                 
234         // create the action listeners
235         
236         compile.addActionListener(new ActionListener() 
237         {
238             public void actionPerformed(ActionEvent e) 
239             {
240                 lejosCompileFile();
241             }
242         });
243         
244         download.addActionListener(new ActionListener() 
245         {
246             public void actionPerformed(ActionEvent e) 
247             {
248                 downloadFile();
249             }
250         });
251                 
252         firmwaredl.addActionListener(new ActionListener() 
253         {
254             public void actionPerformed(ActionEvent e) 
255             {
256                 downloadFirmware();
257             }
258         });
259         
260         // add the menu items to the menu
261         lejosMenu.add(compile);
262         lejosMenu.addSeparator();
263         lejosMenu.add(download);
264         lejosMenu.addSeparator();
265         lejosMenu.add(firmwaredl);
266       
267    
268         // create the sim menu
269         JMenu simMenu = new JMenu("Simulator");
270         simMenu.setMnemonic(KeyEvent.VK_I);
271         simMenu.setBackground(Color.darkGray);
272         simMenu.setForeground(Color.lightGray);
273         
274         // create the lejos menu items
275         
276         ImageIcon manI = new ImageIcon("images/hips.gif");
277         Image image6 = (manI.getImage().getScaledInstance(26,26,0));
278         ImageIcon manIc = new ImageIcon(image6);
279         
280         JMenuItem javaCompile = new JMenuItem(" Compile",manIc);
281         javaCompile.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F9,0));
282         JMenuItem openInSim = new JMenuItem("Open controller in simulator");
283         openInSim.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F8,0));
284     
285         //set colors
286         javaCompile.setBackground(Color.darkGray);
287         javaCompile.setForeground(Color.lightGray);
288         openInSim.setBackground(Color.darkGray);
289         openInSim.setForeground(Color.lightGray);
290         
291         // create the action listeners
292     openInSim.addActionListener(new ActionListener() 
293         {
294             public void actionPerformed(ActionEvent e) 
295             {
296                 openFileInSim();
297             }
298         });
299         
300         javaCompile.addActionListener(new ActionListener() 
301         {
302             public void actionPerformed(ActionEvent e) 
303             {
304                 javaCompileFile();
305             }
306         });
307         
308         // add the menu items to the menu
309         simMenu.add(javaCompile);
310         simMenu.addSeparator();
311         simMenu.add(openInSim);
312         
313         // add the menus to the menu bar
314 
315         menuBar.setLayout(new AbsoluteLayout());
316         menuBar.setBackground(Color.DARK_GRAY);
317         menuBar.add(fileMenu,new AbsoluteConstraints(3,0));
318         menuBar.add(lejosMenu,new AbsoluteConstraints(38,0));
319         menuBar.add(simMenu,new AbsoluteConstraints(89,0));
320                 
321         //strictly used to extend the menu bar to proper height
322         JButton sizeButton = new JButton("hi");
323         sizeButton.setSize(new Dimension(20,10));
324         sizeButton.setMargin(new Insets(0,0,0,0));
325         sizeButton.setVisible(false);
326         menuBar.add(sizeButton,new AbsoluteConstraints(263,0));
327     
328         // return the final menu bar
329         return menuBar;
330     }
331     
332     /** Creates a new editor pane which hosts a new file. */
333     public void createNewFile()
334     {
335     MainInterface.createCodeEditorFrame();
336     }
337    
338     /** Opens a file which currently exists */
339     private void openFile()
340     {
341         JFileChooser chooser=new JFileChooser(new File(System.getProperties().getProperty("user.dir"),"controllers"));
342     
343          for(int a=0;a<chooser.getComponentCount();a++){
344             Container a1 =(Container)chooser.getComponent(a);
345                 if(a1 instanceof JTextField ||a1 instanceof JComboBox || a1 instanceof JButton ){
346                     a1.setBackground(Color.darkGray);
347                     a1.setForeground(Color.lightGray);
348                  }
349             for(int b=0;b<((Container)chooser.getComponent(a)).getComponentCount();b++){
350                 Container b1 =(Container)((Container)chooser.getComponent(a)).getComponent(b);
351                 if(b1 instanceof JTextField ||b1 instanceof JComboBox || b1 instanceof JButton ){
352                     b1.setBackground(Color.darkGray);
353                     b1.setForeground(Color.lightGray);
354                 }
355                  for(int c=0;c<((Container)((Container)chooser.getComponent(a)).getComponent(b)).getComponentCount();c++){
356                     Container c1 =(Container)((Container)((Container)chooser.getComponent(a)).getComponent(b)).getComponent(c);
357                     if(c1 instanceof JTextField ||c1 instanceof JComboBox || c1 instanceof JButton ){
358                         c1.setBackground(Color.darkGray);
359                         c1.setForeground(Color.lightGray);
360                      }
361                 }
362             }
363         }
364     
365     // add a filename filter for java files
366     String[] extensions={".java"};
367     chooser.addChoosableFileFilter(new FileChooserFilter(extensions,"Java Controller Files"));
368         chooser.showOpenDialog(this);
369         
370         File file=chooser.getSelectedFile();
371         
372         if(file == null){
373             //do nothing
374         }
375         else
376         {
377             //try to open the file
378                 
379             try 
380             {
381                 URL filePath=chooser.getSelectedFile().toURL();
382 
383                 // set this file as the page in the codePane
384                 codePane.setPage(filePath);
385 
386                 // set file as current file
387                 currentFile=file;
388 
389                 // set current directory
390                 currentDir=chooser.getCurrentDirectory();
391                 codePane.updateUI();
392                 codePane.setVisible(true);
393 
394                 // and change the title
395                 fileString = file.toString();
396                 super.setTitle("Code Editor:  "+fileString);
397 
398                 this.oldFileContents = codePane.getText();
399             }
400             catch (Exception e)
401             {
402                 MainInterface.displayMessage("Cannot open file");
403                 Intellego.addToLog("CodeEditor.openFile(): Failed to open file: "+e);
404             }
405         }
406         
407     }
408     
409     /**
410     * Saves the current file
411     */
412     public void saveFile()
413     {
414         if (currentFile!=null)
415     {
416             // save file
417             try
418             {
419                 FileWriter fw=new FileWriter(currentFile);
420         fw.write(codePane.getText());
421         fw.close();
422                 super.setTitle("Code Editor:  ....SAVING.... ");
423                 this.saveTimer.start();
424                 
425                 this.oldFileContents = this.codePane.getText();
426             }
427             
428             catch (Exception e)
429             {
430                 MainInterface.displayMessage("Cannot save file");
431         Intellego.addToLog("CodeEditor.saveFile(): Save to file failed: "+e);
432             }
433         }
434     else
435     {
436             // no current file, so it must be new, so save as
437             saveFileAs();
438         }
439     }
440     
441     /** Saves the file under a specified name. */    
442     private void saveFileAs()
443     {
444         JFileChooser chooser=new JFileChooser(new File(System.getProperties().getProperty("user.dir"),"controllers"));
445         
446          //set color
447         for(int a=0;a<chooser.getComponentCount();a++){
448             Container a1 =(Container)chooser.getComponent(a);
449                 if(a1 instanceof JTextField ||a1 instanceof JComboBox || a1 instanceof JButton ){
450                     a1.setBackground(Color.darkGray);
451                     a1.setForeground(Color.lightGray);
452                  }
453             for(int b=0;b<((Container)chooser.getComponent(a)).getComponentCount();b++){
454                 Container b1 =(Container)((Container)chooser.getComponent(a)).getComponent(b);
455                 if(b1 instanceof JTextField ||b1 instanceof JComboBox || b1 instanceof JButton ){
456                     b1.setBackground(Color.darkGray);
457                     b1.setForeground(Color.lightGray);
458                 }
459                  for(int c=0;c<((Container)((Container)chooser.getComponent(a)).getComponent(b)).getComponentCount();c++){
460                     Container c1 =(Container)((Container)((Container)chooser.getComponent(a)).getComponent(b)).getComponent(c);
461                     if(c1 instanceof JTextField ||c1 instanceof JComboBox || c1 instanceof JButton ){
462                         c1.setBackground(Color.darkGray);
463                         c1.setForeground(Color.lightGray);
464                      }
465                 }
466             }
467         }
468         
469         int returnValue=chooser.showSaveDialog(this);
470         
471     if(returnValue==JFileChooser.APPROVE_OPTION)
472     {
473             // save file as
474             try
475             {
476                 FileWriter fw=new FileWriter(chooser.getSelectedFile().getPath()+".java");
477         fw.write(codePane.getText());
478         fw.close();
479                 super.setTitle("Code Editor:  "+chooser.getSelectedFile().getPath()+".java");
480                 // set file as current file
481                 currentFile=new File(chooser.getSelectedFile().getPath()+".java");
482             
483                 // set current directory
484                 currentDir=chooser.getCurrentDirectory();
485             }
486             catch (Exception e)
487             {
488                 MainInterface.displayMessage("Cannot save file");
489         Intellego.addToLog("CodeEditor.saveFile(): Save to file failed: "+e);
490             }
491     }
492     
493         else
494     {   
495             // cancel, do nothing atm
496         }
497     }
498     
499     /**
500     * Closes the current file
501     */
502     private void closeFile()
503     {
504         if(oldFileContents != null && this.codePane.getText() != null)
505         {
506             if(!this.oldFileContents.equals(this.codePane.getText())){
507                
508                 VerificationPopUp check = new VerificationPopUp();
509                 check.createPopUpWindow("Save Updated Changes",370,95,"Do you want to Save your last changes?",1,this);
510             }
511 
512             else{
513                 // save the file
514                 saveFile();
515 
516                 // and get rid of it
517                 currentFile=null;
518                 codePane.setVisible(false);
519 
520                 // and change the title
521                 super.setTitle("Code Editor:  (no file)");
522                 this.dispose();
523             }
524         }
525         
526         else if(oldFileContents == null && this.codePane.getText().trim().length() != 0)
527         {
528             VerificationPopUp check = new VerificationPopUp();
529             check.createPopUpWindow("Save Updated Changes",370,95,"Do you want to Save your last changes?",1,this);
530         }
531         
532         else
533         {
534             // and get rid of it
535             currentFile=null;
536             codePane.setVisible(false);
537 
538             // and change the title
539             super.setTitle("Code Editor:  (no file)");
540             this.dispose();
541         }
542     }
543     
544     /**
545     * Compiles the current file with lejosc
546     */
547     private void lejosCompileFile()
548     {   
549         super.setTitle("Code Editor:  ....LEJOS COMPILE.... ");
550         this.saveTimer.start();
551                 
552         if(currentFile!=null)externalCommand("lejosc "+currentFile.toString());
553     else MainInterface.displayMessage("Cannot compile an empty file");
554     }
555     
556     /**
557     * Compiles the current file with javac
558     */
559     private void javaCompileFile()
560     {   
561         //save the file before compiling
562         //saveFile();
563         
564         super.setTitle("Code Editor:  ....JAVA COMPILE.... ");
565         this.saveTimer.start();
566         
567         if(currentFile!=null) externalCommand("javac "+currentFile.toString());
568     else MainInterface.displayMessage("Cannot compile an empty file");
569     }
570     
571     /**
572     * Downloads the firmware onto the RCX
573     * Modified by: Simon Zienkiewicz
574     */
575     private void downloadFirmware(){
576        VerificationPopUp check = new VerificationPopUp();
577        check.createPopUpWindow("LEJOS Firmware Check:",370,95,"Are you sure that you want to upload the LEJOS firmware?",0,this);
578        check.dispose();
579     }
580     
581     /**
582     * Links and downloads the current file
583     */
584     private void downloadFile()
585     {
586         if(currentFile!=null)
587     {
588             ControllerDL c=new ControllerDL(currentFile,currentDir);
589         }
590     else
591     {
592             MainInterface.displayMessage("You need to open a controller first");
593     }
594     }
595     
596     /** Opens the current Controller file in a Simulator Window. */    
597     public void openFileInSim()
598     {
599         if(currentFile!=null)
600     {
601             String fileName = (currentFile.getAbsolutePath()).substring(0,(currentFile.getAbsolutePath()).length() - 5) +".class";
602             MainInterface.createSimulatorFrame(new File(fileName));
603     }
604     else
605     {
606             MainInterface.displayMessage("You need to open a controller first");
607     }
608     }
609 
610     /** Processes all external calls, i.e calls to lejos & lejosc
611      * @param cmd the command wanting execution
612      */
613     private void externalCommand(String cmd)
614     {
615         int len;
616         byte buffer[] = new byte[1000];
617     Intellego.addToLog("CodeEditor.externalCommand(): Processing External Command: "+cmd);
618     try
619     {
620             Process external=Runtime.getRuntime().exec(cmd);
621             
622             InputStream ees = external.getErrorStream();
623             try 
624             {
625                 ExternalMessager output=MainInterface.createExternalMessagerFrame(0);
626                 
627                 while ((len = ees.read(buffer)) != -1)
628         {
629                     String eo = new String (buffer, 0, len);
630                     output.append(eo);            
631                 }
632                 external.waitFor();
633                 
634                 if(output.successfullCompile()){
635                 
636                     output.append("\n"+"\n"+"   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
637                     output.append("\n"+"\n"+"     |  COMPILING SUCCESSFUL: NO ERRORS FOUND  |");
638                     output.append("\n"+"\n"+"   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
639                 }
640                 
641                 else{
642                     
643                     output.append("\n"+"\n"+"   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
644                     output.append("\n"+"\n"+"     |  COMPILING FAILED: ERRORS FOUND   |");
645                     output.append("\n"+"\n"+"   * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *");
646                 
647                 }
648              }
649              catch (Exception e) 
650              {
651                  Intellego.addToLog("CodeEditor.externalCommand(): error: "+e.getMessage());
652              }
653     }
654     catch (Exception e) 
655     {
656            Intellego.addToLog("CodeEditor.externalCommand(): error: "+e.getMessage());
657         }
658     }
659     
660     /** Sets the title of the frame to the file name. */    
661     public void setTitletoFileName(){
662         super.setTitle("Code Editor: "+fileString);
663     }
664        
665     /** Used to display saving message when the user saves his/her file. */    
666     private class TListener implements ActionListener {
667         /** Invoked when an action occurs.
668          * @param e the event that occured
669          */
670         public void actionPerformed(ActionEvent e) {
671             if(e.getSource() == saveTimer){
672                 setTitletoFileName();
673                 saveTimer.stop();
674             }
675         }
676         
677     }
678 }