Changeset 6466


Ignore:
Timestamp:
06/03/10 15:56:12 (9 years ago)
Author:
curtis
Message:

Fix some problems with the series chooser.
If there are more than 200 series, the thumbnails are not shown.
Works through at least 1000 series, but much beyond that and some systems may
experience display problems. In the future we may want to prompt for a simple
text string listing the enabled series when there are more than 1000 series.

Location:
trunk/components/loci-plugins/src/loci/plugins/in
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/components/loci-plugins/src/loci/plugins/in/MainDialog.java

    r6325 r6466  
    2525 
    2626package loci.plugins.in; 
     27 
     28import com.jgoodies.forms.builder.PanelBuilder; 
     29import com.jgoodies.forms.layout.CellConstraints; 
     30import com.jgoodies.forms.layout.FormLayout; 
    2731 
    2832import ij.gui.GenericDialog; 
     
    4852 
    4953import loci.plugins.util.WindowTools; 
    50  
    51 import com.jgoodies.forms.builder.PanelBuilder; 
    52 import com.jgoodies.forms.layout.CellConstraints; 
    53 import com.jgoodies.forms.layout.FormLayout; 
    5454 
    5555/** 
  • trunk/components/loci-plugins/src/loci/plugins/in/SeriesDialog.java

    r6326 r6466  
    2525 
    2626package loci.plugins.in; 
     27 
     28import com.jgoodies.forms.builder.PanelBuilder; 
     29import com.jgoodies.forms.layout.CellConstraints; 
     30import com.jgoodies.forms.layout.FormLayout; 
    2731 
    2832import ij.gui.GenericDialog; 
     
    4549import javax.swing.ImageIcon; 
    4650import javax.swing.JLabel; 
     51import javax.swing.JPanel; 
    4752 
    4853import loci.formats.FormatException; 
     
    6570 
    6671  public static final int MAX_COMPONENTS = 256; 
     72  public static final int MAX_SERIES_THUMBS = 200; 
    6773 
    6874  // -- Fields -- 
     
    9298 
    9399        // default all series to false 
    94         int seriesCount = process.getSeriesCount(); 
     100        final int seriesCount = process.getSeriesCount(); 
    95101        for (int s=0; s<seriesCount; s++) options.setSeriesOn(s, false); 
    96102 
     
    117123    // call both before and after the dialog here... 
    118124 
     125    final int seriesCount = process.getSeriesCount(); 
     126 
     127    // NB: Load thumbnails only when series count is modest. 
     128    if (seriesCount < MAX_SERIES_THUMBS) { 
     129      // construct thumbnail reader 
     130      thumbReader = new BufferedImageReader(process.getReader()); 
     131 
     132      // set up the thumbnail panels 
     133      p = new Panel[seriesCount]; 
     134      for (int i=0; i<seriesCount; i++) { 
     135        thumbReader.setSeries(i); 
     136        int sx = thumbReader.getThumbSizeX() + 10; // a little extra padding 
     137        int sy = thumbReader.getThumbSizeY(); 
     138        p[i] = new Panel(); 
     139        p[i].add(Box.createRigidArea(new Dimension(sx, sy))); 
     140        if (options.isForceThumbnails()) { 
     141          // load thumbnail immediately 
     142          ThumbLoader.loadThumb(thumbReader, 
     143            i, p[i], options.isQuiet(), options.isAutoscale()); 
     144        } 
     145      } 
     146    } 
     147 
    119148    GenericDialog gd = new GenericDialog("Bio-Formats Series Options"); 
    120149 
    121     // set up the thumbnail panels 
    122     thumbReader = new BufferedImageReader(process.getReader()); 
    123     int seriesCount = thumbReader.getSeriesCount(); 
    124     p = new Panel[seriesCount]; 
    125     for (int i=0; i<seriesCount; i++) { 
    126       thumbReader.setSeries(i); 
    127       int sx = thumbReader.getThumbSizeX() + 10; // a little extra padding 
    128       int sy = thumbReader.getThumbSizeY(); 
    129       p[i] = new Panel(); 
    130       p[i].add(Box.createRigidArea(new Dimension(sx, sy))); 
    131       if (options.isForceThumbnails()) { 
    132         BF.status(options.isQuiet(), 
    133           "Reading thumbnail for series #" + (i + 1)); 
    134         int z = thumbReader.getSizeZ() / 2; 
    135         int t = thumbReader.getSizeT() / 2; 
    136         int ndx = thumbReader.getIndex(z, 0, t); 
    137         try { 
    138           BufferedImage img = thumbReader.openThumbImage(ndx); 
    139           boolean isFloat = thumbReader.getPixelType() != FormatTools.FLOAT; 
    140           if (options.isAutoscale() && isFloat) { 
    141             img = AWTImageTools.autoscale(img); 
    142           } 
    143           ImageIcon icon = new ImageIcon(img); 
    144           p[i].removeAll(); 
    145           p[i].add(new JLabel(icon)); 
    146         } 
    147         catch (FormatException exc) { } 
    148         catch (IOException exc) { } 
    149       } 
    150     } 
    151  
    152     // add the checkboxes 
    153  
    154     // we need to add the checkboxes in groups, to prevent an 
    155     // exception from being thrown if there are more than 512 series 
    156     // see https://skyking.microscopy.wisc.edu/trac/java/ticket/408 and 
    157     // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5107980 
    158  
    159     int nPanels = p.length / MAX_COMPONENTS; 
    160     if (nPanels * MAX_COMPONENTS < p.length) nPanels++; 
    161  
     150    // NB: We need to add the checkboxes in groups, to prevent an 
     151    // exception from being thrown if there are more than 512 series. 
     152    // See also: 
     153    //   https://skyking.microscopy.wisc.edu/trac/java/ticket/408 and 
     154    //   http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=5107980 
     155 
     156    final int nGroups = (seriesCount + MAX_COMPONENTS - 1) / MAX_COMPONENTS; 
    162157    int nextSeries = 0; 
    163     for (int i=0; i<nPanels; i++) { 
    164       int nRows = i == nPanels - 1 ? p.length % MAX_COMPONENTS : MAX_COMPONENTS; 
    165       String[] labels = new String[nRows]; 
    166       boolean[] defaultValues = new boolean[nRows]; 
     158    for (int i=0; i<nGroups; i++) { 
     159      final int nRows = Math.min(MAX_COMPONENTS, seriesCount - nextSeries); 
     160      final String[] labels = new String[nRows]; 
     161      final boolean[] defaultValues = new boolean[nRows]; 
    167162      for (int row=0; row<nRows; row++) { 
    168163        labels[row] = process.getSeriesLabel(nextSeries); 
    169         defaultValues[row] = options.isSeriesOn(nextSeries++); 
     164        defaultValues[row] = options.isSeriesOn(nextSeries); 
     165        nextSeries++; 
    170166      } 
    171167      gd.addCheckboxGroup(nRows, 1, labels, defaultValues); 
    172168    } 
    173169 
     170    // extract checkboxes, for "Select All" and "Deselect All" functions 
    174171    boxes = WindowTools.getCheckboxes(gd).toArray(new Checkbox[0]); 
    175172 
    176     // remove components and re-add everything so that the thumbnails and 
    177     // checkboxes line up correctly 
    178  
    179     rebuildDialog(gd, nPanels); 
     173    // rebuild dialog so that the thumbnails and checkboxes line up correctly 
     174    rebuildDialog(gd); 
    180175 
    181176    return gd; 
     
    185180  protected boolean displayDialog(GenericDialog gd) { 
    186181    ThumbLoader loader = null; 
    187     if (!options.isForceThumbnails()) { 
     182    if (thumbReader != null && !options.isForceThumbnails()) { 
    188183      // spawn background thumbnail loader 
    189184      loader = new ThumbLoader(thumbReader, p, gd, options.isAutoscale()); 
     
    196191  @Override 
    197192  protected boolean harvestResults(GenericDialog gd) { 
     193    final int seriesCount = process.getSeriesCount(); 
    198194    String seriesString = "["; 
    199     int seriesCount = process.getSeriesCount(); 
    200195    for (int i=0; i<seriesCount; i++) { 
    201196      boolean on = gd.getNextBoolean(); 
     
    232227  } 
    233228 
    234   private void rebuildDialog(GenericDialog gd, int nPanels) { 
    235     int seriesCount = process.getSeriesCount(); 
     229  private void rebuildDialog(GenericDialog gd) { 
     230    // rebuild dialog using FormLayout to organize things more nicely 
     231 
     232    final String cols = p == null ? "pref" : "pref, 3dlu, pref"; 
     233 
     234    final StringBuilder sb = new StringBuilder("pref"); 
     235    for (int s=1; s<boxes.length; s++) sb.append(", 3dlu, pref"); 
     236    final String rows = sb.toString(); 
     237 
     238    final PanelBuilder builder = new PanelBuilder(new FormLayout(cols, rows)); 
     239    final CellConstraints cc = new CellConstraints(); 
     240 
     241    int row = 1; 
     242    for (int s=0; s<boxes.length; s++) { 
     243      builder.add(boxes[s], cc.xy(1, row)); 
     244      if (p != null) builder.add(p[s], cc.xy(3, row)); 
     245      row += 2; 
     246    } 
     247 
     248    final JPanel masterPanel = builder.getPanel(); 
    236249 
    237250    gd.removeAll(); 
    238  
    239     Panel masterPanel = new Panel(); 
    240     masterPanel.setLayout(new GridLayout(seriesCount, 2)); 
    241  
    242     for (int i=0; i<seriesCount; i++) { 
    243       masterPanel.add(boxes[i]); 
    244       masterPanel.add(p[i]); 
    245     } 
    246251 
    247252    GridBagLayout gdl = (GridBagLayout) gd.getLayout(); 
     
    250255    gbc.gridy = 0; 
    251256    gdl.setConstraints(masterPanel, gbc); 
     257 
    252258    gd.add(masterPanel); 
    253259 
     
    269275 
    270276    gbc.gridx = 2; 
    271     gbc.gridy = nPanels; 
     277    gbc.gridy = 2; 
    272278    gbc.anchor = GridBagConstraints.EAST; 
    273279    gbc.insets = new Insets(15, 0, 0, 0); 
  • trunk/components/loci-plugins/src/loci/plugins/in/ThumbLoader.java

    r6278 r6466  
    4141import loci.formats.gui.BufferedImageReader; 
    4242import loci.plugins.BF; 
     43import loci.plugins.util.WindowTools; 
    4344 
    4445/** 
     
    100101  /** Does the work of loading the thumbnails. */ 
    101102  public void run() { 
     103    BF.status(false, "Gathering series information"); 
     104    int seriesCount = ir.getSeriesCount(); 
     105 
     106    // find image plane for each series and sort by size 
     107    SeriesInfo[] info = new SeriesInfo[seriesCount]; 
     108    for (int i=0; i<seriesCount; i++) { 
     109      if (stop) return; 
     110      ir.setSeries(i); 
     111      info[i] = new SeriesInfo(i, ir.getSizeX() * ir.getSizeY()); 
     112    } 
     113    if (stop) return; 
     114    Arrays.sort(info); 
     115 
     116    // open each thumbnail, fastest/smallest first 
     117    for (int i=0; i<seriesCount; i++) { 
     118      if (stop) return; 
     119      final int ii = info[i].index; 
     120      loadThumb(ir, ii, p[ii], false, scale); 
     121      if (dialog != null) dialog.validate(); 
     122    } 
     123  } 
     124 
     125  // -- Helper methods -- 
     126 
     127  public static void loadThumb(BufferedImageReader thumbReader, 
     128    int series, Panel panel, boolean quiet, boolean autoscale) 
     129  { 
     130    BF.status(quiet, "Reading thumbnail for series #" + (series + 1)); 
     131    thumbReader.setSeries(series); 
     132    // open middle image thumbnail 
     133    int z = thumbReader.getSizeZ() / 2; 
     134    int t = thumbReader.getSizeT() / 2; 
     135    int ndx = thumbReader.getIndex(z, 0, t); 
     136    Exception exc = null; 
    102137    try { 
    103       BF.status(false, "Gathering series information"); 
    104       int seriesCount = ir.getSeriesCount(); 
    105  
    106       // find image plane for each series and sort by size 
    107       SeriesInfo[] info = new SeriesInfo[seriesCount]; 
    108       for (int i=0; i<seriesCount; i++) { 
    109         if (stop) return; 
    110         ir.setSeries(i); 
    111         info[i] = new SeriesInfo(i, ir.getSizeX() * ir.getSizeY()); 
    112       } 
    113       if (stop) return; 
    114       Arrays.sort(info); 
    115  
    116       // open each thumbnail, fastest/smallest first 
    117       for (int i=0; i<seriesCount; i++) { 
    118         if (stop) return; 
    119         final int ii = info[i].index; 
    120         BF.status(false, "Reading thumbnail for series #" + (ii + 1)); 
    121         ir.setSeries(ii); 
    122         // open middle image thumbnail 
    123         int z = ir.getSizeZ() / 2; 
    124         int t = ir.getSizeT() / 2; 
    125         int ndx = ir.getIndex(z, 0, t); 
    126         BufferedImage thumb = ir.openThumbImage(ndx); 
    127         if (scale && ir.getPixelType() != FormatTools.FLOAT) { 
    128           thumb = AWTImageTools.autoscale(thumb); 
    129         } 
    130         ImageIcon icon = new ImageIcon(thumb); 
    131         p[ii].removeAll(); 
    132         p[ii].add(new JLabel(icon)); 
    133         if (dialog != null) dialog.validate(); 
    134       } 
     138      BufferedImage thumb = thumbReader.openThumbImage(ndx); 
     139      boolean notFloat = thumbReader.getPixelType() != FormatTools.FLOAT; 
     140      if (autoscale && notFloat) thumb = AWTImageTools.autoscale(thumb); 
     141      ImageIcon icon = new ImageIcon(thumb); 
     142      panel.removeAll(); 
     143      panel.add(new JLabel(icon)); 
    135144    } 
    136     catch (IOException exc) { 
    137       exc.printStackTrace(); 
    138     } 
    139     catch (FormatException exc) { 
    140       exc.printStackTrace(); 
     145    catch (FormatException e) { exc = e; } 
     146    catch (IOException e) { exc = e; } 
     147    if (exc != null) { 
     148      WindowTools.reportException(exc, quiet, 
     149        "Error loading thumbnail for series #" + (series + 1)); 
    141150    } 
    142151  } 
Note: See TracChangeset for help on using the changeset viewer.