1    import javax.swing.*;
2    import java.awt.event.*;
3    import java.awt.*;
4    import java.util.*;
5    import java.io.*;
6    import java.lang.reflect.*;
7    
8    public abstract class PrefEditor implements Serializable{//extends JPanel {
9    
10     private static final long serialVersionUID = Version.getSUID();
11   
12     public String name = "";
13   
14     public PrefEditor() {
15     }
16   
17     public String toString() {return(name);}
18   
19     transient Container pane = null;
20     transient JScrollPane scroll = null;
21     transient CartoFrame owner = null;
22   
23     transient JDialog dialog=null;
24   
25     public JScrollPane getPane(CartoFrame owner) {
26       if (scroll!=null && pane!=null) return(scroll);
27       
28       getBarePane(owner);
29       scroll = new JScrollPane(pane);
30       return(scroll);
31     }
32   
33     public Container getBarePane(CartoFrame owner) {
34       if (pane!=null) return(pane);
35       this.owner = owner;
36       pane = new JPanel();
37       try {
38         newPane();
39       } catch (NoSuchFieldException e) {
40         ErrorLog.exception(e,"Attempt to set up parameter for nonexisting field");
41         return(null);     //A bad thing happened, don't try to recover.
42       }
43       return(pane);
44     }
45   
46     public void reset() {
47       pane.removeAll();
48       targets = new Vector();
49       fields = new Vector();
50       try {
51         newPane();
52       } catch (NoSuchFieldException e) {
53         ErrorLog.exception(e,"Attempt to set up parameter for nonexisting field");
54       }
55       pane.validate();
56     }
57   
58     public abstract void apply();
59   
60     public abstract void newPane() throws NoSuchFieldException;
61   
62     transient Vector targets = null;
63     transient Vector fields = null;
64   
65     void setup() {
66       if (targets==null) {
67         targets = new Vector();
68         fields = new Vector();
69       }
70     }
71   
72     Component setUnit(String target,Object[] possible,String lab) throws NoSuchFieldException {
73       return(setUnit(pane,getClass().getField(target),possible,lab));
74     }
75   
76     Component setUnit(Container pane,String target,Object[] possible,String lab) throws NoSuchFieldException {
77       return(setUnit(pane,getClass().getField(target),possible,lab));
78     }
79   
80     Component setUnit(Container pane,Field target,Object[] posible,String label) {
81       setup();    
82       try {
83         JComponent field = addUnit(pane,target.get(this),posible,label);
84         field.setAlignmentX(0);
85         targets.add(target);
86         fields.add(field);
87         return(field);
88       } catch (IllegalAccessException e) {ErrorLog.exception(e,"Trouble adding combo parameter (bad!)");}
89       return(null);
90     }
91   
92     Component setParm(String target) throws NoSuchFieldException {
93       return(setParm(pane,target));
94     }
95   
96     Component setParm(Container pane,String target) throws NoSuchFieldException {
97       return(setParm(pane,getClass().getField(target),target));
98     } 
99   
100    Component setParm(String target,String lab) throws NoSuchFieldException {
101      return(setParm(pane,target,lab));
102    }
103  
104    Component setParm(Container pane,String target,String lab) throws NoSuchFieldException {
105  //    System.out.println(""+this+" class = "+getClass()+" field =|"+target+"|");
106      return(setParm(pane,getClass().getField(target),lab));
107    } 
108  
109    Component setParm(Container pane,Field target,String lab) {
110      setup();    
111      try {
112        JComponent field = null;
113        if (target.getType().equals(double.class)) field = addDouble(pane,target.getDouble(this),lab);
114        else if (target.getType().equals(int.class)) field = addInt(pane,target.getInt(this),lab);
115        else if (target.getType().equals(boolean.class)) field = addCheck(pane,target.getBoolean(this),lab);
116        else if (target.getType().equals(Color.class)) field = addColor(pane,(Color)target.get(this),lab);
117        else if (target.getType().equals(String.class)) field = addString(pane,(String)target.get(this),lab);
118  //      System.out.println("field = "+field+" target = "+target+" type = "+target.getType());
119        field.setAlignmentX(0);
120        targets.add(target);
121        fields.add(field);
122        return(field);
123      } catch (IllegalAccessException e) {ErrorLog.exception(e,"Trouble adding parameter (bad!)");}
124      return(null);
125    }
126  
127    JRadioButton setRadio(Container pane,String targetstring,String lab) throws NoSuchFieldException {
128      Field target = getClass().getField(targetstring);
129      setup();    
130      try {
131        JRadioButton field = null;
132        if (target.getType().equals(boolean.class)) field = addRadio(pane,target.getBoolean(this),lab);
133        else ErrorLog.log("setRadio on pref "+this+"with field = "+target+" which is not boolean");
134        field.setAlignmentX(0);
135        targets.add(target);
136        fields.add(field);
137        return(field);
138      } catch (IllegalAccessException e) {ErrorLog.exception(e,"Trouble adding parameter (bad!)");}
139      return(null);
140    }
141  
142    public void save() {
143  //    System.out.println("Saving prefs "+this);
144      for (int i=0;i<targets.size();i++) {
145        Field target = (Field)(targets.elementAt(i));
146        JComponent field = (JComponent)(fields.elementAt(i));
147        try {
148          if (target.getType().equals(double.class))
149            target.setDouble(this,readDouble((JTextField)field));
150          else if (target.getType().equals(int.class))
151            target.setInt(this,readInt((JTextField)field));
152          else if (target.getType().equals(String.class))
153            target.set(this,((JTextField)field).getText());
154          else if (field instanceof ColorBox)
155            target.set(this,((ColorBox)field).color);
156          else if (field instanceof AbstractButton)
157            target.setBoolean(this,((AbstractButton)field).isSelected());
158          else if (field instanceof JComboBox)
159            target.set(this,((JComboBox)field).getSelectedItem());
160          else if (field instanceof JList)
161            target.set(this,((JList)field).getSelectedValue());
162        } catch (IllegalAccessException e) {ErrorLog.exception(e,"Trouble saving parameters (bad!)");
163        } catch (IllegalArgumentException e) {ErrorLog.exception(e,"Trouble saving parameters");}
164      }
165    }
166  
167    public void update() {
168      try {
169        for (int i=0;i<targets.size();i++) {
170          Field target = (Field)(targets.elementAt(i));
171          JComponent field = (JComponent)(fields.elementAt(i));
172          if (target.getType().equals(double.class))
173            ((JTextField)field).setText(""+target.getDouble(this));
174          if (target.getType().equals(String.class))
175            ((JTextField)field).setText(""+target.get(this));
176          else if (target.getType().equals(int.class))
177            ((JTextField)field).setText(""+target.getInt(this));
178          else if (field instanceof AbstractButton)
179            ((AbstractButton)field).setSelected(target.getBoolean(this));
180          else if (field instanceof JComboBox)
181            ((JComboBox)field).setSelectedItem(target.get(this));	  
182          else if (field instanceof JList)
183            ((JList)field).setSelectedValue(target.get(this),true);
184        }
185      } catch (IllegalAccessException e) {ErrorLog.exception(e,"Trouble updating parameters (bad!)");}
186    }
187  
188    public void abandon() {
189  //    if (pane!=null) pane.dispose();
190      scroll=null;
191      pane=null;
192      fields = null;
193      targets = null;
194      owner = null;
195      dialog=null;
196    }
197  
198    JTextField addDouble(double val,String label) {
199      return(addDouble(pane,val,label));
200    }
201  
202    public static JTextField addDouble(Container pane,double val,String label,int width) {
203      Container subpane = pane;
204      if (label!=null) {
205        subpane = new JPanel();
206        ((JPanel)subpane).setAlignmentX(0);
207        JLabel lab = new JLabel(label);
208        lab.setAlignmentX(0);
209        subpane.add(lab);
210      }
211      String text = ""+(float)val;
212      //if (text.length()>15) text = text.substring(0,14);
213      JTextField field = new JTextField(text);
214      field.setAlignmentX(0);
215      field.setColumns(width);
216      subpane.add(field);
217      if (subpane!=pane) pane.add(subpane);
218      return(field);
219    }
220  
221    public static JTextField addDouble(Container pane,double val,String label) {
222      return(addDouble(pane,val,label,12));
223    }
224  
225    public static double readDouble(JTextField field) {
226      try {
227        String str = field.getText();
228        if (Character.toLowerCase(str.charAt(0))=='i') return(Double.POSITIVE_INFINITY);
229        return(Double.parseDouble(str));
230      } catch (NumberFormatException ex) {
231        ErrorLog.exception(ex,"Couldn't parse number");
232      }
233      return(0.0);
234    }
235  
236    public static JTextField addInt(Container pane,int val,String label) {
237      Container subpane = pane;
238      if (label!=null) {
239        subpane = new JPanel();
240        ((JPanel)subpane).setAlignmentX(0);
241        JLabel lab = new JLabel(label);
242        lab.setAlignmentX(0);
243        subpane.add(lab);
244      }
245      JTextField field = new JTextField(""+val);
246      field.setAlignmentX(0);
247      field.setColumns(6);
248      subpane.add(field);
249      if (subpane!=pane) pane.add(subpane);
250      return(field);
251    }
252  
253    JTextField addInt(int val,String label) {
254      return(addInt(pane,val,label));
255    }
256  
257    public static JTextField addString(Container pane,String val,String label) {
258      Container subpane = pane;
259      if (label!=null) {
260        subpane = new JPanel();
261        ((JPanel)subpane).setAlignmentX(0);
262        JLabel lab = new JLabel(label);
263        lab.setAlignmentX(0);
264        subpane.add(lab);
265      }
266      JTextField field = new JTextField(val);
267      field.setAlignmentX(0);
268      field.setColumns(6);
269      subpane.add(field);
270      if (subpane!=pane) pane.add(subpane);
271      return(field);
272    }
273  
274    JTextField addString(String val,String label) {
275      return(addString(pane,val,label));
276    }
277  
278    public static JComboBox addUnit(Container pane,Object val,Object[] posible,String label) {
279      JComboBox res = new JComboBox(posible);
280      res.setAlignmentX(0);
281      res.setEditable(false);
282      res.setSelectedItem(val);
283      addlabeled(pane,res,label);
284      return(res);
285    }
286  
287    JComboBox addUnit(Object val,Object[] posible,String label) {
288      return(addUnit(pane,val,posible,label));
289    }
290  
291    public static int readInt(JTextField field) {
292      try {
293        return(Integer.parseInt(field.getText()));
294      } catch (NumberFormatException ex) {
295        ErrorLog.exception(ex,"Couldn't parse number");
296      }
297      return(0);
298    }
299  
300    public static JCheckBox addCheck(Container pane,boolean val,String label) {
301      JCheckBox field = new JCheckBox(label);
302      field.setSelected(val);
303      field.setAlignmentX(0);
304      pane.add(field);
305      return(field);
306    }
307  
308    JCheckBox addCheck(boolean val,String label) {
309      return(addCheck(pane,val,label));
310    }
311  
312    public static ColorBox addColor(Container pane,Color val,String label) {
313      ColorBox field = new ColorBox(val,label);
314      pane.add(field);
315      return(field);
316    }
317  
318    ColorBox addColor(Color val,String label) {
319      return(addColor(pane,val,label));
320    }
321  
322    public static JRadioButton addRadio(Container pane,boolean val,String label) {
323      JRadioButton field = new JRadioButton(label);
324      field.setSelected(val);
325      field.setAlignmentX(0);
326      pane.add(field);
327      return(field);
328    }
329  
330    JRadioButton addRadio(boolean val,String label) {
331      return(addRadio(pane,val,label));
332    }
333  
334    public static void addlabeled(Container pane,JComponent comp,String label) {
335      Container pan = pane;
336      if (label!=null) {
337        pan = new JPanel();
338        JLabel lab = new JLabel(label);
339        lab.setAlignmentX(0);
340        ((JPanel)pan).setAlignmentX(0);
341        pan.add(lab);
342      }
343      comp.setAlignmentX(0);
344      pan.add(comp);
345      if (pan!=pane) pane.add(pan);
346    }
347  
348    void addlabeled(JComponent comp,String label) {
349      addlabeled(pane,comp,label);
350    }
351  
352    public static void skip(Container pane) {
353      pane.add(new JLabel(""));
354    }
355  
356    void skip() {
357      pane.add(new JLabel(""));
358    }
359  }
360  
361  
362