Changeset 1873


Ignore:
Timestamp:
11/29/06 13:43:48 (13 years ago)
Author:
curtis
Message:

Fix for sporadic Vector and JList ArrayIndexOutOfBoundsExceptions.

Location:
trunk/loci/visbio/overlays
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/loci/visbio/overlays/OverlayTransform.java

    r1390 r1873  
    134134    int ndx = MathUtil.positionToRaster(lengths, pos); 
    135135    if (ndx < 0 || ndx >= overlays.length) return; 
    136     overlays[ndx].add(obj); 
     136    synchronized (overlays) { 
     137      overlays[ndx].add(obj); 
     138    } 
    137139    if (ObjectUtil.arraysEqual(pos, this.pos)) controls.refreshListObjects(); 
    138140    notifyListeners(new TransformEvent(this)); 
     
    146148    int ndx = MathUtil.positionToRaster(lengths, pos); 
    147149    if (ndx < 0 || ndx >= overlays.length) return; 
    148     overlays[ndx].remove(obj); 
     150    synchronized (overlays) { 
     151      overlays[ndx].remove(obj); 
     152    } 
    149153    if (ObjectUtil.arraysEqual(pos, this.pos)) controls.refreshListObjects(); 
    150154    notifyListeners(new TransformEvent(this)); 
     
    160164    boolean anyRemoved = false; 
    161165    int i = 0; 
    162     while (i < overlays[ndx].size()) { 
    163       OverlayObject obj = (OverlayObject) overlays[ndx].elementAt(i); 
    164       if (obj.isSelected()) { 
    165         overlays[ndx].removeElementAt(i); 
    166         anyRemoved = true; 
    167       } 
    168       else i++; 
     166    synchronized (overlays) { 
     167      while (i < overlays[ndx].size()) { 
     168        OverlayObject obj = (OverlayObject) overlays[ndx].elementAt(i); 
     169        if (obj.isSelected()) { 
     170          overlays[ndx].removeElementAt(i); 
     171          anyRemoved = true; 
     172        } 
     173        else i++; 
     174      } 
    169175    } 
    170176    if (anyRemoved) { 
     
    187193    int ndx = MathUtil.positionToRaster(lengths, pos); 
    188194    if (ndx < 0 || ndx >= overlays.length) return; 
    189     clipboard.removeAllElements(); 
    190     clipboardPos = pos; 
    191     for (int i=0; i<overlays[ndx].size(); i++) { 
    192       OverlayObject obj = (OverlayObject) overlays[ndx].elementAt(i); 
    193       if (obj.isSelected()) clipboard.add(obj); 
    194     } 
    195     controls.refreshPasteComponent(!clipboard.isEmpty()); 
     195    synchronized (overlays) { 
     196      clipboard.removeAllElements(); 
     197      clipboardPos = pos; 
     198      for (int i=0; i<overlays[ndx].size(); i++) { 
     199        OverlayObject obj = (OverlayObject) overlays[ndx].elementAt(i); 
     200        if (obj.isSelected()) clipboard.add(obj); 
     201      } 
     202      controls.refreshPasteComponent(!clipboard.isEmpty()); 
     203    } 
    196204  } 
    197205 
     
    201209  /** Pastes copied objects at the given dimensional position. */ 
    202210  public void pasteObjects(int[] pos) { 
    203     if (clipboard.isEmpty()) return; 
    204211    int ndx = MathUtil.positionToRaster(lengths, pos); 
    205212    if (ndx < 0 || ndx >= overlays.length) return; 
    206     for (int i=0; i<clipboard.size(); i++) { 
    207       OverlayObject orig = (OverlayObject) clipboard.elementAt(i); 
    208       OverlayObject obj = 
    209         OverlayIO.createOverlay(orig.getClass().getName(), this); 
    210       obj.x1 = orig.x1; 
    211       obj.y1 = orig.y1; 
    212       obj.x2 = orig.x2; 
    213       obj.y2 = orig.y2; 
    214       obj.text = orig.text; 
    215       obj.color = orig.color; 
    216       obj.filled = orig.filled; 
    217       obj.group = orig.group; 
    218       obj.notes = orig.notes; 
    219       obj.drawing = false; 
    220       obj.selected = true; 
    221       obj.computeGridParameters(); 
    222       overlays[ndx].add(obj); 
     213    synchronized (overlays) { 
     214      if (clipboard.isEmpty()) return; 
     215      for (int i=0; i<clipboard.size(); i++) { 
     216        OverlayObject orig = (OverlayObject) clipboard.elementAt(i); 
     217        OverlayObject obj = 
     218          OverlayIO.createOverlay(orig.getClass().getName(), this); 
     219        obj.x1 = orig.x1; 
     220        obj.y1 = orig.y1; 
     221        obj.x2 = orig.x2; 
     222        obj.y2 = orig.y2; 
     223        obj.text = orig.text; 
     224        obj.color = orig.color; 
     225        obj.filled = orig.filled; 
     226        obj.group = orig.group; 
     227        obj.notes = orig.notes; 
     228        obj.drawing = false; 
     229        obj.selected = true; 
     230        obj.computeGridParameters(); 
     231        overlays[ndx].add(obj); 
     232      } 
    223233    } 
    224234    controls.refreshListObjects(); 
     
    252262    } 
    253263 
    254     // grab overlay from the clipboard 
    255     int size = clipboard.size(); 
    256     if (size == 0) { 
    257       return "You must first copy an overlay to the clipboard."; 
    258     } 
    259     else if (size > 1) { 
    260       return "There must not be multiple overlays on the clipboard."; 
    261     } 
    262     OverlayObject clip = (OverlayObject) clipboard.firstElement(); 
    263  
    264     // grab currently selected overlay 
    265     OverlayObject sel = null; 
    266     for (int i=0; i<overlays[ndx].size(); i++) { 
    267       OverlayObject obj = (OverlayObject) overlays[ndx].elementAt(i); 
    268       if (obj.isSelected()) { 
    269         if (sel != null) { 
    270           return "There must not be multiple overlays selected."; 
     264    synchronized (overlays) { 
     265      // grab overlay from the clipboard 
     266      int size = clipboard.size(); 
     267      if (size == 0) { 
     268        return "You must first copy an overlay to the clipboard."; 
     269      } 
     270      else if (size > 1) { 
     271        return "There must not be multiple overlays on the clipboard."; 
     272      } 
     273      OverlayObject clip = (OverlayObject) clipboard.firstElement(); 
     274 
     275      // grab currently selected overlay 
     276      OverlayObject sel = null; 
     277      for (int i=0; i<overlays[ndx].size(); i++) { 
     278        OverlayObject obj = (OverlayObject) overlays[ndx].elementAt(i); 
     279        if (obj.isSelected()) { 
     280          if (sel != null) { 
     281            return "There must not be multiple overlays selected."; 
     282          } 
     283          sel = obj; 
    271284        } 
    272         sel = obj; 
    273       } 
    274     } 
    275     if (sel == null) return "There must be an overlay selected."; 
    276  
    277     // ensure matching types 
    278     if (!clip.getClass().equals(sel.getClass())) { 
    279       return "The overlay on the clipboard must " + 
    280         "be the same kind as the selected overlay."; 
    281     } 
    282  
    283     // check dimensional positions 
    284     if (pos.length != clipboardPos.length) return "Incompatible overlays."; 
    285     int diffIndex = -1; 
    286     for (int i=0; i<pos.length; i++) { 
    287       if (pos[i] != clipboardPos[i]) { 
    288         if (diffIndex != -1) { 
    289           return "Dimensional positions of copied overlay and selected " + 
    290             "overlay must not vary across multiple axes."; 
     285      } 
     286      if (sel == null) return "There must be an overlay selected."; 
     287 
     288      // ensure matching types 
     289      if (!clip.getClass().equals(sel.getClass())) { 
     290        return "The overlay on the clipboard must " + 
     291          "be the same kind as the selected overlay."; 
     292      } 
     293 
     294      // check dimensional positions 
     295      if (pos.length != clipboardPos.length) return "Incompatible overlays."; 
     296      int diffIndex = -1; 
     297      for (int i=0; i<pos.length; i++) { 
     298        if (pos[i] != clipboardPos[i]) { 
     299          if (diffIndex != -1) { 
     300            return "Dimensional positions of copied overlay and selected " + 
     301              "overlay must not vary across multiple axes."; 
     302          } 
     303          diffIndex = i; 
    291304        } 
    292         diffIndex = i; 
    293       } 
    294     } 
    295     if (diffIndex == -1) { 
    296       return "Nothing to distribute -- copied overlay and selected overlay " + 
    297         "have identical dimensional positions."; 
    298     } 
    299     int distance = pos[diffIndex] - clipboardPos[diffIndex]; 
    300     boolean reverse = distance < 0; 
    301     if (reverse) distance = -distance; 
    302     if (distance < 2) { 
    303       return "Nothing to distribute -- there are no frames between copied " + 
    304         "overlay and selected overlay."; 
    305     } 
    306  
    307     // compile some information about the overlays 
    308     String className = sel.getClass().getName(); 
    309     boolean filled = clip.filled && sel.filled; 
    310     String group = ObjectUtil.objectsEqual(clip.group, sel.group) ? 
    311       clip.group : null; 
    312     String notes = ObjectUtil.objectsEqual(clip.notes, sel.notes) ? 
    313       clip.notes : null; 
    314  
    315     // loop through intermediate dimensional positions 
    316     int inc = reverse ? 1 : -1; 
    317     int[] p = new int[pos.length]; 
    318     System.arraycopy(pos, 0, p, 0, pos.length); 
    319     for (int i=1; i<distance; i++) { 
    320       p[diffIndex] = pos[diffIndex] + i * inc; 
    321       ndx = MathUtil.positionToRaster(lengths, p); 
    322  
    323       OverlayObject obj = OverlayIO.createOverlay(className, this); 
    324  
    325       float q = (float) i / distance; 
    326       obj.x1 = q * clip.x1 + (1 - q) * sel.x1; 
    327       obj.y1 = q * clip.y1 + (1 - q) * sel.y1; 
    328       obj.x2 = q * clip.x2 + (1 - q) * sel.x2; 
    329       obj.y2 = q * clip.y2 + (1 - q) * sel.y2; 
    330       obj.color = new Color( 
    331         (int) (q * clip.color.getRed() + (1 - q) * sel.color.getRed()), 
    332         (int) (q * clip.color.getGreen() + (1 - q) * sel.color.getGreen()), 
    333         (int) (q * clip.color.getBlue() + (1 - q) * sel.color.getBlue())); 
    334       obj.filled = filled; 
    335       obj.group = group; 
    336       obj.notes = notes; 
    337       obj.drawing = false; 
    338       obj.selected = false; 
    339       obj.computeGridParameters(); 
    340  
    341       overlays[ndx].add(obj); 
     305      } 
     306      if (diffIndex == -1) { 
     307        return "Nothing to distribute -- copied overlay and selected overlay " + 
     308          "have identical dimensional positions."; 
     309      } 
     310      int distance = pos[diffIndex] - clipboardPos[diffIndex]; 
     311      boolean reverse = distance < 0; 
     312      if (reverse) distance = -distance; 
     313      if (distance < 2) { 
     314        return "Nothing to distribute -- there are no frames between copied " + 
     315          "overlay and selected overlay."; 
     316      } 
     317 
     318      // compile some information about the overlays 
     319      String className = sel.getClass().getName(); 
     320      boolean filled = clip.filled && sel.filled; 
     321      String group = ObjectUtil.objectsEqual(clip.group, sel.group) ? 
     322        clip.group : null; 
     323      String notes = ObjectUtil.objectsEqual(clip.notes, sel.notes) ? 
     324        clip.notes : null; 
     325 
     326      // loop through intermediate dimensional positions 
     327      int inc = reverse ? 1 : -1; 
     328      int[] p = new int[pos.length]; 
     329      System.arraycopy(pos, 0, p, 0, pos.length); 
     330      for (int i=1; i<distance; i++) { 
     331        p[diffIndex] = pos[diffIndex] + i * inc; 
     332        ndx = MathUtil.positionToRaster(lengths, p); 
     333 
     334        OverlayObject obj = OverlayIO.createOverlay(className, this); 
     335 
     336        float q = (float) i / distance; 
     337        obj.x1 = q * clip.x1 + (1 - q) * sel.x1; 
     338        obj.y1 = q * clip.y1 + (1 - q) * sel.y1; 
     339        obj.x2 = q * clip.x2 + (1 - q) * sel.x2; 
     340        obj.y2 = q * clip.y2 + (1 - q) * sel.y2; 
     341        obj.color = new Color( 
     342          (int) (q * clip.color.getRed() + (1 - q) * sel.color.getRed()), 
     343          (int) (q * clip.color.getGreen() + (1 - q) * sel.color.getGreen()), 
     344          (int) (q * clip.color.getBlue() + (1 - q) * sel.color.getBlue())); 
     345        obj.filled = filled; 
     346        obj.group = group; 
     347        obj.notes = notes; 
     348        obj.drawing = false; 
     349        obj.selected = false; 
     350        obj.computeGridParameters(); 
     351 
     352        overlays[ndx].add(obj); 
     353      } 
    342354    } 
    343355 
     
    494506      return null; 
    495507    } 
    496  
    497508    int q = MathUtil.positionToRaster(lengths, pos); 
    498509    if (q < 0 || q >= overlays.length) return null; 
    499     int size = overlays[q].size(); 
    500     FieldImpl rgbField = null, txtField = null; 
    501     try { 
    502       if (size > 0) { 
    503         // compute number of selected objects and number of text objects 
    504         int rgbSize = 0, txtSize = 0, sel = 0, outline = 0; 
    505         for (int i=0; i<size; i++) { 
    506           OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
    507           if (obj.hasText()) { 
    508             if (drawText || obj.isSelected()) txtSize++; 
    509             else outline++; 
     510    synchronized (overlays) { 
     511      int size = overlays[q].size(); 
     512      FieldImpl rgbField = null, txtField = null; 
     513      try { 
     514        if (size > 0) { 
     515          // compute number of selected objects and number of text objects 
     516          int rgbSize = 0, txtSize = 0, sel = 0, outline = 0; 
     517          for (int i=0; i<size; i++) { 
     518            OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
     519            if (obj.hasText()) { 
     520              if (drawText || obj.isSelected()) txtSize++; 
     521              else outline++; 
     522            } 
     523            else rgbSize++; 
     524            // do not paint grids for objects still in the initial draw phase 
     525            if (obj.isSelected() && !obj.isDrawing()) sel++; 
    510526          } 
    511           else rgbSize++; 
    512           // do not paint grids for objects still in the initial draw phase 
    513           if (obj.isSelected() && !obj.isDrawing()) sel++; 
    514         } 
    515         RealType index = RealType.getRealType("overlay_index"); 
    516  
    517         // compile standard objects into RGB field 
    518         if (rgbSize > 0 || sel > 0 || outline > 0) { 
    519           FunctionType fieldType = new FunctionType(index, 
    520             new FunctionType(getDomainType(), getRangeType())); 
    521           GriddedSet fieldSet = new Integer1DSet(rgbSize + sel + outline); 
    522           rgbField = new FieldImpl(fieldType, fieldSet); 
    523           // compute overlay data for each non-text object 
    524           for (int i=0, c=0; i<size && c<rgbSize; i++) { 
    525             OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
    526             if (obj.hasText()) continue; 
    527             rgbField.setSample(c++, obj.getData(), false); 
     527          RealType index = RealType.getRealType("overlay_index"); 
     528 
     529          // compile standard objects into RGB field 
     530          if (rgbSize > 0 || sel > 0 || outline > 0) { 
     531            FunctionType fieldType = new FunctionType(index, 
     532              new FunctionType(getDomainType(), getRangeType())); 
     533            GriddedSet fieldSet = new Integer1DSet(rgbSize + sel + outline); 
     534            rgbField = new FieldImpl(fieldType, fieldSet); 
     535            // compute overlay data for each non-text object 
     536            for (int i=0, c=0; i<size && c<rgbSize; i++) { 
     537              OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
     538              if (obj.hasText()) continue; 
     539              rgbField.setSample(c++, obj.getData(), false); 
     540            } 
     541            // compute selection grid for each selected object 
     542            for (int i=0, c=0; i<size && c<sel; i++) { 
     543              OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
     544              if (!obj.isSelected() || obj.isDrawing()) continue; 
     545              rgbField.setSample(rgbSize + c++, obj.getSelectionGrid(), false); 
     546            } 
     547            // compute outline grid for each invisible text object 
     548            for (int i=0, c=0; i<size && c<outline; i++) { 
     549              OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
     550              if (!obj.hasText() || obj.isSelected()) continue; 
     551              rgbField.setSample(rgbSize + sel + c++, 
     552                obj.getSelectionGrid(true), false); 
     553            } 
    528554          } 
    529           // compute selection grid for each selected object 
    530           for (int i=0, c=0; i<size && c<sel; i++) { 
    531             OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
    532             if (!obj.isSelected() || obj.isDrawing()) continue; 
    533             rgbField.setSample(rgbSize + c++, obj.getSelectionGrid(), false); 
    534           } 
    535           // compute outline grid for each invisible text object 
    536           for (int i=0, c=0; i<size && c<outline; i++) { 
    537             OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
    538             if (!obj.hasText() || obj.isSelected()) continue; 
    539             rgbField.setSample(rgbSize + sel + c++, 
    540               obj.getSelectionGrid(true), false); 
     555 
     556          // compile text objects into text field 
     557          if (txtSize > 0) { 
     558            FunctionType fieldType = new FunctionType(index, 
     559              new FunctionType(getDomainType(), getTextRangeType())); 
     560            GriddedSet fieldSet = new Integer1DSet(txtSize); 
     561            txtField = new FieldImpl(fieldType, fieldSet); 
     562            // compute overlay data for each text object 
     563            int c = 0; 
     564            for (int i=0; i<size && c<txtSize; i++) { 
     565              OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
     566              if (!obj.hasText() || !drawText) continue; 
     567              txtField.setSample(c++, obj.getData(), false); 
     568            } 
    541569          } 
    542570        } 
    543  
    544         // compile text objects into text field 
    545         if (txtSize > 0) { 
    546           FunctionType fieldType = new FunctionType(index, 
    547             new FunctionType(getDomainType(), getTextRangeType())); 
    548           GriddedSet fieldSet = new Integer1DSet(txtSize); 
    549           txtField = new FieldImpl(fieldType, fieldSet); 
    550           // compute overlay data for each text object 
    551           int c = 0; 
    552           for (int i=0; i<size && c<txtSize; i++) { 
    553             OverlayObject obj = (OverlayObject) overlays[q].elementAt(i); 
    554             if (!obj.hasText() || !drawText) continue; 
    555             txtField.setSample(c++, obj.getData(), false); 
    556           } 
    557         } 
    558       } 
    559       if (rgbField == null && txtField == null) return null; 
    560       else if (rgbField == null) return txtField; 
    561       else if (txtField == null) return rgbField; 
    562       else return new Tuple(new Data[] {rgbField, txtField}, false); 
    563     } 
    564     catch (VisADException exc) { exc.printStackTrace(); } 
    565     catch (RemoteException exc) { exc.printStackTrace(); } 
     571        if (rgbField == null && txtField == null) return null; 
     572        else if (rgbField == null) return txtField; 
     573        else if (txtField == null) return rgbField; 
     574        else return new Tuple(new Data[] {rgbField, txtField}, false); 
     575      } 
     576      catch (VisADException exc) { exc.printStackTrace(); } 
     577      catch (RemoteException exc) { exc.printStackTrace(); } 
     578    } 
    566579    return null; 
    567580  } 
  • trunk/loci/visbio/overlays/OverlayWidget.java

    r1846 r1873  
    4040import loci.visbio.data.*; 
    4141import loci.visbio.util.*; 
     42import visad.util.Util; 
    4243 
    4344/** OverlayWidget is a set of GUI controls for an overlay transform. */ 
    4445public class OverlayWidget extends JPanel implements ActionListener, 
    45   DocumentListener, ListSelectionListener, TransformListener 
     46  DocumentListener, ListSelectionListener, Runnable, TransformListener 
    4647{ 
    4748 
     
    438439  /** Updates items on overlay list based on current transform state. */ 
    439440  public void refreshListObjects() { 
    440     OverlayObject[] obj = overlay.getObjects(); 
    441     ignoreEvents = true; 
    442     overlayListModel.clear(); 
    443     if (obj != null) { 
    444       overlayListModel.ensureCapacity(obj.length); 
    445       for (int i=0; i<obj.length; i++) overlayListModel.addElement(obj[i]); 
    446     } 
    447     ignoreEvents = false; 
    448     refreshListSelection(); 
     441    Util.invoke(false, this); 
    449442  } 
    450443 
     
    766759  } 
    767760 
     761  // -- Runnable API methods -- 
     762 
     763  /** Refreshes the list selection. */ 
     764  public void run() { 
     765    OverlayObject[] obj = overlay.getObjects(); 
     766    ignoreEvents = true; 
     767    overlayListModel.clear(); 
     768    if (obj != null) { 
     769      overlayListModel.ensureCapacity(obj.length); 
     770      for (int i=0; i<obj.length; i++) overlayListModel.addElement(obj[i]); 
     771    } 
     772    ignoreEvents = false; 
     773    refreshListSelection(); 
     774  } 
     775 
    768776  // -- TransformListener API methods -- 
    769777 
Note: See TracChangeset for help on using the changeset viewer.