Main Page | Packages | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

SequenceColumn.java

Go to the documentation of this file.
00001 /*
00002  * SequenceColumn.java
00003  *
00004  * Copyright (C) 2005 Project SQUID, http://www.cs.helsinki.fi/group/squid/
00005  *
00006  * This file is part of Ikayaki.
00007  *
00008  * Ikayaki is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * Ikayaki is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with Ikayaki; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
00021  */
00022 
00023 package ikayaki.gui;
00024 
00025 import ikayaki.MeasurementStep;
00026 import ikayaki.MeasurementValue;
00027 import ikayaki.Project;
00028 import ikayaki.Settings;
00029 
00030 import javax.swing.*;
00031 import javax.swing.border.Border;
00032 import java.awt.*;
00033 import java.text.DecimalFormat;
00034 import java.text.NumberFormat;
00035 import java.text.ParseException;
00036 
00042 public enum SequenceColumn {
00043 
00047     COUNT("#") {
00048         {
00049             toolTipText = "Number of the measurement step";
00050         }
00051 
00052         @Override public StyledWrapper getValue(int rowIndex, Project project) {
00053             StyledWrapper wrapper = headerWrapper;
00054             if (project != null && project.getSteps() > rowIndex) {
00055                 wrapper.value = new Integer(rowIndex + 1);
00056             } else {
00057                 //wrapper.value = ">"; // greater-than sign
00058                 wrapper.value = "\u00BB"; // right-pointing double angle quotation mark
00059                 //wrapper.value = "\u2192"; // rightwards arrow
00060                 //wrapper.value = "\u25BA"; // black right-pointing pointer
00061             }
00062             return wrapper;
00063         }
00064     },
00065 
00069     STEP("Step Value"){
00070         {
00071             // one decimal is the maximum presision for AF
00072             getNumberFormat().setMaximumFractionDigits(1);
00073         }
00074 
00075         // TODO: remove the need for this hack
00086         private void updateNumberFormat(Project project) {
00087             if (project == null) {
00088                 return;
00089             } else if (project.getType() == Project.Type.THELLIER) {
00090                 // with Thellier the decimals are ".00", ".11", ".12", ".13" or ".14"
00091                 getNumberFormat().setMinimumFractionDigits(2);
00092                 getNumberFormat().setMaximumFractionDigits(2);
00093             } else if (project.getType() == Project.Type.THERMAL) {
00094                 // with Thermal the decimals are always ".00"
00095                 getNumberFormat().setMinimumFractionDigits(0);
00096                 getNumberFormat().setMaximumFractionDigits(0);
00097             } else {
00098                 getNumberFormat().setMinimumFractionDigits(0);
00099                 getNumberFormat().setMaximumFractionDigits(1);
00100             }
00101         }
00102 
00103         @Override public StyledWrapper getValue(int rowIndex, Project project) {
00104             updateNumberFormat(project);    // HACK
00105 
00106             if (rowIndex >= project.getSteps()) {
00107                 return wrap(null, rowIndex, project);
00108             }
00109             double value = project.getStep(rowIndex).getStepValue();
00110             if (value < 0.0) {
00111                 return wrap(null, rowIndex, project);
00112             }
00113             return wrap(getNumberFormat().format(value), rowIndex, project);
00114         }
00115 
00116         @Override public void setValue(Object data, int rowIndex, Project project) {
00117             updateNumberFormat(project);    // HACK
00118 
00119             if (project == null) {
00120                 return;
00121             }
00122             if (data != null && !(data instanceof Number)) {
00123                 if (data.toString().equals("")) {
00124                     data = null;
00125                 } else {
00126                     try {
00127                         data = getNumberFormat().parse(data.toString());
00128                     } catch (ParseException e) {
00129 //                        throw new NumberFormatException("For input string: \"" + data.toString() + "\"");
00130                         return;
00131                     }
00132                 }
00133             }
00134             double value = data != null ? ((Number) data).doubleValue() : -1.0;
00135 
00136             if (rowIndex >= project.getSteps()) {
00137                 // add new row
00138                 if (value < 0.0) {
00139                     return;
00140                 }
00141                 MeasurementStep step = new MeasurementStep(project);
00142                 step.setStepValue(value);
00143                 project.addStep(step);
00144             } else {
00145                 // edit an existing row (the editing of completed steps is prevented by isCellEditable)
00146                 project.getStep(rowIndex).setStepValue(value);
00147             }
00148         }
00149 
00150         @Override public boolean isCellEditable(int rowIndex, Project project) {
00151             if (rowIndex >= project.getSteps()) {
00152                 return true;    // the last row
00153             }
00154             if (project.getStep(rowIndex).getState() == MeasurementStep.State.READY) {
00155                 return true;    // uncompleted steps
00156             }
00157             return false;       // completed steps
00158         }
00159 
00160         @Override public String getColumnName(Project project) {
00161             final String AF_COLUMN_NAME = "AF (mT)";
00162             final String TEMP_COLUMN_NAME = "T (\u00b0C)";
00163 
00164             if (project == null) {
00165                 return AF_COLUMN_NAME;
00166             }
00167             String s;
00168             switch (project.getType()) {
00169             case AF:
00170             case CALIBRATION:
00171                 s = AF_COLUMN_NAME;
00172                 break;
00173             case THELLIER:
00174             case THERMAL:
00175                 s = TEMP_COLUMN_NAME;
00176                 break;
00177             default:
00178                 assert false;
00179                 s = "";
00180                 break;
00181             }
00182             return s;
00183         }
00184 
00185         @Override public String getToolTipText(Project project) {
00186             final String AF_TOOL_TIP = "Intensity of the alternating-field demagnetization";
00187             final String TEMP_TOOL_TIP = "Temperature used for demagnetization";
00188 
00189             if (project == null) {
00190                 return AF_TOOL_TIP;
00191             }
00192             String s;
00193             switch (project.getType()) {
00194             case AF:
00195             case CALIBRATION:
00196                 s = AF_TOOL_TIP;
00197                 break;
00198             case THELLIER:
00199             case THERMAL:
00200                 s = TEMP_TOOL_TIP;
00201                 break;
00202             default:
00203                 assert false;
00204                 s = null;
00205                 break;
00206             }
00207             return s;
00208 
00209         }
00210     },
00211 
00215     MASS("Mass"){ // unit is grams
00216         {
00217             // at least 5 decimals
00218             getNumberFormat().setMaximumFractionDigits(6);
00219             toolTipText = "Mass of the sample (grams)";
00220         }
00221 
00222         @Override public StyledWrapper getValue(int rowIndex, Project project) {
00223             if (rowIndex >= project.getSteps()) {
00224                 return wrap(null, rowIndex, project);
00225             }
00226             double value = project.getStep(rowIndex).getMass();
00227             if (value < 0.0) {
00228                 value = project.getMass();
00229             }
00230             if (value < 0.0) {
00231                 return wrap(null, rowIndex, project);
00232             }
00233             return wrap(getNumberFormat().format(value), rowIndex, project);
00234         }
00235 
00236         @Override public void setValue(Object data, int rowIndex, Project project) {
00237             if (project == null) {
00238                 return;
00239             }
00240             if (data != null && !(data instanceof Number)) {
00241                 if (data.toString().equals("")) {
00242                     data = null;
00243                 } else {
00244                     try {
00245                         data = getNumberFormat().parse(data.toString());
00246                     } catch (ParseException e) {
00247 //                        throw new NumberFormatException("For input string: \"" + data.toString() + "\"");
00248                         return;
00249                     }
00250                 }
00251             }
00252             double value = data != null ? ((Number) data).doubleValue() : -1.0;
00253 
00254             if (rowIndex < project.getSteps()) {
00255                 project.getStep(rowIndex).setMass(value);
00256             }
00257         }
00258 
00259         @Override public boolean isCellEditable(int rowIndex, Project project) {
00260             if (rowIndex < project.getSteps()) {
00261                 return true;
00262             }
00263             return false;
00264         }
00265     },
00266 
00270     VOLUME("Volume"){ // unit is cm^3
00271         {
00272             // at least 2 decimals
00273             getNumberFormat().setMaximumFractionDigits(6);
00274             toolTipText = "Volume of the sample (cm\u00B3)";
00275         }
00276 
00277         @Override public StyledWrapper getValue(int rowIndex, Project project) {
00278             if (rowIndex >= project.getSteps()) {
00279                 return wrap(null, rowIndex, project);
00280             }
00281             double value = project.getStep(rowIndex).getVolume();
00282             if (value < 0.0) {
00283                 value = project.getVolume();
00284             }
00285             if (value < 0.0) {
00286                 return wrap(null, rowIndex, project);
00287             }
00288             return wrap(getNumberFormat().format(value), rowIndex, project);
00289         }
00290 
00291         @Override public void setValue(Object data, int rowIndex, Project project) {
00292             if (project == null) {
00293                 return;
00294             }
00295             if (data != null && !(data instanceof Number)) {
00296                 if (data.toString().equals("")) {
00297                     data = null;
00298                 } else {
00299                     try {
00300                         data = getNumberFormat().parse(data.toString());
00301                     } catch (ParseException e) {
00302 //                        throw new NumberFormatException("For input string: \"" + data.toString() + "\"");
00303                         return;
00304                     }
00305                 }
00306             }
00307             double value = data != null ? ((Number) data).doubleValue() : -1.0;
00308 
00309             if (rowIndex < project.getSteps()) {
00310                 project.getStep(rowIndex).setVolume(value);
00311             }
00312         }
00313 
00314         @Override public boolean isCellEditable(int rowIndex, Project project) {
00315             if (rowIndex < project.getSteps()) {
00316                 return true;
00317             }
00318             return false;
00319         }
00320     },
00321 
00325     SUSCEPTIBILITY("Susceptibility"){ // unit is 10^-6 SI
00326         {
00327             // usually no decimals are needed
00328             getNumberFormat().setMaximumFractionDigits(6);
00329             toolTipText = "Susceptibility of the sample (10^-6 SI)";
00330         }
00331 
00332         @Override public StyledWrapper getValue(int rowIndex, Project project) {
00333             if (rowIndex >= project.getSteps()) {
00334                 return wrap(null, rowIndex, project);
00335             }
00336             double value = project.getStep(rowIndex).getSusceptibility();
00337             if (value < 0.0) {
00338                 value = project.getSusceptibility();
00339             }
00340             if (value < 0.0) {
00341                 return wrap(null, rowIndex, project);
00342             }
00343             return wrap(getNumberFormat().format(value), rowIndex, project);
00344         }
00345 
00346         @Override public void setValue(Object data, int rowIndex, Project project) {
00347             if (project == null) {
00348                 return;
00349             }
00350             if (data != null && !(data instanceof Number)) {
00351                 if (data.toString().equals("")) {
00352                     data = null;
00353                 } else {
00354                     try {
00355                         data = getNumberFormat().parse(data.toString());
00356                     } catch (ParseException e) {
00357 //                        throw new NumberFormatException("For input string: \"" + data.toString() + "\"");
00358                         return;
00359                     }
00360                 }
00361             }
00362             double value = data != null ? ((Number) data).doubleValue() : -1.0;
00363 
00364             if (rowIndex < project.getSteps()) {
00365                 project.getStep(rowIndex).setSusceptibility(value);
00366             }
00367         }
00368 
00369         @Override public boolean isCellEditable(int rowIndex, Project project) {
00370             if (rowIndex < project.getSteps()) {
00371                 return true;
00372             }
00373             return false;
00374         }
00375     },
00376 
00377     /*
00378      * Showing the values calculated by MeasurementValue.
00379      */
00380     GEOGRAPHIC_X(MeasurementValue.GEOGRAPHIC_X) {
00381         {
00382             setNumberFormat(new DecimalFormat("0.000E0"));  // TODO: maybe make a new class that could show the format: 1.123e+05
00383         }
00384     },
00385     GEOGRAPHIC_Y(MeasurementValue.GEOGRAPHIC_Y) {
00386         {
00387             setNumberFormat(new DecimalFormat("0.000E0"));
00388         }
00389     },
00390     GEOGRAPHIC_Z(MeasurementValue.GEOGRAPHIC_Z) {
00391         {
00392             setNumberFormat(new DecimalFormat("0.000E0"));
00393         }
00394     },
00395     SAMPLE_X(MeasurementValue.SAMPLE_X) {
00396         {
00397             setNumberFormat(new DecimalFormat("0.000E0"));
00398         }
00399     },
00400     SAMPLE_Y(MeasurementValue.SAMPLE_Y) {
00401         {
00402             setNumberFormat(new DecimalFormat("0.000E0"));
00403         }
00404     },
00405     SAMPLE_Z(MeasurementValue.SAMPLE_Z) {
00406         {
00407             setNumberFormat(new DecimalFormat("0.000E0"));
00408         }
00409     },
00410     GEOGRAPHIC_X_NORMALIZED(MeasurementValue.GEOGRAPHIC_X_NORMALIZED) {
00411         {
00412             setNumberFormat(new DecimalFormat("0.000E0"));
00413         }
00414     },
00415     GEOGRAPHIC_Y_NORMALIZED(MeasurementValue.GEOGRAPHIC_Y_NORMALIZED) {
00416         {
00417             setNumberFormat(new DecimalFormat("0.000E0"));
00418         }
00419     },
00420     GEOGRAPHIC_Z_NORMALIZED(MeasurementValue.GEOGRAPHIC_Z_NORMALIZED) {
00421         {
00422             setNumberFormat(new DecimalFormat("0.000E0"));
00423         }
00424     },
00425     SAMPLE_X_NORMALIZED(MeasurementValue.SAMPLE_X_NORMALIZED) {
00426         {
00427             setNumberFormat(new DecimalFormat("0.000E0"));
00428         }
00429     },
00430     SAMPLE_Y_NORMALIZED(MeasurementValue.SAMPLE_Y_NORMALIZED) {
00431         {
00432             setNumberFormat(new DecimalFormat("0.000E0"));
00433         }
00434     },
00435     SAMPLE_Z_NORMALIZED(MeasurementValue.SAMPLE_Z_NORMALIZED) {
00436         {
00437             setNumberFormat(new DecimalFormat("0.000E0"));
00438         }
00439     },
00440     DECLINATION(MeasurementValue.DECLINATION) {
00441         {
00442             // 2 decimals is good, or maybe just one
00443             getNumberFormat().setMinimumFractionDigits(1);
00444             getNumberFormat().setMaximumFractionDigits(1);
00445         }
00446     },
00447     INCLINATION(MeasurementValue.INCLINATION) {
00448         {
00449             // 2 decimals is good, or maybe just one
00450             getNumberFormat().setMinimumFractionDigits(1);
00451             getNumberFormat().setMaximumFractionDigits(1);
00452         }
00453     },
00454     MOMENT(MeasurementValue.MOMENT) {
00455         {
00456             setNumberFormat(new DecimalFormat("0.000E0"));
00457         }
00458     },
00459     MAGNETIZATION(MeasurementValue.MAGNETIZATION) {
00460         {
00461             setNumberFormat(new DecimalFormat("0.000E0"));
00462         }
00463     },
00464     RELATIVE_MAGNETIZATION(MeasurementValue.RELATIVE_MAGNETIZATION) {
00465         {
00466             getNumberFormat().setMinimumFractionDigits(3);
00467             getNumberFormat().setMaximumFractionDigits(3);
00468         }
00469     },
00470     THETA63(MeasurementValue.THETA63) {
00471         {
00472             // one decimal should be enough
00473             getNumberFormat().setMinimumFractionDigits(1);
00474             getNumberFormat().setMaximumFractionDigits(1);
00475         }
00476     };
00477 
00482     public static SequenceColumn[] getAllColumns() {
00483         return new SequenceColumn[]{
00484             COUNT,
00485             STEP,
00486             VOLUME,
00487             MASS,
00488             SUSCEPTIBILITY,
00489             DECLINATION,
00490             INCLINATION,
00491             MAGNETIZATION,
00492             RELATIVE_MAGNETIZATION,
00493             THETA63,
00494             GEOGRAPHIC_X_NORMALIZED,
00495             GEOGRAPHIC_Y_NORMALIZED,
00496             GEOGRAPHIC_Z_NORMALIZED,
00497             SAMPLE_X_NORMALIZED,
00498             SAMPLE_Y_NORMALIZED,
00499             SAMPLE_Z_NORMALIZED,
00500             MOMENT,
00501             GEOGRAPHIC_X,
00502             GEOGRAPHIC_Y,
00503             GEOGRAPHIC_Z,
00504             SAMPLE_X,
00505             SAMPLE_Y,
00506             SAMPLE_Z,
00507         };
00508     }
00509 
00510     /* Styles for the cell renderer */
00511 
00512     private static final StyledWrapper defaultWrapper = Settings.getDefaultWrapperInstance();
00513     private static final StyledWrapper measuringWrapper = Settings.getMeasuringWrapperInstance();
00514     private static final StyledWrapper doneRecentlyWrapper = Settings.getDoneRecentlyWrapperInstance();
00515     private static final StyledWrapper headerWrapper = new StyledWrapper();
00516     private static final Border editableCellBorder =
00517             BorderFactory.createMatteBorder(1, 1, 1, 1, new Color(0xEEEEFF));
00518     private static final Border editableCellFocusBorder =
00519             BorderFactory.createMatteBorder(1, 1, 1, 1, new Color(0x9999CC));
00520 
00521     static {
00522         // align all fields to right
00523         defaultWrapper.horizontalAlignment = SwingConstants.TRAILING;
00524         measuringWrapper.horizontalAlignment = SwingConstants.TRAILING;
00525         doneRecentlyWrapper.horizontalAlignment = SwingConstants.TRAILING;
00526         headerWrapper.horizontalAlignment = SwingConstants.TRAILING;
00527 
00528         // styles for the COUNT column
00529         Color headerBackground = new Color(0xE1E1E1);
00530         Border headerBorder = BorderFactory.createEmptyBorder(1, 2, 1, 2);
00531         headerWrapper.opaque = true;
00532         headerWrapper.background = headerBackground;
00533         headerWrapper.selectedBackground = headerBackground;
00534         headerWrapper.focusBackground = headerBackground;
00535         headerWrapper.selectedFocusBackground = headerBackground;
00536         headerWrapper.border = headerBorder;
00537         headerWrapper.selectedBorder = headerBorder;
00538         headerWrapper.focusBorder = headerBorder;
00539         headerWrapper.selectedFocusBorder = headerBorder;
00540     }
00541 
00542     /* Begin class SequenceColumn */
00543 
00544     protected String columnName;
00545 
00546     protected String toolTipText;
00547 
00548     protected MeasurementValue value;
00549 
00550     protected NumberFormat numberFormat;
00551 
00552     private SequenceColumn(String columnName) {
00553         this.columnName = columnName;
00554         this.toolTipText = null;
00555         this.value = null;
00556         this.numberFormat = NumberFormat.getNumberInstance();
00557         this.numberFormat.setGroupingUsed(false);
00558     }
00559 
00560     private SequenceColumn(MeasurementValue value) {
00561         this.columnName = null;
00562         this.toolTipText = null;
00563         this.value = value;
00564         this.numberFormat = NumberFormat.getNumberInstance();
00565         this.numberFormat.setGroupingUsed(false);
00566     }
00567 
00576     public StyledWrapper wrap(Object value, int rowIndex, Project project) {
00577 
00578         // choose the style according to the state of the step
00579         StyledWrapper wrapper;
00580         if (project == null || rowIndex >= project.getSteps()) {
00581             wrapper = defaultWrapper;
00582         } else {
00583             switch (project.getStep(rowIndex).getState()) {
00584             case READY:
00585             case DONE:
00586                 wrapper = defaultWrapper;
00587                 break;
00588             case MEASURING:
00589                 wrapper = measuringWrapper;
00590                 break;
00591             case DONE_RECENTLY:
00592                 wrapper = doneRecentlyWrapper;
00593                 break;
00594             default:
00595                 assert false;
00596                 wrapper = null;
00597                 break;
00598             }
00599         }
00600 
00601         // visible border for editable cells
00602         if (isCellEditable(rowIndex, project)) {
00603             wrapper.border = editableCellBorder;
00604             wrapper.selectedBorder = editableCellBorder;
00605             wrapper.focusBorder = editableCellFocusBorder;
00606             wrapper.selectedFocusBorder = editableCellFocusBorder;
00607         } else {
00608             wrapper.border = null;
00609             wrapper.selectedBorder = null;
00610             wrapper.focusBorder = null;
00611             wrapper.selectedFocusBorder = null;
00612         }
00613 
00614         // wrap the cell's value and return it
00615         wrapper.value = value;
00616         return wrapper;
00617     }
00618 
00628     public StyledWrapper getValue(int rowIndex, Project project) {
00629         if (value == null || rowIndex >= project.getSteps()) {
00630             return wrap(null, rowIndex, project);
00631         }
00632         Object obj = project.getValue(rowIndex, value);
00633         if (obj == null || !(obj instanceof Number)) {
00634             return wrap(obj, rowIndex, project);
00635         }
00636 
00637         // format the return value with NumberFormatter
00638         double doubleValue = ((Number) obj).doubleValue();
00639         String formatted = getNumberFormat().format(obj);
00640 
00641         // check for Infinity and NaN
00642         if (formatted.charAt(0) == 65533) { // for some reason "doubleValue == Double.NaN" doesn't work
00643             formatted = "NaN";
00644         } else if (doubleValue == Double.POSITIVE_INFINITY) {
00645             formatted = "\u221e";
00646         } else if (doubleValue == Double.NEGATIVE_INFINITY) {
00647             formatted = "-\u221e";
00648         }
00649         return wrap(formatted, rowIndex, project);
00650     }
00651 
00660     public void setValue(Object data, int rowIndex, Project project) {
00661         // DO NOTHING
00662     }
00663 
00672     public boolean isCellEditable(int rowIndex, Project project) {
00673         return false;
00674     }
00675 
00682     public String getColumnName(Project project) {
00683         if (value == null) {
00684             return columnName;
00685         } else if (value.getUnit(project).equals("")) {
00686             return value.getCaption(project);
00687         } else {
00688             return value.getCaption(project) + " (" + value.getUnit(project) + ")";
00689         }
00690     }
00691 
00699     public String getToolTipText(Project project) {
00700         if (value == null) {
00701             return toolTipText;
00702         } else {
00703             return value.getDescription(project);
00704         }
00705     }
00706 
00711     public Class<?> getColumnClass() {
00712         return StyledWrapper.class;
00713     }
00714 
00718     public NumberFormat getNumberFormat() {
00719         return numberFormat;
00720     }
00721 
00727     public void setNumberFormat(NumberFormat numberFormat) {
00728         if (numberFormat == null) {
00729             throw new NullPointerException();
00730         }
00731         this.numberFormat = numberFormat;
00732     }
00733 }

Generated on Fri May 6 16:00:32 2005 for Squid by  doxygen 1.4.1