Changeset 7838 for trunk/projects


Ignore:
Timestamp:
12/19/11 01:35:32 (8 years ago)
Author:
aivar
Message:

Continued work on histogram, add fields to user interface.

Location:
trunk/projects/slim-plugin/src/main/java
Files:
1 added
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/projects/slim-plugin/src/main/java/imagej/slim/fitting/AbstractBaseFittedImage.java

    r7833 r7838  
    107107     */ 
    108108    public void recalcHistogram() { 
    109         _histogramData.setAuto(true); //TODO KLUDGE!!! NOT HERE!!! WHERE DOES AUTO GET SET? 
    110         double[] minMax = _histogramData.getMinMax(); 
     109        double[] minMaxLUT = _histogramData.recalcHistogram(); 
    111110 
    112         if (null != minMax) { 
     111        if (null != minMaxLUT) { 
    113112            // update palette bounds 
    114             _image.setMinAndMax(minMax[0], minMax[1]); 
    115             System.out.println("min max " + minMax[0] + " " +  minMax[1]); 
     113            _image.setMinAndMax(minMaxLUT[0], minMaxLUT[1]); 
     114            System.out.println("min max " + minMaxLUT[0] + " " +  minMaxLUT[1]); 
    116115        } 
    117116        else System.out.println("min max null"); 
  • trunk/projects/slim-plugin/src/main/java/imagej/slim/histogram/ColorBarPanel.java

    r7825 r7838  
    5959    private int _inset; 
    6060    private Color[] _color; 
    61     float _start; 
    62     float _stop; 
    63     float _startLUT; 
    64     float _stopLUT; 
     61    double _min; 
     62    double _max; 
     63    double _minLUT; 
     64    double _maxLUT; 
    6565 
    6666    /** 
     
    6868     * 
    6969     * @param width 
     70     * @param inset 
    7071     * @param height 
    7172     */ 
    72     public ColorBarPanel(int width, int height, int inset) { 
     73    public ColorBarPanel(int width, int inset, int height) { 
    7374        super(); 
    7475         
    7576        _width = width; 
     77        _inset = inset; 
    7678        _height = height; 
    77         _inset = inset; 
    7879         
    79         setPreferredSize(new Dimension(width, height)); 
     80        setPreferredSize(new Dimension(width + 2 * inset, height)); 
    8081 
    81         _start = _stop = _startLUT = _stopLUT = 0.0f; 
    82         _start  = 0.0f; 
    83         _stop = 100.0f; 
    84         _startLUT = 25.0f; 
    85         _stopLUT = 75.0f; 
     82        _min = _max = _minLUT = _maxLUT = 0.0f; 
    8683    } 
    8784 
     
    10198     * Changes the values and redraws. 
    10299     *  
    103      * @param start 
    104      * @param stop 
    105      * @param startLUT 
    106      * @param stopLUT  
     100     * @param min 
     101     * @param max 
     102     * @param minLUT 
     103     * @param maxLUT 
    107104     */ 
    108     public void setStartStop(float start, float stop, 
    109             float startLUT, float stopLUT) { 
     105    public void setMinMax(double min, double max, double minLUT, double maxLUT) { 
    110106        synchronized (_synchObject) { 
    111             _start = start; 
    112             _stop = stop; 
    113             _startLUT = startLUT; 
    114             _stopLUT = stopLUT; 
     107            _min = min; 
     108            _max = max; 
     109            _minLUT = minLUT; 
     110            _maxLUT = maxLUT; 
     111        } 
     112        repaint(); 
     113    } 
     114 
     115    /** 
     116     * Changes the LUT ranges and redraws. 
     117     *  
     118     * @param minLUT 
     119     * @param maxLUT 
     120     */ 
     121    public void setMinMaxLUT(double minLUT, double maxLUT) { 
     122        synchronized (_synchObject) { 
     123            _minLUT = minLUT; 
     124            _maxLUT = maxLUT; 
    115125        } 
    116126        repaint(); 
     
    122132        if (null != _color) { 
    123133            synchronized (_synchObject) { 
    124                 for (int i = 0; i < _width - 2 * _inset; ++i) { 
    125                     System.out.println("colorize " + i); 
     134                for (int i = 0; i < _width; ++i) { 
    126135                    g.setColor(colorize(i)); 
    127136                    g.drawLine(_inset + i, 0, _inset + i, _height-1); 
     
    134143        byte[] bytes = lut.getBytes(); 
    135144        int numberColors = bytes.length / 3; 
    136         System.out.println("numberColors " + numberColors + " = bytes " + bytes.length + " / 3"); 
    137145        //TODO make sure numberColors is 256! 
    138146        Color[] color = new Color[numberColors]; 
     
    141149            int green = 0xff & (int) bytes[256 + n]; 
    142150            int blue  = 0xff & (int) bytes[512 + n]; 
    143             System.out.println("R " + red + " G " + green + " B " + blue); 
    144151            color[n] = new Color(red, green, blue); 
    145152        } 
    146153        return color; 
    147154    } 
    148      
     155 
    149156    private Color colorize(int i) { 
    150157        Color color = Color.BLACK; 
    151         float value = _start + (_stop - _start) * i / _width; 
    152         if (value >= _startLUT && value <= _stopLUT) { 
    153             int index = (int)((value - _startLUT) 
    154                     * _color.length / (_stopLUT - _startLUT)); 
    155             index = Math.max(index, 0); 
    156             index = Math.min(index, _color.length - 1); 
    157             color = _color[index]; 
     158        // wait till we have initial range 
     159        if (_min < _max) { 
     160            double value = _min + (_max - _min) * i / _width; 
     161            if (value >= _minLUT && value <= _maxLUT) { 
     162                int index = (int)((value - _minLUT) 
     163                        * _color.length / (_maxLUT - _minLUT)); 
     164                index = Math.max(index, 0); 
     165                index = Math.min(index, _color.length - 1); 
     166                color = _color[index]; 
     167            } 
    158168        } 
    159169        return color; 
  • trunk/projects/slim-plugin/src/main/java/imagej/slim/histogram/HistogramData.java

    r7834 r7838  
    1515    private HistogramDataChannel[] _channel; 
    1616    private int _channelIndex; 
    17     private boolean _auto; 
    18     private boolean _combine; 
    19     private boolean _showAll; 
     17    private boolean _autoScale; 
     18    private boolean _combineChannels; 
     19    private boolean _displayChannels; 
    2020    private double _minView; 
    2121    private double _maxView; 
    2222    private double _minLUT; 
    2323    private double _maxLUT; 
     24    private IHistogramDataListener _listener; 
    2425 
    2526    /** 
     
    3132        _title = title; 
    3233        _channel = channel; 
     34        _autoScale = true; 
     35        _combineChannels = true; 
     36        _displayChannels = true; 
    3337        _channelIndex = 0; 
    3438        _minView = _maxView = 0.0f; 
    3539        _minLUT = _maxLUT = 0.0f; 
     40        _listener = null; 
     41    } 
     42 
     43    public void setListener(IHistogramDataListener listener) { 
     44        _listener = listener; 
    3645    } 
    3746     
     
    6473    } 
    6574 
     75    public boolean getDisplayChannels() { 
     76        return _displayChannels; 
     77    } 
     78 
     79    public void setDisplayChannels(boolean displayChannels) { 
     80 
     81    } 
     82 
    6683    /** 
    6784     * Gets whether or not histogram should combine all the channels. 
     
    6986     * @return whether to combine all the channels 
    7087     */ 
    71     public boolean getCombine() { 
    72         return _combine; 
     88    public boolean getCombineChannels() { 
     89        return _combineChannels; 
    7390    } 
    7491 
     
    7693     * Sets whether or not histogram should combine all the channels. 
    7794     *  
    78      * @param combine  
    79      */ 
    80     public void setCombine(boolean combine) { 
    81         _combine = combine; 
     95     * @param combineChannels 
     96     */ 
     97    public void setCombineChannels(boolean combineChannels) { 
     98        _combineChannels = combineChannels; 
    8299    } 
    83100 
     
    87104     * @return whether automatically scales 
    88105     */ 
    89     public boolean getAuto() { 
    90         return _auto; 
     106    public boolean getAutoScale() { 
     107        return _autoScale; 
    91108    } 
    92109     
     
    96113     * @param auto whether automatically scales 
    97114     */ 
    98     public void setAuto(boolean auto) { 
    99         _auto = auto; 
     115    public void setAutoScale(boolean autoScale) { 
     116        _autoScale = autoScale; 
    100117    } 
    101118     
     
    110127 
    111128    /** 
     129     * Sets minimum and maximum extents of the view. 
     130     * 
     131     * @param min 
     132     * @param max 
     133     */ 
     134    public void setMinMaxView(double min, double max) { 
     135        _minView = min; 
     136        _maxView = max; 
     137    } 
     138 
     139    /** 
    112140     * Gets minimum and maximum extents of the LUT. 
    113141     *  
     
    119147 
    120148    /** 
     149     * Sets minimum and maximum extents of the LUT. 
     150     * 
     151     * @param min 
     152     * @param max 
     153     */ 
     154    public void setMinMaxLUT(double min, double max) { 
     155        _minLUT = min; 
     156        _maxLUT = max; 
     157    } 
     158 
     159    /** 
    121160     * Sets the current min and max automatically if need be. 
    122      *  
    123      * @return min and max 
    124      */ 
    125     public double[] getMinMax() { 
    126         double[] minMax = null; 
    127          
    128         if (_auto) { 
    129             if (_combine) { 
    130                 double min = Double.MAX_VALUE; 
    131                 double max = Double.MIN_VALUE; 
     161     * 
     162     * Called periodically during the fit process. 
     163     * 
     164     * Updates listener as a side effect. 
     165     *  
     166     * @return min and max of the LUT 
     167     */ 
     168    public double[] recalcHistogram() { 
     169        double minData; 
     170        double maxData; 
     171        double minDataCurrent; 
     172        double maxDataCurrent; 
     173        double minLUT; 
     174        double maxLUT; 
     175        double minView; 
     176        double maxView; 
     177        double[] minMaxData; 
     178 
     179        minData = maxData = 0.0; 
     180        minDataCurrent = maxDataCurrent = 0.0; 
     181        minLUT = maxLUT = 0.0; 
     182        minView = maxView = 0.0; 
     183        if (_displayChannels || _combineChannels) { 
     184            minData = Double.MAX_VALUE; 
     185            maxData = Double.MIN_VALUE; 
    132186                 
    133                 // calculate actual minimum and maximum for all channels 
    134                 for (int i = 0; i < _channel.length; ++i) { 
    135                     minMax = _channel[i].findMinMax(); 
    136                     if (minMax[0] < min) { 
    137                         min = minMax[0]; 
    138                     } 
    139                     if (minMax[1] > max) { 
    140                         max = minMax[1]; 
    141                     } 
    142                 } 
    143                 minMax = new double[] { min, max };   
     187            // calculate actual minimum and maximum for all channels 
     188            for (int i = 0; i < _channel.length; ++i) { 
     189                minMaxData = _channel[i].findMinMax(); 
     190                if (minMaxData[0] < minData) { 
     191                    minData = minMaxData[0]; 
     192                } 
     193                if (minMaxData[1] > maxData) { 
     194                    maxData = minMaxData[1]; 
     195                } 
     196                if (i == _channelIndex) { 
     197                    minDataCurrent = minMaxData[0]; 
     198                    maxDataCurrent = minMaxData[1]; 
     199                } 
     200            } 
     201        } 
     202        else { 
     203            // calculate actual minimum and maximum for current channel 
     204            minMaxData = _channel[_channelIndex].findMinMax(); 
     205            minData = minDataCurrent = minMaxData[0]; 
     206            maxData = minDataCurrent = minMaxData[1]; 
     207        } 
     208 
     209        if (_autoScale) { 
     210            if (_combineChannels) { 
     211                // LUT and view bounded by data for all channels 
     212                _minLUT = minData; 
     213                _maxLUT = maxData; 
    144214            } 
    145215            else { 
    146                 // calculate actual minimum and maximum for current channel 
    147                 minMax = _channel[_channelIndex].findMinMax(); 
    148             } 
    149             _minView = _minLUT = minMax[0]; 
    150             _maxView = _maxLUT = minMax[1]; //TODO kludgy 
    151         } 
    152         return minMax; //TODO returns null if not automatically ranging 
     216                // LUT is bounded by data for current channel 
     217                _minLUT = minDataCurrent; 
     218                _maxLUT = maxDataCurrent; 
     219            } 
     220        } 
     221 
     222        _minView = minData; 
     223        _maxView = maxData; 
     224 
     225        if (null != _listener) { 
     226            _listener.minMaxChanged(_minView, _maxView, _minLUT, _maxLUT); 
     227        } 
     228 
     229        return new double[] { minLUT, maxLUT }; 
    153230    } 
    154231     
     
    163240        System.out.println("_minLUT is " + _minLUT + " maxLUT " + _maxLUT); 
    164241         
    165         if (_showAll) { 
     242        if (_displayChannels) { 
    166243            // add all channels 
    167244            for (int i = 0; i < _channel.length; ++i) { 
  • trunk/projects/slim-plugin/src/main/java/imagej/slim/histogram/HistogramPanel.java

    r7837 r7838  
    1515 
    1616/** 
     17 * This is a panel that represents a histogram.  Scale is logarithmic.  Cursors 
     18 * can be drawn and manipulated, representing the range of the LUT inside the 
     19 * bounds of the view.  Dragging the cursor off the edge stretches those bounds. 
    1720 * 
    1821 * @author Aivar Grislis 
     
    3740     * 
    3841     * @param width 
     42     * @param inset 
    3943     * @param height 
    4044     */ 
    41     public HistogramPanel(int width, int height, int inset) { 
     45    public HistogramPanel(int width, int inset, int height) { 
    4246        super(); 
    4347         
    4448        _width = width; 
     49        _inset = inset; 
    4550        _height = height; 
    46         _inset = inset; 
    4751        _bins = null; 
    4852         
     
    5155        _draggingMinCursor = _draggingMaxCursor = false; 
    5256         
    53         setPreferredSize(new Dimension(width, height)); 
     57        setPreferredSize(new Dimension(width + 2 * inset, height)); 
    5458        addMouseListener(new MouseListener() { 
     59            @Override 
    5560            public void mousePressed(MouseEvent e) { 
    5661                synchronized (_synchObject) { 
    5762                    if (null != _minCursor && null != _maxCursor) { 
     63                        // start dragging minimum or maximum cursor 
    5864                        if (Math.abs(_minCursor - e.getX()) < FUDGE_FACTOR) { 
    5965                            _draggingMinCursor = true; 
     
    6672            } 
    6773             
     74            @Override 
    6875            public void mouseReleased(MouseEvent e) { 
    6976                boolean changed = false; 
     
    7178                    if (_draggingMinCursor) { 
    7279                        _minCursor = e.getX(); 
     80                        // snap to bounds of inset 
    7381                        if (_minCursor < _inset) { 
    7482                            _minCursor = _inset - 1; 
    7583                        } 
     84                        // don't exceed maxCursor 
    7685                        if (_minCursor >= _maxCursor) { 
    7786                            _minCursor = _maxCursor - 1; 
     
    8291                    else if (_draggingMaxCursor) {  
    8392                        _maxCursor = e.getX(); 
    84                         if (_maxCursor > _width - _inset) { 
    85                             _maxCursor = _width - _inset; 
    86                         } 
     93                        // snap to bounds of inset 
     94                        if (_maxCursor > _inset + _width) { 
     95                            _maxCursor = _inset + _width; 
     96                        } 
     97                        // must be greater than minCursor 
    8798                        if (_maxCursor <= _minCursor) { 
    8899                            _maxCursor = _minCursor + 1; 
     
    103114            } 
    104115             
     116            @Override 
    105117            public void mouseEntered(MouseEvent e) { } 
    106118             
    107             public void mouseExited(MouseEvent e) { } 
    108              
     119            @Override 
     120            public void mouseExited(MouseEvent e) { 
     121                _listener.exited(); 
     122            } 
     123             
     124            @Override 
    109125            public void mouseClicked(MouseEvent e) { } 
    110126             
    111127        }); 
    112128        addMouseMotionListener(new MouseMotionListener() { 
     129            @Override 
    113130            public void mouseMoved(MouseEvent e) { } 
    114131             
     132            @Override 
    115133            public void mouseDragged(MouseEvent e) { 
    116134                boolean changed = false; 
     
    141159                if (changed) { 
    142160                    repaint(); 
    143                      
    144                     boolean expanding = false; 
    145                     if (_minCursor < _inset) { 
    146                         expanding = true; 
    147                     } 
    148                     else if (_maxCursor > _width - _inset) { 
    149                         expanding = true; 
    150                     } 
    151                     if (expanding) { 
    152                         if (null != _listener) { 
    153                             // convert to 0..width - 1 range 
    154                             int min = _minCursor - _inset + 1; 
    155                             int max = _maxCursor - _inset - 1; 
    156                             _listener.setMinMax(min, max); 
    157                         } 
     161 
     162                    if (null != _listener) { 
     163                        // convert to 0..width - 1 range 
     164                        int min = _minCursor - _inset + 1; 
     165                        int max = _maxCursor - _inset - 1; 
     166                        // report dragged cursor position 
     167                        _listener.dragMinMax(min, max); 
    158168                    } 
    159169                }   
     
    172182 
    173183    /** 
    174      * Changes settings and redraws. 
     184     * Changes histogram counts and redraws. 
    175185     *  
    176186     * @param bins  
     
    213223            synchronized (_synchObject) { 
    214224                int height; 
    215                 for (int i = 0; i < _width - 2 * _inset; ++i) { 
     225                for (int i = 0; i < _width; ++i) { 
    216226                    if (0 == _bins[i]) { 
    217227                        height = 0; 
  • trunk/projects/slim-plugin/src/main/java/imagej/slim/histogram/HistogramTool.java

    r7837 r7838  
    3232 
    3333/** 
    34  * This is the main class for this histogram tool.  It handles layout, wiring, 
    35  * and logic. 
     34 * This is the main class for this histogram tool.  It handles layout and wiring 
     35 * of UI components and the logic of updating the histogram. 
    3636 * 
    3737 * @author Aivar Grislis 
    3838 */ 
    3939public class HistogramTool { 
    40     private final static int WIDTH = 264; 
     40    private final static int WIDTH = 256; 
     41    private final static int INSET = 5; 
    4142    private final static int HISTOGRAM_HEIGHT = 140; 
    4243    private final static int COLORBAR_HEIGHT = 20; 
    43     private final static int EXTRA = 4; 
    44     private final static int TASK_PERIOD = 100; 
     44    private final static int TASK_PERIOD = 1000; 
    4545    //TODO kludged in, user s/b able to select LUTS, somewhere else: 
     46    //TODO note that most IJ LUTs are unsuitable here, so having one standard lifetime LUT is not so bad 
    4647    private final static String HARDCODED_LUT =  "/Applications/ImageJ/luts/aivar6.lut"; // aivar6 is my five color blue/cyan/green/yellow/red spectral palette 
    4748    private static HistogramTool INSTANCE = null; 
     49    private final Object _synchObject = new Object(); 
    4850    private HistogramData _histogramData; 
    4951    private JFrame _frame; 
    50     private HistogramPanel _histogram; 
    51     private ColorBarPanel _colorBar; 
     52    private HistogramPanel _histogramPanel; 
     53    private ColorBarPanel _colorBarPanel; 
     54    private UIPanel _uiPanel; 
    5255  
    5356    /** 
     
    5659    private HistogramTool() { 
    5760        // create the histogram and color bar display panels 
    58         _histogram = new HistogramPanel(WIDTH, HISTOGRAM_HEIGHT, EXTRA); 
    59         _histogram.setListener(new HistogramPanelListener()); 
    60         _colorBar = new ColorBarPanel(WIDTH, COLORBAR_HEIGHT, EXTRA); 
    61         _colorBar.setLUT(getLUT()); 
     61        _histogramPanel = new HistogramPanel(WIDTH, INSET, HISTOGRAM_HEIGHT); 
     62        _histogramPanel.setListener(new HistogramPanelListener()); 
     63        _colorBarPanel = new ColorBarPanel(WIDTH, INSET, COLORBAR_HEIGHT); 
     64        _colorBarPanel.setLUT(getLUT()); 
     65        _uiPanel = new UIPanel(); 
    6266 
    6367        _frame = new JFrame("Histogram"); 
    64         //TODO closes the entire plugin: 
    65         //m_frame.setDefaultCloseOperation(m_frame.EXIT_ON_CLOSE); 
    6668        _frame.setResizable(false); 
    6769        _frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); //TODO kind of lame, for now 
    68         _frame.getContentPane().add(_histogram, BorderLayout.NORTH); 
    69         _frame.getContentPane().add(_colorBar, BorderLayout.CENTER); 
    70         //TODO_frame.getContentPane().add(_inputPanel, BorderLayout.SOUTH); 
     70        _frame.getContentPane().add(_histogramPanel, BorderLayout.NORTH); 
     71        _frame.getContentPane().add(_colorBarPanel, BorderLayout.CENTER); 
     72        _frame.getContentPane().add(_uiPanel, BorderLayout.SOUTH); 
    7173        _frame.pack(); 
    7274        _frame.setVisible(true); 
    7375         
    7476       //TODO FOR A TEST: 
    75         _histogram.setCursors(3, 44); 
     77        _histogramPanel.setCursors(3, 44); 
    7678    } 
    7779 
     
    121123    //TODO this method is called from the focus listener only??? 
    122124    //  what about changes during the fit? 
     125    // How is initial histogramData aassigned? 
    123126    public void setHistogramData(HistogramData histogramData) { 
    124         _histogramData = histogramData; 
     127        synchronized (_synchObject) { 
     128            _histogramData = histogramData; 
     129        } 
    125130        if (_frame.isVisible()) { 
    126131            _frame.setVisible(true); 
    127132        } 
    128133        _frame.setTitle(histogramData.getTitle()); 
    129         _histogram.setBins(histogramData.binValues(WIDTH)); 
     134        _histogramPanel.setBins(histogramData.binValues(WIDTH)); 
     135        _histogramData.setListener(new HistogramDataListener()); //TODO a new one? 
     136    } 
     137 
     138    /* 
     139     * Converts histogram onscreen horizontal pixel amounts to image values. 
     140     */ 
     141    private double pixelToValue(int pixel) { 
     142        synchronized (_synchObject) { 
     143            double[] minMaxView = _histogramData.getMinMaxView(); 
     144            double min = minMaxView[0]; 
     145            double max = minMaxView[1]; 
     146            double value = (max - min) / 256; 
     147            return (pixel - INSET) * value; 
     148        } 
     149    } 
     150 
     151    /* 
     152     * Converts image value to histogram onscreen horizontal pixel. 
     153     */ 
     154    private int valueToPixel(double value) { 
     155        synchronized (_synchObject) { 
     156            double[] minMaxView = _histogramData.getMinMaxView(); 
     157            double min = minMaxView[0]; 
     158            double max = minMaxView[1]; 
     159            int pixel = (int)(256 * (value - min) / (max - min)); 
     160            return pixel; 
     161        } 
     162    } 
     163 
     164    /* 
     165     * Updates histogram and color bar during the fit. 
     166     */ 
     167    private void changed(double minView, double maxView, 
     168                double minLUT, double maxLUT) { 
     169        synchronized (_synchObject) { 
     170            int[] bins = _histogramData.binValues(WIDTH); 
     171            _histogramPanel.setBins(bins); 
     172            _colorBarPanel.setMinMax(minView, maxView, minLUT, maxLUT); 
     173        } 
     174    } 
     175 
     176    /** 
     177     * Inner class listens for changes during the fit. 
     178     */ 
     179    private class HistogramDataListener implements IHistogramDataListener { 
     180        public void minMaxChanged(double minView, double maxView, 
     181                double minLUT, double maxLUT) { 
     182            changed(minView, maxView, minLUT, maxLUT); 
     183        } 
    130184    } 
    131185 
     
    135189    private class HistogramPanelListener implements IHistogramPanelListener { 
    136190        private Timer _timer = null; 
     191        private volatile int _dragPixels; 
    137192         
    138         private HistogramPanelListener() { 
    139         } 
     193        private HistogramPanelListener() { } 
    140194  
    141195        /** 
    142196         * Listens to the HistogramPanel, gets minimum and maximum cursor bar 
    143197         * positions in pixels.  Called when the cursor bar is moved and the 
    144          * mouse button released.  Also called during a drag operation when the 
    145          * cursor bar is out of bounds. 
     198         * mouse button released.  A new LUT range has been specified. 
    146199         *  
    147200         * @param min 
     
    149202         */ 
    150203        public void setMinMax(int min, int max) { 
    151             System.out.println("setMinMax(" + min + "," + max + ")"); 
    152             if (min < 0 || max > 255) { 
     204            killTimer(); 
     205 
     206            // get new minimum and maximum values for LUT 
     207            double minLUT = pixelToValue(min); 
     208            double maxLUT = pixelToValue(max); 
     209 
     210            // redraw image and save 
     211            _histogramData.setMinMaxLUT(minLUT, maxLUT); 
     212 
     213            // redraw color bar 
     214            _colorBarPanel.setMinMaxLUT(minLUT, maxLUT); 
     215        } 
     216 
     217        /** 
     218         * Listens to the HistogramPanel, gets minimum and maximum cursor bar 
     219         * positions in pixels.  Called during a drag operation. 
     220         * 
     221         * @param min 
     222         * @param max 
     223         */ 
     224        @Override 
     225        public void dragMinMax(int min, int max) { 
     226            System.out.println("dragMinMax(" + min + "," + max + ")"); 
     227            if (min < 0 || max > 255) { //TODO express  0/255in a variable or constants 
    153228                // cursor is out of bounds, set up a periodic task to stretch 
    154                 // the bounds 
     229                // the bounds, if not already running 
     230                if (min < 0) { 
     231                    _dragPixels = min; 
     232                } 
     233                else { 
     234                    _dragPixels = max - 255; 
     235                } 
    155236                if (null == _timer) { 
    156237                    System.out.println("Schedule"); 
     
    160241            } 
    161242            else { 
    162                 if (null != _timer) { 
    163                     _timer.cancel(); 
    164                     _timer = null; 
     243                // dragging within bounds now, kill the periodic task 
     244                killTimer(); 
     245            } 
     246        } 
     247 
     248        @Override 
     249        public void exited() { 
     250            // dragged off the panel, kill the periodic task 
     251            killTimer(); 
     252        } 
     253 
     254        // stop our timer for animating view expansion 
     255        private void killTimer() { 
     256            if (null != _timer) { 
     257                _timer.cancel(); 
     258                _timer = null; 
     259            } 
     260        } 
     261 
     262        /** 
     263         * Inner class used to animate view expansion, triggered by the initial 
     264         * report of a mouse drag event off the edge of the histogram. 
     265         */ 
     266        private class PeriodicTask extends TimerTask { 
     267 
     268            @Override 
     269            public void run() { 
     270                // how much are we dragging, converted to our value 
     271                double value = pixelToValue(_dragPixels); 
     272                System.out.println("value " + value + " dp " + _dragPixels); 
     273                synchronized (_synchObject) { 
     274                    // get current LUT bounds 
     275                    double[] minMaxLUT = _histogramData.getMinMaxLUT(); 
     276                    double minLUT = minMaxLUT[0]; 
     277                    double maxLUT = minMaxLUT[1]; 
     278 
     279                    // adjust the appropriate left or right side of the view 
     280                    double[] minMaxView = _histogramData.getMinMaxView(); 
     281                    double minView = minMaxView[0]; 
     282                    double maxView = minMaxView[1]; 
     283                    if (value < 0) { 
     284                        minView += value; 
     285                        minLUT = minView; 
     286                    } 
     287                    else { 
     288                        maxView += value; 
     289                        maxLUT = maxView; 
     290                    } 
     291 
     292                    // get updated histogram data & show it 
     293                    _histogramData.setMinMaxView(minView, maxView); 
     294                    int[] bins = _histogramData.binValues(256); 
     295                    _histogramPanel.setBins(bins); 
     296                    _colorBarPanel.setMinMax(minView, maxView, minLUT, maxLUT); 
     297                    System.out.println("set to " + minView + " " + maxView); 
     298                 //   _colorBarPanel. update color bar also 
    165299                } 
    166300            } 
    167301        } 
    168          
    169         public void expand() { } 
    170          
    171         private class PeriodicTask extends TimerTask { 
    172             public void run() { 
    173                 System.out.println("timer task"); 
    174             }    
    175         } 
    176302    } 
    177303} 
  • trunk/projects/slim-plugin/src/main/java/imagej/slim/histogram/IHistogramPanelListener.java

    r7837 r7838  
    1313 */ 
    1414public interface IHistogramPanelListener { 
    15     public enum Direction { LEFT, RIGHT }; 
    1615     
    1716    /** 
     
    2322     */ 
    2423    public void setMinMax(int min, int max); 
    25      
    26     public void expand(); //TODO direction 
     24 
     25    /** 
     26     * Called during a mouse drag.  Values in pixels. 
     27     * 
     28     * @param min 
     29     * @param max 
     30     */ 
     31    public void dragMinMax(int min, int max); 
     32 
     33    /** 
     34     * Mouse has exited the HistogramPanel. 
     35     */ 
     36    public void exited(); 
    2737} 
  • trunk/projects/slim-plugin/src/main/java/imagej/slim/histogram/UIPanel.java

    r7825 r7838  
    55package imagej.slim.histogram; 
    66 
     7import java.awt.event.ActionEvent; 
     8import java.awt.event.ActionListener; 
     9import java.awt.event.ItemEvent; 
     10import java.awt.event.ItemListener; 
     11 
     12import javax.swing.BoxLayout; 
     13import javax.swing.JCheckBox; 
     14import javax.swing.JComponent; 
     15import javax.swing.JFrame; 
     16import javax.swing.JLabel; 
     17import javax.swing.JPanel; 
     18import javax.swing.JFormattedTextField; 
     19import javax.swing.JTextField; 
     20 
    721/** 
    822 * 
    923 * @author aivar 
    1024 */ 
    11 public class UIPanel { 
    12      
     25public class UIPanel extends JPanel { 
     26    JCheckBox m_autoCheckBox; 
     27    JTextField m_startTextField; 
     28    JTextField m_stopTextField; 
     29    boolean m_auto; 
     30    double m_start; 
     31    double m_stop; 
     32    double m_min; 
     33    double m_max; 
     34 
     35    /** 
     36     * Constructor.  Passed in an initial state and a state change //TODO this doc. et. al. outdated 
     37     * listener. 
     38     * 
     39     * @param auto 
     40     * @param start 
     41     * @param stop 
     42     */ 
     43    UIPanel() { 
     44        super(); 
     45        //m_listener = listener; 
     46 
     47        m_auto = true; 
     48        m_start = m_stop = m_min = m_max = 0.0; 
     49 
     50        setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 
     51 
     52        m_autoCheckBox = new JCheckBox("Auto", m_auto); 
     53        m_autoCheckBox.addItemListener( 
     54            new ItemListener() { 
     55                public void itemStateChanged(ItemEvent e) { 
     56                    m_auto = m_autoCheckBox.isSelected(); 
     57                    if (m_auto) { 
     58                        m_start = m_min; 
     59                        m_startTextField.setText("" + m_start); 
     60 
     61                        m_stop = m_max; 
     62                        m_stopTextField.setText("" + m_stop); 
     63                    } 
     64                    enableAppropriately(); 
     65                 //   m_listener.setRange(m_auto, m_start, m_stop, m_min, m_max); 
     66                } 
     67            } 
     68        ); 
     69        add(m_autoCheckBox); 
     70 
     71        m_startTextField = new JTextField(); 
     72        m_startTextField.setText("" + m_start); 
     73        m_startTextField.addActionListener( 
     74            new ActionListener() { 
     75                public void actionPerformed(ActionEvent e) { 
     76                    m_start = Double.parseDouble(m_startTextField.getText()); 
     77                //    m_listener.setRange(m_auto, m_start, m_stop, m_min, m_max); 
     78                } 
     79            } 
     80        ); 
     81        add(m_startTextField); 
     82 
     83        m_stopTextField = new JTextField(); 
     84        m_startTextField.setText("" + m_stop); 
     85        m_stopTextField.addActionListener( 
     86            new ActionListener() { 
     87                public void actionPerformed(ActionEvent e) { 
     88                    m_stop = Double.parseDouble(m_stopTextField.getText()); 
     89                 //   m_listener.setRange(m_auto, m_start, m_stop, m_min, m_max); 
     90                } 
     91            } 
     92        ); 
     93        add(m_stopTextField); 
     94 
     95        enableAppropriately(); 
     96    } 
     97 
     98    /** 
     99     * IColorizeRangeListener method.  Gets external changes to settings. 
     100     * 
     101     * @param auto 
     102     * @param start 
     103     * @param stop 
     104     * @param min 
     105     * @param max 
     106     */ 
     107    public void setRange(boolean auto, double start, double stop, double min, double max) { 
     108        if (auto != m_auto) { 
     109            m_auto = auto; 
     110            m_autoCheckBox.setSelected(auto); 
     111            enableAppropriately(); 
     112        } 
     113 
     114        if (start != m_start) { 
     115            m_start = start; 
     116            m_startTextField.setText("" + start); 
     117        } 
     118 
     119        if (stop != m_stop) { 
     120            m_stop = stop; 
     121            m_stopTextField.setText("" + stop); 
     122        } 
     123        m_min = min; 
     124        m_max = max; 
     125    } 
     126 
     127    /** 
     128     * Enable/disable start/stop text fields. 
     129     */ 
     130    private void enableAppropriately() { 
     131        m_startTextField.setEnabled(!m_auto); 
     132        m_stopTextField.setEnabled(!m_auto); 
     133    } 
    13134} 
  • trunk/projects/slim-plugin/src/main/java/loci/slim/ui/IUserInterfacePanel.java

    r7804 r7838  
    5959    } 
    6060 
     61    public static enum NoiseModel { 
     62        POISSON 
     63    } 
     64 
    6165 
    6266    /** 
     
    97101     */ 
    98102    public FitFunction getFunction(); 
     103 
     104    /** 
     105     * Gets noise model for fit. 
     106     * 
     107     * @return 
     108     */ 
     109    public NoiseModel getNoiseModel(); 
     110 
     111    /** 
     112     * Returns list of fitted images to display. 
     113     * 
     114     * @return 
     115     */ 
     116    public String[] getImages(); 
    99117 
    100118    /** 
     
    164182    public String getBinning(); 
    165183 
     184    public double getChiSquareTarget(); 
     185 
    166186    /** 
    167187     * Gets pixel x. 
  • trunk/projects/slim-plugin/src/main/java/loci/slim/ui/UserInterfacePanel.java

    r7837 r7838  
    102102    private static final String STRETCHED_EXPONENTIAL = "Stretched Exponential"; 
    103103 
     104    private static final String GAUSSIAN = "Gaussian"; 
     105    private static final String POISSON = "Poisson"; 
     106    private static final String MAXIMUM_LIKELIHOOD = "Maximum Likelihood"; 
     107 
     108    private static final String A_T_Z_X2 = "A " + TAU + " Z " + CHI + SQUARE; 
     109    private static final String A_T_X2 = "A " + TAU + " " + CHI +  SQUARE; 
     110    private static final String A_T = "A " + TAU; 
     111    private static final String T_X2 = TAU + " " + CHI + SQUARE; 
     112    private static final String T = TAU + ""; 
     113    private static final String F_UPPER = "F"; 
     114    private static final String F_LOWER = "f"; 
     115 
     116    private static final String CHI_SQ_TARGET = "" + CHI + SQUARE + " Target"; 
     117 
    104118    private static final String EXCITATION_NONE = "None"; 
    105119    private static final String EXCITATION_FILE = "Load from File"; 
     
    115129    private static final String ALGORITHM_ITEMS[] = { JAOLHO_LMA_ALGORITHM, GRAY_RLD_ALGORITHM, GRAY_LMA_ALGORITHM, SLIM_CURVE_RLD_ALGORITHM, SLIM_CURVE_LMA_ALGORITHM, SLIM_CURVE_RLD_LMA_ALGORITHM }; 
    116130    private static final String FUNCTION_ITEMS[] = { SINGLE_EXPONENTIAL, DOUBLE_EXPONENTIAL, TRIPLE_EXPONENTIAL, STRETCHED_EXPONENTIAL }; 
     131    private static final String NOISE_MODEL_ITEMS[] = { GAUSSIAN, POISSON, MAXIMUM_LIKELIHOOD }; 
     132    private static final String FITTED_IMAGE_ITEMS[] = { A_T_Z_X2, A_T_X2, A_T, T_X2, T, F_UPPER, F_LOWER }; 
    117133 
    118134    private static final String EXCITATION_ITEMS[] = { EXCITATION_NONE, EXCITATION_FILE, EXCITATION_CREATE }; 
     
    130146    JComboBox m_algorithmComboBox; 
    131147    JComboBox m_functionComboBox; 
     148    JComboBox m_noiseModelComboBox; 
     149    JComboBox m_fittedImagesComboBox; 
    132150    JCheckBox[] m_analysisCheckBoxList; 
    133151    JCheckBox m_fitAllChannels; 
     
    139157    JTextField m_stopField; 
    140158    JTextField m_thresholdField; 
     159    JTextField m_chiSqTargetField; 
    141160    JComboBox m_binningComboBox; 
    142161    JComboBox m_excitationComboBox; 
     
    343362        fitPanel.add(m_functionComboBox); 
    344363 
     364        JLabel noiseModelLabel = new JLabel("Noise Model"); 
     365        noiseModelLabel.setHorizontalAlignment(SwingConstants.RIGHT); 
     366        fitPanel.add(noiseModelLabel); 
     367        m_noiseModelComboBox = new JComboBox(NOISE_MODEL_ITEMS); 
     368        fitPanel.add(m_noiseModelComboBox); 
     369 
     370        JLabel fittedImagesLabel = new JLabel("Fitted Images"); 
     371        fittedImagesLabel.setHorizontalAlignment(SwingConstants.RIGHT); 
     372        fitPanel.add(fittedImagesLabel); 
     373        m_fittedImagesComboBox = new JComboBox(FITTED_IMAGE_ITEMS); 
     374        fitPanel.add(m_fittedImagesComboBox); 
     375 
    345376        int choices = analysisChoices.length; 
    346377        if (choices > 0) { 
     
    361392         
    362393        // rows, cols, initX, initY, xPad, yPad 
    363         SpringUtilities.makeCompactGrid(fitPanel, 3 + choices, 2, 4, 4, 4, 4); 
     394        SpringUtilities.makeCompactGrid(fitPanel, 5 + choices, 2, 4, 4, 4, 4); 
    364395 
    365396        JPanel panel = new JPanel(new BorderLayout()); 
     
    410441        m_thresholdField = new JTextField(9); 
    411442        controlPanel.add(m_thresholdField); 
     443 
     444        JLabel chiSqTargetLabel = new JLabel(CHI_SQ_TARGET); 
     445        chiSqTargetLabel.setHorizontalAlignment(SwingConstants.RIGHT); 
     446        controlPanel.add(chiSqTargetLabel); 
     447        m_chiSqTargetField = new JTextField(9); 
     448        controlPanel.add(m_chiSqTargetField); 
    412449 
    413450        JLabel binningLabel = new JLabel("Bin"); 
     
    456493 
    457494        // rows, cols, initX, initY, xPad, yPad 
    458         SpringUtilities.makeCompactGrid(controlPanel, 7, 2, 4, 4, 4, 4); 
     495        SpringUtilities.makeCompactGrid(controlPanel, 8, 2, 4, 4, 4, 4); 
    459496 
    460497        JPanel panel = new JPanel(new BorderLayout()); 
     
    9741011    } 
    9751012 
     1013    /** 
     1014     * Get noise model for fit. 
     1015     * 
     1016     * @return 
     1017     */ 
     1018    public NoiseModel getNoiseModel() { 
     1019        return NoiseModel.POISSON; 
     1020    } 
     1021 
     1022    /** 
     1023     * Returns list of fitted images to display. 
     1024     * 
     1025     * @return 
     1026     */ 
     1027    public String[] getImages() { 
     1028        return new String[0]; 
     1029    } 
     1030 
    9761031    public boolean getFitAllChannels() { 
    9771032        return m_fitAllChannels.isSelected(); 
     
    10271082        String selected = (String) m_binningComboBox.getSelectedItem(); 
    10281083        return selected; 
     1084    } 
     1085 
     1086    public double getChiSquareTarget() { 
     1087        return 1.0; 
    10291088    } 
    10301089 
Note: See TracChangeset for help on using the changeset viewer.