1   package main;
2   
3   import intellego.Intellego;
4   import util.*;
5   import interfaces.*;
6   import real.*;
7   import simworldobjects.*;
8   import main.*;
9   import NetBeansResources.*;
10  import javax.swing.plaf.basic.BasicBorders.*;
11  
12  import java.awt.*;
13  import java.lang.*;
14  import java.awt.event.*;
15  import java.awt.event.ItemListener.*;
16  import javax.swing.*;
17  import javax.swing.event.*;
18  import javax.swing.filechooser.*;
19  import java.io.*;
20  import javax.imageio.*;
21  import java.awt.image.*;
22  import java.util.*;
23  
24  /** Provides a dialog box for the user to define colour value which the robot can
25   * read within the simulation environment.
26   * @author Simon Zienkiewicz
27   */ 
28  public class LightSensorPropertiesDialog extends JFrame implements ActionListener, ItemListener, ChangeListener, WindowFocusListener
29  {
30      private JLabel checkL, colorL, rangeL, errorL;
31      private JLabel[] tA = new JLabel[11];
32      private JLabel[] pA = new JLabel[11];
33      private JLabel[] mA = new JLabel[11];
34      private JButton OK, cancel, save, open, clear;
35      private JTextArea[] previewA = new JTextArea[11];
36      private JTextField[] nameA = new JTextField[11];
37      private JCheckBox c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11;
38      private JCheckBox[] checkA = new JCheckBox[11];
39      private JSpinner[] lrSpinner = new JSpinner[11];
40      private JSpinner[] urSpinner = new JSpinner[11];
41      private JSpinner[] leSpinner = new JSpinner[11];
42      private JSpinner[] ueSpinner = new JSpinner[11];
43      private Container[][] containerArray = new Container[11][7];
44      private int row=11; 
45      private int column=7;
46      private Color desiredColor;
47      private Color[] colorA={Color.black,Color.blue,Color.cyan,Color.gray,Color.green,Color.magenta,Color.orange,Color.pink,Color.red,Color.white,Color.yellow};
48      private String[] availableColors = {"Black","Blue","Cyan","Gray","Green","Magenta","Orange","Pink","Red","White","Yellow"};
49      private int index;
50      private final int b=30;
51      private static boolean[] desiredColors= new boolean[11];;
52      private static int[] lowerRange= new int[11];
53      private static int[] upperRange= new int[11];
54      private static int[] lowerError= new int[11];
55      private static int[] upperError= new int[11];
56      private LightSensorColorLibrary lib=null;
57      
58     
59  
60      /** Creates and displays a LightSensorProperties popup. */    
61      public void createLightSensorPropertiesPopUp()
62      {
63          
64          //sets the properties of the popup window
65          setTitle("LightSensor Properties:");
66          setSize(390+b,550);
67          setLocation(400,180);
68          
69          this.addWindowFocusListener(this);
70          
71          this.setDefaultLookAndFeelDecorated(false);
72          this.setUndecorated(true);
73          this.getRootPane().setWindowDecorationStyle(JRootPane.FRAME);
74          
75          setVisible(true);
76          this.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
77          this.setResizable(false);
78          
79          //load icon image from a file
80          try{ 
81                  BufferedImage simIcon= ImageIO.read(new File("images\\lego.png"));
82                  this.setIconImage(simIcon);
83          }
84          catch(Exception e){}
85          
86          Container mainPanel=getContentPane();
87          mainPanel.setLayout(new BorderLayout(1,1));
88  
89          Container Panell=new Container();
90          Panell.setLayout(new AbsoluteLayout());
91  
92          Container Panel5=new Container();
93          Panel5.setLayout(new FlowLayout());
94          
95          this.checkL = new JLabel("Check:");
96          this.colorL = new JLabel("Color:");
97          this.rangeL = new JLabel("Range:");
98          this.errorL = new JLabel("Error:");
99          //set color
100         checkL.setForeground(Color.lightGray);
101         colorL.setForeground(Color.lightGray);
102         rangeL.setForeground(Color.lightGray);
103         errorL.setForeground(Color.lightGray);
104         
105         for(int i=0;i<tA.length;i++){tA[i] = new JLabel("~"); tA[i].setForeground(Color.yellow); tA[i].setVisible(false);}
106         
107         for(int i=0;i<mA.length;i++){mA[i] = new JLabel("-"); mA[i].setForeground(Color.yellow);mA[i].setVisible(false);}
108         
109         for(int i=0;i<pA.length;i++){pA[i] = new JLabel("+"); pA[i].setForeground(Color.yellow);pA[i].setVisible(false);}
110         
111         for(int i=0;i<previewA.length;i++)
112         {
113             previewA[i] = new JTextArea(1,2); 
114             previewA[i].setBackground(this.colorA[i]);
115             previewA[i].setFocusable(false);
116         }
117         
118         for(int i=0;i< nameA.length;i++){
119             nameA[i] = new JTextField(5);
120             nameA[i].setText(this.availableColors[i]);
121             nameA[i].setForeground(Color.darkGray);
122             nameA[i].setBackground(Color.yellow);
123             nameA[i].setEditable(false);
124         }
125          
126         for(int i=0;i< nameA.length;i++){
127             (checkA[i] = new JCheckBox((i+1)+").")).addItemListener(this);
128             checkA[i].setForeground(Color.darkGray);
129             checkA[i].setBackground(Color.yellow);
130         }
131        
132         for(int i=0;i< lrSpinner.length;i++){
133             (lrSpinner[i] = new JSpinner(new SpinnerNumberModel(20,0,60,1))).addChangeListener(this);;
134             lrSpinner[i].setForeground(this.colorA[i]);
135             lrSpinner[i].setBackground(this.colorA[i]);
136             lrSpinner[i].setVisible(false);
137          }
138         
139         for(int i=0;i< urSpinner.length;i++){
140             (urSpinner[i] = new JSpinner(new SpinnerNumberModel(40,(Integer.parseInt(lrSpinner[i].getValue().toString())+1),60,1))).addChangeListener(this);
141             urSpinner[i].setForeground(this.colorA[i]);
142             urSpinner[i].setBackground(this.colorA[i]);
143             urSpinner[i].setVisible(false);
144         }
145        
146         for(int i=0;i< leSpinner.length;i++){
147             leSpinner[i] = new JSpinner(new SpinnerNumberModel(0,0,5,1));
148             leSpinner[i].setForeground(this.colorA[i]);
149             leSpinner[i].setBackground(this.colorA[i]);
150             leSpinner[i].setVisible(false);
151         }
152          for(int i=0;i< ueSpinner.length;i++){
153             ueSpinner[i] = new JSpinner(new SpinnerNumberModel(0,0,5,1));
154             ueSpinner[i].setForeground(this.colorA[i]);
155             ueSpinner[i].setBackground(this.colorA[i]);
156             ueSpinner[i].setVisible(false);
157         }
158         
159         //array containing all the hiddable components
160         for(int r=0;r<row;r++){
161             for(int c=0;c<column;c++){
162                 switch(c){
163                     case 0:     containerArray[r][c]=lrSpinner[r];
164                                 break;
165                     case 1:     containerArray[r][c]=tA[r];
166                                 break;
167                     case 2:     containerArray[r][c]=urSpinner[r];
168                                 break;
169                     case 3:     containerArray[r][c]=pA[r];
170                                 break;
171                     case 4:     containerArray[r][c]=leSpinner[r];
172                                 break;
173                     case 5:     containerArray[r][c]=mA[r];
174                                 break;
175                     case 6:     containerArray[r][c]=ueSpinner[r];
176                                 break;
177                 }
178                
179             }
180         }
181          
182         (OK=new JButton("OK")).addActionListener(this);
183         (open=new JButton("Open")).addActionListener(this);
184         (save=new JButton("Save")).addActionListener(this);
185         (clear=new JButton("Clear")).addActionListener(this);
186         (cancel=new JButton("Cancel")).addActionListener(this);
187         
188         //set color
189         OK.setBackground(Color.lightGray);
190         OK.setForeground(Color.darkGray);
191         open.setBackground(Color.lightGray);
192         open.setForeground(Color.darkGray);
193         save.setBackground(Color.lightGray);
194         save.setForeground(Color.darkGray);
195         clear.setBackground(Color.lightGray);
196         clear.setForeground(Color.darkGray);
197         cancel.setBackground(Color.lightGray);
198         cancel.setForeground(Color.darkGray);
199         cancel.setEnabled(false);
200 
201         //labels placed in panel
202         Panell.add(this.checkL,new AbsoluteConstraints(20,10));
203         Panell.add(this.colorL,new AbsoluteConstraints(95,10));
204         Panell.add(this.rangeL,new AbsoluteConstraints(187+b,10));
205         Panell.add(this.errorL,new AbsoluteConstraints(310+b,10));
206 
207         for(int a=0;a<checkA.length;a++){
208             int num = (int)(40*a);
209             Panell.add(this.checkA[a],new AbsoluteConstraints(20,40+num));
210             
211             Panell.add(this.previewA[a],new AbsoluteConstraints(80,44+num));
212             
213             Panell.add(this.nameA[a],new AbsoluteConstraints(80+b,42+num));
214             Panell.add(this.lrSpinner[a],new AbsoluteConstraints(155+b,40+num));
215             Panell.add(this.tA[a],new AbsoluteConstraints(202+b,43+num));
216             Panell.add(this.urSpinner[a],new AbsoluteConstraints(213+b,40+num));
217 
218             Panell.add(this.mA[a],new AbsoluteConstraints(278+b,41+num));
219             Panell.add(this.leSpinner[a],new AbsoluteConstraints(286+b,40+num));
220             Panell.add(this.pA[a],new AbsoluteConstraints(328+b,43+num));
221             Panell.add(this.ueSpinner[a],new AbsoluteConstraints(336+b,40+num));
222         }
223         
224         Panel5.add("South",OK);
225         Panel5.add("South",open);
226         Panel5.add("South",save);
227         Panel5.add("South",clear);
228         Panel5.add("South",cancel);
229 
230         mainPanel.setBackground(Color.darkGray);
231         mainPanel.add("North",Panell);
232         mainPanel.add("South",Panel5);
233         
234         if(lib != null) setupProperties();
235         
236         //load default file
237         try{this.loadDefaultLightProperties();}
238         catch(Exception e){};
239         
240         
241         this.show();
242     }
243     
244     /** Loads the defaul light values for any simulation world. */    
245     private void loadDefaultLightProperties(){
246     
247         File oneF = new File(System.getProperties().getProperty("user.dir"),"LightSenesorReadings");
248         File twoF = new File(oneF.getAbsolutePath()+"/DEFAULT.light");
249         
250         char[] stringA = new char[220];
251         // open selected file
252         try
253         {
254             FileReader fw=new FileReader(twoF);
255             fw.read(stringA); 
256             fw.close();
257         }
258         
259         catch(Exception e)
260         {
261             MainInterface.displayMessage("Cannot open LightProperties file");
262             Intellego.addToLog("LightSensorPropertiesDialog.openFromTextfile(): Opening of file failed: "+e);
263         }
264         
265         String fileData = new String(stringA);
266         fileData = fileData.trim();
267         
268         StringTokenizer breakup = new StringTokenizer(fileData," ");
269         
270         while(breakup.hasMoreTokens()){
271             
272             String data = breakup.nextToken();
273             
274             if(data.equals("true")){
275                 int index = Integer.parseInt(breakup.nextToken());
276                 this.checkA[index].setSelected(true);
277                 ((SpinnerNumberModel)(lrSpinner[index].getModel())).setValue(new Integer(breakup.nextToken()));
278                 ((SpinnerNumberModel)(urSpinner[index].getModel())).setValue(new Integer(breakup.nextToken()));
279                 ((SpinnerNumberModel)(leSpinner[index].getModel())).setValue(new Integer(breakup.nextToken()));
280                 ((SpinnerNumberModel)(ueSpinner[index].getModel())).setValue(new Integer(breakup.nextToken()));
281            }
282            
283             else if(data.equals("false")){
284                 int index = Integer.parseInt(breakup.nextToken());
285                 this.checkA[index].setSelected(false);
286            }
287        }
288      }
289      
290     /** Makes sure that the minimum colour value does not exceed the maximum colour
291      * value when the values are selected by the user.
292      * @param e event
293      */    
294     public void stateChanged(ChangeEvent e){
295     
296          Object source = e.getSource();
297       
298          for(int i=0;i< urSpinner.length;i++){
299             if(source == urSpinner[i]){
300                 ((SpinnerNumberModel)(lrSpinner[i].getModel())).setMaximum(new Integer(Integer.parseInt(urSpinner[i].getValue().toString())-1));     
301                 ((SpinnerNumberModel)(urSpinner[i].getModel())).setMinimum(new Integer(Integer.parseInt(lrSpinner[i].getValue().toString())+1));     
302             }
303          }
304         
305          //makes sure that every lower value spinner can not exceed the upper value spinner
306          for(int i=0;i< lowerRange.length;i++){
307             if(source == lrSpinner[i]){
308                 ((SpinnerNumberModel)(urSpinner[i].getModel())).setMinimum(new Integer(Integer.parseInt(lrSpinner[i].getValue().toString())+1));     
309                 ((SpinnerNumberModel)(lrSpinner[i].getModel())).setMaximum(new Integer(Integer.parseInt(urSpinner[i].getValue().toString())-1));     
310             }
311          }
312    }
313     
314     /** Makes sure that once a colour is selected via the check box, that appropriate
315      * spinners are displayed to allow the user to set the values
316      * @param e the event
317      */    
318     public void itemStateChanged(ItemEvent e) {
319     
320         Object source = e.getItemSelectable();
321         
322         int row=0;
323         boolean isSelected=false;
324                 
325         for(int i=0;i<checkA.length;i++){
326             if(source == checkA[i]){
327                 isSelected =checkA[i].isSelected();
328                 row=i;
329             }
330         }
331        
332         for(int i=0;i<this.column;i++){
333             containerArray[row][i].setVisible(isSelected);
334         }
335     }
336         
337     /** Sets up the dialog properties. */    
338     private void setupProperties(){
339          //fill checkboxes
340         try{
341             for(int i=0;i<checkA.length;i++){
342                 checkA[i].setSelected(lib.getColorInfo()[i]);
343                 for(int a=0;a<this.column;a++) containerArray[i][a].setVisible(checkA[i].isSelected());
344             }
345 
346             //fill lower range values
347             for(int i=0;i<this.lrSpinner.length;i++){
348                 if(checkA[i].isSelected()) ((SpinnerNumberModel)(lrSpinner[i].getModel())).setValue(new Integer(lib.getLowerRangeInfo()[i]));
349             }
350 
351             //fill upper range values
352             for(int i=0;i<this.urSpinner.length;i++){
353                 if(checkA[i].isSelected()) ((SpinnerNumberModel)(urSpinner[i].getModel())).setValue(new Integer(lib.getUpperRangeInfo()[i]));
354             }
355 
356             //fill lower error values
357             for(int i=0;i<this.leSpinner.length;i++){
358                 if(checkA[i].isSelected()) ((SpinnerNumberModel)(leSpinner[i].getModel())).setValue(new Integer(lib.getLowerErrorInfo()[i]));
359             }
360             //fill upper error values
361             for(int i=0;i<this.ueSpinner.length;i++){
362                 if(checkA[i].isSelected()) ((SpinnerNumberModel)(ueSpinner[i].getModel())).setValue(new Integer(lib.getUpperErrorInfo()[i]));
363             }
364         }
365         catch(Exception e){
366             //do nothing
367         }
368    }
369     
370     /** Initialises the values in each array, from the changes the user made in the
371      * dialog.
372      */    
373     private void initializeArrays(){
374     
375         //fill desired color array
376         for(int i=0;i<desiredColors.length;i++) this.desiredColors[i] =checkA[i].isSelected();
377               
378         //fill lower range array
379         for(int i=0;i<this.lowerRange.length;i++){
380             if(checkA[i].isSelected()) lowerRange[i]= Integer.parseInt(lrSpinner[i].getValue().toString());
381         }
382         
383         //fill upper range array
384         for(int i=0;i<this.upperRange.length;i++){
385             if(checkA[i].isSelected()) upperRange[i]= Integer.parseInt(urSpinner[i].getValue().toString());
386         }
387         //fill lower error array
388         for(int i=0;i<this.lowerError.length;i++){
389             if(checkA[i].isSelected()) lowerError[i]= Integer.parseInt(leSpinner[i].getValue().toString());
390         }
391         //fill upper error array
392         for(int i=0;i<this.upperError.length;i++){
393             if(checkA[i].isSelected()) upperError[i]= Integer.parseInt(ueSpinner[i].getValue().toString());
394         }
395    }
396     
397     /** Shows the dialog to the user. */    
398     public void call(){
399         this.cancel.setEnabled(true);
400         this.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
401         this.show();
402     
403     }
404     
405     /** Saves the current dialog settings to a text file. */    
406     private void saveToTextfile(){ 
407         // create the log file
408         
409         JFileChooser chooser=new JFileChooser(new File(System.getProperties().getProperty("user.dir"),"LightSenesorReadings"));
410                 
411           //set color
412         for(int a=0;a<chooser.getComponentCount();a++){
413             Container a1 =(Container)chooser.getComponent(a);
414                 if(a1 instanceof JTextField ||a1 instanceof JComboBox || a1 instanceof JButton ){
415                     a1.setBackground(Color.darkGray);
416                     a1.setForeground(Color.lightGray);
417                  }
418             for(int b=0;b<((Container)chooser.getComponent(a)).getComponentCount();b++){
419                 Container b1 =(Container)((Container)chooser.getComponent(a)).getComponent(b);
420                 if(b1 instanceof JTextField ||b1 instanceof JComboBox || b1 instanceof JButton ){
421                     b1.setBackground(Color.darkGray);
422                     b1.setForeground(Color.lightGray);
423                 }
424                  for(int c=0;c<((Container)((Container)chooser.getComponent(a)).getComponent(b)).getComponentCount();c++){
425                     Container c1 =(Container)((Container)((Container)chooser.getComponent(a)).getComponent(b)).getComponent(c);
426                     if(c1 instanceof JTextField ||c1 instanceof JComboBox || c1 instanceof JButton ){
427                         c1.setBackground(Color.darkGray);
428                         c1.setForeground(Color.lightGray);
429                      }
430                 }
431             }
432         }
433         
434         String[] extensions={".light"};
435     chooser.addChoosableFileFilter(new FileChooserFilter(extensions,"LightSensor Reading Files"));
436         int returnValue=chooser.showSaveDialog(this);
437         
438     if(returnValue==JFileChooser.APPROVE_OPTION)
439     {
440             // save file as
441             try
442             {
443                 FileWriter fw=new FileWriter(chooser.getSelectedFile().getPath()+".light");
444         for(int i=0; i<this.checkA.length;i++){
445                     if(checkA[i].isSelected()){
446                         fw.write(checkA[i].isSelected()+" "+i+" ");
447                         fw.write(lrSpinner[i].getValue().toString()+ " ");
448                         fw.write(urSpinner[i].getValue().toString()+ " ");
449                         fw.write(leSpinner[i].getValue().toString()+ " ");
450                         fw.write(ueSpinner[i].getValue().toString()+ " ");
451                     }
452                     else{
453                         fw.write(checkA[i].isSelected()+" "+i+" ");
454                     }
455                 }
456         fw.close();
457                 
458             }
459             catch (Exception e)
460             {
461                 MainInterface.displayMessage("Cannot save LightProperties file");
462         Intellego.addToLog("LightSensorPropertiesDialog.saveToTextfile(): Save to file failed: "+e);
463             }
464     }
465     }
466     
467     /** Takes a text file and sets the settings within the dialog to that of the text
468      * file.
469      */    
470     private void openFromTextfile(){ 
471         JFileChooser chooser=new JFileChooser(new File(System.getProperties().getProperty("user.dir"),"LightSenesorReadings"));
472         
473         //set color
474         for(int a=0;a<chooser.getComponentCount();a++){
475             Container a1 =(Container)chooser.getComponent(a);
476                 if(a1 instanceof JTextField ||a1 instanceof JComboBox || a1 instanceof JButton ){
477                     a1.setBackground(Color.darkGray);
478                     a1.setForeground(Color.lightGray);
479                  }
480             for(int b=0;b<((Container)chooser.getComponent(a)).getComponentCount();b++){
481                 Container b1 =(Container)((Container)chooser.getComponent(a)).getComponent(b);
482                 if(b1 instanceof JTextField ||b1 instanceof JComboBox || b1 instanceof JButton ){
483                     b1.setBackground(Color.darkGray);
484                     b1.setForeground(Color.lightGray);
485                 }
486                  for(int c=0;c<((Container)((Container)chooser.getComponent(a)).getComponent(b)).getComponentCount();c++){
487                     Container c1 =(Container)((Container)((Container)chooser.getComponent(a)).getComponent(b)).getComponent(c);
488                     if(c1 instanceof JTextField ||c1 instanceof JComboBox || c1 instanceof JButton ){
489                         c1.setBackground(Color.darkGray);
490                         c1.setForeground(Color.lightGray);
491                      }
492                 }
493             }
494         }
495         // add a filename filter for light files
496     String[] extensions={".light"};
497     chooser.addChoosableFileFilter(new FileChooserFilter(extensions,"LightSensor Reading Files"));
498         chooser.showOpenDialog(this);
499         
500         char[] stringA = new char[220];
501         // open selected file
502         try
503         {
504             FileReader fw=new FileReader(chooser.getSelectedFile());
505             fw.read(stringA); 
506             fw.close();
507         }
508         
509         catch (Exception e)
510         {
511             MainInterface.displayMessage("Cannot open LightProperties file");
512             Intellego.addToLog("LightSensorPropertiesDialog.openFromTextfile(): Opening of file failed: "+e);
513         }
514         
515         String fileData = new String(stringA);
516         fileData = fileData.trim();
517         
518         StringTokenizer breakup = new StringTokenizer(fileData," ");
519         
520         while(breakup.hasMoreTokens()){
521             
522             String data = breakup.nextToken();
523             
524             if(data.equals("true")){
525                 int index = Integer.parseInt(breakup.nextToken());
526                 this.checkA[index].setSelected(true);
527                 ((SpinnerNumberModel)(lrSpinner[index].getModel())).setValue(new Integer(breakup.nextToken()));
528                 ((SpinnerNumberModel)(urSpinner[index].getModel())).setValue(new Integer(breakup.nextToken()));
529                 ((SpinnerNumberModel)(leSpinner[index].getModel())).setValue(new Integer(breakup.nextToken()));
530                 ((SpinnerNumberModel)(ueSpinner[index].getModel())).setValue(new Integer(breakup.nextToken()));
531            }
532            
533             else if(data.equals("false")){
534                 int index = Integer.parseInt(breakup.nextToken());
535                 this.checkA[index].setSelected(false);
536            }
537        }
538    }
539     
540     
541     /**
542     *  Action event handler - sets up color code according to user selection
543     *
544     *  @param e the action event
545     */
546     public void actionPerformed(ActionEvent e)
547     {
548         if (e.getSource()==OK){
549             
550             initializeArrays();
551             if(lib == null){
552                 lib = new LightSensorColorLibrary(this.desiredColors,this.lowerRange,this.upperRange,this.lowerError,this.upperError);
553             }
554             else{
555                 lib.updateDesiredColors(this.desiredColors,this.lowerRange,this.upperRange,this.lowerError,this.upperError);
556             }
557                     
558             this.hide();
559         }
560         
561         else if(e.getSource()==open){
562             openFromTextfile();
563         }
564         else if(e.getSource()==save){
565             saveToTextfile();
566         }
567         
568         else if(e.getSource()==clear){
569             for(int i=0;i<this.checkA.length;i++){
570                 checkA[i].setSelected(false);
571             }
572         }
573         
574         else
575         {
576             this.setupProperties();
577             this.hide();
578         }
579     }
580          
581     public void windowGainedFocus(WindowEvent e) 
582     {
583         OK.requestFocusInWindow(); 
584     }
585     
586     public void windowLostFocus(WindowEvent e){}
587     
588 }